CMake doesn't add dependency libraries to the project files - visual-studio

I am writing a simple example code using pcl just as the link
http://pointclouds.org/documentation/tutorials/writing_pcd.php.
Even though I follow the link, Visual studio reports link errors.
The reason is that pcl depends on boost library and cmake doesn't
add boost library to the project setting files of visual studio.
If I add boost library with the following line, everything will be OK.
target_link_libraries(progname ${Boost_LIBRARIES})
Why doesn't CMake handle this? Is there a better solution?
CMake: 3.13.2,
Visual studio: Community 2017
PCL: PCL-1.9.1-AllInOne-msvc2017-win64.exe
Edit:
CMakeLists.txt
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
project(MY_GRAND_PROJECT)
set(Boost_DEBUG ON)
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost 1.45.0)
find_package(PCL 1.9.1 REQUIRED COMPONENTS common io)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable(pcd_write_test pcd_write.cpp)
target_link_libraries(pcd_write_test ${PCL_COMMON_LIBRARIES} ${PCL_IO_LIBRARIES} ${Boost_LIBRARIES})

According to the PCLConfig.cmake script in the official repo, Boost libraries are appended to the PCL_LIBRARIES variable. (This is performed near the end of the script).
So, for automatically link with Boost libraries when use PCL, you need to use PCL_LIBRARIES variable for linking, not PCL_<comp>_LIBRARIES variables.
I don't know, whether given behaviour is intended or not. If you assume that Boost libraries should be part of PCL_<comp>_LIBRARIES variables too, then you may fill a bug-report about that.

Related

CMake found and NOT found boost simultaneously

I am trying to install ismrmrd and following the installation guide for Windows.
In the step cmake-gui.exe my cmake is not finding installed Boost.
After adding those lines to CMakeLists.txt the result became interesting.
Any ideas?
UPDATE 8/21
thanks vre and user1234567
Now I changed to boost 1.66 and still no luck.
The new screenshot shows FindBoost is not complain anything now.
But still not any boost found.
UPDATE 8/22
After adding
cmake_policy(SET CMP0074 NEW)
and
set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_MULTITHREADED ON) find_package(Boost REQUIRED system filesystem) include_directories(${Boost_INCLUDE_DIRS}) target_link_libraries(ismrmrd ${Boost_LIBRARIES}) into CMakeLists.txt by the suggestion from vre
The resulting error became this screenshot
As it is to long for comments I try to come up with a recipe:
The commands needed for using Boost header only/static libraries are:
set(Boost_ADDITIONAL_VERSIONS 1.66.0 1.66)
set(BOOST_ROOT "C:/local/boost_1_66_0")
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
For using solely header only libraries use
find_package(Boost)
otherwise name the components (libraries) to be used after the COMPONENTS keyword and use
find_package(Boost COMPONENTS <e.g. filesystem system ...>)
if (Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
add_definitions( "-DHAS_BOOST" )
endif()
Later you reference the imported targets (libraries) for header only Boost in a call
target_link_libraries(yourproject Boost::boost)
or for named library components in a call
target_link_libraries(yourproject ${Boost_LIBRARIES})
Be sure to always delete the CMakeCache.txt file in the build directory when making changes to the CMakeLists.txt regarding Boost and Boost components, as it might cache the values of a previous CMake run.

Use framework in static library

I have a library which is being generated as .a file (to be statically linked). There I want to include Qt framework (QtCore.framework) since I am on OSX. Is that possible? How could I do it using cmake?
My attempt:
In CMakeLists.txt I have
FIND_LIBRARY(QTCORE_LIBRARY NAMES QtCore
HINTS "${CMAKE_SOURCE_DIR}/osx/frameworks")
Then I print variable ${QTCORE_LIBRARY} and it gives right path.
Then in src/CMakeLists.txt (where my sources are) I link the library
TARGET_LINK_LIBRARIES(libname $${QTCORE_LIBRARY})
However when I launch the compilation it complains because it does not find
fatal error: 'QtGlobal' file not found
I have checked and QtCore.framework contains QtGlobal header
EDIT: In case someone has same problem I found solution.
I needed to add "${QTCORE_LIBRARY}/Headers" in my project include directories
Thanks in advance and regards
Why don't using the CMake "config.cmake" provided by Qt5 ?
something like:
# Qt Setting
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets)
...
target_link_libraries(libname Qt5::Core Qt5::Gui Qt5::Widgets)
CMake can find and use [...] Qt5 libraries. [...] Qt5 libraries are found using “Config-file Packages” shipped with Qt5
src: https://cmake.org/cmake/help/latest/manual/cmake-qt.7.html
In order for find_package to be successful, Qt 5 must be found below the CMAKE_PREFIX_PATH, or the Qt5_DIR must be set in the CMake cache to the location of the Qt5WidgetsConfig.cmake file. The easiest way to use CMake is to set the CMAKE_PREFIX_PATH environment variable to the install prefix of Qt 5.
src: http://doc.qt.io/qt-5/cmake-manual.html

Boost VS2017 linking to the wrong DLL

I have a CMake file which does this:
find_package(Boost COMPONENTS system filesystem)
add_library(MyModule MODULE main.cpp)
target_include_directories(MyModule PUBLIC ${Boost_INCLUDE_DIRS})
target_link_libraries(MyModule Boost::system Boost::filesystem)
I'm using VS 2017 as my generator. When I generate the project file with cmake, it finds boost_system-vc141-mt-1_63.lib and I can see that it is in the linking rules of the vcxproj. However, when I try to compile I get this error:
LINK : fatal error LNK1104: cannot open file 'libboost_system-vc140-mt-1_63.lib
Note the different generators (vc140 vs vc141). I know my compiler has output the right values because I built boost from source, so I tried to just rename vc141 to vc140, but the error stayed the same. I also confirmed that vc140 is not referenced in the project file.
What's going on? How can I force boost to link to the correct version?
When building with Visual Studio, boost has some pragma statements which do the linking for you. This is called "Auto-linking" and it over-rides any command-line arguments you may be passing to the linker.
The solution is to define BOOST_ALL_NO_LIB. This can be done in two ways:
In source code before including boost headers as #define BOOST_ALL_NO_LIB.
It could be added to your cmake file as: add_definitions("-DBOOST_ALL_NO_LIB").
As of CMake 3.5: Use the disable_autolinking imported target:
target_link_libraries(MyModule Boost::system Boost::filesystem Boost::disable_autolinking)

Boost is using pthread but should use win32

I used Cmake gui and the FindBoost module to add Boost as a dependency in my visual studio 2010 c++ project. I set the parameter that tells FindBoost to use the win32 thread library instead of pthread (because I'm running on windows). When i build my code, all the calls to boost libraries compile fine, but boost itself is having a compile error. its failing on
boost\thread\pthread\mutex.hpp line 11
cannot open include file: 'pthread.h': No such file or directory
If I could make it use the win32 library, the mutex.hpp (and all the other files) dont call pthread.h
How do I build so that it uses boost\thread\win32 ?
here is the section of my cmakelists.txt
# include boost
set(BOOST_ROOT "E:/boost_1_58_0/boost_1_58_0")
add_definitions( -DBOOST_ALL_NO_LIB )
find_package(Boost COMPONENTS thread system)
if(Boost_FOUND)
message(STATUS "Boost was found, Success!")
# telling it to use win32 threads not pthreads
set(Boost_THREADAPI "win32")
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
endif()
CMake comes with a module called FindBoost which i used, and it correctly found the boost directory and set the following
Boost_INCLUDE_DIR
E:/boost_1_58_0/boost_1_58_0/
Boost_LIBRARY_DIR
E:/boost_1_58_0/boost_1_58_0/stage/lib
Boost_SYSTEM_LIBRARY_DEBUG
E:/boost_1_58_0/boost_1_58_0/stage/lib/boost_system-vc100-mt-gd-1_58.lib
Boost_SYSTEM_LIBRARY_RELEASE
E:/boost_1_58_0/boost_1_58_0/stage/lib/boost_system-vc100-mt-1_58.lib
Boost_THREAD_LIBRARY_DEBUG
E:/boost_1_58_0/boost_1_58_0/stage/lib/boost_system-vc100-mt-gd-1_58.lib
Boost_THREAD_LIBRARY_RELEASE
E:/boost_1_58_0/boost_1_58_0/stage/lib/boost_thread-vc100-mt-1_58.lib
visual studio project settings
C/C++ -> General -> Additional Include Directories:
...bunch of my other dependencies
E:\boost_1_58_0\boost_1_58_0
Linker -> General -> Additional Library Directories
E:/boost_1_58_0/boost_1_58_0/stage/lib;E:/boost_1_58_0/boost_1_58_0/stage/lib/$(Configuration);%(AdditionalLibraryDirectories)
Linker -> General -> Link Library Dependencies - No
Linker -> General -> Use LIbrary Dependency Inputs - No
Linker -> Input -> Additional Dependencies:
...bunch of my other .libs
boost_thread.lib
boost_system.lib
I fixed the error but I had try what I call the "dumb" way. The "smart" way didnt work. Smart way was reviewing several times the cmakelists code and the visual studio include library settings. i even did a clean and rebuild boost using b2 and manually set threading=multi and link=static because i thought maybe the library just wasnt built correct.
Finally i gave up and tried the dumb way: I cut and pasted the pthread folder and moved it somewhere else, so that it was no longer in the boost/thread folder, only the win32 folder.
I wish i tried it so long ago, because i didnt think that the compilation error would be due to my project's code, but rather an environment setting in the include and linking. But sure enough i got an error showing that in one of my project's files i was directly trying to include that mutex.hpp from the pthread folder. i didnt write this code (its open source) so i couldnt have exactly known, but still i want to slap myself
#include <boost/thread.hpp>
#include <boost/thread/pthread/mutex.hpp>
changing pthread to win32 made the error go away.

CMake and Visual Studio 2010 and Additional Library Directories

How can I tell CMake that I want it to generate a Visual Studio 2010 solution by setting also the "Additional Library Directories" field in the "Linker" section of the Project properties?
Language is C++ and not using the .NET platform, simply I want that my project to find the stage/lib dir where Boost .lib and .dll are stored...
Obviously, I have tried with following settings but, while the field Additional include dirs for the compiler are correctly set, the Additional library dirs for the linker still remains empty...
unset(Boost_LIBRARIES)
find_package(Boost 1.55.0 REQUIRED COMPONENTS system filesystem)
if(Boost_FOUND)
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(BOOST_LIBRARYDIR stage/lib)
include_directories(${Boost_INCLUDE_DIRS})
endif()
...
target_link_libraries(cpp-lib ${Boost_LIBRARIES})
I specify also that I want to use the dynamic version of Boost libs, that is why I set the switch USE_STATIC_LIBS to OFF for the use of the static version of Boost at the beginning of the CMakelists.txt.
This is what has been put in the Additional Dependencies field (beyond the usual .lib automatically specified there by Visual Studio):
C:\Program Files\boost\boost_1_56_0\stage\lib\boost_system-vc100-mt-gd-1_56.lib
C:\Program Files\boost\boost_1_56_0\stage\lib\boost_filesystem-vc100-mt-gd-1_56.lib
Beyond the wrong field in which this has been written, I would also add that the above lines are not what I want. I would like to have only the specification of the Boost .lib and .dll path, that is simply:
C:\Program Files\boost\boost_1_56_0\stage\lib\
I have tried by putting this last path in the Linker->General->Additional Library Directories field and all compiles fine, so I need a way to tell CMake to set the correct path (the last above) in the correct field (Linker->General->Additional Library Directories).
Tnx a lot
D.
By using link_directories(), I was able to update "Additional Library Directories" field in the "Linker" section of the Project properties.
find_package(Boost 1.55.0 REQUIRED COMPONENTS system filesystem)
if(Boost_FOUND)
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(BOOST_LIBRARYDIR stage/lib)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
endif()
... so I need a way to tell CMake to set the correct path (the last
above) in the correct field (Linker->General->Additional Library
Directories).
CMake link_directories maps to VS Properties->Linker->General->Additional Library Directories
Related to it, CMake target_link_libraries maps to VS Properties->Linker->Input->Additional Dependencies.
Take a look at CMake and Visual Studio which lists other CMake commands in the context of Visual Studio with an example.

Resources