Java Cmake:don';在执行makeinstall时,不能再次生成项目

Java Cmake:don';在执行makeinstall时,不能再次生成项目,java,maven,makefile,build,cmake,Java,Maven,Makefile,Build,Cmake,我有一个CMakeList.txt,当运行make时,它会用Maven将一个Java项目构建为war文件,但当我运行makeinstall时,它会在复制到Web应用程序的安装文件夹之前重新构建它 如何仅使用make构建Java一次,而不使用makeinstall再次构建Java?以下是CMakeList.txt: add_custom_target(JavaProject ALL COMMAND ${MAVEN_EXECUTABLE} package WORKIN

我有一个CMakeList.txt,当运行
make
时,它会用Maven将一个Java项目构建为war文件,但当我运行
makeinstall
时,它会在复制到Web应用程序的安装文件夹之前重新构建它

如何仅使用
make
构建Java一次,而不使用
makeinstall
再次构建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})
正如上面所说的,定制目标总是被认为是过时的,这意味着每次调用包含它们的
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\u PROJECT\u TARGET\u DIR}/JAVA\u PROJECT.war”
的文件是如何生成的。对于文件,CMake可以很好地生成依赖项检查,因此它不会不必要地重新构建。请注意,您可能还希望在该
添加自定义命令()
中包含一些
依赖项
,否则它在生成后将永远不会重新生成(1)

然后,您还需要一件事:自定义命令的驱动程序。这将取决于命令的
输出
,并实际导致生成它。因此,您将添加一个自定义目标:

然后,顺序如下所示:

make
过程中,
JavaProject
将被视为过时(因为它是一个定制目标),并将被构建。这意味着它的依赖项将被检查是否是最新的,如果不是最新的,则重新构建。这就是自定义命令的作用。之后,自定义目标本身将运行其
命令
,但它没有任何命令,因此不会发生其他任何事情

在随后的
make
调用中,
JavaProject
将再次被视为过时,因此将被构建。再次检查它的依赖项,但这一次,它们是最新的(因为
.war
已经存在)。因此,它不再建造。自定义目标仍然没有
命令
,因此没有进一步的操作

这种“自定义目标作为自定义命令的驱动程序”的方法是一段非常惯用的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
)
set(MyFiles
  a/file1.java
  a/file2.java
  a/b/file1.java
  a/c/file1.java
  # ... list all files as necessary
)
文件中的。cmake

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
)
set(MyFiles
  a/file1.java
  a/file2.java
  a/b/file1.java
  a/c/file1.java
  # ... list all files as necessary
)

这使CMakeList本身保持可读性,同时允许您显式地依赖于所需的一切。

尽管Angew有一个很好的答案,但不幸的是,它并没有像我预期的那样工作(即:当更新源代码文件夹并运行make时,它将不会再次构建war)

以下是解决我想要的问题的方法:

set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY TRUE) 

然后,当我运行make it时,它将生成,make install将只复制到安装文件夹。

您是否阅读了的文档,特别是明确强调的“总是被认为过时”位?啊,是的,谢谢您提供的信息,因此我需要更改为添加自定义命令()。。。然后为它添加一个驱动程序。请看我的答案。谢谢你的帮助,我对Cmake非常陌生,并尝试更改版本。我有一个问题,请帮助。正如您在add_custom_command()中所说的,我可能需要添加依赖项,否则在我更改了源文件夹中的某些文件后,它将不会再次构建java_project.war。如果有任何更改(编辑java_项目源文件夹中的文件),最好让它重新生成java_项目。我试图用源文件夹中的特定文件夹添加依赖项,它可以工作,但不考虑子目录中的更改。@BằngRikimaru您必须在那里列出各个文件。最好有一个明确的列表,这将迫使CMake重新运行并更新构建系统,如果您向该列表中添加文件。我认为CMake支持通配符,但如果不支持,则有很多文件夹可以更改(因此我无法在列表中列出);(当我运行make时,它将不会再次生成。因此,您接受的答案有一个缺点。@BằngRikimaru“因此我无法在
中列出依赖项
”我对此提出质疑。在工作中,我们有超过一百个项目,其中许多项目都有数百个源文件。我们仍然明确列出这些文件,并且它是有效的。我将用几句话来扩展答案,说明如何管理这一点。当然,这意味着每次运行
make
都将重新构建
war
是的,这正是我想要的(它应该重建这个war文件(它不够大,所以我必须按你的答案列出,但如果有很多,当然必须按你的答案)。