What is the -lrt flag in gnu-make? - gcc

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.

Related

Cannot pass flags to Makefile to compile my code

I have a project that basically compiles from the command line in the following form:
g++ -o stack_raster stack_raster.cpp -lgdal -lboost_filesystem -lboost_system
I made a Makefile, and this is the content:
CXX =g++
LDDFLAGS = -lgdal -lboost_system -lboost_filesystem
all: clean stack_raster
clean:
rm -f stack_raster
However I got a collect2: error: ld returned 1 exit status.
A second variation of my Makefile I tried was:
CXX = g++
CPPFLAGS = -lgdal -lboost_system -lboost_filesystem
all: clean stack_raster
clean:
rem -f stack_raster
but I still receive the following message (even though the compile flags appear as they should for my program to compile successfully).
collect2: error: ld returned 1 exit status
<builtin>: recipe for target `stack_raster` failed
make: *** [stack_raster] Error 1
Does anyone could help me with a reference or hint about my problem, and how could I tackle it?
Does anyone could help me with a reference or hint about my problem, and how could I tackle it?
To begin with, you should have a look at the actual link command that make executed. It should have been echoed to make's output just before the error message from collect2. Understanding what's wrong with the command is the first step in determining how to fix your makefile.
In the first case, the command is probably something like
g++ stack_raster.cpp -o stack_raster
In the second, it is probably something like
g++ -lgdal -lboost_system -lboost_filesystem stack_raster.cpp -o stack_raster
The latter is probably also very similar to what you would get with the first makefile if you corrected the spelling of LDDFLAGS to LDFLAGS.
You will note that the library flags come in a different place in that command than they do in your manual command, and I assume you know that the order of objects and library flags on the linker command line is significant to Unix-style linkers such as GNU's (which is the one that the g++ driver will use).
You can certainly fix this by writing an explicit rule, as you describe in your own answer, but your makes' built-in rules may be up to the task, too. If you are using GNU make then they certainly are. For this purpose it is useful to know what the built-in rules actually are, and essential to know what the variables on which these rules depend mean.
Specifically,
LDFLAGS provides options to pass when invoking the linker, and conventionally, they appear on the command line before the objects being linked. As a result, this variable typically is not appropriate for specifying libraries (but it is fine for other link-specific options, such as -L to add directories to the library search path).
CPPFLAGS provides options for modulating the behavior of the C preprocessor (including when compiling C++). These do not typically appear at all in link(-only) commands executed by make, but they will appear (early) in commands for compiling object files from C or C++ sources, and in rules for building executables directly from C or C++ sources.
Neither of those is what you want, but if you are using GNU make, then its documentation for the former explicitly tells you what (with that make implementation) you should do instead:
Extra flags to give to compilers when they are supposed to invoke the
linker, ‘ld’, such as -L. Libraries (-lfoo) should be added to the
LDLIBS variable instead.
(emphasis added)
In GNU make, and perhaps some others, the LDLIBS variable serves exactly the purpose you need: to specify the libraries to link. These will appear at the end of the link command line from built-in rules, as you can confirm from GNU make's catalog of implicit rules, or from the list obtainable by running make -p in a directory containing no makefile.
So, with GNU make you can get the build you seem to want from the built-in rules, with this:
CXX = g++
LDLIBS = -lgdal -lboost_system -lboost_filesystem
all: clean stack_raster
clean:
rm -f stack_raster
In closing, I note that cleaning before building by default, as your examples do and mine imitates, largely defeats the purpose of using make instead of a simple script. Part of the point of make is to do the minimum work necessary, and if your target executable is present and not out of date with respect to its sources then there is no reason to force it to be rebuilt.
Check out the answer:
Set up my makefile to compile C with just "make"
YOu have to specify in the Makefile the file you want to create in this case stack_raster.exe and the objective file in this case stack_raster.cpp and specify the command line arguments you normally pass for compiling. So the Makefile would be something like:
CXX=g++
stack_raster.exe: stack_raster.cpp
g++ -o stack_raster.exe stack_raster.cpp -lgdal -lboost_filesystem -lboost_system
all: clean stack_raster.exe
clean:
rm -f stack_raster.exe

automake: the ordering of compiler options hinders make

I am new to automake tools. In "src/Makefile.am", I use "AM_LDFLAGS = -L... -l...".
Then, I run "autoreconf --force --install ; ./configure ; make"
In the last command,
$ g++ -O2 -L... -l... -o target_name [some *.o files]
the compiler complains "undefined reference to ...".
But if I copy it and move "-L... -l..." to the end, and run it independently it is fine (below).
$ g++ -O2 -o target_name [some *.o files] -L... -l...
So the order of options does matter? Anyway, how to smooth it?
Thanks a lot.
For the "-L" options, try using the LDADD or target_name_LDADD variable instead (where target_name is replaced with the actual target name). This places these flags at the end of the linking command.
The order of "-l" and "-L" does make a difference. From http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html:
-l library
Search the library named library when linking. ... 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 handles an archive file by scanning through it for members which define symbols that have so far been referenced but not defined.
So libraries should appear after object files/other libraries that depend upon them.

Force solib dependency to have relative path of non-standard named shared library under a directory using gcc

I have an issue regarding the linking of a shared library with a non-standard naming convention under several directories. I need the generated executable to search for the shared library within the executables current location, but cannot find a command line parameter to force this behavior.
To demonstrate this behavior all that is required is a shared library that is under a directory.
gcc -shared mylib.c -o some/dir/mylib.so
gcc main.c -o main -Lsome/dir -l:mylib.so
The executable main gives the following ldd output:
ldd main
some/dir/mylib.so (0xf76e2000)
The output that I require is:
ldd main
mylib.so => some/dir/mylib.so (0xf7700000)
This output can be created if the library is named conventionally as libmylib.so rather than mylib.so like so:
mv some/dir/mylib.so some/dir/libmylib.so
gcc main.c -o main -Lsome/dir -lmylib
This also drops the path some/dir in the ldd listing as required.
I have investigated the use of rpath, and command line options for both the ld and gcc but I am unable to find a satisfactory solution. The strict requirements of a non-standard name and directory structure cannot be changed easily in this case.
My question is how can I force the dependency of the library to be relative to the current directory rather than absolute as in the second ldd through gcc command line options.
Thank you for your time, I hope I have explained the problem reasonably.
Jon.
Try to add soname in your shared library:
$ gcc -shared mylib.c -o some/dir/mylib.so -Wl,-soname=mylib.so
$ gcc main.c -o main -Lsome/dir -l:mylib.so
$ LD_LIBRARY_PATH=some/dir:$LD_LIBRARY_PATH ldd main
mylib.so => some/dir/mylib.so (0x00007fa7a4fd6000)
There's a magic variable you can pass to rpath to do this: $ORIGIN. See man ld.so for details.
I think in your case, the command should look like this (untested):
gcc main.c -o main -Lsome/dir -lmylib -Wl,-rpath,'$ORIGIN/some/path'
Note that you mustn't let the shell expand $ORIGIN as a shell variable.
BTW, this was the first Google hit for "rpath relative".

Is it not allowed create a static library without a .c file in it?

I have two files -> fact.h and main.c in the /home/snyp1/new folder. main.c has the main function which calls the fact(int x) function in fact.h. I am creating a .a archive with the ar command ->
snyp1#Snyp:~/new$ ar -r -s libfact.a fact.o
ar: creating libfact.a
fact.h fact.o libfact.a main.c
snyp1#Snyp:~/new$ gcc main.c -L/home/snyp1/new -lfact -o main
/home/snyp1/new/libfact.a: could not read symbols: Archive has no index; run ranlib to add one
collect2: ld returned 1 exit status
snyp1#Snyp:~/new$ ranlib libfact.a
snyp1#Snyp:~/new$ gcc main.c -L/home/snyp1/new -lfact -o main
/home/snyp1/new/libfact.a: could not read symbols: Archive has no index; run ranlib to add one
collect2: ld returned 1 exit status
I am on ubuntu 12.04. Please let me know whats wrong. (Also, if I don't use the -L/.../new, gcc will say it can't find "lfact", maybe its because its not in /usr/local/lib)
EDIT: OK I have found the cause. Its due to the fact that I was using fact.h to build the fact.o and then putting it in the library, it wasn't working as expected. So I now changed it into file.c and is working fine now. I should have provided that information, I'm sorry. Though I don't know why this kind of problem should arise. Aren't libraries possible to make without at least one .c file in it?
I was using fact.h to build the fact.o and then putting it in the library, it wasn't working as expected.
Do you mean you were compiling fact.h to produce fact.o?
If so, that wasn't doing what you expect. When you invoke gcc on a header file it produces a precompiled header, not an object file. So although you got a file called foo.o it wasn't a valid object file. If you had just run gcc -c fact.h it would have produced a precompiled header fact.gch, but presumably you ran gcc -c fact.h -o fact.o which causes the file to be called fact.o even though it's still a precompiled header. file fact.o would have shown that:
$ file fact.o
fact.o: GCC precompiled header (version 013) for C
You could have forced GCC to treat the file as C code, not a header, by running gcc -x c -c fact.h -o fact.o (the -x c says to treat the input as C code instead of inferring the type from the file extension) but it's probably simpler and less confusing to just name your file correctly instead of trying to compile a header.
Aren't libraries possible to make without at least one .c file in it?
They need at least one object file (i.e. .o file) but you didn't have a valid object, you had a precompiled header misleadingly named as .o, but it was not actually an object file.
if I don't use the -L/.../new, gcc will say it can't find "lfact", maybe its because its not in /usr/local/lib
The linker doesn't only look in /usr/local/lib, there are other default places it looks, but yes, that's basically the problem. Note that you can also say -L. if the library is in the current directory, that's easier than giving an absolute path.
I'm not sure ar supports a dash on anything other than the first option. Try
ar -rs libfact.a fact.o
or just
ar rs libfact.a fact.o
Mind you, I don't know why running ranlib didn't work though.

gcc compiling linking .a file

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 ..

Resources