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
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:
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.
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/...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With