首页 > 其他分享 >cmake的add_custom_command如何处理多输出+多依赖

cmake的add_custom_command如何处理多输出+多依赖

时间:2024-06-05 22:34:21浏览次数:7  
标签:cmake sub custom touch add cpp main

intro

在一个复杂的项目中,免不了需要动态生成文件,此时可能就需要用到cmake的add_custom_command命令,这个命令可以生成cmake识别的输出文件,并作为构建过程中其它命令的依赖和输出。

add_custom_command(OUTPUT output1 [output2 ...]
COMMAND command1 [ARGS] [args1...]
[COMMAND command2 [ARGS] [args2...] ...]
[MAIN_DEPENDENCY depend]
[DEPENDS [depends...]]
[IMPLICIT_DEPENDS depend1
[ depend2] ...]
[WORKING_DIRECTORY dir]
[COMMENT comment] [VERBATIM] [APPEND])

这个命令里有有一个很好用的功能:可以同时有多个个输(OUTPUT)出和多个依赖(DEPENDS),并且公用的是同一个命令。

这个功能翻译成Makefile看起来应该也很直观:

output1 output2: depend1 depend1
	command1
	command2

但是这里有一个隐藏的问题:make是支持多任务并发构建的

 -j [jobs], --jobs[=jobs]                                                                                                                                                                                                      
      Specifies the number of jobs (commands) to run simultaneously.  If there is more than one -j option, the last one is effective.  If the -j option is given without an argument, make will not limit the number of jobs t 
      can run simultaneously.                                                                                                                                                                                                  

在多任务构建时,假设output1和output2都需要重新生成,那么相同的命令会被多次执行。多次执行的冗余可能还是次要的,关键是这些命令可能都会修改相同的文件,很容易因为并发写而导致输出文件错乱。

cmake的处理

下面是一个简单的测试脚本:

cmake_minimum_required (VERSION 3.10)
project (tsecer)
add_executable(main main.cpp sub.cpp)

add_custom_command(OUTPUT main.cpp sub.cpp   
                    COMMAND touch main.cpp touch sub.cpp
                    DEPENDS main.h sub.h)

依赖关系在Makefile中的表示为

main.cpp: main.hmain.cpp: sub.h
    @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue --bold --progress-dir=/home/tsecer/cmake/add_custom_command_multiple_output/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Generating main.cpp, sub.cpp"    touch main.cpp touch sub.cpp

sub.cpp: main.cpp
    @$(CMAKE_COMMAND) -E touch_nocreate sub.cpp

其中比较巧妙的地方在于sub.cpp并不是和main.cpp有相同的依赖,而是sub.cpp会依赖于main.cpp,而main.cpp依赖cmake脚本描述的所有依赖。并且sub.cpp的脚本命令不会真正执行构建动作。而是假设main.cpp和sub.cpp有相同的时间戳,让main.cpp来替换sub.cpp的依赖。

由于make在多任务调度时会考虑这种同一个目标的依赖关系,所以避免了多任务执行时的并发写问题。

而其中的一个关键是cmake添加的,看似平平无奇的touch_nocreate命令

  touch_nocreate <file>...                                                                                                                   
         Touch a file if it exists but do not create it.  If a file does not exist it will be silently ignored.                              

outro

个人认为cmake使用简单的方法,优雅的解决了构建并发问题,是一个巧妙的思路。

标签:cmake,sub,custom,touch,add,cpp,main
From: https://www.cnblogs.com/tsecer/p/18234050

相关文章

  • VSCode中配置CMake+GLFW渲染基础-轻量级架构
    一、核心基础库下载1、GLFW库下载   下载链接如下:进入Download|GLFWGLFWsourcecodeandbinarydistributiondownloadlinks.https://www.glfw.org/download.html 选择2、GLAD库下载  下载链接如下:https://glad.dav1d.de/WebgeneratorfortheGladtoolht......
  • js的 addEventListener如果添加的是相同名称的事件,会被覆盖吗
    在JavaScript中,使用addEventListener方法向元素添加事件监听器时,如果有多个相同的事件名称(比如多次调用addEventListener("click",function)),这些监听器不会互相覆盖,而是会累加。这意味着所有为同一事件类型注册的监听器都会按照添加的顺序依次触发,而不是只有最后一个生效。这......
  • 控制台警告:[Violation] Added non-passive event listener to a scroll-blocking 'mou
    控制台警告:[Violation]Addednon-passiveeventlistenertoascroll-blocking'mousewheel'event.Considermarkingeventhandleras'passive'tomakethepagemoreresponsive.Seehttps://www.chromestatus.com/feature/5745543795965952[Viola......
  • 巧用CMake编译策略:C++二次开发中的Release与Debug模式切换秘籍
    往期本博主的C++精讲优质博文可通过这篇导航进行查找:《Lemo的C++精华博文导航:进阶、精讲、设计模式文章全收录》前言在C++二次开发的过程中,理解各种编译模式并能灵活切换,对于提升软件性能和调试效率至关重要。本文将深入讨论Debug与Release模式的区别、默认编......
  • nginx如果上层还有其他 slb 需要使用 $proxy_add_x_forwarded_for 获取真实 ip
    #Todo:Maybecanautodiscoveryupstreamhttp_server{ip_hash;serverweb:8080;#这个是可以通过容器访问,外部访问是80端口#serverHOST2:80;#另外的要写真实IP}server{listen80;#listen[::]:80;#server_namedemo.jumpserver.org;#取消注释并......
  • 连接 Dynamics 365 Customer Engagement (on-premises)
    AuthType=AD创建项目模板是.NETframework4.6.2的控制台程序添加nuget包Microsoft.CrmSdk.CoreAssemblies,Microsoft.CrmSdk.XrmTooling.CoreAssemblyProgram类添加以下代码usingSystem;usingSystem.Configuration;usingMicrosoft.Crm.Sdk.Messages;usingMic......
  • Install-Package 和 dotnet add package安装NuGet包对比
    关于使用场景Install-PackageSSH.NET和dotnetaddpackageSSH.NET这两个命令都用于安装NuGet包,但它们是用于不同命令行工具和环境的。这里是两者的主要区别:Install-PackageSSH.NET:这是一个用于NuGet包管理器控制台的命令,这个控制台是集成在VisualStudio中的。主要用......
  • CMakeFile.txt通过sysroot方式后生成makefile报错
    怪不得博客园干不过别家,体验真的不太好。通过openwrite发布文章,其他平台都能发布,就博客园限制了,理由是文字少的文章限制发布到该平台。哎,这种行为当真是扶不起的阿斗。以后也不要太把博客园当回事了,迟早要关门的报错信息如下:--TheCcompileridentificationisunknown--T......
  • CMake -- CMake Release 编译
    1.Release和Debug的区别Debug:调试版本,包含了调试需要用到的信息,程序员可以通过这个版本对程序进行调试。通常有一个.pdb格式的文件,包含了断点等调试信息。Release:发布版本,不对程序进行调试,自然就比Debug版本容量更小。同时在编译时会对程序进行优化,速度也比Debug更快。......
  • C# PaddleOCR 单字识别效果
    C#PaddleOCR 单字识别效果效果说明        根据《百度办公文档识别C++离线SDKV1.2用户接入文档.pdf》,使用C++封装DLL,C#调用。背景        为使客户、第三方开发者等能够更快速、方便的接入使用百度办公文档识别SDK、促进百度OCR产品赋能更多客户,......