我們有一個代碼生成器,可以將通信協議定義生成多個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)。您可能會發現這裏的討論更加詳細。它採用了類似的方法,爲生成器設置子構建,以便爲主構建創建文件列表。 –