I'm trying to install boost in a custom dir. I did:
cd boost_dir
./bootstrap.sh --prefix=/custom_dir
./b2
Now what I want to do is tell CMake to point to that library. To that end, I added:
set(BOOST_ROOT "/custom_dir")
FIND_PACKAGE(Boost COMPONENTS program_options REQUIRED)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(myProject ${Boost_LIBRARIES})
And CMake apparently found boost in that dir:
cmake .
-- Found Boost: /custom_dir (found suitable version "1.66.0", minimum required is "1.66") found components: program_options -- Configuring done
-- Generating done
-- Build files have been written to: /my_project
However, when compiling, I still get:
undefined reference to `boost::program_options::options_description::options_description(std::string const&, unsigned int, unsigned int)'
A few answers have noted that boost must have been compiled with the same compiler as the program I'm using. However, I'm not sure if the steps I did above actually compiled boost or simply copies the uncompressed libs?
Also, does it use the path-resolved g++ or something in the system default /usr/bin? Reason is that I do not have root access and installed an updated GCC in a custom dir as well. I've pointed my PATH to the updated g++.
So as it turns out, the GCC version was correct but it would only work if I compiled Boost with static linking and told CMake to link statically. I experimented with dynamic linking (both compiling Boost and setting CMake for my target app) and it doesn't work for some reason.
Just make sure to compile with the same ABI options.
Related
I'm trying to use wxWidgets on an arm64 macOS with vcpkg, CMake, and VS Code. Everything is wired up correctly because other vcpkg libraries include, link, and run fine. But, when I try to use wxWidgets there's a linking error.
My CMakeLists.txt:
cmake_minimum_required(VERSION 3.22.0)
project(main VERSION 0.1.0)
add_executable(main main.cpp)
set_property(TARGET main PROPERTY CXX_STANDARD 17)
find_package(wxWidgets REQUIRED)
include(${wxWidgets_USE_FILE})
target_include_directories(main PRIVATE ${wxWidgets_INCLUDE_DIRS})
target_link_libraries(main PRIVATE ${wxWidgets_LIBRARIES})
The CMake error I get:
[build] [ 50%] Linking CXX executable main
[build] ld: library not found for -llibjpeg.a>
[build] clang: error: linker command failed with exit code 1 (use -v to see invocation)
The value of the wxWidgets_LIBRARIES list (set by find_package(wxWidgets REQUIRED)):
-L/Users/myname/cpp/vcpkg/packages/wxwidgets_arm64-osx/lib;-pthread;/Users/myname/cpp/vcpkg/packages/wxwidgets_arm64-osx/lib/libwx_osx_cocoau_xrc-3.1.a;/Users/myname/cpp/vcpkg/packages/wxwidgets_arm64-osx/lib/libwx_osx_cocoau_qa-3.1.a;/Users/myname/cpp/vcpkg/packages/wxwidgets_arm64-osx/lib/libwx_baseu_net-3.1.a;/Users/myname/cpp/vcpkg/packages/wxwidgets_arm64-osx/lib/libwx_osx_cocoau_html-3.1.a;/Users/myname/cpp/vcpkg/packages/wxwidgets_arm64-osx/lib/libwx_osx_cocoau_core-3.1.a;/Users/myname/cpp/vcpkg/packages/wxwidgets_arm64-osx/lib/libwx_baseu_xml-3.1.a;/Users/myname/cpp/vcpkg/packages/wxwidgets_arm64-osx/lib/libwx_baseu-3.1.a;-lwx_osx_cocoau_core-3.1;libjpeg.a>;libjpeg.a>;libpng.a>;libpng16d.a>;libz.a>;libz.a>;libtiff.a>;libtiffd.a>;liblzma.a>;liblzma.a>;libjpeg.a>;libjpeg.a>;libz.a>;libz.a>;m;-framework AudioToolbox;-framework WebKit;-lwx_baseu-3.1;libexpat.a>;libexpat.a>;libz.a>;libz.a>;-lwxregexu-3.1;libiconv.tbd;-framework CoreFoundation;-framework Security;-framework Carbon;-framework Cocoa;-framework IOKit;-framework QuartzCore;TIFF::TIFF;expat::expat;ZLIB::ZLIB;png_static
I don't have much experience with CMake, so I don't know what the right angle bracket is for, but is that the problem? Could its being the first non-full-path file in the list mean that it doesn't know where to look?
-L is for directories, and -l is for individual library files. I see you have mixed .a files with directories. You'll need to fix that.
Your best bet is to debug cmake configure with --trace-expand and see who is setting wxWidgets_LIBRARIES to a incomplete and very strange generator expression libjpeg.a>;libjpeg.a>;libpng.a>;libpng16d.a>;
Another suspicious thing is that your library paths contain packages/wxwidgets_arm64-osx which indicates either wrong usage of vcpkg or there is a -config.cmake involved which was not fixed by vcpkg. (everything vcpkg finds via cmake should be living in /installed/<triplet>)
I'm linking against boost statically. When I do so, I get some undefined reference errors (below).
[100%] Linking CXX executable infiniteTests
/home/wdog/src/protos/infinite/libinfinite.a(ServiceDiscovery.cpp.o): In function `boost::date_time::month_formatter<boost::gregorian::greg_month, boost::date_time::simple_format<char>, char>::format_month(boost::gregorian::greg_month const&, std::ostream&)':
/home/wdog/src/3rdp/boost_1_63_0/boost/date_time/date_formatting.hpp:44: undefined reference to `boost::gregorian::greg_month::as_short_string() const'
/home/wdog/src/3rdp/boost_1_63_0/boost/date_time/date_formatting.hpp:49: undefined reference to `boost::gregorian::greg_month::as_long_string() const'
collect2: error: ld returned 1 exit status
When I link dynamically, the references are presumably present, and the build links successfully.
I need to be able to build this statically; requirement of the project.
I'm building with cmake. My link directories are ordered thus:
link_directories(
$ENV{PROJECT_LIB_DIR}
$ENV{BOOST_LIBRARY_DIR}
$ENV{HIREDIS_LIB_DIR}
$ENV{LIBEVENT_LIB_DIR}
$ENV{PROJECT_ROOT}
/usr/lib
/usr/local/lib
)
My target link libaries are defined as:
target_link_libraries(
${sThisProject}
${Boost_LIBRARIES}
libhiredis.a
libevent.a
libevent_core.a
libevent_pthreads.a
libssl.so
libcrypto.so
libpthread.so.0
)
Here's the CMakeLists.txt entry where I find boost:
find_package( Boost 1.63 EXACT REQUIRED COMPONENTS system chrono date_time filesystem program_options regex thread REQUIRED )
I also set the following:
SET (Boost_NO_SYSTEM_PATHS ON)
SET (Boost_USE_STATIC_LIBS ON)
SET (Boost_USE_MULTITHREADED ON)
SET (Boost_USE_STATIC_RUNTIME ON)
I've checked that my build of 1.63 has successfully built the appropriate static lib - libboost_date_time.a - and it's present in ${BOOST}/stage/lib/
It's my understanding that this can happen if the linker finds a boost static lib on the system install before the correct path.
Cmake appears to find the correct path for boost 1_63:
(output during build:)
-- Boost version: 1.63.0
-- Found the following Boost libraries:
-- system
-- chrono
-- date_time
-- filesystem
-- program_options
-- regex
-- thread
I run fedora 25, so my system installed version of boost was 1_60, so to avoid the above problem, I uninstalled it completely:
sudo dnf remove boost boost-atomic boost-chrono boost-container boost-context boost-coroutine boost-date-time boost-devel boost-filesystem boost-graph boost-iostreams boost-locale boost-log boost-math boost-program-options boost-python boost-random boost-regex boost-serialization boost-signals boost-system boost-test boost-thread boost-timer boost-type_erasure boost-wave
I built but do not install 1.63 in a 3rd party directory in my source tree. It's built with the following commands:
./bootstrap.sh
./b2 -j8
I set linker output with:
SET (CMAKE_EXE_LINKER_FLAGS -v)
And determined via the following output that I'm linking against the correct static libary:
-o
...
/home/wdog/src/3rdp/boost_1_63_0/stage/lib/libboost_system.a
/home/wdog/src/3rdp/boost_1_63_0/stage/lib/libboost_chrono.a
**/home/wdog/src/3rdp/boost_1_63_0/stage/lib/libboost_date_time.a**
/home/wdog/src/3rdp/boost_1_63_0/stage/lib/libboost_filesystem.a
/home/wdog/src/3rdp/boost_1_63_0/stage/lib/libboost_program_options.a
/home/wdog/src/3rdp/boost_1_63_0/stage/lib/libboost_regex.a
/home/wdog/src/3rdp/boost_1_63_0/stage/lib/libboost_thread.a
...
I've run out of ideas; is there something else I should check?
That libinfinite.a needs to precede the boost libraries in the command line.
First Attempt
In my cmake/c++ project I get the following error when compiling:
C:\local\projects\synergy-usb\synergy-through-usb-master>cmake .
You have called ADD_LIBRARY for library cryptopp without any source files. This typically indicates a problem with your CMakeLists.txt file
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
LIBUSB_1_INCLUDE_DIR
used as include directory in directory C:/local/projects/synergy-usb/synergy-through-usb-master/src/lib/arch
used as include directory in directory C:/local/projects/synergy-usb/synergy-through-usb-master/src/lib/net
LIBUSB_1_LIBRARY
linked by target "arch" in directory C:/local/projects/synergy-usb/synergy-through-usb-master/src/lib/arch
-- Configuring incomplete, errors occurred!
See also "C:/local/projects/synergy-usb/synergy-through-usb-master/CMakeFiles/CMakeOutput.log".
So I am missing libusb libraries.
Second Attempt
So now I have found a version of libusb_1 (libusbx-1.0.18-win) which includes the folders:
examples
include
MinGW32
MinGW64
MS32
MS64
I copied MS64/dll (windows 64-bit) contents and put it here:
C:\local\libs\libusbx
I added this path to my PATH variable and then tried to run cmake again:
C:>cd local\projects\synergy-usb\synergy-through-usb-master
C:\local\projects\synergy-usb\synergy-through-usb-master>cmake .
You have called ADD_LIBRARY for library cryptopp without any source files. This typically indicates a problem with your CMakeLists.txt file
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
LIBUSB_1_LIBRARY
linked by target "arch" in directory C:/local/projects/synergy-usb/synergy-through-usb-master/src/lib/arch
-- Configuring incomplete, errors occurred!
See also "C:/local/projects/synergy-usb/synergy-through-usb-master/CMakeFiles/CMakeOutput.log".
Now I am stuck again. I have no idea what it wants me to do. It knows where libusb is...
Edit
Here is the contects (part of) the CMakeLists.txt that has libusb in it:
find_package(libusb-1.0 REQUIRED)
set(inc
.
../base
../common
../mt
../platform
../synergy
${LIBUSB_1_INCLUDE_DIRS}
)
if (UNIX)
list(APPEND inc
../../..
../arch
)
endif()
include_directories(${inc})
add_library(arch STATIC ${src})
set(libs
../lib
${LIBUSB_1_LIBRARIES}
)
if (WIN32)
if (GAME_DEVICE_SUPPORT)
list(APPEND libs synxinhk)
endif()
endif()
target_link_libraries(arch ${libs})
Edit 2
I added the following lines into the findlibusb-1.0.cmake file:
set(LIBUSB_1_LIBRARY C:\\local\\libs\\libusbx\\libusb-1.0.dll)
message(STATUS "***********************************> LIBUSB_1_LIBRARY: ${LIBUSB_1_LIBRARY}")
Here is the output from that:
C:\local\projects\synergy-usb\synergy-through-usb-master>cmake .
-- ***********************************> LIBUSB_1_LIBRARY: C:\local\libs\libusbx\libusb-1.0.dll
-- Found libusb-1.0:
-- - Includes: C:/local/libs/libusbx
-- - Libraries: C:\local\libs\libusbx\libusb-1.0.dll
You have called ADD_LIBRARY for library cryptopp without any source files. This typically indicates a problem with your CMakeLists.txt file
-- Configuring done
CMake Error: CMake can not determine linker language for target: cryptopp
CMake Error: CMake can not determine linker language for target: cryptopp
CMake Error: CMake can not determine linker language for target: cryptopp
CMake Error: CMake can not determine linker language for target: cryptopp
-- Generating done
-- Build files have been written to: C:/local/projects/synergy-usb/synergy-through-usb-master
Still does not build, but this particular library seems to be added ok now :)
synergy had such approach to keep some 3rd party libs compressed in zip in ext subdirectory. synergy-through-usb though kept cmake way to specify include through -DLIBUSB_1_INCLUDE_DIR=... -DLIBUSB_1_LIBRARY=... for Windows.
So you just need go to 'ext' directory and uncompress its zip archives with libraries gtest, gmock and crypto.
I'm trying to use glbinding in my own project. I'm using cmake to build everything. The problem is linker cannot find this library. Probably I don't build library thus it cannot be linked, but I don't know how to achive that.
I've written linking code according to https://github.com/hpicgs/glbinding#linking-binaries.
Cmake:
set(SOURCE_FILES main.cpp)
add_executable(AKOpenGLEngine ${SOURCE_FILES})
set(CMAKE_PREFIX_PATH ${CMAKE_MODULE_PATH} glbinding )
find_package(glbinding REQUIRED)
include_directories(${GLBINDING_INCLUDES})
target_link_libraries(AKOpenGLEngine glbinding ${GLBINDING_LIBRARIES})
Error:
Linking CXX executable AKOpenGLEngine
ld: library not found for -lglbinding
main.cpp:
#include <glbinding/gl/gl.h>
int main(void) {
glbinding::Binding::initialize();
exit(EXIT_SUCCESS);
}
My current project structure:
Have you tried to remove the glbinding from target_link_libraries? ${GLBINDING_LIBRARIES} should be sufficient; it passes <your_specific_file_path_to_glbinding_library> to the linker. With -lglbinding the linker searches for a library within some default directories, your glbinding or build directory not included, thus throwing a library not found. To verify the content of ${GLBINDING_LIBRARIES} you can print it to cmake output, e.g., via message(STATUS ${GLBINDING_LIBRARIES}). However, i also suggest to integrate glbinding as external project as suggested by #janisz.
EDIT: sorry, didn't see the valid, but collapsed answer of #jet47
I downloaded libboost1.50-all in Raspberry Pi and has successfully compiled and execute a program using threads. Libraries were also found in CMake. I then copied the libraries of the boost and its include from /usr/lib and /usr/include/boost respectively to C:\Boost such that the hierarchy becomes:
C:
-> Boost
-> lib
... files
-> include
-> boost
... files
I then used the same CMakeLists.txt and the source code but the library was not found.
NOTE: The cross compiler that I used is fully working and I was able to produce an executable with CMake in Cygwin using the std library. I even specified the location of the library and the user and the root.
Is there anything that I missed out?
cmake_minimum_required(VERSION 2.8)
set(BOOST_ROOT C:/Boost/)
set(BOOST_INCLUDEDIR C:/Boost/include/)
set(BOOST_LIBRARYDIR C:/Boost/lib/)
SET(Boost_DEBUG ON)
find_package(Boost 1.50.0 COMPONENTS thread system)
if (Boost_FOUND)
include_directories (${Boost_INCLUDE_DIRS})
add_executable (thread thread.cpp)
target_link_libraries(thread ${Boost_LIBRARIES})
endif()
Use CMAKE -GUI and then check whether your boost libraries are detected . If not then manually set in the CMAKE-GUI and configure again.
TEMPORARY SOLUTION that I was able to come up to!
I placed the boost lib and include to where the cross compiler is installed since the cross compile was able to link the source code to libstdc++.
The library is placed here:
C:\cygwin\opt\cross\x-tools\arm-unknown-linux-gnueabi\arm-unknown-linux-gnueabi\sysroot\lib
The include files are placed here:
C:\cygwin\opt\cross\x-tools\arm-unknown-linux-gnueabi\arm-unknown-linux-gnueabi\include\c++\4.6.3
The CMakeLists content is as follows now:
cmake_minimum_required(VERSION 2.8)
add_executable (thread main.cpp)
target_link_libraries(thread boost_thread boost_system)
Open Cygwin terminal and invoke cmake there, then make. Viola! It now compiles successfully! :>
The magic lies in here:
target_link_libraries(thread boost_thread boost_system)
I found this in one of the questions here in Stackoverflow where someone said to manually link the libraries..
Even though that it worked, why is it that CMake cannot detect the boost library both in Windows (Cygwin terminal) and Linux (VMware) -- These I tried -- but the library was found in Raspberry Pi (Raspbian) using the same CMakeLists.txt and main.cpp. Isn't it the purpose of CMake is to find the libraries itself? If I were just to link them manually, better do it like this then:
arm-unknown-linux-gnueabi-g++.exe -lboost_thread -lboost_system