diff options
-rw-r--r-- | Help/command/add_custom_command.rst | 55 | ||||
-rw-r--r-- | Source/CMakeVersion.cmake | 2 | ||||
-rw-r--r-- | Source/cmFileCommand.cxx | 6 | ||||
-rw-r--r-- | Source/cmFindPackageCommand.cxx | 7 | ||||
-rw-r--r-- | Tests/RunCMake/file/MAKE_DIRECTORY-fail-result.txt | 1 | ||||
-rw-r--r-- | Tests/RunCMake/file/MAKE_DIRECTORY-fail-stderr.txt | 9 | ||||
-rw-r--r-- | Tests/RunCMake/file/MAKE_DIRECTORY-fail.cmake | 2 | ||||
-rw-r--r-- | Tests/RunCMake/file/RunCMakeTest.cmake | 2 |
8 files changed, 74 insertions, 10 deletions
diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst index 5878997..9dd8b95 100644 --- a/Help/command/add_custom_command.rst +++ b/Help/command/add_custom_command.rst @@ -31,14 +31,12 @@ This defines a command to generate specified ``OUTPUT`` file(s). A target created in the same directory (``CMakeLists.txt`` file) that specifies any output of the custom command as a source file is given a rule to generate the file using the command at build time. -Do not list the output in more than one independent target that -may build in parallel or the two instances of the rule may conflict -(instead use the :command:`add_custom_target` command to drive the -command and make the other targets depend on that one). -In makefile terms this creates a new target in the following form:: - OUTPUT: MAIN_DEPENDENCY DEPENDS - COMMAND +Do not list the output in more than one independent target that +may build in parallel or the instances of the rule may conflict. +Instead, use the :command:`add_custom_target` command to drive the +command and make the other targets depend on that one. See the +`Example: Generating Files for Multiple Targets`_ below. The options are: @@ -389,6 +387,49 @@ will re-run whenever ``in.txt`` changes. where ``<config>`` is the build configuration, and then compile the generated source as part of a library. +Example: Generating Files for Multiple Targets +"""""""""""""""""""""""""""""""""""""""""""""" + +If multiple independent targets need the same custom command output, +it must be attached to a single custom target on which they all depend. +Consider the following example: + +.. code-block:: cmake + + add_custom_command( + OUTPUT table.csv + COMMAND makeTable -i ${CMAKE_CURRENT_SOURCE_DIR}/input.dat + -o table.csv + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/input.dat + VERBATIM) + add_custom_target(generate_table_csv DEPENDS table.csv) + + add_custom_command( + OUTPUT foo.cxx + COMMAND genFromTable -i table.csv -case foo -o foo.cxx + DEPENDS table.csv # file-level dependency + generate_table_csv # target-level dependency + VERBATIM) + add_library(foo foo.cxx) + + add_custom_command( + OUTPUT bar.cxx + COMMAND genFromTable -i table.csv -case bar -o bar.cxx + DEPENDS table.csv # file-level dependency + generate_table_csv # target-level dependency + VERBATIM) + add_library(bar bar.cxx) + +Output ``foo.cxx`` is needed only by target ``foo`` and output ``bar.cxx`` +is needed only by target ``bar``, but *both* targets need ``table.csv``, +transitively. Since ``foo`` and ``bar`` are independent targets that may +build concurrently, we prevent them from racing to generate ``table.csv`` +by placing its custom command in a separate target, ``generate_table_csv``. +The custom commands generating ``foo.cxx`` and ``bar.cxx`` each specify a +target-level dependency on ``generate_table_csv``, so the targets using them, +``foo`` and ``bar``, will not build until after target ``generate_table_csv`` +is built. + .. _`add_custom_command(TARGET)`: Build Events diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index a4955c9..a980320 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 25) -set(CMake_VERSION_PATCH 20221208) +set(CMake_VERSION_PATCH 20221209) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index cdd0408..dfce033 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -845,8 +845,10 @@ bool HandleMakeDirectoryCommand(std::vector<std::string> const& args, cmSystemTools::SetFatalErrorOccurred(); return false; } - if (!cmSystemTools::MakeDirectory(*cdir)) { - std::string error = "problem creating directory: " + *cdir; + cmsys::Status mkdirStatus = cmSystemTools::MakeDirectory(*cdir); + if (!mkdirStatus) { + std::string error = cmStrCat("failed to create directory:\n ", *cdir, + "\nbecause: ", mkdirStatus.GetString()); status.SetError(error); return false; } diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 60b0a7b..71c7e13 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -379,6 +379,8 @@ private: # pragma diag_suppress 3288 // parameter was declared but never referenced # define CM_LCC_DIAG_SUPPRESS_3301 # pragma diag_suppress 3301 // parameter was declared but never referenced +# define CM_LCC_DIAG_SUPPRESS_3308 +# pragma diag_suppress 3308 // parameter was declared but never referenced #endif void ResetGenerator() @@ -423,6 +425,11 @@ bool TryGeneratedPaths(CallbackFn&& filesCollector, return false; } +#ifdef CM_LCC_DIAG_SUPPRESS_3308 +# undef CM_LCC_DIAG_SUPPRESS_3308 +# pragma diag_default 3308 +#endif + #ifdef CM_LCC_DIAG_SUPPRESS_3301 # undef CM_LCC_DIAG_SUPPRESS_3301 # pragma diag_default 3301 diff --git a/Tests/RunCMake/file/MAKE_DIRECTORY-fail-result.txt b/Tests/RunCMake/file/MAKE_DIRECTORY-fail-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/MAKE_DIRECTORY-fail-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/MAKE_DIRECTORY-fail-stderr.txt b/Tests/RunCMake/file/MAKE_DIRECTORY-fail-stderr.txt new file mode 100644 index 0000000..95fccdf --- /dev/null +++ b/Tests/RunCMake/file/MAKE_DIRECTORY-fail-stderr.txt @@ -0,0 +1,9 @@ +^CMake Error at [^ +]*/MAKE_DIRECTORY-fail.cmake:[0-9]+ \(file\): + file failed to create directory: + + [^ +]*/Tests/RunCMake/file/MAKE_DIRECTORY-fail-build/file/directory + + because: [^ +]+$ diff --git a/Tests/RunCMake/file/MAKE_DIRECTORY-fail.cmake b/Tests/RunCMake/file/MAKE_DIRECTORY-fail.cmake new file mode 100644 index 0000000..57a68e5 --- /dev/null +++ b/Tests/RunCMake/file/MAKE_DIRECTORY-fail.cmake @@ -0,0 +1,2 @@ +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/file" "") +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/file/directory") diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake index 752f7a0..c75e062 100644 --- a/Tests/RunCMake/file/RunCMakeTest.cmake +++ b/Tests/RunCMake/file/RunCMakeTest.cmake @@ -61,6 +61,8 @@ run_cmake_script(COPY_FILE-arg-unknown) run_cmake_script(COPY_FILE-input-missing) run_cmake_script(COPY_FILE-output-missing) +run_cmake_script(MAKE_DIRECTORY-fail) + run_cmake_script(RENAME-file-replace) run_cmake_script(RENAME-file-to-file) run_cmake_script(RENAME-file-to-dir-capture) |