I am trying to build a project on Windows using CMake and MinGW.
When using the command mingw32-make.exe I got link errors for any boost library (except for unit_test library), as for example: "undefined reference to `boost::chrono::system_clock::now()'"
My boost installation is under C:\boost\ that contains both include and lib directories. I know that the boost installation is correct because if I use a handmade Makefile and I link the libraries with -l I can compile my project without any issue. So I guess the problem is related to how I link libraries in my CMakeLists.txt.
I tried these solution but they didn't work:
- CMake Boost Static Libraries Undefined Reference boost::chrono::steady_clock::now()
- Cmake with "undefined references" Despite Finding Boost Libs
- Undefined reference to 'boost::system::generic_category()'?
This is the CMakeLists I am using, that correctly finds the libraries, as printed by Boost_DEBUG:
CMAKE_MINIMUM_REQUIRED(VERSION 3.23)
SET(CMAKE_CXX_STANDARD 11)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
SET(CMAKE_CXX_EXTENSIONS OFF)
SET(Boost_USE_STATIC_LIBS ON)
SET(Boost_DETAILED_FAILURE_MSG OFF)
SET(Boost_USE_MULTITHREADED ON)
SET(Boost_THREADAPI win32)
SET(BOOST_ROOT "C:\\boost")
SET(Boost_LIBRARY_DIR "C:\\boost\\lib")
SET(Boost_INCLUDE_DIR "C:/boost/include/boost-1_76")
SET(Boost_INCLUDE_DIRS "C:/boost/include/boost-1_76")
SET(Boost_USE_STATIC_RUNTIME OFF)
SET(Boost_DEBUG ON)
PROJECT(myproject LANGUAGES CXX)
find_package(Boost 1.76.0
COMPONENTS
log
system
timer
chrono
unit_test_framework
REQUIRED
)
add_executable(test_cmake test_cmake.cpp)
target_include_directories(test_cmake PRIVATE ${Boost_INCLUDE_DIRS})
target_include_directories(test_cmake PRIVATE ${Boost_LIBRARY_DIR})
target_link_libraries(test_cmake
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
${Boost_LIBRARIES}
)
This is the simple main file that can be compiled and produces "undefined reference to `boost::chrono::system_clock::now()'" error.
#define BOOST_AUTO_TEST_MAIN
#define BOOST_TEST_DYN_LINK
#include <boost/test/included/unit_test.hpp>
#include <turtle/mock.hpp>
// #include <boost/chrono.hpp> // I tried this too but it didn't work as well
#include <boost/chrono/chrono.hpp>
/**
* @brief Test of boost chrono library
*/
BOOST_AUTO_TEST_CASE(test_boost_chrono) {
auto start_time = boost::chrono::system_clock::now();
int sleep_time = 1000;
// boost::this_thread::sleep_for(boost::chrono::milliseconds(sleep_time));
auto curr_time = boost::chrono::system_clock::now();
auto diff_time = boost::chrono::duration_cast<boost::chrono::milliseconds>(curr_time - start_time);
BOOST_CHECK(diff_time.count() > sleep_time);
int epsilon = 10;
BOOST_CHECK(diff_time.count() < (sleep_time + epsilon));
}
I think the problem is related to target_include_directories and target_link_libraries but I cannot understand which is the issue.
Do you have any suggestion?
Edit:
This is what I get when compiling with mingw32-make.exe VERBOSE=1
:
PS C:\Workspace\test_cmake_project_cmake\build> mingw32-make.exe VERBOSE=1
"C:\Program Files\CMake\bin\cmake.exe" -SC:\Workspace\test_cmake_project_cmake -BC:\Workspace\test_cmake_project_cmake\build --check-build-system CMakeFiles\Makefile.cmake 0
"C:\Program Files\CMake\bin\cmake.exe" -E cmake_progress_start C:\Workspace\test_cmake_project_cmake\build\CMakeFiles C:\Workspace\test_cmake_project_cmake\build\\CMakeFiles\progress.marks
C:/MinGW/bin/mingw32-make -f CMakeFiles\Makefile2 all
mingw32-make[1]: Entering directory 'C:/Workspace/test_cmake_project_cmake/build'
C:/MinGW/bin/mingw32-make -f test_cmake\CMakeFiles\test_cmake.dir\build.make test_cmake/CMakeFiles/test_cmake.dir/depend
mingw32-make[2]: Entering directory 'C:/Workspace/test_cmake_project_cmake/build'
"C:\Program Files\CMake\bin\cmake.exe" -E cmake_depends "MinGW Makefiles" C:\Workspace\test_cmake_project_cmake C:\Workspace\test_cmake_project_cmake\test_cmake C:\Workspace\test_cmake_project_cmake\build C:\Workspace\test_cmake_project_cmake\build\test_cmake C:\Workspace\test_cmake_project_cmake\build\test_cmake\CMakeFiles\test_cmake.dir\DependInfo.cmake --color=
Dependencies file "test_cmake/CMakeFiles/test_cmake.dir/test_cmake.cpp.obj.d" is newer than depends file "C:/Workspace/test_cmake_project_cmake/build/test_cmake/CMakeFiles/test_cmake.dir/compiler_depend.internal".
Consolidate compiler generated dependencies of target test_cmake
mingw32-make[2]: Leaving directory 'C:/Workspace/test_cmake_project_cmake/build'
C:/MinGW/bin/mingw32-make -f test_cmake\CMakeFiles\test_cmake.dir\build.make test_cmake/CMakeFiles/test_cmake.dir/build
mingw32-make[2]: Entering directory 'C:/Workspace/test_cmake_project_cmake/build'
[ 50%] Linking CXX executable test_cmake.exe
cd /d C:\Workspace\test_cmake_project_cmake\build\test_cmake && "C:\Program Files\CMake\bin\cmake.exe" -E cmake_link_script CMakeFiles\test_cmake.dir\link.txt --verbose=1
"C:\Program Files\CMake\bin\cmake.exe" -E rm -f CMakeFiles\test_cmake.dir/objects.a
C:\MinGW\bin\ar.exe qc CMakeFiles\test_cmake.dir/objects.a @CMakeFiles\test_cmake.dir\objects1.rsp
C:\MinGW\bin\g++.exe -g -Wl,--whole-archive CMakeFiles\test_cmake.dir/objects.a -Wl,--no-whole-archive -o test_cmake.exe -Wl,--out-implib,libtest_cmake.dll.a -Wl,--major-image-version,0,--minor-image-version,0 @CMakeFiles\test_cmake.dir\linklibs.rsp
CMakeFiles\test_cmake.dir/objects.a(test_cmake.cpp.obj): In function `main':
C:/Workspace/test_cmake_project_cmake/test_cmake/test_cmake.cpp:6: undefined reference to `boost::chrono::system_clock::now()'
C:/Workspace/test_cmake_project_cmake/test_cmake/test_cmake.cpp:11: undefined reference to `boost::chrono::system_clock::now()'
collect2.exe: error: ld returned 1 exit status
mingw32-make[2]: *** [test_cmake\CMakeFiles\test_cmake.dir\build.make:99: test_cmake/test_cmake.exe] Error 1
mingw32-make[2]: Leaving directory 'C:/Workspace/test_cmake_project_cmake/build'
mingw32-make[1]: *** [CMakeFiles\Makefile2:97: test_cmake/CMakeFiles/test_cmake.dir/all] Error 2
mingw32-make[1]: Leaving directory 'C:/Workspace/test_cmake_project_cmake/build'
mingw32-make: *** [Makefile:90: all] Error 2
Edit:
It seems it was an issue of Visual Studio Code: maybe some variables were set with wrong values and CMake could not link boost.
Finally I have created a new project and I have used a minimal CMakeLists without setting any boost variable but BOOST_ROOT (SET(BOOST_ROOT "C:\\boost")
and now it works!!
Unfortunately I did not find the real reason :(, but cleaning the project and starting from scretch helped! Thanks everybody!