2016-10-06 38 views
0

我有一個CMakeList.txt,它將在運行make時使用Maven將Maven構建到一個war文件中,但是當我運行make install時,它會在複製之前重新生成它到Web應用程序的安裝文件夾。Cmake:執行make install時不要重新構建項目

我怎樣才能只用make建立Java一次,但不能再用make install?這裏是CMakeList.txt:

add_custom_target(JavaProject ALL 
     COMMAND ${MAVEN_EXECUTABLE} package 
     WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 
     VERBATIM) 
install(FILES "${JAVA_PROJECT_TARGET_DIR}/java_project.war" 
     DESTINATION ${WAR_DIR}) 
+2

你讀過的['add_custom_target()'](https://cmake.org/cmake/help/latest/command/add_custom_target.html),特別是明確強調的文檔「是*總是被認爲過時*「位? – Angew

+0

啊,是的,感謝您的信息,所以我需要更改爲add_custom_command() –

+0

...然後添加一個驅動程序。看到我的答案。 – Angew

回答

1

隨着documentation of add_custom_target()說,自定義目標是一直被認爲過時了,這意味着他們將與make每次調用,其中包括他們重新建立。

你想,而不是什麼是自定義命令產生.war文件:

add_custom_command(
    OUTPUT "${JAVA_PROJECT_TARGET_DIR}/java_project.war" 
    COMMAND ${MAVEN_EXECUTABLE} package 
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 
    VERBATIM 
) 

這告訴CMake的,當有人請求它是如何產生命名"${JAVA_PROJECT_TARGET_DIR}/java_project.war"文件。對於文件,CMake可以生成依賴性檢查,所以它不會不必要地重新構建。請注意,您可能還需要在該add_custom_command()中包含一些DEPENDS,否則它將會從不重建一旦建成(1)

然後,您還需要一件事:自定義命令的驅動程序。這將取決於命令的OUTPUT,並且實際上會導致它被構建。所以,你要添加自定義目標:

add_custom_target(
    JavaProject ALL 
    DEPENDS "${JAVA_PROJECT_TARGET_DIR}/java_project.war" 
) 

之後,順序將是如下:

期間makeJavaProject將被視爲過時的(因爲它是一個自定義的目標)和將建成。這意味着它的依賴性將被檢查爲最新版本,並且如果它們不是最新的,則重新構建。這就是自定義命令的用途。在那之後,定製目標本身會運行它的COMMAND,但它沒有任何東西,所以沒有其他事情發生。

在後續的make調用中,JavaProject將再次被視爲過期,因此將被構建。它的依賴被再次檢查,但這一次,它們是最新的(因爲.war已經存在)。因此它不會再被構建。自定義目標仍然沒有COMMAND,所以沒有進一步的發生。

這個「作爲自定義命令驅動程序的自定義目標」方法是非常習慣的CMake代碼片段,您會在許多項目中看到它產生不參與進一步構建步驟(如文檔)的其他文件。


(1)如果依賴性列表是非常大的,你想把它移到一個單獨的文件,包括。事情是這樣的:

CMakeLists.txt

include(files.cmake) 
add_custom_command(
    OUTPUT "${JAVA_PROJECT_TARGET_DIR}/java_project.war" 
    COMMAND ${MAVEN_EXECUTABLE} package 
    DEPENDS ${MyFiles} 
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 
    VERBATIM 
) 

files.cmake

set(MyFiles 
    a/file1.java 
    a/file2.java 
    a/b/file1.java 
    a/c/file1.java 
    # ... list all files as necessary 
) 

這使CMakeList本身的可讀性,同時讓您顯式依賴於你所需要的。

+0

感謝您的幫助,我真的與Cmake一起新,並嘗試更改構建。 –

+0

我有問題,請幫忙。正如您在add_custom_command()中所說的,我可能需要添加DEPENDS,否則在更改源文件夾中的某個文件後,它不會再構建java_project.war。 這是最好的,如果我能把它重建java_project如果任何改變(在java_project源文件夾中編輯文件)。我試圖添加DEPENDS與源文件夾中的特定文件夾,它的工作原理,但它不考慮子目錄中的更改。 –

+0

@BằngRikimaru你必須在那裏列出單個文件。最好有一個明確的列表,如果你將文件添加到列表中,這將強制CMake重新運行並更新構建系統。 – Angew

0

雖然Angew具有優良的答案,但遺憾的是,我希望它不工作(即:當更新源代碼文件夾,運行make時,不會再建造戰爭)。

這裏是解決辦法我想要的東西:

set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY TRUE) 

然後當我運行make將建立和make install將剛纔複製到安裝文件夾。

+0

當然,這意味着* *每次的make''運行將重新編譯'war' 。這可能是你想要的,或者不是。 – Angew

+0

是的,這是我想要的(它應該重建這個戰爭文件(它不夠大,所以我必須列出取決於你的,但如果有很多當然會有t做你的回答)。 –