summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/command/add_custom_command.rst55
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmFileCommand.cxx6
-rw-r--r--Source/cmFindPackageCommand.cxx7
-rw-r--r--Tests/RunCMake/file/MAKE_DIRECTORY-fail-result.txt1
-rw-r--r--Tests/RunCMake/file/MAKE_DIRECTORY-fail-stderr.txt9
-rw-r--r--Tests/RunCMake/file/MAKE_DIRECTORY-fail.cmake2
-rw-r--r--Tests/RunCMake/file/RunCMakeTest.cmake2
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)