非常感谢您阅读这篇长文章! 我正在尝试配置CMake项目以与Boost和Catch2一起使用,但是boost无法从某个文件夹链接。对于简短版本,只需跳至问题。我将解释设置,然后说明问题。
设置:
. ~/.bashrc
(从devtoolset 8安装,系统上的标准是:libstdc++.so.6 (libc6,x86-64) => /lib64/libstdc++.so.6
libstdc++.so.6 (libc6) => /lib/libstdc++.so.6
Red Hat Enterprise Linux Server release 7.6 (Maipo)
gcc (GCC) 8.2.1 20180905 (Red Hat 8.2.1-3)
)
我目前正在尝试设置cmake构建系统。不幸的是,在当前的开发机器上,boost已安装,所以我的boost位于
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36)
当我看着BOOST_INCLUDE_DIR=/opt/boost/boost_1_69_0/boost/
BOOST_LIB_DIR=/opt/boost/current/stage/release/lib/
时,我可以看到正确的版本/opt/boost/boost_1_69_0/boost/
我还知道这些库是版本1_69,因为它们的编译名称为#define BOOST_LIB_VERSION "1_69"
很遗憾,系统已经安装了boost,所以libboost_math_tr1f-gcc8-mt-x64-1_69.so.1.69.0
包含/usr/include/boost/version.hpp
这是我当前的树
#define BOOST_LIB_VERSION "1_53"
这是我的2个Cmake文件:
├── bin
│ ├── debug
│ │ └── libtest_utility.a
│ └── release
│ └── libtest_utility.a
├── build
│ ├── debug
│ └── release
├── CMakeLists.txt
├── include
│ └── test_utility.h
├── src
│ ├── exmaple.cpp
│ └── test_utility.cpp
└── test
├── bin
│ ├── debug
│ └── release
├── build
│ ├── debug
│ └── release
├── CMakeLists.txt
└── src
├── main2.cpp
└── main.cpp
测试Cmake文件:
cmake_minimum_required(VERSION 3.13)
set (NAME "test_utility")
set (TestUtility_VERSION_MAJOR 0)
set (TestUtility_VERSION_MINOR 1)
set (TestUtility_VERSION_PATCH 0)
set (TestUtility_VERSION_STRING ${TestUtility_VERSION_MAJOR}.${TestUtility_VERSION_MINOR}.${TestUtility_VERSION_PATCH})
project(TestUtility
VERSION ${TestUtility_VERSION_STRING}
DESCRIPTION "Testing the library target utility in Cmake"
LANGUAGES CXX)
set (DEV_ROOT $ENV{DEV_ROOT})
set (BOOST_INCLUDE_DIR $ENV{BOOST_INCLUDE_DIR})
set (BOOST_LIB_DIR $ENV{BOOST_LIB_DIR})
set (PROJECT_SOURCES "${DEV_ROOT}/${NAME}/src/test_utility.cpp"
"${DEV_ROOT}/${NAME}/include/test_utility.h" )
add_library (${NAME} STATIC ${PROJECT_SOURCES})
target_include_directories (${NAME} PUBLIC "${DEV_ROOT}/${NAME}/include"
PRIVATE "${BOOST_INCLUDE_DIR}")
target_link_directories (${NAME} PRIVATE ${BOOST_LIB_DIR})
target_link_options(${NAME} PRIVATE "-Wl --verbose")
if(CMAKE_BUILD_TYPE MATCHES DEBUG)
target_link_libraries(${NAME} libboost_regex-gcc8-mt-d-x64-1_69.a)
ELSEIF(CMAKE_BUILD_TYPE MATCHES RELEASE)
target_link_libraries(${NAME} libboost_regex.a)
ENDIF()
set_target_properties(${NAME} PROPERTIES VERSION ${TestUtility_VERSION_STRING}
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${DEV_ROOT}/${NAME}/bin/debug"
ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${DEV_ROOT}/${NAME}/bin/release")
问题
当我在实际的build文件夹中运行cmake_minimum_required(VERSION 3.13)
set (NAME "test_utility")
set (TEST_NAME "test_${NAME}")
set (TestUtility_VERSION_MAJOR 0)
set (TestUtility_VERSION_MINOR 1)
set (TestUtility_VERSION_PATCH 0)
set (TestUtility_VERSION_STRING ${TestUtility_VERSION_MAJOR}.${TestUtility_VERSION_MINOR}.${TestUtility_VERSION_PATCH})
project(Test_TestUtility
VERSION ${TestUtility_VERSION_STRING}
DESCRIPTION "Testing the library target utility in Cmake"
LANGUAGES CXX)
set (DEV_ROOT $ENV{DEV_ROOT})
set (BOOST_INCLUDE_DIR $ENV{BOOST_INCLUDE_DIR})
set (BOOST_LIB_DIR $ENV{BOOST_LIB_DIR})
set (CATCH_INCLUDE_DIR $ENV{CATCH_INCLUDE_DIR})
set (PROJECT_SOURCES "${DEV_ROOT}/${NAME}/test/src/main.cpp"
"${DEV_ROOT}/${NAME}/src/test_utility.cpp"
"${DEV_ROOT}/${NAME}/include/test_utility.h" )
add_executable (${TEST_NAME} ${PROJECT_SOURCES})
target_include_directories (${TEST_NAME} PUBLIC "${DEV_ROOT}/${NAME}/include"
PRIVATE "${BOOST_INCLUDE_DIR}"
PRIVATE "${CATCH_INCLUDE_DIR}")
target_link_directories (${TEST_NAME} PRIVATE ${BOOST_LIB_DIR})
if(CMAKE_BUILD_TYPE MATCHES DEBUG)
target_link_libraries(${TEST_NAME} libboost_regex-gcc8-mt-d-x64-1_69.a)
ELSEIF(CMAKE_BUILD_TYPE MATCHES RELEASE)
target_link_libraries(${TEST_NAME} libboost_regex.a)
ENDIF()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_GLIBCXX_USE_CXX11_ABI=1")
set_target_properties(${TEST_NAME} PROPERTIES VERSION ${TestUtility_VERSION_STRING}
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${DEV_ROOT}/${NAME}/test/bin/debug"
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${DEV_ROOT}/${NAME}/test/bin/release")
add_test(NAME ${TEST_NAME}
COMMAND ${NAME} )
时,一切都会完美构建。当我在测试的build文件夹中运行它时,出现以下链接错误 cmake ../.. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=RELEASE
。
所以我添加了ABI标志,然后再次尝试了同样的问题。我不明白它如何从源文件夹链接而不能从测试文件夹链接。
这是我的test_utility.cpp的代码
/usr/include/boost/regex/v4/regex_match.hpp:50: undefined reference to boost::re_detail::perl_matcher<__gnu_cxx::__normal_iterator<char const*, std::string>, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::string> > >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::match()
更新链接输出:
void boostTestFunc()
{
std::string line = "Subject: Re: Lalalala";
boost::regex pat( "^Subject: (Re: |Aw: )*(.*)" );
boost::smatch matches;
if (boost::regex_match(line, matches, pat))
{
std::cout << matches[2] << std::endl;
}
}
Update2编译输出:
Linking CXX executable ../../bin/release/test_test_utility
/usr/local/bin/cmake -E cmake_link_script CMakeFiles/test_test_utility.dir/link.txt --verbose=1
/opt/rh/devtoolset-8/root/usr/bin/c++
-D_GLIBCXX_USE_CXX11_ABI=1 -O3 -DNDEBUG CMakeFiles/test_test_utility.dir/src/main.cpp.o CMakeFiles/test_test_utility.dir/net/nas/uxhome/name/TestCmake/test_utility/src/test_utility.cpp.o -o ../../bin/release/test_test_utility-0.1.0 -L/opt/boost/current/stage/release/lib -Wl,-rpath,/opt/boost/current/stage/release/lib -Wl,-Bstatic -lboost_regex -Wl,-Bdynamic
Update3: 我已经将test_utility编译到一个lib中,现在在Cmake中,我仅调用main并与该库链接,但是链接失败,尽管该库/归档(静态)已成功构建并链接 [11:54] Linux [name @ machine:/ net / nas / uxhome / name / TestCmake / test_utility / test / build / debug]> make VERBOSE = 1 / usr / local / bin / cmake -S / net / nas / uxhome / name / TestCmake / test_utility / test -B / net / nas / uxhome / name / TestCmake / test_utility / test / build / debug --check-build-系统CMakeFiles / Makefile.cmake 0 / usr / local / bin / cmake -E cmake_progress_start / net / nas / uxhome / name / TestCmake / test_utility / test / build / debug / CMakeFiles / net / nas / uxhome / name / TestCmake / test_utility / test / build / debug / CMakeFiles / progress.marks
/usr/local/bin/cmake -S/net/nas/uxhome/name/TestCmake/test_utility/test -B/net/nas/uxhome/name/TestCmake/test_utility/test/build/release --check-build-system CMakeFiles/Makefile.cmake 0
/usr/local/bin/cmake -E cmake_progress_start /net/nas/uxhome/name/TestCmake/test_utility/test/build/release/CMakeFiles /net/nas/uxhome/name/TestCmake/test_utility/test/build/release/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/net/nas/uxhome/name/TestCmake/test_utility/test/build/release'
make -f CMakeFiles/test_test_utility.dir/build.make CMakeFiles/test_test_utility.dir/depend
make[2]: Entering directory '/net/nas/uxhome/name/TestCmake/test_utility/test/build/release'
cd /net/nas/uxhome/name/TestCmake/test_utility/test/build/release && /usr/local/bin/cmake -E cmake_depends "Unix Makefiles" /net/nas/uxhome/name/TestCmake/test_utility/test /net/nas/uxhome/name/TestCmake/test_utility/test /net/nas/uxhome/name/TestCmake/test_utility/test/build/release /net/nas/uxhome/name/TestCmake/test_utility/test/build/release /net/nas/uxhome/name/TestCmake/test_utility/test/build/release/CMakeFiles/test_test_utility.dir/DependInfo.cmake --color=
make[2]: Leaving directory '/net/nas/uxhome/name/TestCmake/test_utility/test/build/release'
make -f CMakeFiles/test_test_utility.dir/build.make CMakeFiles/test_test_utility.dir/build
make[2]: Entering directory '/net/nas/uxhome/name/TestCmake/test_utility/test/build/release'