2015-07-03 46 views
0

我有一個工具可以生成包含定義和聲明的文件。這些文件需要包含在其他源文件或頭文件中 - 它們不能單獨使用。如何使用cmake生成包含的文件?

顯而易見的事情是有一個自定義命令來生成它們。我的CMakeLists.txt這樣做如下。我目前正在使用GNU makefile生成器。

project(test_didl) 
cmake_minimum_required(VERSION 3.0) 

add_custom_command(
    OUTPUT test_didl_structs.h test_didl_structs.c 
    COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/didl.py --decls=test_didl_structs.h --defs=test_didl_structs.c ${CMAKE_CURRENT_SOURCE_DIR}/test_didl_structs.py 
    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/didl.py ${CMAKE_CURRENT_SOURCE_DIR}/test_didl_structs.py 
    MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/test_didl_structs.py) 

add_executable(test_didl test_didl.c) 
target_include_directories(test_didl PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) 
target_link_libraries(test_didl shared_lib) 

test_didl.c很簡單:

#include <stdint.h> 
#include <stdio.h> 
#include <string.h> 

#include "test_didl_structs.h" 
#include "test_didl_structs.c" 

int main(void) { 
} 

但在第一次構建,使嘗試構建test_didl.c,這當然失敗了,因爲test_didl_structs *尚未產生。當然,在test_didl.c第一次成功構建之前,依賴信息是未知的,所以make不知道先運行python命令。

我嘗試了一個自定義目標,但這並不好,因爲自定義目標被認爲總是很髒。這意味着C文件將在每個構建版本上重新編譯,並且EXE已鏈接。這種方法不會擴展。

我最終的解決辦法是使輸出.h文件中輸入的可執行文件:

add_executable(test_didl test_didl.c test_didl_structs.h) 

.h文件中輸入作爲依賴治療,但不以其他方式做任何有趣的makefile的發電機。 (我目前不對其他發電機感興趣。)

這樣工作,但感覺有點難看。它並沒有明確說明自定義命令需要先運行,但實際上這似乎發生了。雖然我不太清楚,但(但我還沒有趕上閱讀CMake生成的Makefiles的速度)。

這是它應該如何工作?或者有更好的東西我應該做的呢? (我想象的是,像Visual Studio預構建步驟,因爲它被認爲是在每個構建上運行,在正常的依賴性檢查之前運行。但是我想要這個預構建步驟來有相關性檢查,因此,如果其輸入比其產出年長它跳過)。

回答

1

我最終的解決方案是讓輸出.h文件輸入到可執行文件。

這種方式是正確的。

它實際上指出,該建築物可執行取決於給定文件,如果該文件是對一些add_custom_command()輸出,這個命令將被執行建築可執行之前


另一種方法是使用在execute_process()configuration階段以產生需要的標頭。在這種情況下,不需要添加頭文件作爲add_executable()的源代碼:CMake具有自動檢測編譯依賴關係的概念,因此test_didl將在test_didl_structs.h再生後重建。

execute_process(COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/didl.py --decls=test_didl_structs.h --defs=test_didl_structs.c ${CMAKE_CURRENT_SOURCE_DIR}/test_didl_structs.py) 
# ... 
add_executable(test_didl test_didl.c) 

這種方法的缺點是您需要在更改.py文件後手動重新運行配置階段。另請參閱question並回答它。 另一個問題是,每次運行配置時,頭文件都會更新