我必须通过外部工具生成源(我从 IDL 文件为 fastDDS 消息生成 c++ 类),该工具还生成 CMakeLists.txt 文件,允许我将生成的文件编译为 <msgs_lib>.a 文件。
在我的一个 exec 目标的大型超级项目中,我不会检查生成文件的存在及其构建结果。如果 <msgs_lib>.a 不存在,我不会调用生成并构建它。
我知道 CMake 命令add_custom_command
和add_custom_target
. 但是我不能以正确的方式使用它们,在某些情况下,即使所有文件都存在并且它们是以正确的顺序构建的,也不会生成调用,在某些情况下不会生成任何东西(并且在清理之后也不会生成任何东西),在某些情况下 exec-target 确实不明白它应该检查并调用生成。
例如,我将在上面写一个案例来开始讨论。我已经简化了很多:
github上的项目: https ://github.com/gladijos/test_project
一个 zip 文件中的项目: mediaDrive-link
或者就在这里:
项目目录树:
.
├── CMakeLists.txt
├── deps
│ ├── gen_deps
│ └── gen_source
│ └── tb_msgs
│ ├── CMakeLists.txt
│ ├── tb_msg.cpp
│ └── tb_msg.h
├── scripts
│ └── build_msgs.sh
└── test_app
├── CMakeLists.txt
└── main.cpp
根 CMakeLists.txt:
cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
project(test_project LANGUAGES CXX VERSION 0.0.3)
set(TB_MSGS ${CMAKE_HOME_DIRECTORY}/deps/gen_deps/tb_msgs/build/libtb_msgs_lib.a)
add_custom_command(
OUTPUT ${TB_MSGS}
WORKING_DIR ${CMAKE_HOME_DIRECTORY}
COMMAND ${CMAKE_HOME_DIRECTORY}/scripts/build_msgs.sh ${CMAKE_HOME_DIRECTORY}
)
add_custom_target(build_dds_msgs
# ALL
DEPENDS ${TB_MSGS}
)
# apps
add_subdirectory(test_app)
add_dependencies(test_app build_dds_msgs)
tb_msgs CMakeLists.txt:
cmake_minimum_required(VERSION 3.5.1)
project("tb_lib")
set(CMAKE_CXX_STANDARD 11)
add_library(tb_msgs_lib
tb_msg.cpp
)
tb_msg.cpp:
#include "tb_msg.h"
MyClass::MyClass(){};
tb_msg.h:
#pragma once
class MyClass
{
public:
MyClass();
};
build_msgs.sh:
cp -rf $1/deps/gen_source/* $1/deps/gen_deps/;
cd $1/deps/gen_deps/tb_msgs;
mkdir -p $1/deps/gen_deps/tb_msgs/build;
cd $1/deps/gen_deps/tb_msgs/build;
cmake .. ;
make;
test_app CMakeListst.txt:
cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
project(test_app LANGUAGES CXX VERSION 0.0.1)
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME}
${CMAKE_HOME_DIRECTORY}/deps/gen_deps/tb_msgs/build/libtb_msgs_lib.a
)
test_app main.cpp:
#include "../deps/gen_deps/tb_msgs/tb_msg.h"
int main()
{
MyClass myClass;
return 0;
}
在这种情况下,我每次构建都会调用 scripts/build_msgs.sh,即使libtb_msgs_lib.a
存在,并且是在之前构建的test_app
。
就比较单一。在add_custom_command
OUTPUT
我放的部分.a
,但在最好的情况下,这里应该是 dir gen_source/* 中的所有文件,但我认为这是另一个问题,我可以在解决主要问题后解决它。