I have a problem on linking static libraries..
I have checked and proceeded some methods to solve it, like.. reordering libraries or using some options..
However, All what I've done didn't work..
--
First of all, I'm quite sure it is from link error because I have checked the .a file by nm command and there was specific functions shown in error log.
So, I linked static library like below..
LOCAL_LINK_STATIC_LIBS := \
-I$(libdir)/libmicrohttpd.a\
-I$(libdir)/libcryptopp.a\
...
myprog_LDFLAGS = -lstdc++ -g -ldl -lpthread #GLIB_CFLAGS# $(LOCAL_LINK_STATIC_LIBS)
Is there other way to solve it? I really need your feedback..
Thanks for reading.
You must only supply the name with the -l option, e.g. -lmicrohttpd. The linker will add "lib" and ".a" or ".so". Use the -L option to set the search path for the libraries, e.g. -L$(libdir).
Also try using -pthread instead of -lpthread. -lpthread only links the pthread library whereas -pthread will do some additional work.
Related
Using the Makefile provided by the Pi GPIO library, I made the libpigpio.so shard object using:
# from line 119 in make file
make libpigpio.so
The shared object is created fine. The Makefile first created the pigpio.o object, then the command.o object, and links them together as a shared object. So far so good!
I wrote a very small main function that calls the gpioInitialise and gpioGetPWMfrequency.
It doesn't really matter which functions, what's important is they are defined in pigpio.h and written in pigpio.c.
Meaning the shared object should have them.
The compile command for my code is:
gcc -Wall -pthread -fpic -L. -lpigpio -o drive drive.c
Still I get the undefined reference error to both those functions.
It makes no sense! If it didn't find the shared object, it would reject the command. I also tried it -l:libpigpio.so and still the same problem.
I am compiling directly on the Rpi A+ (not using a cross compiler). So it should work!
What am I missing here?
It is a link order question. Please try the flowing command.
gcc drive.c -Wall -pthread -fpic -o drive -L. -lpigpio
you can read Why does the order in which libraries are linked sometimes cause errors in GCC? for more details.
I try to write a Makefile that takes several static libraries that have been created before and link the to an executable. Although one libary has a main-routine.
I get the error:
/lib/../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
make: *** [dockSIM_gcc_release] Error 1
I tried it with just linking the library that has the main routine but the error stays the same and comes directly after invoking make.
The Makefile:
SHELL = /bin/sh
RM=/bin/rm -f
CXX=g++
PROGNAME=dockSIM_gcc_release
DEFINES=-DDOCKSIM_VERBOSE=FALSE -DNDEBUG -DPRINT_LOG_MSG=0 -DPRINT_DEBUG_MSG=0
LDFLAGS = -fopenmp -g -O3 -std=c++11 -mavx -mstackrealign -fstrict-aliasing
LIBS= -lnagc_mkl -lm -L../externalCode -lpardiso500-GNU481-X86-64 -lacml
FILENAMES = commandInterpreter_lib.a
OBJNAMES =
all: $(PROGNAME)
$(PROGNAME): $(FILENAMES)
$(CXX) $(LDFLAGS) $(DEFINES) -o $(PROGNAME) $(FILENAMES)
clean:
$(RM) *.mo *.ho *.o $(PROGNAME) core *~
test:
echo $(FILENAMES)
showlibs:
echo $(LIBS)
The flags are compatible with those that were used to compile the code.
g++ 4.9.3 is used.
Signature of the main-Routine:
int main(int argc, char* argv[])
Thanks for help and kind regards.
I can only guess what's wrong.
There is more to linking a static library than just a convenient bundle of object files to reduce command line length. In addition to that, the linker only links in object files which it thinks are needed. An object file is needed if there's some undefined symbol that the linker is looking for, that is contained in that object. If there's no symbol that the linker needs in the object, then the linker ignores the object and doesn't link it.
The normal way to build a program is to have the main program listed as object files on the command line: the linker always links every object file. This gives the linker a set of symbols which are defined (by the object files) and undefined (things the object files use but that aren't defined by them). Then the linker will go through the libraries on the link line and add in object files that resolve undefined symbols. These object files in turn may have other undefined symbols that the linker will need to resolve later, etc.
All I can guess is that by not having any object files on your link line, the linker doesn't see the object file in the library containing main as needed and so it doesn't link it.
I don't know why building with debug vs. non-debug makes a difference.
I didn't understand your comment about why you need to do things this way: even if the person who knew about this left, someone will need to learn about it to maintain the software.
In any event you have a few options.
One simple one is to use the "ar" program to extract out the object file containing main and link it directly: in addition to adding objects to libraries ar can extract them. Then you can link that object directly. See the man page for ar.
Another would be to look at the documentation for your compiler and linker and find flags that will force it to include the entire library, not just the unresolved symbols in the library. For the GCC/binutils linker, for example, you can pass -Wl,--whole-archive before the libraries you want to be fully included on the command line, then -Wl,--no-whole-archive after them to turn off that feature.
In a later stage of the gnu-make process gmake sent a command similar to:
gcc -static foo.so.0 bar.o bizz.o buzz.o -pthreads -lrt
In that command, what dos the -lrt mean?
That has not related to make; make will never add a flag like that on its own. Whomever wrote your makefile will have added that flag to the link line themselves. That is a compilation command, and -lrt is a flag passed to the compiler. The -l flag specifies that you should link with a library, and the name of the library follows; so for -lrt it means "link with the rt library". This causes the linker to go look for libraries named librt.a or librt.so (for shared libraries) and link them with the output file.
Trying to compile something for 64 bit unix using Ubuntu. As a disclaimer I only started using linux and gcc a few days ago so still learning my way around. Anyway, getting the following error:
/home/myuser/myproject/myfile.cpp:437: undefined reference to `clock_gettime'
A quick google reveals I need the -lrt option to link with librt.a. So I check my command line ( formatted for readability, different file names and I've remove lists of file names ):
/usr/bin/g++
-Wl,
--gc-sections
-fno-exceptions
-m64
-B/usr/bin
-o
"/home/myuser/myproject"
-Wl,
-Map, "/home/myuser/myproject/myproject.map"
-g
"/home/myuser/myproject/myproject.cpp.obj"
..and some more .objs..
-Xlinker
--start-group
"-lpthread"
"-lrt"
"/home/myuser/myproject/lib/mylib.a"
..and some more .as..
-Xlinker
--end-group
Hmm. Looks like -lrt is already there, maybe I don't have librt.a? Nope searching all files reveals I have /usr/lib/x86_64-linux-gnu/librt.a. I guess g++ is looking in the wrong place. So in the above command line I replace -lrt with /usr/lib/x86_64-linux-gnu/librt.a and bingo! it compiles and links fine. Unfortunately, this is an automated tool and I need this to work on many computers and can't make assumptions about the location of librt.a so I really need it to work with -lrt. So how do I set the local libary search path? First attempt is changing LD_LIBRARY_PATH environment variable but apparently ( from what I can tell from more googling ) this is ignored on ubuntu and instead I should be messing with .conf files in /etc/ld.so.conf.d/, however I already it looks like I already have x86_64-linux-gnu.conf in there with the following lines:
# Multiarch support
/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu
From my reading up this point it looks that should be all I need. Kind of stuck as to where to go from here...
Answering my own question just in case someone else has this problem. Turns out the correct librt.a was being linked but the linker is very sensitive to the link order. Putting -lrt and -lpthread at the end of the group fixes the problem.
in my homework i must use this command to compile my program:
gcc -o mtm_rentals -std=c99 -Wall -pedantic-errors -Werror -DNDEBUG mtm_ex2.c rentals.c list.c -L -lmtm
what i can change in that line are the files im writing after -DNDEBUG. when i do this the gcc says that there are undefined references to specific functions. now those functions are declared in an .h file and are implemented in a given file called libmtm.a
i concluded that it doesnt recognize libmtm.a, but our homework task says that the -lmtm flag(which is not declared anywhere) is supposed to link libmtm.a to the program.
what am i missing here? am i supposed to implement somehow the -lmtm flag?
thank you!
You are missing a . (single dot) behind the -L.
-lmtm will link against a libmtm library, this is correct. It's not an -lmtm flag, it's a -l flag concatenated with mtm, the library you want to link against. This library is searched in some predefined paths (like /usr/lib/) and additionally in the paths given by -L. Assuming libmtm lives in your current directory, you need to add that to -L, which is done with a ..