"Undefined reference" when linking C code in Linux
I have a code library (written entirely in C) that I typically compile under Windows, into a .DLL
.开发者_C百科
I want to compile it under Linux so I can distribute it. I don't care if I distribute it as a .a
, a .so
, or a bunch of .o
files.
All of the individual .c
files compile successfully. But when I try to compile a test executable that includes all the .o
files, I get a bunch of undefined reference errors.
All of the .o
files are on the command line as full paths, and I don't get any errors about missing files.
cc testctd.c -o testctd.out -lm -lc $LIBRARY-PATH/*.o
I also have undefined references to _open
, _write
, etc.
You have the -l options in the wrong place
-llibrary
-l library
Search the library named library when linking. (The second alternative with the library as a separate argument is only for POSIX compliance> and is not recommended.)
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus,
foo.o -lz bar.o
searches library z after file foo.o but before bar.o. If bar.o refers to functions in z, those functions may not be loaded.
The linker searches a standard list of directories for the library, which is actually a file named liblibrary.a. The linker then uses this file as if it had been specified precisely by name.
You haven't given enough information for a complete answer, but I think I know one of your problems: The functions open
, read
, write
, close
, etc. have underscores in front of their names on Windows, but they do not on Linux (or any other Unix for that matter). The compiler should have warned you about that when you compiled the .c
files -- if it didn't, turn on warnings! Anyway, you're going to have to remove all those underscores. I would recommend a header file that does something like the following:
#ifdef _WIN32
#define open(p, f, m) _open(p, f, m)
#define read(f, b, n) _read(f, b, n)
#define write(f, b, n) _write(f, b, n)
#define close(f) _close(f)
/* etc */
#endif
and then use only the no-underscore names in your actual code.
Also, -l
options (such as -lm
) must be placed after all object files. It is unnecessary to specify -lc
(and it may cause problems, under circumstances which are too arcane to go into here).
精彩评论