add_custom_command
例如,Glow中在编译时运行编译得到的InstrGen和NodeGen生成对应的源代码文件,用于接下来的编译。
1 | # AutoGenNodes |
在文件改变时拷贝文件到指定目录。1
2
3
4add_custom_command(
OUTPUT ${GLOW_BINARY_DIR}/glow/caffe.pb.h
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CAFFE_HDRS} ${GLOW_BINARY_DIR}/glow/caffe.pb.h
DEPENDS ${CAFFE_HDRS})
然而,仅仅这样,命令并不会被执行。除非其OUTPUT时某个target的依赖项。1
2
3
4
5
6
7
8
9
10
11add_library(Importer
ProtobufLoader.cpp
Caffe2.cpp
Caffe.cpp
ONNX.cpp
ONNXIFILoader.cpp
ONNXExporter.cpp
${CAFFE_SRCS}
${CAFFE2_SRCS}
${GLOW_BINARY_DIR}/glow/caffe.pb.h
${GLOW_BINARY_DIR}/glow/caffe2.pb.h)
因此一个办法是,作为某个target/library的依赖项;另一办法是专门为某个源文件添加property。set_property(SOURCE Caffe.cpp APPEND PROPERTY OBJECT_DEPENDS ${GLOW_BINARY_DIR}/glow/caffe.pb.h)
find_package
如何知道某个库是否支持find_package方法呢,如find_package(Protobuf)
macOS
在cmake安装的目录路径$PREFIX/share/cmake/Modules
中(如果用brew 默认安装cmake则为/usr/local/Cellar/cmake/share/cmake/Modules
),我们可以看到大量的[package].cmake文件,如FindProtobuf.cmake, FindPNG.cmake, FindMPI.cmake等。这些可以看作是默认支持的软件包。
当我们安装gflags,则可以在/usr/local/lib/cmake/
中找到gflags/
目录,其中包括了gflags-config.cmake
等文件。
此外,可以自己编写文件用于find_package.参见cmake文档。
install 命令
install命令并非在cmake或者make编译时运行,而是在编译后执行install时。
以makefile为例,cmake中的install命令会生成到对应的Makefile中,对应make install
命令。
CMAKE_INSTALL_PREFIX : 默认安装路径,一般是/usr/local,可以用message命令打印查看。
message(STATUS “${CMAKE_INSTALL_PREFIX}”)
TARGETS版本的install命令1
2
3
4
5
6
7
8
9install(TARGETS targets... [EXPORT <export-name>]
[[ARCHIVE|LIBRARY|RUNTIME|FRAMEWORK|BUNDLE|
PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE]
[DESTINATION <dir>]
[PERMISSIONS permissions...]
[CONFIGURATIONS [Debug|Release|...]]
[COMPONENT <component>]
[OPTIONAL] [NAMELINK_ONLY|NAMELINK_SKIP]
] [...])
其中,静态链接库对应ARCHIVE;链接库对应LIBRARY;可执行文件则是RUNTIME。
安装期间要执行脚本或者代码,如打印信息。可以使用CODE或者SCRIPAT版本的install命令,如
install(CODE “MESSAGE(\“some message\”)”)
cmake 命令时的宏-DMACRONAME=XXX
为了实现LEVELDEBUG
,即将cmake命令添加-DLEVELDEBUG=5
时,当且仅当DEBUG(i) << 中的i>=5时方进行打印。
遇到的问题如下。
1.设置LEVELDEBUG宏1
2cmake -DCMAKE_BUILD_TYPE=Debug .. -DLEVELDEBUG=5
vim vim CMakeFiles/testDSL.dir/flags.make
结果CXX_DEFINES = -DLEVELDEBUG=5
2.命令中去除LEVELDEBUG宏1
2cmake -DCMAKE_BUILD_TYPE=Debug ..
vim CMakeFiles/testDSL.dir/flags.make
结果中仍然有该宏。CXX_DEFINES = -DLEVELDEBUG=5
另外Release模式,该宏还是存在。
3.设置Release模式时,将该宏设置为极大值100.1
2
3
4
5
6
7if(LEVELDEBUG)
if(CMAKE_BUILD_TYPE STREQUAL Debug)
add_definitions(-DLEVELDEBUG=${LEVELDEBUG})
else()
add_definitions(-DLEVELDEBUG=100)
endif()
endif ()
测试1
2cmake -DCMAKE_BUILD_TYPE=Release ..
vim CMakeFiles/testDSL.dir/flags.make
结果中CXX_DEFINES = -DLEVELDEBUG=100
4.再次切换回Debug模式1
2cmake -DCMAKE_BUILD_TYPE=Debug ..
vim CMakeFiles/testDSL.dir/flags.make
结果仍然恢复为CXX_DEFINES = -DLEVELDEBUG=5
这个5可能来自cache中。有待考证。
相关讨论
cmake: how to check if preprocessor is defined - Stack Overflow