2

I have some basic questions regarding linking against a C/C++ library. I am trying to understand the difference in using the two different usages -L/usr/local/lib -lm usage and /usr/local/lib/libm.a usage. E.g., when I compile and link an example from the [SUNDIALS] library, both of the following work

gcc -Wall cvRoberts_dns.c -o cvRoberts_dns.exe -I/usr/local/include -L/usr/local/lib/ -lsundials_cvode -lsundials_nvecserial -lm

OR

gcc -Wall cvRoberts_dns.c -o cvRoberts_dns.exe /usr/local/lib/libsundials_cvode.a /usr/local/lib/libsundials_nvecserial.a

However, to compile and link an example from the library [libsbml], the following works

g++ -Wall readSBML.cpp -o readSBML.exe -I/usr/local/include -L/usr/local/lib -lsbml

but the this does not

g++ -Wall readSBML.cpp -o readSBML.exe /usr/local/lib/libsbml.a

If required, I can post the complete error message I get, but the last line of the message is as follows

ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

My questions are as follows:

  1. In the second style of linking (of the first example), there is no information regarding where to find the include files (header files), how does the compiler know the information supplied in -I/usr/local/include which is provided in the first style of the first example?

  2. In the second style of first example there is no /usr/local/lib/libm.a (it actually gives an error message that libm.a cannot be found if I try to include it), then why -lm is required in the first style?

  3. How do I compile the second example in the second style (i.e., using /usr/local/lib/libsbml.a)? I do see that there are files - libsbml.a and libsbml-static.a in the /usr/local/lib folder, but none of them work.

If it helps, I am on an OS X machine.

I would be very thankful if any one could help in this regard.

Just an update - I tried

g++ -Wall readSBML.cpp -o readSBML.exe /usr/local/lib/libsbml.5.dylib

and that compiled and linked just fine.

Thanks SN

Satya
  • 1,708
  • 1
  • 15
  • 39

1 Answers1

1

In general

  • The -L option is meant to find where the libraries themselves are. Each library is a collection of one or more object code (machine language) files. There is no need to find the include files.
  • The -I option has nothing to with linker, it helps the compiler resolve the header files used in your driver programme( eg Roberts_dns.c). This happens during the pre-processing stage.

In the second style of linking (of the first example), there is no information regarding where to find the include files (header files),..

If the compilation worked as you expected,it may be because /usr/local/include is in the default include path for gcc. To check the default include path for gcc do gcc -xc -E -v -.

In the second style of first example there is no /usr/local/lib/libm.a(it actually gives an error message that libm.a cannot be found if I try to include it), then why -lm is required in the first style?

In Linux, some libraries like libc.a are directly linked to your execultable by default while libm.a is not. In Mac (your environment), though, libm is directly link to the executable by default. So you don't have to explicitly link it. It is less likely that libm.a is located in /usr/local/lib/. So you got an error. But why link it in the first place?

sjsam
  • 21,411
  • 5
  • 55
  • 102
  • Thank you for your explanation. I do understand the `-I` and `-L` flags, however, I don't understand why they are not required in the second style. I did run the command - `gcc -xc -E -v`, the output is pasted below - `Apple LLVM version 7.3.0 (clang-703.0.31) Target: x86_64-apple-darwin15.5.0 Thread model: posix InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin`. Thank you. – Satya Jul 24 '16 at 20:09