由于项目需要用到thrift,而每次修改.thrift文件后,需要重新进到别的目录生成thrift的.cpp及.h文件,于是想在cmake中能否自动生成,本来想用add_custom_command就可以了,但是发现即使在cmake文件中添加了add_custom_command,仍然无法自动生成。 于是详细研究了下add_custom_command及add_custom_target:
add_custom_command
The first signature is for adding a custom command to produce an output:
add_custom_command(OUTPUT output1 [output2 ...]
COMMAND command1 [ARGS] [args1...]
[COMMAND command2 [ARGS] [args2...] ...]
[MAIN_DEPENDENCY depend]
[DEPENDS [depends...]]
[BYPRODUCTS [files...]]
[IMPLICIT_DEPENDS <lang1> depend1
[<lang2> depend2] ...]
[WORKING_DIRECTORY dir]
[COMMENT comment]
[DEPFILE depfile]
[VERBATIM] [APPEND] [USES_TERMINAL]
[COMMAND_EXPAND_LISTS])
这是一个用来定义生成输出文件的命令,在本目录的CMakeLists.txt中的任何一个目标,如果这个目标使用的源文件是在add_custom_command的输出文件中的,那么add_custom_command将被执行。在最终生成的Makefile中,add_custom_command将生成如下命令: OUTPUT:MAIN_DEPENDENCY DEPENDS COMMAND
所以,还需要将命令生成的文件添加到目标的源文件中;
所以命令应该如下形式:
设置thrift最终生成的文件列表
set(THRIFT_SRCS
${PROJECT_SOURCE_DIR}/thrift/xxx.h
${PROJECT_SOURCE_DIR}/thrift/xxx.cpp
...)
#定义生成命令,注意将skeleton.cpp文件要删除的
add_custom_command(
OUTPUT ${THRIFT_SRCS}
COMMAND thrift --gen cpp ${PROJECT_SOURCE_DIR}/thrift/my_server.thrift -out ${PROJECT_SOURCE_DIR}/thrift
COMMAND rm -f {PRJJECT_SOURCE_DIR}/thrift/xxx.skeleton.cpp
DEPENDS ${PROJECT_SOURCE_DIR}/thrift/my_server.thrift
COMMENT "Now Generating thrift files..."
)
注意,这里都不要加双引号,否则会出现不生成的情况。
定义目标可执行文件
add_executable(my_exe main.cpp ${THRIFT_SRCS} ...)
因为add_custom_command中DEPENDS写了my_server.thrift,相当于在Makeflie的DEPENDS上多了这项,所以my_server.thrift更新后,将自动编译出源文件; 谨记要把add_custom_command的输出文件添加到目标源文件中
推广到gprc等其他自动生成代码的流程一样,
另外还需要注意一点:
如果add_custom_command和add_executable在不同的CMakeLists.txt,那么add_executable那个CMakeLists.txt无法引用到add_custom_command,也就是说,最好add_custom_command和add_executable在同一个CMakeLists.txt中