I am working on a system that needs to embed python in a C++ program on Windows. I installed boost with the boost python packages and everything seems to be correct. When I run CMake it finds the debug and the release libraries from Boost python (the mt and mt-gd ones) and links them correctly with the program via TARGET_LINK_LIBRARIES. However when I build the project in Debug mode the compiler refuses to build, but when I build in Release mode everything is builds fine.
Here is the way I link the library:
FIND_PACKAGE(Python3 COMPONENTS Interpreter Development REQUIRED)
FIND_PACKAGE(Boost COMPONENTS python REQUIRED)
add_executable(ExampleProject "Example.cpp")
TARGET_LINK_LIBRARIES(ExampleProject Boost::python)
TARGET_INCLUDE_DIRECTORIES(ExampleProject PUBLIC ${Boost_INCLUDE_DIR})
I have checked that the correct boost library is linked and I have used the Boost_PYTHON_LIBRARY_DEBUG, to which the compiler says it cannot open the library:
fatal error LNK1104: cannot open file 'boost_python310-vc143-mt-gd-x32-1_79.lib'
I did notice that it does not say libboost here, but when checking the linker it does say libboost, I guess the error output is just different.
When I use Boost::python in CMake it does link but it throws unresolved external symbols like this one:
error LNK2019: unresolved external symbol "__declspec(dllimport) void __cdecl boost::python::throw_error_already_set(void)" (__imp_?throw_error_already_set#python#boost##YAXXZ) referenced in function "struct _object * __cdecl boost::python::expect_non_null<struct _object>(struct _object *)" (??$expect_non_null#U_object###python#boost##YAPAU_object##PAU2##Z)
I have also tried to set the Boost_USE_DEBUG_LIBS and Boost_USE_RELEASE_LIBS, but that did not change anything.
Furthermore the compiler does give the warning that release and debug are mixed:
warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library
Which does indicate that they have been mixed up, but when I check the linker it uses the libboost_python310-vc143-mt-gd-x32-1_79.lib which is the Debug version of the python library.
Did I miss anything? Did I do something wrong? I do not understand why this happens and I am still fairly new to CMake and Boost, but I feel like I did all that I could to make it work.
Related
Every time I try to build my project with CMAKE having the wxWidgets as library I get a lot of linker errors LNK I even get two errors for just compiling my main.cpp that only includes this :
#include "wx/wx.h"
int main(){
return 0;
}
I just downloaded the source code of wxwidgets, put it in a lib folder and linked it with cmake
This is my CMakeLists.txt :
cmake_minimum_required(VERSION 3.10)
# set the project name
project(wxtest VERSION 1.0)
add_subdirectory(libs/wxWidgets)
add_executable(wx_test WIN32 src/main.cpp)
target_link_libraries(wx_test wx::net wx::core wx::base)
Here are the errors:
Error LNK1120 1 unresolved externals
Error LNK2019 unresolved external symbol WinMain referenced in function "int __cdecl invoke_main(void)" (?invoke_main##YAHXZ)
Is there anything wrong with linking the wxWidgets lib to my project ?
wxWidgets programs are compiled as GUI Win32 applications and so use WinMain() entry point by default, which you don't define.
The usual way to define it is by using wxIMPLEMENT_APP() macro, but you may also do it manually if you really need to -- but you must define it, one way or the other.
I am trying to setup a simple C++ project with CMake and Boost libraries (Boost.Test in this case). I am following this guide except trying to link statically: https://www.jetbrains.com/help/clion/boost-test-support.html. I have installed Boost using this guide: https://www.boost.org/doc/libs/1_73_0/more/getting_started/windows.html and successfully followed step 5 to generate the library binaries.
Using the below CMake configuration, I get this error when trying to build with cmake --build .:
test1.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl boost::unit_test::unit_test_log_t::test_start(unsigned long)" (?test_start#unit_test_log_t#unit_test#boost##UEAAXK#Z)
tests2.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl boost::unit_test::unit_test_log_t::test_start(unsigned long)" (?test_start#unit_test_log_t#unit_test#boost##UEAAXK#Z)
MSVCRTD.lib(exe_main.obj) : error LNK2019: unresolved external symbol main referenced in function "int __cdecl invoke_main(void)" (?invoke_main##YAHXZ)
CMakeLists.txt
cmake_minimum_required(VERSION 3.13)
project(cmake_boost_test)
set(CMAKE_CXX_STANDARD 14)
add_executable(cmake_boost_test main.cpp)
add_subdirectory(Boost_tests)
Boost_tests/CMakeLists.txt
set(Boost_DEBUG ON)
set(Boost_USE_STATIC_LIBS ON)
find_package(Boost REQUIRED COMPONENTS unit_test_framework)
include_directories(${Boost_INCLUDE_DIRS})
add_executable(Boost_Tests_run test1.cpp tests2.cpp)
target_link_libraries(Boost_Tests_run ${Boost_LIBRARIES})
Boost_tests/test1.cpp
#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>
Boost_tests/tests2.cpp
#include <boost/test/unit_test.hpp>
There are basically 3 steps:
building boost and the relevant libraries and their variant (see here for Boost.Test)
configure the project with CMake (an example here)
build the project
It seems like you have all the steps, but what makes things difficult is that those 3 steps are related and should be done in a coherent manner:
Step 1+2: if you are building specific variants of Boost (or Boost.Test) in step 1, you have to instruct CMake with that variant
Step 3: when you build your project, your code program should in some cases be build with defines that instruct what is the variant being built. For instance if you want to link with the shared library version of Boost.Test, you have to define BOOST_TEST_DYN_LINK (in the code before any include of Boost.Test or with target_compile_definitions(test_executable PRIVATE "BOOST_TEST_DYN_LINK=1"))
In the case of Boost.Test, there is another gotcha: on Windows there is the autolink feature that will instruct the linker to link automatically with one version of a .lib: this is something I usually disable by passing a define BOOST_ALL_NO_LIB.
If you are able to make CMake detect for Boost.Test, I would not bother at the beginning with all those linking issues and use the header variant for which no linking issue is involved.
Coming back to what you have currently:
the error Could NOT find Boost (missing: unit_test_framework) (found version 1.60.0") is related to step 1+2: CMake is unable to find the libraries with the configuration you are indicating. Sometimes you need to give more variables to CMake such that it finds the right libraries, but my guess is that you just did not build the shared variant (see here). For instance I use Boost_COMPILER and Boost_ARCHITECTURE sometimes.
Boost_USE_STATIC_LIBS is an instruction for CMake only: it will not enforce the compilation of your with the right defines.
If you post the error that you get with CMake by passing -DBoost_DEBUG=ON, we will be able to support you with more precision.
How can I get around missing boost::throw_exception while building PCL?
I've built PCL on Windows (MSVC 2013) a few times in the past, but I've never see this error. It's been blocking me all today and yesterday:
LNK2019: unresolved external symbol "void __cdecl boost::throw_exception(class std::exception const &)" (?throw_exception#boost##YAXAEBVexception#std###Z) referenced in function "public: __cdecl boost::detail::shared_count::shared_count<struct pcl::io::ply::ply_parser::list_property<unsigned char,signed char> >(struct pcl::io::ply::ply_parser::list_property<unsigned char,signed char> *)" (??$?0U?$list_property#EC#ply_parser#ply#io#pcl###shared_count#detail#boost##QEAA#PEAU?$list_property#EC#ply_parser#ply#io#pcl###Z) [C:\Users\mrussell\.conan\data\pcl\1.7.2\ntc\stable\build\d63ff451cbfa147e3b952f2f3790530e1116d93c\io\pcl_io_ply.vcxproj]
It appears that BOOST_NO_EXCEPTIONS is set in boost\config\compiler\visualc.hpp, which prevents boost/throw_exception.hpp from defining it.
I've tried to set TPN_WIN32 to /EHsc (see this answer) both through CMake and via the project properties in Visual Studio to no avail, and even tried sneaking a definition into a high level PCL include (see this answer), nothing worked.
My CMake generator is Visual Studio 12 2013 Win64 and my definitions are:
-DBOOST_ROOT:PATH=%CONAN_BOOST%
-DCMAKE_INSTALL_PREFIX=%CONAN_PCL%
-DEIGEN3_DIR:PATH=%CONAN_EIGEN%\share\eigen3\cmake
-DEIGEN_INCLUDE_DIR:PATH=%CONAN_EIGEN%\include\eigen3
-DFLANN_INCLUDE_DIR:PATH=%CONAN_FLANN%\include
-DFLANN_LIBRARY:FILEPATH=%CONAN_FLANN%\lib\libflann_cpp.so
-DQHULL_INCLUDE_DIR:PATH=%CONAN_QHULL%\include
-DQHULL_LIBRARY:FILEPATH=%CONAN_QHULL%\lib\libqhull.so
-DGTEST_ROOT:PATH=%CONAN_GTEST%
-DBUILD_surface_on_nurbs:BOOL=ON
I've tried:
Removing Qt & VTK
With Boost 1.60, 1.66, and 1.59
Linking against a shared and static versions of boost. (PCL does not seem to like shared boost on Windows...)
Attempting to build shared and static versions of PCL
I feel like I'm chasing the wrong thing, or am missing something. Maybe I'm missing a _CPPUNWIND define for exceptions? I'm really just stuck.
TPN_WIN32 is a user defined variable on that post you reference. You need to append /EHsc to your CMAKE_CXX_FLAGS to pass it to the compiler.
Unrelated but really suspicious -DFLANN_LIBRARY:FILEPATH=%CONAN_FLANN%\lib\libflann_cpp.so is a unix dynamic library. You can't link it on windows with MSVC.
I installed and integrated latest version of vcpkg:
e:\work\vcpkg>vcpkg version
Vcpkg package management program version 0.0.65-692a363701156f1bc319306fbde93fb6748325f6
See LICENSE.txt for license information.
e:\work\vcpkg>vcpkg integrate install
Applied user-wide integration for this vcpkg root.
All C++ projects can now #include any installed libraries.
Linking will be handled automatically.
Installing new libraries will make them instantly available.
I installed google test:
e:\work\vcpkg>vcpkg list
gtest:x64-windows 1.8 GoogleTest and GoogleMock testing frameworks.
gtest:x86-windows 1.8 GoogleTest and GoogleMock testing frameworks.
I included gtest.h in my project in Visual Studio 2015 Update 3:
#include <gtest/gtest.h>
It compiles fine, but I have linker errors:
1>main.obj : error LNK2001: unresolved external symbol "void __cdecl testing::InitGoogleTest(int *,char * *)" (?InitGoogleTest#testing##YAXPEAHPEAPEAD#Z)
1>main.obj : error LNK2001: unresolved external symbol "public: int __cdecl testing::UnitTest::Run(void)" (?Run#UnitTest#testing##QEAAHXZ)
1>main.obj : error LNK2001: unresolved external symbol "public: static class testing::UnitTest * __cdecl testing::UnitTest::GetInstance(void)" (?GetInstance#UnitTest#testing##SAPEAV12#XZ)
Apparently, Visual Studio does not know it should link with gtest.lib. And I cannot understand why. Vcpkg only says that "Linking will be handled automatically." No idea how it is going to do this.
In "Additional Library Dependencies" of my project I can see these inherited values:
$(VcpkgRoot)lib
$(VcpkgRoot)lib\manual-link
And $(VcpkgRoot) is resolved to e:\work\vcpkg\installed\x64-windows\. So it seems like integration was successful. But how Visual Studio knows it should link with gtest.lib?
Note that if I add gtest.lib to "Additional Dependencies" manually, all works fine, and gtest.dll is automatically copied to output directory.
I think that the autolinking behavior has been intentionally disabled for gtest, see vcpkg issue #306.
Original comment on the issue: here.
The vcpkg implementation requires manual linking because Google Test can redefine main(), and the gtest functionality is duplicated in all of the four separate library files.
Official documentation.
The required per project configuration:
In: Configuration Properties > Linker > Input > Additional Dependencies
For release-builds:
$(VcpkgRoot)lib\manual-link\gtest_main.lib
For debug-builds:
$(VcpkgRoot)debug\lib\manual-link\gtest_main.lib
If you want to create your own custom main(), replace gtest_main.lib with gtest.lib.
If you want to use gmock, you can replace it with gmock_main.lib or gmock.lib.
This is an old thread but I would like to point out what I've found.
You need to link the libs in the manual-link directory, but you need to link them in the right order.
First link gmock_main then gtest_main.
The other way around just results in 0 test.
I have a large and complicated project that is finally getting unit tests. I've built googleTest 1.6.0 locally with Visual Studio 2010, the project files built with cmake as the README specifies.
This project has many dependent libraries that are statically and dynamically linked. Many of them proprietary. All attempts to link generate 220 such errors. Here is a sampling:
msvcprtd.lib(MSVCP100D.dll) : error LNK2005: "public: void __cdecl std::_Container_base12::_Orphan_all(void)" (?_Orphan_all#_Container_base12#std##QEAAXXZ) already defined in gtest.lib(gtest-all.obj)
libcpmtd.lib(cerr.obj) : error LNK2005: "protected: char * __cdecl std::basic_streambuf >::_Gndec(void)" (?_Gndec#?$basic_streambuf#DU?$char_traits#D#std###std##IEAAPEADXZ) already defined in msvcprtd.lib(MSVCP100D.dll)
LIBCMTD.lib(setlocal.obj) : error LNK2005: _configthreadlocale already defined in MSVCRTD.lib(MSVCR100D.dll)
LINK : warning LNK4098: defaultlib 'MSVCRTD' conflicts with use of other libs; use /NODEFAULTLIB:library
LINK : warning LNK4098: defaultlib 'LIBCMTD' conflicts with use of other libs; use /NODEFAULTLIB:library
fatal error LNK1169: one or more multiply defined symbols found
I've tried the /NODEFAULTLIB flag, and I've tried to ignore just msvcprtd.lib, MSVCRTD.lib, and LIBCMTD.lib, as suggested, but then I suffer from unresolved symbols...
Both the project and googleTest are compiled with x64, /MP, /MDd, and no /clr.
I've been playing around with compiler flags, wondering if there's some sort of version mismatch. Dumpbin, to the extent with which I understand it, hasn't hinted anything I might understand. I was hoping for an er
It looks like your question is answered in Google Talk's FAQ. Make sure all your libraries use the /MD(d) setting.
You may get a number of the following linker error or warnings if you attempt to link your test project with the Google Test library when your project and the are not built using the same compiler settings.
LNK2005: symbol already defined in object
LNK4217: locally defined symbol 'symbol' imported in function 'function'
LNK4049: locally defined symbol 'symbol' imported
The Google Test project (gtest.vcproj) has the Runtime Library option set to /MT (use multi-threaded static libraries, /MTd for debug). If your project uses something else, for example /MD (use multi-threaded DLLs, /MDd for debug), you need to change the setting in the Google Test project to match your project's.
To update this setting open the project properties in the Visual Studio IDE then select the branch Configuration Properties | C/C++ | Code Generation and change the option "Runtime Library". You may also try using gtest-md.vcproj instead of gtest.vcproj.