How do you set the order of libraries in automake? - c

How do you set the order of libraries in automake?
In my am file I have something like:
myprog_DEPENDENCIES = adhoc-target
myprog_SOURCES = myprog.c
myprog_LDADD = libmine.la
myprog_LDFLAGS = -static -L/home/user/lib -ladhoc
Now, when I compile I get this compile line similar too:
gcc -static myprog-myprog.o -o myprog -L/home/user/lib -ladhoc ./.libs/libmine.a
The problem is that libmine.a depends on libadhoc.a, therefore the compile line should be:
gcc -static myprog-myprog.o -o myprog ./.libs/libmine.a -L/home/user/lib -ladhoc
How do you set the order of libraries in automake? (Or maybe a work around; how do you repeat all the libraries in the compile line. That's what I do in my custom Makefiles.)

From the Automake manual (mostly §8.1.2 but also §8.4):
PROG_LDADD is inappropriate for
passing program-specific linker flags
(except for -l, -L, -dlopen and
-dlpreopen). So, use the
PROG_LDFLAGS variable for this
purpose.
That implies you can (but actually you should) use -l and -L in LDADD, not in LDFLAGS. In other words your Makefile.am should simply read
myprog_DEPENDENCIES = adhoc-target
myprog_SOURCES = myprog.c
myprog_LDADD = libmine.la -L/home/user/lib -ladhoc
myprog_LDFLAGS = -static

One idea from the automake book (http://sources.redhat.com/autobook/autobook/autobook_92.html): create a convenience library out of libmine and libadhoc, and link myprog against that.

Related

How to include -lm in Makefile.am or configure.ac

I have a program called neuromz that I compile using
gcc neuromz.c -lm -o neuromz
It's work fine but if I try to add to my project a configure.ac and Makefile.am, with Makefile.am:
bin_PROGRAMS = neuromz
neuromz_SOURCES = neuromz.c neuromz.h ann.c ann.h
neuromz_CFLAGS = -lm
the result is:
/home/mz/programming/ctest/ANN/ann.c:11: undefined reference to `exp'
/home/mz/programming/ctest/ANN/ann.c:11: undefined reference to `exp'
How can I fix it?
Your commandline:
gcc neuromz.c -lm -o neuromz
is shorthand that gcc helpfully translates into the necessary compile step and
link step, as if you did:
gcc -c -o neuromz.o neuromz.c # Compile
gcc -o neuromz neuromz.o -lm # Link
Automake always separates compilation and linkage, because that typically makes
builds as economical as they can be.
neuromz_CFLAGS = -lm
adds -lm to the compiler options (CFLAGS) for compiling neuromz.c.
But -lm ( = link the math library) is a linkage option and ignored in compilation. You need it
in the linkage options (LDADD):
neuromz_LDADD = -lm
See the automake manual 8.4 Program and Library Variables
As #MikeKinghan already described, the Automake variables for specifying extra libraries into a program are *_LDADD. I'll add, however, that if you're only building one program, or if all of the programs you're building need the same libraries, then you can use LDADD instead. This can be more convenient, and it sometimes produces smaller Makefile's, too:
bin_PROGRAMS = neuromz
LDADD = -lm
neuromz_SOURCES = neuromz.c neuromz.h ann.c ann.h
HOWEVER, if you're satisfied to make a once-for-all decision about libm for the programs built by your build system, then I'd recommend handling it in Autoconf instead of Automake. If you put this in your configure.ac ...
AC_SEARCH_LIBS([sqrt], [m])
... then
Your configure script will check whether libm needs to be explicitly linked at all (which depends on your environment and tool chain), and will add -lm only if necessary.
You don't then need to say anything about it in your Makefile.am, nor be concerned with which Automake variable to use.

How to let gcc compiler know where a certain file is

I'm trying to compile my C code but I need to tell the GCC compiler where two file are.
The two files are located here
/usr/local/ssl/include/
/usr/local/ssl/lib/
I want to add this to my gcc -o file file.c so that my program can work.
In gcc, the -I option is used for adding a directory to the set of directories to search for header files, and the -L option is used for adding a directory to the set of directories to search for libraries. Since you're not explicitly linking in any libraries, you shouldn't need the -L option in this case.
gcc -I/usr/local/ssl/include -o file file.c
If you were linking in libraries, something like the following format should work, assuming that file.c calls a function in libmyLib.a:
gcc -I/usr/local/ssl/include -o file file.c -L/path/to/my/library -lmyLib
See this question for more details regarding library linking order.

How to include static library in makefile

I have the following makefile
CXXFILES = pthreads.cpp
CXXFLAGS = -O3 -o prog -rdynamic -D_GNU_SOURCE -L./libmine
LIBS = -lpthread -ldl
all:
$(CXX) $(CXXFILES) $(LIBS) $(CXXFLAGS)
clean:
rm -f prog *.o
I am trying to include the ./libmine library within CXXFLAGS, but it seems like it is not the right way to include a static library, because when I compile the program, I get many undefined references error. So what is actually the right way to include a static library in the makefile?
use
LDFLAGS= -L<Directory where the library resides> -l<library name>
Like :
LDFLAGS = -L. -lmine
for ensuring static compilation you can also add
LDFLAGS = -static
Or you can just get rid of the whole library searching, and link with with it directly.
Say you have main.c, fun.c and a static library libmine.a.
Then you can just do in your final link line of the Makefile
$(CC) $(CFLAGS) main.o fun.o libmine.a
CXXFLAGS = -O3 -o prog -rdynamic -D_GNU_SOURCE -L./libmine
LIBS = libmine.a -lpthread
Make sure that the -L option appears ahead of the -l option; the order of options in linker command lines does matter, especially with static libraries. The -L option specifies a directory to be searched for libraries (static or shared). The -lname option specifies a library which is with libmine.a (static) or libmine.so (shared on most variants of Unix, but Mac OS X uses .dylib and HP-UX used to use .sl). Conventionally, a static library will be in a file libmine.a. This is convention, not mandatory, but if the name is not in the libmine.a format, you cannot use the -lmine notation to find it; you must list it explicitly on the compiler (linker) command line.
The -L./libmine option says "there is a sub-directory called libmine which can be searched to find libraries". I can see three possibilities:
You have such a sub-directory containing libmine.a, in which case you also need to add -lmine to the linker line (after the object files that reference the library).
You have a file libmine that is a static archive, in which case you simply list it as a file ./libmine with no -L in front.
You have a file libmine.a in the current directory that you want to pick up. You can either write ./libmine.a or -L . -lmine and both should find the library.
The -L merely gives the path where to find the .a or .so file. What you're looking for is to add -lmine to the LIBS variable.
Make that -static -lmine to force it to pick the static library (in case both static and dynamic library exist).
Addition: Suppose the path to the file has been conveyed to the linker (or compiler driver) via -L you can also specifically tell it to link libfoo.a by giving -l:libfoo.a. Note that in this case the name includes the conventional lib-prefix. You can also give a full path this way. Sometimes this is the better method to "guide" the linker to the right location.

Linking troubles in C

I have a test.c that is using code from two libraries. One is statically linked (say libstatic.a, the other - dynamically (e.g. libdynamic.so).
I compiled my c file as follows:
gcc -I../inc -c test_subframeip_omap.c -o test_subframeip_omap.o
How do I link now the static and dynamic libraries in order to produce the final executable?
Thanks!
You generally need something like:
gcc -I../inc -c test_subframeip_omap.c -o test_subframeip_omap.o
gcc -L/path/to/libs -l static -ldynamic -o test_subframeip_omap test_subframeip_omap.o
The -L adds directories to the library search path and -l specifies a library to link with. It's also done as part of the link, not the compile.

Using dlsym and adding -ldl to flags

I am trying to write a C program that uses dlysm, and I keep getting an undefined reference to dlysm. I think I need to set my -ldl flags but I have no idea how to do this.
I am very new to linux and setting variables. If this is what I need to do can someone help me out with the commands?
-l library options are used at link time.
If you compile just one source file (gcc -o program program.c), then you both compile and link in one go. Just add the -ldl.
If you compile multiple object (*.o) files, and then link them together, specify the -ldl option to the linker (ld).
See also man ld and man cc
Pass -ldl as a parameter to the compiler.
Example:
gcc myprog.c -o app -ldl

Resources