Linking libraries (C++) - c++

Using MinGW through Eclipse for C/C++, and attempting to get GLUT (OpenGL Utility Toolkit) working on it, but I suspect it's a simple problem.
Attempts to build result in:
g++ -LC:\Documents and Settings\C\workspace\GLUTtest\Debug -LC:\Tools\MinGW\include\GL -LC:\Tools\MinGW\include -oGLUTtest.exe main.o -lglut32.lib
C:\Tools\MinGW\bin..\lib\gcc\mingw32\3.4.5........\mingw32\bin\ld.exe: cannot find -lglut32.lib
I have glut32.lib in the workspace directory, C:\Documents and Settings\C\workspace\GLUTtest. Here are the options as given by eclipse:
-L"C:\Documents and Settings\C\workspace\GLUTtest" -L"C:\Documents and Settings\C\workspace\GLUTtest\Debug" -L"C:\Documents and Settings\C\workspace\GLUTtest\GL" -L"C:\Tools\MinGW\include\GL" -L"C:\Tools\MinGW\include"
Any idea why it isn't picking up the library?

Seems your trying to pass include directories as link directories. Find the directory that contains glut32.lib and add a link-directory parameter (-L) with the directory you find.

Let's say you have a library file named libxxx.a, libxxx.so or xxx.lib. When linking, you should put the parameter as -lxxx
And second, sometimes you have to put library path with ( -L/path/to/lib/dir )

Your are passing "C:\Tools\MinGW\include\GL -LC:\Tools\MinGW\include" as your linking directory ( -L ) which seems to be your include path. so pass your include directory in include path which will appear with -I option and just check that whether your linking path is present in the list given with -L options, if not then add it in the list otherwise it will say undefined references.

Related

Link with self-compiled static libraries with cmake

I try to write some tests for project. If I need some project files I write include_directories statement and all will be included. In case of need of some manually compiled static libraries I try to set target_link_libraries.
If I set absolute path then all links ok, but for task I need another way to link another libraries, because the relative path to libraries gives undefined references.
In this case everything works fine:
target_link_libraries(ConsoleDumperTest GTest::GTest GTest::Main PocoFoundation PocoUtil PocoNet ${YAML_LIBRARIES})
target_link_libraries(ConsoleDumperTest /home/yrusinov/projects/build-fleetd-2-Desktop-dbg/protocols/libprotocols.a)
target_link_libraries(ConsoleDumperTest /home/yrusinov/projects/build-fleetd-2-Desktop-dbg/consumers/libconsumers.a)
target_link_libraries(ConsoleDumperTest /home/yrusinov/projects/build-fleetd-2-Desktop-dbg/consumers/Console/libconsole.a)
but if I do:
target_link_libraries(ConsoleDumperTest GTest::GTest GTest::Main PocoFoundation PocoUtil PocoNet ${YAML_LIBRARIES})
target_link_libraries(ConsoleDumperTest ../../../protocols/libprotocols.a)
target_link_libraries(ConsoleDumperTest ../../../consumers/libconsumers.a)
target_link_libraries(ConsoleDumperTest ../../../consumers/Console/libconsole.a)
I receive undefined references, despite of libraries contains in there directories. Which way I have to set path to link libraries?
According to documentation, target_link_libraries is not expected to work with relative paths: you should use either an absolute path, or a library name.
By knowing relative path, it is easy to construct absolute path in CMake. E.g., assuming you know relative path to the current source directory (the directory contained currently executed CMakeLists.txt), use CMAKE_CURRENT_SOURCE_DIR variable:
target_link_libraries(ConsoleDumperTest
${CMAKE_CURRENT_SOURCE_DIR}/../../../protocols/libprotocols.a
)
CMake's link_directories(...) command provides this:
link_directories(directory1 directory2 ...)
Specify the paths in which the linker should search for libraries. The command will apply only to targets created after it is called. Relative paths given to this command are interpreted as relative to the current source directory, see CMP0015.
Note also that, if these library dependencies are defined within the same CMake project, using add_library(target_name ...), you may specify the target name instead of the binary name within target_link_libraries.

Linking with CMakeLists: ld cannot find library

I have a CMakeLists.txt file, with the following:
target_link_libraries(${PROJECT_NAME} OpenNI2)
When I run cmake, I receive no errors. But when I run make, I receive the following error:
/usr/bin/ld: cannot find -lOpenNI2
However, I have a file called libOpenNI2.so in my build directory. So why can ld not find this? I thought that the build directory was on the search path for target_link_libraries?
Thanks!
That's because when linking, the linker doesn't look in the current directory but only in a set of predefined directories.
You need to tell CMake where the library is, for example by giving the full path to the library in the target_link_library command, or adding it as an imported library.
it works if adding like:
target_link_libraries(${PROJECT_NAME} /path_to_library_build/libOpenNI2.a)
details:
ld is looking for the libraries in a very short list of folders defined in
/etc/ld.so.conf
and it usually looks like following:
include /etc/ld.so.conf.d/*.conf
and actual paths list from those *.conf files usually is like:
# Legacy biarch compatibility support
/lib32
/usr/lib32
# Multiarch support
/usr/local/lib/x86_64-linux-gnu
/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu
if your project linking library is not in the folder of this list, ld won't find it unless either a special linking variable set LD_LIBRARY_PATH with the path to your library or a complete path/library name provided in cmake target_link_libraries directive.
details on how to proper setup LD_LIBRARY_PATH variable discussed here

MINGW BOOST linking fails

I'm trying to compile this code using MINGW and BOOST
http://ttic.uchicago.edu/~cotter/projects/SBP/
First I compiled this under Linux/UBUNTu and no problem. Then I tried under W764 using MINGW64. Up to level of creating object all was OK but linking failed. Here is a command
g++ issvm_evaluate.o svm_kernel_base.o svm_kernel_private_cache.o
svm_optimizer_base.o svm_optimizer_classification_biased_perceptron.o
svm_optimizer_classification_biased_sbp.o
svm_optimizer_classification_biased_smo.o
svm_optimizer_classification_biased_sparsifier.o
svm_optimizer_classification_private_find_water_level.o
svm_optimizer_classification_unbiased_perceptron.o
svm_optimizer_classification_unbiased_sbp.o
svm_optimizer_classification_unbiased_smo.o
svm_optimizer_classification_unbiased_sparsifier.o -o issvm_evaluate -fopenmp
-LC:/boost_1_57_0/boost_1_57_0/bin.v2/libs/serialization/build/gcc-mingw-
4.9.0/release/ -lstdc++ -lm -LC:/boost_1_57_0/boost_1_570/bin.v2/libs/iostreams
/build\gcc-mingw-4.9.0/release/ -LC:/boost_1_57_0/boost_1_570/bin.v2
/libs/program_options/build/gcc-mingw-4.9.0/release/
and response
issvm_evaluate.o:issvm_evaluate.cpp:(.text+0x2a81): undefined reference to boos
t::archive::detail::archive_serializer_map<boost::archive::binary_iarchive>::era
se(boost::archive::detail::basic_serializer const*)'
issvm_evaluate.o:issvm_evaluate.cpp:(.text+0x2ac1): undefined reference to `boos
t::archive::detail::archive_serializer_map<boost::archive::binary_iarchive>::era
se(boost::archive::detail::basic_serializer const*)'
Make file from LINUX using l option in gcc but I couldn't find build libraries or
file ${patsubst %,-lboost_%,$(BOOST_LIBRARIES)} under LINUX so I suspect headers were just enough but under W7 i use L option and give directory to build libraries of boost. Any idea what the problem can be ??
As build directory of BOOST in W7 contains a lot of library files including dlls maybe l option of compiler should be used and linking to dll ??
I also tried with forward slashes but its the same
Seems that i fixed my problem. The problem was multiple using of -L option with different paths which don't give multiple search paths, only 1st -L is working. Additionally
library must be explicitly specified by -l option, setting just -L which points to correct directory with sub directories with libraries was not enough. Global setting of library path by LIBRARY_PATH environment variable is working so I replaced -L with this and copied all requested libraries to just one directory and specified by -l requested libraries.

convert -l, -L on C++ linker line to full paths

I have in my make file a list of libraries to link into the executable formatted as follows:
LIBRARIES=-L/usr/lib -lmail
and I want to use it to fill out a makefile dependency list so that the executable will re-link any time one of the linked libraries changes.
I expect that I will need to translate the linker line into full paths for each library and then specify them as dependencies like so
$(EXEC_NAME) : /usr/lib/libmail.so
Is there a utility that will translate the search paths and lib names into full paths? or is there a better way to specify the makefile dependencies?

Cannot open shared object file

I am trying to compile one of the projects found here
USB-I2C/SPI/GPIO Interface Adapter.
I downloaded the i2c_bridge-0.0.1-rc2.tgz package. I installed libusb and that seemed to go well with no issues. I go into the i2c_bridge-0.0.1-rc2/ directory and make. That compiles. I move into the i2c_bridge-0.0.1-rc2/i2c folder and make. It compiles and gives me ./i2c. However, when I run it, it says error while loading shared libraries: libi2cbrdg.so: cannot open shared object file: No such file or directory
The makefile in i2c_bridge-0.0.1-rc2/i2c has the library directory as ../. The libi2cbrdg.so is in this directory (i2c_bridge-0.0.1-rc2). I also copied the file to /usr/local/lib. An ls of the i2c_bridge-0.0.1-rc2/ directory is
i2c i2cbrdg.d i2cbrdg.o libi2cbrdg.a Makefile tests
i2cbrdg.c i2cbrdg.h INSTALL libi2cbrdg.so README u2c4all.sh
(That i2c is a directory)
If I sudo ./i2c, it still gives me the problem.
I had to take away the -Werror and -noWdecrepated (spelling?) options in all the makefiles to get them to compile, but that shouldn't affect this should it?
What else is necessary for it to find the .so file? If anyone can help me find out what is wrong I would be very grateful. If more information is needed I can post it.
You have to distinguish between finding so's at compile-time and at run-time. The -L flag you give at compile-time has nothing to do with localizing the library at run-time. This is rather done via a number of variables and some paths embedded in the library.
The best hot-fix for this problem is often setting LD_LIBRARY_PATH to the directory with the .so file, e.g.:
$ LD_LIBRARY_PATH=.. ./i2c
For a long-term solution, you need to either have a close look at the whole LD system with rpath and runpath, or use libtool (which solves these issues for your portably).
Copying a file to /usr/local/lib is often insufficient because ld caches the available libraries, so you need to re-run ldconfig (as root) after you copied a library to /usr/local/lib.
If you are building the code from source that needs the the library, you can put the path that the library is in in the environment variable LD_RUN_PATH before building, and the linker will save that path into the binary, so that it will automatically be looked for in the right place at runtime.
Linux specific: Alternately, put the library in /lib, /usr/lib, or some other path referenced in your /etc/ld.so.conf or its imported config fragments, and then all you need to do is run /sbin/ldconfig to refresh ld.so (the dynamic linker)'s cache of libraries.
This works for my issue,hope will help anyone.
gcc test.c -Wl,-rpath /usr/local/lib -lfcgi -o test.fcg
And -Wl,-rpath option is the key trick.