CMake 为项目添加自定义事件

为满足需求:

项目编译前需要预处理一些自定义命令,如生成代码文件,拷贝成果文件等。

解决该问题有两种方案:

add_custom_command prebuild

vcxproj 可以自定义生成事件,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<ItemDefinitionGroup>
<PreBuildEvent>
<Command>copy $(ProjectDir)main.cpp $(ProjectDir)copyOfMain.cpp</Command>
<Message>Making a copy of main.cpp </Message>
</PreBuildEvent>
<PreLinkEvent>
<Command>copy $(ProjectDir)$(Configuration)\main.obj $(ProjectDir)$(Configuration)\copyOfMain.obj</Command>
<Message>Making a copy of main.obj</Message>
</PreLinkEvent>
<PostBuildEvent>
<Command>copy $(ProjectDir)$(Configuration)\$(TargetFileName) $(ProjectDir)$(Configuration)\copyOfMyproject.exe</Command>
<Message>Making a copy of myproject.exe</Message>
</PostBuildEvent>
</ItemDefinitionGroup>

具体可以参考这里。这些标签在 VS 的UI 上表现类似于:

通过 CMake 的 add_custom_command 命令可以完成这项任务:

如:

1
2
3
4
add_custom_command(${PROJECT_NAME}
PRE_BUILD
COMMAND do_sth.py arg1 arg2
)

具体可以参考这里

PRE_BUILD 也可以是 PRE_LINK POST_BUILD
这种方案适合于分阶段地执行某些自定义任务。但有一点不足,即如果项目依赖文件没有修改,项目就不会编译,那么这些任务自然也不会执行。

add_custom_target out_put

这个技巧利用了项目依赖。使用 add_custom_target 输出一个假的文件,让目标项目依赖于该文件。由于该文件不存在,编译目标项目时总会先编译自定义的项目:
CMakeLists.txt:

1
2
3
4
5
6
7
8
9
10
11
add_executable(${PROJECT_NAME}
${SRC_FILES}
"./fake_header.h"
)

add_custom_command(
OUTPUT ./fake_header.h
COMMAND do_sth
COMMENT "fake header"
VERBATIM
)

它也会在 vcxproject 里插入 <CustomBuild> 标签,不过这些标签不会在 VS 的 UI 上显示出来

在实际项目中,根据需要选择合适的方案。也可以将两种方案混用