我有一个CMakeList.txt,它会在运行make
时使用Maven构建一个带有war文件的Java项目,但是当我运行make install
时,它会在复制到安装文件夹之前再次重建它Web应用程序。
如何只使用make
构建Java一次,而不是make install
再构建一次Java?这是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})
答案 0 :(得分: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可以很好地生成依赖性检查,因此不会不必要地重新构建。请注意,您可能还希望在DEPENDS
中包含一些add_custom_command()
,否则一旦构建(1),它将从不重建。
然后,您还需要一件事:自定义命令的驱动程序。这取决于命令的OUTPUT
并实际上导致它被构建。因此,您将添加自定义目标:
add_custom_target(
JavaProject ALL
DEPENDS "${JAVA_PROJECT_TARGET_DIR}/java_project.war"
)
然后,序列如下:
在make
期间,JavaProject
将被视为过时(因为它是自定义目标)并将构建。这意味着将检查其依赖关系的最新状态,并在它们不是最新时重新构建。这就是自定义命令的用途。之后,自定义目标本身将运行其COMMAND
,但它没有任何,所以没有其他事情发生。
在随后的make
次调用中,JavaProject
将再次被视为已过期,因此将构建。它的依赖关系会再次被检查,但这一次,它们是最新的(因为.war
已经存在)。因此它不会再建造。自定义目标仍然没有COMMAND
,因此没有进一步发生。
这个“自定义命令驱动程序的自定义目标”方法是一个非常惯用的CMake代码,您将在许多项目中看到它,这些项目会产生不参与进一步构建步骤的其他文件(例如文档)。 / p>
(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本身可以读取,同时允许您明确依赖所需的一切。
答案 1 :(得分:0)
尽管Angew有一个很好的答案,但不幸的是它没有按照我的预期工作(即:当更新源代码文件夹并运行make时,它不会再次构建战争。)
这是解决我想要的方法:
set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY TRUE)
然后,当我运行make时,它将构建并且make install将只复制到安装文件夹。