Using static Boost libraries with vcpkg and CMake - c++

I'm using the package manager vcpkg to install the (static) Boost libraries via vcpkg install boost:x64-windows-static.
Furthermore, I use CMake as my build system and I'm passing C:\vcpkg\scripts\buildsystems\vcpkg.cmake to CMake via the -DCMAKE_TOOLCHAIN_FILE CMake command.
In my CMakeLists.txt I force static Boost libraries:
set(Boost_USE_STATIC_LIBS ON)
find_package(Boost COMPONENTS filesystem iostreams REQUIRED)
if (Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
endif ()
# ...
target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES})
However, Visual Studio still tries to look at the wrong file path for my Boost libraries:
Error 'C:/vcpkg/installed/x64-windows/lib/boost_filesystem-vc140-mt.lib', needed by 'MyProject.exe', missing and no known rule to make it
If I install the dynamic Boost libraries, it will build fine since this is where Visual Studio looks. However, I want to use the static libraries in my build instead so that all DLLs are "merged" into the final EXE.
How can I accomplish this?

I had the same problem.
Solved with
define set(Boost_INCLUDE_DIR "path")
before find_package force.
When you using cmake with vcpkg, find _VCPKG_INSTALLED_DIR variable in CmakeCache.txt
set(Boost_INCLUDE_DIR ${_VCPKG_INSTALLED_DIR}/x64-windows-static/include)

It seems that by default vcpkg.cmake script auto-detect dynamic libraries that are installed by vcpkg.
You can override this behavior for your project by setting a variable when invoking cmake:
cmake .. -DCMAKE_TOOLCHAIN_FILE=.../vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static
Or using the CMakePresets.json:
"cacheVariables": {
...
"CMAKE_TOOLCHAIN_FILE": {
"value": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
"type": "FILEPATH"
},
"VCPKG_TARGET_TRIPLET": "x64-windows-static"
},
I haven't yet found how to do this on a per library basis.
More details here and here.

Actually, what I have found to work correctly is the following CMake:
# Boost settings
set(Boost_USE_STATIC_LIBS ON) # only find static libs
set(Boost_USE_DEBUG_LIBS OFF) # ignore debug libs and
set(Boost_USE_RELEASE_LIBS ON) # only find release libs
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME ON) # link Boost Static libraries

Related

custom boost prefix/namspace - how to build with

I need to use custom build of boost lib, which uses own library naming prefix as well as namespace in the code.
I need to link with it in CMakeLists.txt:
set(BOOST_INCLUDEDIR /path/to/custom/boost/include)
set(BOOST_LIBRARYDIR /path/to/custom/boost/lib)
set(BOOST_NAMESPACE my_boost_161)
set(Boost_NO_SYSTEM_PATHS OFF)
set (Boost_USE_STATIC_LIBS OFF)
find_package (Boost REQUIRED COMPONENTS my_unit_test_framework)
include_directories (${Boost_INCLUDE_DIRS})
the libraries have a names like :
libmy_boost_161_unit_test_framework.so
and really exist in lib folder
there is a errors like:
CMake Error at
/home/user1/.localcmake/share/cmake-3.14/Modules/FindBoost.cmake:2132
(message): Unable to find the requested Boost libraries.
Boost version: 1.61.0
Boost include path:
/path/to/custom/boost/include
Could not find the following Boost libraries:
boost_unit_test_framework
No Boost libraries were found. You may need to set BOOST_LIBRARYDIR
to the directory containing Boost libraries or BOOST_ROOT to the
location of
How can I specify to look for libs with names like (my_ addition to standard names):
similar to Boost_LIB_VERSION which gives an ability to add the version to lib name
my_boost_161_unit_test_framework
This addition to the CMake script fixes the problem:
...
set(Boost_NO_SYSTEM_PATHS OFF)
set(Boost_LIB_PREFIX my_boost_161)
set(Boost_NAMESPACE my_boost_161)
set(Boost_USE_STATIC_LIBS OFF)
...

cmake cannot find boost in a custom location or stock location

This question is one that has occurred before on SO. For instance this question:
Cmake doesn't find Boost
But the answers there and elsewhere don't seem to work.
On Ubuntu 16.04 with the stock boost 1.58.0 installed, I have also built, in a custom location, boost 1.68.0.
Now I am trying to compile a simple c++ program using boost, with cmake. It does not find boost. Either version (although 1.68.0 is the one I really want to use).
It gives:
-- Could NOT find Boost (missing: Boost_DIR)
The CMakeLists.txt file is below. CMake 3.12.1 is being used.
cmake_minimum_required(VERSION 3.0.0)
set(CMAKE_CXX_STANDARD 17)
project(mytest CXX)
set(Boost_DEBUG ON)
set(Boost_DETAILED_FAILURE_MSG ON)
set(BOOST_ROOT /home/hal/projects/boost/boost)
# set(Boost_DIR /home/hal/projects/boost/boost)
#set(Boost_USE_DEBUG_LIBS ON)
#set(Boost_USE_STATIC_LIBS ON)
#set(Boost_USE_MULTITHREADED ON)
# set(Boost_USE_STATIC_RUNTIME OFF)
#set(Boost_INCLUDE_DIR /home/hal/projects/boost/boost )
set(Boost_ADDITIONAL_VERSIONS "1.58" "1.58.0")
#set(BOOST_INCLUDEDIR /home/hal/projects/boost/boost/include )
#set(BOOST_LIBRARYDIR /home/hal/projects/boost/boost/lib )
#SET(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "/home/hal/projects/boost/boost")
#SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "/home/hal/projects/boost/boost/lib")
find_package(Boost 1.68.0 COMPONENTS system date_time PATHS /home/hal/projects/boost/boost )
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
add_executable(mytest main.cpp)
target_link_libraries(mytest ${Boost_LIBRARIES} stdc++)
endif()
Unless you work with implementing of searching packaging, option PATHS for find_package is not such useful, just remove it:
find_package(Boost 1.68.0 COMPONENTS system date_time)
Explanations
There are two ways for search packages in CMake:
With XXXConfig.cmake script, shipped with a specific package installation. In this script all paths (libraries, include directories, etc.) are hardcoded.
With FindXXX.cmake script, shipped with CMake itself. This script searches the libraries and headers under the system directories (like /usr/local/lib) but also takes hints from the user.
By default, the second way is tried; only if FindXXX.cmake script is absent, the first way is used.
But some options for find_package are applied only for the first way, and PATHS is exactly an option of this sort: it specifies paths where XXXConfig.cmake file can be found. With such options, find_package uses the second way - it tries to find XXXConfig.cmake script and execute it. But it seems that your Boost installation lacks of this config script, so CMake fails to find Boost.

CMake user built libraries; cannot specify link libraries for target

I'm building a project in Cpp that will communicate with my Java apps via rabbitmq and post updates to twitter. I'm using a few libraries from github
rabbitmq-c
Rabbit installed to /usr/local/lib64
jansson - json library
I installed this a while back for another project, went to /usr/local/lib
twitcurl - C lib for Twitter API
Got installed to /usr/local/lib
If it matters, I'm using CLion as my IDE, which displays jansson and rabbit under auto-complete when defining includes - so that's picking the libs off my system somehow
e.g.
#include <jansson.h>
#include <amqp.h>
I link them using the target_link_libraries(name libs...) and I see output saying
build$ cmake ..
CMake Error at CMakeLists.txt:30 (target_link_libraries):
Cannot specify link libraries for target "twitcurl" which is not built by
this project.
I set LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib64
I try to set the CMAKE_LIBRARY_PATH to include usr/local/lib and lib64 but doesn't seem to have any effect. Here's my CMakeLists.txt file
#
# This is a CMake makefile. You can find the cmake utility and
# information about it at http://www.cmake.org
#
cmake_minimum_required(VERSION 2.6)
set(PROJECT_NAME twitterUpdater)
set(SOURCE_FILES main.cpp)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "/usr/local/lib"
"/usr/local/lib64")
project(${PROJECT_NAME})
find_package(X11 REQUIRED)
find_package(OpenCV REQUIRED)
IF (X11_FOUND)
INCLUDE_DIRECTORIES(${X11_INCLUDE_DIR})
LINK_LIBRARIES(${X11_LIBRARIES})
ENDIF ( X11_FOUND )
IF (OpenCV_FOUND)
include_directories(${OpenCV_INCLUDE_DIRS})
link_libraries(${OpenCV_LIBS})
ENDIF(OpenCV_FOUND)
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
target_link_libraries(${project_name} twitcurl jansson rabbitmq)
What's confusing me is another project I have uses jansson by simply adding it here TARGET_LINK_LIBRARIES(${project_name} dlib jansson)
What did I miss?? Thanks
CMake variables are case sensitive, thus the variable ${project_name} results in an empty string. Use ${PROJECT_NAME} instead, i.e.:
target_link_libraries(${PROJECT_NAME} twitcurl jansson rabbitmq)
Running CMake with the flag --warn-uninitialized helps you detect mistakes like this.

Cannot find boost with CMake on Linux Mint

I have been working on a library in C++ and have run into a bit of difficulty trying to integrate boost into my project. I kept the message that boost could not be found, but on the other hand, my fellow developer using Arch had no issues.
We figured out that this is because Linux Mint (at least with the libboost-all-dev package) installs the libraries to /usr/lib/x86_64-linux-gnu which is not searched by the FindBoost module. We fixed this by creating symbolic links:
ln -s /usr/lib/x86_64-linux-gnu/libboost* /usr/lib/
What I want to know: is there a better (more acceptable) way of fixing this because when I compile major projects, I do not run into this problem.
Here is CMakeLists.txt (with some omissions)
cmake_minimum_required(VERSION 2.8)
project(testlibrary CXX)
set(CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS}")
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED OFF)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost 1.55.0 COMPONENTS unit_test_framework thread log REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})
add_library(testlibrary STATIC ${SOURCE_MAIN})
target_link_libraries(testlibrary ${Boost_LIBRARIES})
You can set the hint BOOST_LIBRARYDIR:
set(BOOST_LIBRARYDIR "/usr/lib/x86_64-linux-gnu")
find_package(Boost 1.55.0 COMPONENTS unit_test_framework thread log REQUIRED)
Alternative, you can set this when running CMake like this:
cmake -DBOOST_LIBRARYDIR="/usr/lib/x86_64-linux-gnu" <project_root>
If you just run:
cmake <project_root>
then FindBoost.cmake will look in the usual spots for your boost libaries.
See the documentation of FindBoost.cmake for your CMake version here.

Cmake error when adding Boost library

I am trying to add Boost library to my project using the CMakeLists.txt in the follwing way:
set(BOOST_INCLUDEDIR "C:/boost_1_57_0")
set(BOOST_LIBRARYDIR "C:/boost_1_57_0/stage/lib")
find_package(Boost 1.57.0 COMPONENTS filesystem)
include_directories(${Boost_INCLUDE_DIRS})
add_executable(test test.cpp)
target_link_libraries(test ${Boost_LIBRARIES})
However, I get the followng error: LINK : fatal error LNK1104: cannot open file 'libboost_filesystem-vc120-mt-1_57.lib'
libboost_filesystem-vc120-mt-1_57.lib is located in the stage/lib folder, so I don't know what is going on. I am compiling with Visual Studio 2013.
Any thoughts?
Try setting the Boost_USE_STATIC_LIBS and Boost_USE_MULTITHREADED CMake variables to ON before using find_package, i.e.:
set( Boost_USE_STATIC_LIBS ON )
set( Boost_USE_MULTITHREADED ON )
find_package( Boost 1.57.0 COMPONENTS filesystem )
I've come across this problem before and it seems as though, on multithreaded windows systems, the Boost bootstrap installer compiles multithreaded, static libraries by default. However, the CMake FindBoost script (which is used by find_package) searches for single-threaded, dynamic libraries by default.
Since you're using VS compiler I'll say you're working on Windows.
The error refers to the linker, which is failing to find boost libraries, as noticed.
Taking into account that the library exists in the boost path, my solution was to do a file(COPY) for the specific library, as a last resort.
if(WIN32)
set(BOOST_ROOT "C:/boost_1_57_0")
set(BOOST_LIBRARYDIR ${BOOST_ROOT}/stage/lib/)
endif()
find_package(Boost 1.57.0 EXACT REQUIRED system filesystem)
if(Boost_FOUND)
message(STATUS "found boost, Boost_LIBRARIES <" ${Boost_LIBRARIES} ">")
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
else()
message(STATUS "boost not found")
endif()
target_link_libraries(boost_test ${Boost_LIBRARIES})
file(COPY "${Boost_LIBRARY_DIRS}/boost_filesystem-vc120-mt-1_57.dll" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
You may add some log messages to the CMake in order to know the values returned in the
find_package.
Make sure the architecture (x64) matches.
$ cmake -A x64 ..
Use link_directories command before adding executables just like include_directories.
link_directories(${Boost_LIBRARY_DIRS})