gcc cannot find function in lib - c

I am trying to make a C program using libmbus, which I have installed on my raspberry pi. In my /usr/lib directory I have the file libmbus.so and in my /usr/include directory I have the the file ./mbus/mbus.h.
The program looks like this:
#include <stdio.h>
#include <mbus/mbus.h>
int main(void)
{
mbus_handle* MbusHandle;
MbusHandle = mbus_connect_serial("/dev/ttyS1");
return 0;
}
When I try to run "gcc main.cpp -lmbus" I get:
main.cpp:(.text+0xe): undefined reference to `mbus_connect_serial(char const*)'
I tried to run
nm -D /usr/lib/libmbus.so
which among others gives
00009930 T mbus_connect_serial
So it appears that the function mbus_connect_serial is part of libmbus.so.
In the header file the function mbus_connect_serial is defined like this:
mbus_handle * mbus_connect_serial(const char * device);
I can't seem to figure out what is wrong. Can anyone guide me in the right direction?

If you're really trying to create a c program, rename main.cpp to main.c

Related

undefined reference to `__imp_CreateSolidBrush'

Trying to use CreateSolidBrush to change a window background color.
I've included wingdi.h, I believe I've linked gdi32.lib ( however I converted gdi32.lib to a gdi32.a by using LIB2A, and I wonder if this may be an issue? ).
I wouldn't mind using another function but I worry this could be come a re-occuring issue if I'm not able to find a solution.
Some relevant code:
#include <stdio.h>
#include <windows.h>
#include <wingdi.h>
#include <main.h>
DWORD CreateMainWindow(void)
{
.............
WNDCLASSEXA WindowClass = { 0 };
WindowClass.hbrBackground = CreateSolidBrush(RGB(200, 200, 200));
.............
}
I use a function to easily compile
int Compile()
{
................
int result = 0;
char *include = "C:\\Users\\Coding\\C\\src\\include";
char *link = "C:\\Users\\Coding\\C\\src\\lib";
char command[256];
if(snprintf(
command,
sizeof(command),
"gcc -o main -I%s -l gdi32 -L%s main.c", include, link) >= sizeof(command))
{
//exception catching and handling
}
else
{
system(command);
}
return result;
}
I have no reason to believe the file isn't being linked as I'm not receiving an error.
Also I'm only using Notepad++, mingw64, and command prompt.
The error is a linker error, because it can't find the shared library symbol CreateSolidBrush.
All that is needed is linker flag -lgdi32, so it links with MinGW's libgdi32.a.
Don't try to generate this file by converting it from some other file you found which is probably built with a totally different compiler. If you already experimented with that make sure to clean up any lingering gdi32 .a or .lib files from your previous attempts.
Well the answer was extremely simple, linkages and includes must come after the file.
C:\User> gcc main.c -lgdi32 -I<include path> -o main
If this was obvious then I apologize, hopefully this helps another confused individual

Linking files / header files in C

I have 2 c files (& their header files). I have included the function "put" in the corresponding header, but I still have the following errors, when I input "gcc -o main main.c" in the terminal.
main.c:(.text+0x389): undefined reference to `put' collect2: error: ld
returned 1 exit status
may I know the reason? How should I modify my code?
I tried to change the linking order in makefile but failed. Any advice is appreciated, thanks!
CMakeLists.txt
cmake_minimum_required(VERSION 3.19)
project(Demo)
set(CMAKE_CXX_STANDARD 14)
include_directories(.)
add_executable(Demo
main.c main.h KeyValueStore.c KeyValueStore.h )
main.c
#include "main.h"
...
int main() {
...
if (strcmp("PUT", tokens[0]) == 0) {
put(tokens[1], tokens[2]);
...
}
main.h
...
#include "KeyValueStore.h"
...
KeyValueStore.c
#include "KeyValueStore.h"
#define BUFSIZE 1024
typedef struct KeyValueStore {
char key[BUFSIZE];
char value[BUFSIZE];
} KV_Store;
KV_Store kvStore[BUFSIZE];
...
int put(char* key, char* value){
...
}
KeyValueStore.h
...
typedef struct KeyValueStore;
int put(char* key, char* value);
...
Check to see if you have any .o files in that folder and delete them if you do. It's possible the compiler failed at some point while compiling which left *.o files that aren't linked properly
EDIT: I misread the question because for some reason it came up as a c++17 question for me. I'm not sure if what I said still applies to C though I do know it works with C++. Sorry about that to everyone that read my answer before I edited it
Not 100% sure if this is why you are having the error, though you need to put all .c files in the compiler.
So you currently are trying to "gcc -o main main.c" where instead you want to do something more like "gcc -o main main.c keyValueStore.c".
If you do not give the compiler every .c file, it won't have all the definitions and you will get an error similar to what you have.
I also don't really think you need main.h, assuming there isn't any more code in there, it really isn't worth having a whole extra file and instead just putting the #include in main.c.

how to use generated code from matlab

I want to use the C-coder in Matlab. This translates an m-code to C-code.
I use a simple function that adds 5 numbers.
When the code is generated there are a lot of C- and H-files.
of course you could just pick the code you need and import it in your code, but that's not the point of this exercise, as this will no longer be possible when the matlab-code will get more difficult.
Matlab delivers a main.c file and a .mk file.
/* Include Files */
#include "rt_nonfinite.h"
#include "som.h"
#include "main.h"
#include "som_terminate.h"
#include "som_initialize.h"
//Declare all the functions
int main(int argc, const char * const argv[]){
(void)argc;
(void)argv;
float x1=10;
float x2=20;
float x3=30;
float x4=40;
float x5=50;
float result;
/* Initialize the application.
You do not need to do this more than one time. */
som_initialize();
main_som();
result=som(x1,x2,x3,x4,x5);
printf("%f", result);
som_terminate();
return 0;
}
When I run this on a raspberry-pi with
gcc -o test1 main.c
It gives me undefined references to all the functions...
Any ideas what went wrong?
You have to build it with the generated makefile (the mk file) so it links with the correct Matlab libraries - that's where those functions are defined:
$ make -f test.mk
You also need to compile the other C files along with your main.c. If main.c is in the same directory as the generated code, you should be able to just do:
gcc -o test1 *.c
If the generated code is in another directory, then you can do something like:
gcc -o test1 /path/to/code/*.c -I/path/to/code main.c

multiple definition of main

I’m trying to create ./configure + make set for building C codes in following structure by using autotools. drive.c uses function in mylib.c
[mylib]
+mylib.c
+mylib.h
[src]
+drive.c
More details are here.
[mylib.c]
#include <stdio.h>
#include "mylib.h"
int main(){
mylib();
return 0;
}
void
mylib(void)
{
printf ("Hello world! I AM mylib \n");
}
[mylib.h]
void mylib(void);
[drive.c]
#include <mylib.h>
int
main (int argc, char **argv)
{
mylib();
return 0;
}
Actually I’ve given main() both mylib.c and drive.c.
If I make them on CentOS process is noremally finished however If I make them on MINGW an error message multiple definition ofmain'` is shown
How can I make them on MINGW even if they have multiply have main()?
And those followings are config files for autotools.
[confiugre.ac]
AC_PREREQ([2.69])
AC_INIT([libmylib], [1], [admin#localhost])
AC_CONFIG_SRCDIR([mylib/mylib.c])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([foreign])
LT_INIT
AC_PROG_CC
AC_CONFIG_FILES([mylib/Makefile
src/Makefile
Makefile])
AC_OUTPUT
[Makefile.am]
SUBDIRS = mylib src
ACLOCAL_AMFLAGS = -I m4
[Makefile.am#src]
bin_PROGRAMS = drive
drive_SOURCES = drive.c
LDADD = ../mylib/libmylib.la
AM_CPPFLAGS = -I../mylib
[Makefile.am#mylib]
lib_LTLIBRARIES = libmylib.la
libmylib_la_SOURCES = mylib.c
include_HEADERS = mylib.h
You are confusing things, the idea of having multiple main() is fundamentally wrong. Libraries never ever contain a main() function.
(With the exception of Windows DLLs that contain a DllMain, but that means something different.)
If you want to provide a test case for your library, you make the test case as a separate project which includes the library. The test code should not be inside the library itself, neither should main().
Also, I very much doubt you are able to build a program with several function definitions that have the same name, be it main() or something else. If you believe you have managed this, I would either suspect that you haven't linked the files correctly, or that the linker is crap.

C compilation problem

I am learning how to use cygwin for alchemy. I created a test library celconv.h which is there inside the folder celconv. I want to use that header file in my c code.
When i use #include <celconv/celconv.h> the compiler gives an error "No such file or directory"
i compile the code like this:
gcc -c test.c
Test.c inside a folder named test
#include <stdio.h>
#include <celconv/celconv.h>
int main()
{
float UserInput;
printf("Enter a temperature in celsius to convert to fahrenheit:");
scanf("%f",&UserInput);
celconvert(UserInput);
return 0;
}
celconv.h inside a folder celconv which is inside test folder:
extern void celconv(float Cel);
celconv.c:
#include<stdio.h>
#include"celconv.h"
void celconvert(float Cel)
{
float Fah;
Fah = Cel * 9/5 + 32;
printf("%f",Fah);
}
Is the path you are giving correct? Be careful about using < > and " ". The first tells the compiler "search for include files in your include folder", while the second says "look into source files directory".
If the "celconv" directory is in the current directory, the best way is probably use #include "celconv/celconv.h" syntax. If it is somewhere else, then do this:
gcc -I/path/to/wherever/celconv/directory/is -c test.c
Note that it's not the path to the celconv directory itself, but to the containing directory!
As mentioned in the comment, this approach will work for the current directory too if you don't want to use "celconv/celconv.h" for whatever reason:
gcc -I. -c test.c
Include files in the local directory need to be referenced using the
#include "file.h"
syntax. The angle brackets do not look into the current directory.

Resources