【问题标题】:Is there a way to include and link external libraries throughout my project only editing my top level CMakeList?有没有办法在我的项目中包含和链接外部库,只编辑我的顶级 CMakeList?
【发布时间】:2017-02-03 05:33:40
【问题描述】:

我正在尝试编译一个同时具有 BOOST 和 PETSc 依赖项的小项目。我无法以包含这些外部库并将其链接到我的项目的方式配置我的顶级 CMakeList。看来我可以通过配置我构建的每个库/可执行文件的每个 CMakeList 来实现这个目标,但是我正在寻找一种更实用的方法。

有吗?

根据要求,这是我的顶级 CMakeList:

CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
# WHERE THE FILES WILL BE
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/libs)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/shared_libs)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/apps) 
# BOOST MANAGEMENT
find_package(Boost)
if(Boost_FOUND)
    include_directories(${Boost_INCLUDE_DIR})
endif()
# COMPILER SETTINGS
set(CMAKE_C_COMPILER        "mpicc") 
set(CMAKE_CXX_COMPILER      "mpicxx") # both compilers are in the path
set(CMAKE_CXX_FLAGS_DEBUG   "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wextra -pedantic -std=c++11")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic -std=c++11")
# SET BUILD TYPE
set(CMAKE_BUILD_TYPE "RELEASE")
set(CMAKE_BUILD_DIR "Release")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/${CMAKE_BUILD_DIR})
# ABOUT THE PROJECT
project(MinorTest)
set(VERSION_MAJOR "1")
set(VERSION_MINOR "0")
set(VERSION_PATCH "0")
set(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
# ADD SUBDIRECTORIES
add_subdirectory(MuParserLib)
add_subdirectory(UtilsLib)
#add_subdirectory(UtilsTest)
add_subdirectory(ScriptSystemLib)
add_subdirectory(ScriptSystemTest)

ScriptSystemTest 项目链接可执行文件时显示以下错误:

/usr/lib/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../lib/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
CMakeFiles/ScriptSystemTest.dir/source/TestScriptSystem.cpp.o: In function `init_unit_test_suite(int, char**)':
/home/felipe/Libraries/boost_1_63_0/boost/test/unit_test_suite.hpp:346: undefined reference to `boost::unit_test::framework::master_test_suite()'
CMakeFiles/ScriptSystemTest.dir/source/TestScriptSystem.cpp.o: In function `TestParser::test_method()':
/home/felipe/Workspace/Z_TestEFv/ScriptSystemTest/source/TestScriptSystem.cpp:20: undefined reference to `boost::unit_test::unit_test_log_t::set_checkpoint(boost::unit_test::basic_cstring<char const>, unsigned long, boost::unit_test::basic_cstring<char const>)'
/home/felipe/Workspace/Z_TestEFv/ScriptSystemTest/source/TestScriptSystem.cpp:20: undefined reference to `boost::test_tools::tt_detail::report_assertion(boost::test_tools::assertion_result const&, boost::unit_test::lazy_ostream const&, boost::unit_test::basic_cstring<char const>, unsigned long, boost::test_tools::tt_detail::tool_level, boost::test_tools::tt_detail::check_type, unsigned long, ...)'

最后,这是 ScriptSystemTest CMakeList:

project(ScriptSystemTest)
#
include_directories(${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/include)
include_directories(${CMAKE_SOURCE_DIR}/UtilsLib/include)
include_directories(${CMAKE_SOURCE_DIR}/ScriptSystemLib/include)
include_directories(${CMAKE_SOURCE_DIR}/MuParserLib/include)
#
link_directories(${CMAKE_SOURCE_DIR}/UtilsLib/source)
link_directories(${CMAKE_SOURCE_DIR}/ScriptSystemLib/source)
link_directories(${CMAKE_SOURCE_DIR}/MuParserLib/source)
# SEARCH FOR .CPP FILES
file(GLOB ${PROJECT_NAME}_sources ${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/source/ *.cpp)
#
add_executable(${PROJECT_NAME} ${${PROJECT_NAME}_sources})
#
target_link_libraries(${PROJECT_NAME} UtilsLib)
target_link_libraries(${PROJECT_NAME} ScriptSystemLib)
target_link_libraries(${PROJECT_NAME} MuParserLib)
#
install(
    TARGETS ${PROJECT_NAME}
    RUNTIME DESTINATION apps
) 

【问题讨论】:

  • find_package() 是关键。在add_subdirectory() 之前执行此操作。还要确保你有 1 个 PROJECT()
  • 您能加一个minimal reproducible example吗?如果我正确理解您的问题,您应该查看 CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIESCMAKE_CXX_STANDARD_LIBRARIES 全局变量(应用于您的 CMake 项目中的所有目标)。
  • @drescherjm - 是的,我尝试使用 find_package()。一个项目是什么意思?
  • 只有在顶层 CMakeLists.txt 你有一个 project()。在其他 CMakeLists.txt 中使用 project() 会重置您的一些项目变量,而不是从顶级 CMakeLists.txt 继承它们
  • @drescherjm - 我明白了。但是,在这种情况下,我必须在依赖于主项目中的 boost 的每个项目中使用 find_package()。

标签: c++ cmake


【解决方案1】:

把我的评论变成答案

扩展CMAKE_CXX_STANDARD_LIBRARIES你可以这样做:

find_package(Boost REQUIRED COMPONENTS unit_test_framework)

if(Boost_FOUND)
    include_directories(${Boost_INCLUDE_DIRS})
    list(APPEND CMAKE_CXX_STANDARD_LIBRARIES ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE})
endif()

add_subdirectory(ScriptSystemTest)

或者你会走很长的路来覆盖/扩展add_executable()本身:

find_package(Boost REQUIRED COMPONENTS unit_test_framework)

macro(add_executable _target)
    _add_executable(${_target} ${ARGN})
    target_link_libraries(${_target} Boost::unit_test_framework)
endmacro()

add_subdirectory(ScriptSystemTest)

【讨论】:

  • 支持选项 #2!
猜你喜欢
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
  • 2016-05-03
  • 1970-01-01
  • 2023-04-04
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多