我们有一个代码生成器,可以将通信协议定义生成多个C++文件,并且希望将我们的生成系统切换为使用cmake。 我做了一个示例项目来演示我们面临的问题。cmake动态生成的源文件列表
码生成器接收输入文件,并且可以产生几百 输出文件,以便列举它们CMakeLists.txt
没有特别的,因为在开发过程中的协议改变的选项。我们既不想为此使用通配符。
根据文档我们认为configure_file
应该能够做到这一点,但它显然在它的工作上失败了,我们没有找到一种方法让cmake重新生成makefile文件,如果其中一个输入文件发生更改。
我们希望为主营项目的生成文件(在例子中main
文件夹),以通过cmake的时候要么发电机再生(在例子中gen
文件夹)的代码更改或协议定义文件(在我们的例子中是in.txt
)已更新。
我有以下文件结构:
src
├── CMakeLists.txt
├── gen
│ ├── CMakeLists.txt
│ └── gen.cpp
├── in.txt
└── main
├── CMakeLists.txt
└── main.cpp
具有以下内容: SRC /的CMakeLists.txt:
cmake_minimum_required(VERSION 3.5.1)
project(cmake-config)
add_subdirectory(main)
add_subdirectory(gen)
add_dependencies(main gen run_gen)
GEN /的CMakeLists.txt:
cmake_minimum_required(VERSION 3.5.1)
project(gen)
add_executable(gen gen.cpp)
add_custom_target(
run_gen
COMMAND ./gen ${CMAKE_SOURCE_DIR}/in.txt
COMMENT running gen
)
add_dependencies(run_gen gen)
gen/gen.cpp:
#include <fstream>
#include <string>
using namespace std;
int main(int argc, char *argv[]){
ifstream inf(argv[1]);
ofstream outf("input.txt");
string word;
while(inf >> word)
outf << "set(SOURCES ${SOURCES} " << word << ")\n";
}
主/的CMakeLists.txt:
cmake_minimum_required(VERSION 3.5.1)
project(main)
if(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/../gen/input.txt)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/../gen/input.txt "")
endif()
configure_file(${CMAKE_CURRENT_BINARY_DIR}/../gen/input.txt ${CMAKE_CURRENT_BINARY_DIR}/input.txt COPYONLY)
set(SOURCES main.cpp)
include(${CMAKE_CURRENT_BINARY_DIR}/input.txt)
message(${SOURCES})
add_executable(main ${SOURCES})
主/ main.cpp中:
int main(){}
gen
生成input.txt
使用src/in.txt
。 input.txt
包含我想用它来构建main
源文件的列表:
set(SOURCES ${SOURCES} a.cpp)
set(SOURCES ${SOURCES} b.cpp)
set(SOURCES ${SOURCES} c.cpp)
我们正在寻找不需要引导cmake
溶液或需要发展的过程中,每次重新运行该协议的变化。这很容易实现,但不受欢迎,因为如果团队中的某些人没有意识到协议文件(或生成器)发生了变化,则会导致产生有问题的代码,最终会使用较旧的协议定义。
这似乎基本上解决了[这里]相同的问题(http://stackoverflow.com/q/36084785/1938798)。您可能会发现这里的讨论更加详细。它采用了类似的方法,为生成器设置子构建,以便为主构建创建文件列表。 –