Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setting library include paths in c++

Tags:

c++

macos

gd

I just installed gd2 using mac ports (sudo install gd2), which installed libraries in the following places:

/opt/local/include/gd.h
/opt/local/lib/libgd.dylib (link)
/opt/local/lib/libgd.la
/opt/local/lib/libgd.a

Here is my make file also:

dev: main.o
    g++ -L/opt/local/lib -I/opt/local/include -lgd -lpng -lz -ljpeg -lfreetype -lm main.o -o heatmap

main.o: main.cpp
    g++ -c main.cpp

So when I create my c++ app I add '#include "gd.h"', which throws:

main.cpp:4:16: error: gd.h: No such file or directory

If I set gd.h as an absolute path (as above)(not a solution, but was curious), I am thrown:

g++ -L/opt/local/include -L/opt/local/lib main.o -o heatmap
Undefined symbols:
  "_gdImagePng", referenced from:
      _main in main.o
  "_gdImageLine", referenced from:
      _main in main.o
  "_gdImageColorAllocate", referenced from:
      _main in main.o
      _main in main.o
  "_gdImageDestroy", referenced from:
      _main in main.o
  "_gdImageCreate", referenced from:
      _main in main.o
  "_gdImageJpeg", referenced from:
      _main in main.o
ld: symbol(s) not found

So, I understand this means that ld can not find the libraries it needs (hence trying to give it hints with the "-L" values). So after giving g++ the -L hints and the absolute path in #include, I can get it to work, but I don't think I have to do this, how can I make g++/ld search int eh right places for the libraries?

Drew J. Sonne.

PS. using: - OSX 10.6.2 - gcc version 4.2.1 (Apple Inc. build 5646) (dot 1)

EDIT: Ok, so after taking into account stfanB and Michael's answer, I've recompiled gd into a local directory (libraries) and thus, I've changed that first line of my Makefile (I will def check out cmake) to g++ -L./libraries/lib -I./libraries/include -lgd -lpng -lz -ljpeg -lfreetype -lm main.o -o heatmap But I'm still getting main.cpp:3:16: error: gd.h: No such file or directory

EDIT: Thanks all for the answers, here's my final (working) makefile for anyone else who many want an answer:

dev: main.o
    g++ -I./libraries/include -L./libraries/lib -lgd -lpng -lz -ljpeg -lfreetype -lm main.o -o heatmap

main.o: main.cpp
    g++ -I./libraries/include -c main.cpp
like image 663
Drew Avatar asked Mar 23 '10 01:03

Drew


2 Answers

Rather than invoke g++ directly, I strongly advise you to use CMake (watch the CMake Google Techtalk if you'd like to learn more) as it will make your life way easier and greatly simplifies locating and linking against a variety of libraries. That said, I believe the problem with your invocation is that you have not specified the library, which you would do with -lgd. Your -L/opt/local/lib correctly tells g++ to look in /opt/local/lib, but you never told it what to look for. As for finding the appropriate header, you can use -I/opt/local/include to put /opt/local/include in the compiler's include search path.

If you were to heed my advice to use CMake, doing this would look like:

FIND_PACKAGE(GD2 REQUIRED)
INCLUDE_DIRECTORIES(${GD2_INCLUDE_DIRS})
LINK_DIRECTORIES(${GD2_LIBRARY_DIRS})

ADD_EXECUTABLE(heatmap main Heatmap_Map Heatmap_Point)
TARGET_LINK_LIBRARIES(heatmap ${GD2_LIBRARIES})

If you are interested in learning more about CMake, you might want to take a look at the C++ Application Project Template and C++ Library Project Template, which make use of the CMake build system. CMake is available through MacPorts via the command "sudo port install cmake".

In case you are not interested in installing CMake, I should also point out that there are some environment variables that you might be interested in knowing about to make your life easier, namely:

  • CPATH
  • LIBRARY_PATH
  • DYLD_FALLBACK_LIBRARY_PATH

The CPATH environment variable is much like the PATH environment variable (it is a colon separated list of directories), except that the directories in that variable will automatically be used by gcc and g++ as if they were specified on the commandline with the -I flag (i.e. headers will be searched in those paths). The LIBRARY_PATH is the equivalent except that it is as if the folders were given with -L (i.e. libraries will automatically be searched in that path). DYLD_FALLBACK_LIBRARY_PATH will be used by the dynamic linker (so you should probably include the paths from LIBRARY_PATH into this variable).

You can read more about the environment variables affecting gcc at the link.

like image 193
Michael Aaron Safyan Avatar answered Oct 21 '22 03:10

Michael Aaron Safyan


The answer is quite complicated.

The short answer, when you compile your own libs/tools place them in some local directory such as you used above or /usr/local/lib and /usr/local/include or even ~/local/lib and ~/local/include and always add these to your compiler/linker.

The longer answer - read Programming Library HOWTO for Linux that explains what each of the tool involved looks for, from compiler/linker to execution, and have a look at standard directory structure of Linux system which is of course not binding but it's nice to know.

I'm assuming that you have a simple Makefile setup for each of your projects so you don't have to bother with typing all those commands. If you don't I strongly recommend to setup a simple Makefile template that you can reuse for your projects.

EDIT:

In your edited answer your paths may be incorrect.

The . in your path like ./libraries specifies current directory, meaning it will look into libraries directory in the current directory. If you ment libraries directory in root directory then remove the . so it should be like this -L/libraries/lib and similarly for -I/libraries/...

like image 43
stefanB Avatar answered Oct 21 '22 01:10

stefanB