将 CMake 与具有钻石依赖项的库一起使用

2024-04-13

假设我有四个独立的项目。三是图书馆、Common, Foo, and Bar,其中之一是可执行文件,App. Both Foo and Bar依赖于公共库,并且App依赖于取决于Foo and Bar。此外,其中一些项目有一些脚本需要运行来生成一些头文件和源文件。

现在我有一堆这样的电话:

if (NOT TARGET common)
  add_subdirectory(${common_lib_directory})
endif()

但这感觉不是正确的解决方案。如果我不将其包装在 if 保护中,则会出现错误,因为它尝试构建Common不止一次。将 if 守卫放入每个项目的 CMakeLists 中似乎也不正确。我应该写吗Find<Library>每个库的脚本?我尝试寻找有关如何设置 CMakeLists 文件的示例或最佳实践,但我能找到的唯一示例要么太琐碎,要么涵盖完全不同的用例。


评论中要求我发布一些代码。这或多或少是我的 CMakeLists.txt 文件的样子:

cmake_minimum_required(VERSION 2.8.12)

project(app)

# Temporary files (like object files) created while compiling projects.
set(tmp_dir ${CMAKE_BINARY_DIR}/obj)

# Directory which contains the source for 3rd party libraries.
if(NOT DEFINED dependencies_root)
  get_filename_component(
    dependencies_root "${CMAKE_CURRENT_SOURCE_DIR}/../../../../external"
    REALPATH)
endif()

set(dependencies_foo_dir "${dependencies_root}/foo"
    CACHE PATH "Directory containing the foo library.")
set(dependencies_bar_dir "${dependencies_root}/bar"
    CACHE PATH "Directory containing the bar library.")

if(NOT TARGET foo)
  add_subdirectory("${dependencies_foo_dir}" ${tmp_dir}/foo)
endif()

if(NOT TARGET bar)
  add_subdirectory("${dependencies_bar_dir}" ${tmp_dir}/bar)
endif()

include_directories(${dependencies_foo_dir}/include)
include_directories(${foo_generated_include_dir})

include_directories(${dependencies_bar_dir}/include)
include_directories(${bar_generated_include_dir})

set(app_srcs ...)

add_executable(app ${app_SRCS})

target_link_libraries(app foo bar common)

如前所述,我的原因是if (NOT TARGET blah)守卫是因为如果我不这样做,我就会收到如下错误:

CMake Error at /path/to/my/project/CMakeLists.txt:267 (add_library):
  add_library cannot create target "blah" because another target with the
  same name already exists.  The existing target is a static library created
  in source directory
  "/path/to/blah".
  See documentation for policy CMP0002 for more details.

如果您有如此紧密联系的项目,最好的决定似乎是使用防止重新包含在每个项目开始时。这种保护可以很容易地使用返回命令 https://cmake.org/cmake/help/v3.0/command/return.html,从当前执行返回add_subdirectory() call:

Foo/CMakeLists.txt:

if(DEFINED Foo_GUARD)
    if(NOT Foo_GUARD STREQUAL ${CMAKE_CURRENT_BINARY_DIR})
        return() # Project has been already included by someone else
    endif()
else()
    set(Foo_GUARD ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "Foo guard")
endif()

project(Foo)

...

所以任何项目都可以使用不受保护的 add_subdirectory()要求包括给定的一个:

应用程序/CMakeLists.txt:

...
# Need *Foo* functionality? Simply include it!
add_subdirectory("${dependencies_foo_dir}" ${tmp_dir}/foo)

可以将 Guard 作为宏来实现,将其放入库中并在每个项目中使用它:

cmake/utils.cmake:

macro(project_guarded name)
    if(DEFINED ${name}_GUARD)
        if(NOT ${name}_GUARD STREQUAL ${CMAKE_CURRENT_BINARY_DIR})
            return() # return() *doesn't* terminate a macro!
        endif()
    else()
        set(${name}_GUARD ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "${name} guard")
    endif()
    project(${name})
endmacro()

宏的用法很简单:

project_guarded(Foo)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 CMake 与具有钻石依赖项的库一起使用 的相关文章

  • 为dlib创建共享库

    按照说明使用 cmake 编译 dlib here http dlib net compile html 生成静态 dlib 库 cd examples mkdir build cd build cmake cmake build conf
  • 如何将脚本的依赖项添加到 CMake 中的目标?

    链接我的程序后 我需要对其执行一些后处理 我添加了一个add custom command TARGET 效果很好 但是 这个额外的自定义命令运行一个脚本 未生成 它已签入代码库 并且我希望如果该脚本发生更改 目标将被视为过时 以便正确重建
  • cmake 找不到 boost 库,因为它查找错误的文件名

    我根据文档在 Windows 8 1 机器上构建了 boost 1 56 库 作为共享库和静态库 他们全部出现在BOOST ROOT stage lib目录 文件名格式如下 boost thread vc120 mt 1 56 dll bo
  • MySQL C++ 连接器未解决的依赖关系(VS 2015)

    我正在尝试在 Windows Visual Studio 2015 上编译 MySQL Connector C 我根据以下内容使用CMake生成了项目文件官方说明 https dev mysql com doc connector cpp
  • libSDL、CMake 和 Mac OS X Lion

    我正在尝试在我的Mac上编译cmake项目 但它取决于SDL框架 我安装了这个框架 在 cmake 之后向我报告找不到 libSDL 我自己设置了以下导出变量 按照 cmake 的建议 export SDL INCLUDE DIR Libr
  • 在 Android Studio 中使用预构建的共享库

    我需要在我的 android 项目中使用自定义的预构建共享库 在独立 ndk 上构建为 libdynamic so 我在路径 src main 中创建了一个文件夹 jniLibs 然后在其中创建了 4 个文件夹 即 armeabi arme
  • MinGW Make 抛出“系统找不到指定的路径。”错误

    我正在尝试在 Windows 7 上使用 cmake 生成一个 c 项目 在实际创建项目之前 cmake 会对您的工具链进行快速测试 我正在使用 MinGW 这就是我的问题所在 Cmake 触发 make 构建 最终失败并返回 系统找不到指
  • 如何从 CMake 构建目标仅生成目标文件 (*.o)?

    我正在尝试使用 CMake 构建一个对象文件 但我似乎无法让 CMake 构建除完整可执行文件之外的其他内容 我基本上是在寻找以下编译的结果 结果将加载到 VxWorks 目标上并然后链接 CC CFLAGS INC DIRS c src
  • CMake“项目”指令的正确用法是什么

    我有一个很大的代码库 它构建了几十个库和几个可执行文件 代码库按层次结构进行分解 并且几乎在每个级别都构建了库 我已经仔细检查并在每个目录中放置了一个 CMakeLists txt 文件来构建每个库 在每个 CMakeLists txt 中
  • 如何在 Windows 下使用 cmake 生成使用 Intel 编译器的 Visual Studio 项目

    我正在用 C 开发一个跨平台 Linux Windows 应用程序 我已经厌倦了维护可用的 Makefile 和 Visual Studio 解决方案 项目 所以我想过渡到 cmake 我在两个平台上都使用英特尔编译器 我在 Windows
  • 具有许多第三方依赖项的大型跨平台 C++ 项目在磁盘上的物理布局

    我正在重新组织物理 磁盘上 布局大型跨平台 C 项目 https github com jupiter jazz appleseed具有许多第三方依赖项 使用 CMake 构建 由于我们需要支持 Windows 这个平台上没有完善的包管理器
  • CMake 中 LINK_LIBRARIES 的递归列表

    我正在尝试获取链接到 CMake 中特定目标的所有库的绝对路径列表 以便在调用中使用add custom command 然而 get target property LINK LIBRARIES TARGET LINK LIBRARIES
  • Python pip install pyarrow错误,无法执行'cmake'

    我尝试在 EMR 集群的主实例上安装 pyarrow 但总是收到此错误 hadoop ip XXX XXX XXX XXX sudo usr bin pip 3 4 install pyarrow Collecting pyarrow Do
  • 在cmake中,什么是“项目”?

    这个问题是关于project命令 推而广之 是什么concept of a project意思是cmake中的 我真的不明白什么是project是 以及它与target 我想我确实理解 我看了一下cmake 文档project http w
  • CMake:连续编译程序两次

    为了能够进行许多自动优化 我希望能够使用标志编译我的程序 fprofile generate首先 然后运行它生成配置文件 然后使用以下命令重新编译程序 fprofile use反而 这意味着我想连续编译我的程序两次 使用两个不同的CMAKE
  • 在cmake中设置PKG_CONFIG_PATH

    我已经在本地构建了 opencv 并将其安装到本地目录 不是系统默认目录 opencv pc存在于该本地文件夹中的 pkgconfig 文件夹下 我怎样才能找到这个opencv pc来自 cmake 因为我想从我的程序链接并包含 openc
  • 在 C 中使用 pow 时,CMake 可以检测是否需要链接到 libm 吗?

    对于某些编译器 using powC 程序中的某些其他函数需要链接到m library https stackoverflow com q 8671366 1959975 但是 某些编译器不需要这样做 并且在链接到m图书馆 C 也存在几乎相
  • 如何在使用 Cmake 构建期间编译 HLSL 着色器?

    我正在开发 d3d 应用程序 我想在使用 cmake 构建期间编译我的 hlsl 着色器 我不知道从哪里开始 这是我当前的 CMakeLists txt cmake minimum required VERSION 3 20 project
  • 为什么 cmake 在 git commit 后编译所有内容

    假设我有时在 Linux 上使用 cmake 2 8 编译一段代码 我更改了一个文件 my changed file 运行 cmake 并且只构建了这个文件 到目前为止 一切都很好 现在我想提交这个 git add my changed f
  • 使用星号更改多个源文件的 CMake 编译器标志

    我正在尝试调试与编译器优化相关的问题 O2 或以下版本没有问题 O3 出现段错误 并且我希望能够切换我的源代码块的编译器标志 以便我可以尝试缩小段错误的来源范围 我可以将全局优化级别设置为 O2 并更改单个文件的属性 如下所示 SET SO

随机推荐

  • 从 F# 调用 C# 异步方法会导致死锁

    我有一组 F 脚本 它们调用我们创建的各种库 其中许多库公开了最初用 C 编写的异步方法 最近我发现脚本停止工作了 我想距离我上次使用它们已经有半年了 当时它们还可以工作 我试图隔离问题并提出了以下代码来重现它 首先 我们考虑一个包含以下
  • 如何在 Pandas 数据框的多列上运行 Ta-Lib?

    我有一个数据框 其中包含多种证券的价格作为列 但我找不到一次性运行 TA Lib 的解决方案 因为它需要 numpy ndarray 如何在多种证券上运行 TA Lib 并获得数据帧作为回报 import talib as ta d sec
  • 缓存 VS 会话 VS cookie?

    缓存 会话 Cookie 的注意事项是什么 例如 我经常使用会话变量 有时当用户开始订购产品然后去吃午餐并在几个小时后回来并继续预订时 预订应用程序中有时会出现问题 我将预订存储在会话中 直到用户确认或中止预订 因此当用户只需单击浏览器中的
  • 使用单选按钮 PHP SQL 过滤搜索

    我有一个有效的搜索列表 搜索的工作原理是查找搜索词是否如姓名 家庭和工作 现在我想把这个搜索分开 我的意思是 创建三个单选按钮 单击第一个按钮按姓名搜索 单击第二个按钮按家庭搜索 单击第三个按钮按工作搜索 所以我的基本代码在这里 这里需要添
  • 使用 JSON.NET 作为 ASP.NET MVC 3 中的默认 JSON 序列化器 - 可能吗?

    是否可以使用JSON NET http json codeplex com 作为 ASP NET MVC 3 中的默认 JSON 序列化器 根据我的研究 似乎实现这一目标的唯一方法是扩展操作结果 http james newtonking
  • 如何更改 Laravel 中的日期语言?

    我想将我看到的日期的语言从英语更改为法语 strftime d B Y H M strtotime article gt created at 我们可以使用另一种方法与translatedFormat Carbon setLocale fr
  • Selenium WebDriver 拖放到滚动条

    我对 Selenium WebDriver 拖放有疑问 它不想拖放到滚动条中的 webelement 我试过这个 new Actions SeleniumDriver getDriver dragAndDrop element target
  • DB2 SQLCODE=-805,SQLSTATE=51002,SQLERRMC=NULLID.SYSLH203 0X5359534C564C3031

    我收到以下错误 com ibm db2 jcc am SqlException DB2 SQL Error SQLCODE 805 SQLSTATE 51002 SQLERRMC NULLID SYSLH203 0X5359534C564C
  • Angular 4打字稿解析响应对象中的枚举接口属性

    我收到来自 API 的响应 它返回一个枚举值 从 API 返回的值在请求中表示为字符串 这个值是一个enumTypescript 接口的属性 Problem 当收到响应时 TS接口将该值存储为字符串 可能这就是问题 所以我不能直接使用它en
  • 在 Hibernate 中禁用延迟加载

    如何在 Hibernate 中禁用延迟加载 我使用的是持久性注释 而不是 hbm xml 文件 我正在按 ID 获取单个对象 并希望加载所有属性 在我使用该对象之前会话已关闭 Thanks 您需要使用 FetchType EAGER 注释您
  • java中将十进制转换为格雷码

    最近出现一个问题是 编写算法将十进制数转换为n位格雷码 例如 使用 1 位 最简单 0 gt 0 1 gt 1 使用 2 位 0 gt 00 1 gt 01 2 gt 11 3 gt 10 使用 3 位 0 gt 000 1 gt 001
  • 如何使用 if/else 语句更改全局变量

    我有这个代码我想改变var n如果var thisRoll is not green 但我只得到undefined在输出中console log n var thisRoll red var n var base bet 1 functio
  • 带 margin-left 和 width:100% 右侧溢出的 Div

    我有 2 个嵌套的 div 宽度应为 100 不幸的是 带有文本框的内部 div 溢出 并且实际上比外部 div 更大 它有一个左边距 并且溢出了大约该边距的大小 我该如何解决这个问题 div style width 100 div sty
  • 使用 ctypes 从 python 调用 C 函数

    我有以下 C 代码 我正在尝试使用Python从Python调用这个函数ctypes int add int arr printf number d n arr 0 arr 0 1 return arr 0 我用以下方法编译了这个 gcc
  • 动态包含/排除 Gitlab Pipeline 中的作业

    我有一个有几个阶段的管道 detect test build deploy The detect阶段检测应用程序的类型和test and build阶段的作业根据计算结果包含或排除detect The detectstage 将其值写入名为
  • 如何在 webkit 浏览器中访问粘贴的文件? (如谷歌浏览器)

    如果能够在 Stack Exchange 上粘贴图像而不是干扰文件对话框 那将非常方便 类似的功能在这里实现了 是 但是仅适用于 Webkit 浏览器 https meta stackexchange com a 233874 209994
  • 快速获取剪贴板更改通知

    swift 中有剪贴板更改事件吗 当 iOS 应用程序中剪贴板发生更改时 我如何收到通知 谢谢 这里有一个可以复制的迅捷5 0 version NotificationCenter default addObserver self sele
  • 使用反应登录表单在 Spring Boot 中对用户进行身份验证

    我已将 spring security 添加到我的项目中 并且正在尝试进行用户身份验证 我正在使用 CrudRepository 来查找用户并验证详细信息是否正确 我已经能够使用开箱即用的弹簧登录页面让它工作 我的问题是我想通过我的反应登录
  • 如何实现带有可折叠搜索栏的 SliverAppBar

    这就是我想做的 https i stack imgur com f9SYe jpg 这是 iOS 上非常常见的 Widget 这是我的代码 return Scaffold backgroundColor Colors white body
  • 将 CMake 与具有钻石依赖项的库一起使用

    假设我有四个独立的项目 三是图书馆 Common Foo and Bar 其中之一是可执行文件 App Both Foo and Bar依赖于公共库 并且App依赖于取决于Foo and Bar 此外 其中一些项目有一些脚本需要运行来生成一