是否只有在编辑顶级CMakeList时才可以在整个项目中包含和链接外部库? [英] Is there a way to include and link external libraries throughout my project only editing my top level CMakeList?

查看:147
本文介绍了是否只有在编辑顶级CMakeList时才可以在整个项目中包含和链接外部库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



有没有?



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

  CMAKE_MINIMUM_REQUIRED(3.2版)
#文件将在
设置的位置(CMAKE_ARCHIVE_OUTPUT_DIRECTORY $ {CMAKE_BINARY_DIR} / libs)
设置(CMAKE_LIBRARY_OUTPUT_DIRECTORY $ {DAKE_BIN)
$ b set(CMAKE_RUNTIME_OUTPUT_DIRECTORY $ {CMAKE_BINARY_DIR} / apps)
#提升管理
find_package(Boost)
if(Boost_FOUND)
include_directories($ {Boost_INCLUDE_DIR})
endif()
#编译器设置
set(CMAKE_C_COMPILER mpicc)
set(CMAKE_CXX_COMPILER mpicxx)#两个编译器均位于
set(CMAKE_CXX_FLAGS_DEBUG $ {CMAKE_CXX_FLAGS_DEBUG } -Wall -Wextra -pedantic -std = c ++ 11)
set(CMAKE_CXX_FLAGS_RELEASE $ {CMAKE_CXX_FLAGS_RELE ASE} -pedantic -std = c ++ 11)
#设置构建类型
set(CMAKE_BUILD_TYPE RELEASE)
set(CMAKE_BUILD_DIR发布)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY $ {CMAKE_ARCHIVE_OUTPUT_DIRECTORY} / $ {CMAKE_BUILD_DIR})
#关于项目
项目(MinorTest)
设置(VERSION_MAJOR 1)
设置(VERSION_MINOR 0)
set(VERSION_PATCH 0)
set(VERSION $ {VERSION_MAJOR}。$ {VERSION_MINOR}。$ {VERSION_PATCH}))
#添加子目录
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:在函数'_start'中:
(.text + 0x20):对 main的未定义引用
CMakeFiles / ScriptSystemTest.dir / source / TestScriptSystem.cpp.o:在函数ʻinit_unit_test_suite(int,char **)':
/home/felipe/Libraries/boost_1_63_0/boost/test/unit_test_suite.hpp:346:未定义对`boost :: unit_test :: framework :: master_test_suite( )'
CMakeFiles / ScriptSystemTest.dir / source / TestScriptSystem.cpp.o:在函数`TestParser :: test_method()'中:
/ home / felipe / Workspace / Z_TestEFv / ScriptSystemTest / source / TestScriptSystem。 cpp:20:对`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>)'的未定义引用b /home/felipe/Workspace/Z_TestEFv/ScriptSystemTest/source/TestScriptSystem.cpp:20:未定义对`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> ;,无符号长,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)

链接目录($ {CMAKE_SOURCE_DIR} / UtilsLib /源)
链接目录($ {CMAKE_SOURCE_DIR} / ScriptSystemLib /源)
链接目录($ {CMAKE_SOURCE_DIR} / MuParserLib /源)
#搜索FOR .CPP文件
文件(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)$ b b#
安装(
目标$ {PROJECT_NAME}
运行时目的地应用程序


解决方案

将我的评论变成答案



扩展 CMAKE_CXX_STANDARD_LIBRARIES 您可以执行以下操作:

  find_package(Boost必需的组件unit_test_framework)

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

add_subdirectory(ScriptSystemTest)





否则,您将覆盖/扩展 add_executable()本身:

  find_package(Boost必需组件unit_test_framework)

宏(add_executable _target)
_add_execut able($ {_ target} $ {ARGN})
target_link_libraries($ {_ target} Boost :: unit_test_framework)
endmacro()

add_subdirectory(ScriptSystemTest)


I'm trying to compile a small project which has both BOOST and PETSc dependencies. I couldn't configure my top level CMakeList in a way to include and link these external libraries to my project. It seems that I can achieve this objective by configuring each CMakeList of each library / executable that I've built, however I'm looking for a more practical way to do so.

Is there any?

As requested, this is my top level 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)

The following errors are shown when linking the executable from ScriptSystemTest project:

/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, ...)'

Finally, this is the 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
) 

解决方案

Turning my comment into an answer

Extending CMAKE_CXX_STANDARD_LIBRARIES you can do:

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)


Or you go the long way of overwriting/extending add_executable() itself:

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)

这篇关于是否只有在编辑顶级CMakeList时才可以在整个项目中包含和链接外部库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆