Cmake:执行make install时不要再次构建项目

时间:2016-10-06 12:11:21

标签: java maven makefile build cmake

我有一个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})

2 个答案:

答案 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将只复制到安装文件夹。