summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Auxiliary/cmake-mode.el62
-rw-r--r--Help/command/add_test.rst2
-rw-r--r--Help/command/file.rst15
-rw-r--r--Help/command/target_include_directories.rst6
-rw-r--r--Help/manual/cmake-qt.7.rst7
-rw-r--r--Help/manual/ctest.1.rst3
-rw-r--r--Help/prop_tgt/AUTOMOC.rst3
-rw-r--r--Help/prop_tgt/XCODE_LINK_BUILD_PHASE_MODE.rst1
-rw-r--r--Help/release/dev/after-option-in-target_include-directories.rst5
-rw-r--r--Help/release/dev/ctest-test-dir.rst5
-rw-r--r--Help/release/dev/file-generate-permissions.rst6
-rw-r--r--Help/release/dev/qt-autogen-per-config.rst4
-rw-r--r--Modules/CMakeDetermineCompilerId.cmake4
-rw-r--r--Modules/FindOpenSSL.cmake24
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmCTest.cxx35
-rw-r--r--Source/cmComputeLinkInformation.cxx18
-rw-r--r--Source/cmComputeLinkInformation.h1
-rw-r--r--Source/cmCreateTestSourceList.cxx2
-rw-r--r--Source/cmFileCommand.cxx82
-rw-r--r--Source/cmGeneratorExpressionEvaluationFile.cxx12
-rw-r--r--Source/cmGeneratorExpressionEvaluationFile.h4
-rw-r--r--Source/cmGeneratorTarget.cxx2
-rw-r--r--Source/cmGeneratorTarget.h5
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx8
-rw-r--r--Source/cmMakefile.cxx5
-rw-r--r--Source/cmMakefile.h2
-rw-r--r--Source/cmQtAutoGenInitializer.cxx127
-rw-r--r--Source/cmQtAutoGenInitializer.h7
-rw-r--r--Source/cmQtAutoMocUic.cxx46
-rw-r--r--Source/cmSystemTools.cxx3
-rw-r--r--Source/cmTargetIncludeDirectoriesCommand.cxx1
-rw-r--r--Source/cmTargetPropCommandBase.cxx7
-rw-r--r--Source/cmTargetPropCommandBase.h5
-rw-r--r--Source/ctest.cxx1
-rw-r--r--Templates/TestDriver.cxx.in2
-rw-r--r--Tests/Framework/CMakeLists.txt16
-rw-r--r--Tests/Framework/External/CMakeLists.txt5
-rw-r--r--Tests/Framework/External/external.c4
-rw-r--r--Tests/Framework/useExternal.c6
-rw-r--r--Tests/QtAutogen/AutogenOriginDependsOff/CMakeLists.txt13
-rw-r--r--Tests/QtAutogen/GlobalAutogenTarget/CMakeLists.txt8
-rw-r--r--Tests/QtAutogen/MocOnly/CMakeLists.txt12
-rw-r--r--Tests/QtAutogen/MocOnly/CfgDebug.cpp5
-rw-r--r--Tests/QtAutogen/MocOnly/CfgDebug.hpp15
-rw-r--r--Tests/QtAutogen/MocOnly/CfgOther.cpp5
-rw-r--r--Tests/QtAutogen/MocOnly/CfgOther.hpp15
-rw-r--r--Tests/QtAutogen/MocOnly/main.cpp8
-rw-r--r--Tests/QtAutogen/TestMacros.cmake10
-rw-r--r--Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake17
-rw-r--r--Tests/RunCMake/CTestCommandLine/test-dir-invalid-arg-result.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/test-dir-invalid-arg-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-result.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-stdout.txt1
-rw-r--r--Tests/RunCMake/File_Generate/CustomFilePermissions.cmake15
-rw-r--r--Tests/RunCMake/File_Generate/CustomFilePermissionsVerify.cmake36
-rw-r--r--Tests/RunCMake/File_Generate/NoSourcePermissions.cmake10
-rw-r--r--Tests/RunCMake/File_Generate/NoSourcePermissionsVerify.cmake36
-rw-r--r--Tests/RunCMake/File_Generate/RunCMakeTest.cmake21
-rw-r--r--Tests/RunCMake/File_Generate/SourcePermissions1-result.txt1
-rw-r--r--Tests/RunCMake/File_Generate/SourcePermissions1-stderr.txt5
-rw-r--r--Tests/RunCMake/File_Generate/SourcePermissions1.cmake5
-rw-r--r--Tests/RunCMake/File_Generate/SourcePermissions2-result.txt1
-rw-r--r--Tests/RunCMake/File_Generate/SourcePermissions2-stderr.txt5
-rw-r--r--Tests/RunCMake/File_Generate/SourcePermissions2.cmake5
-rw-r--r--Tests/RunCMake/File_Generate/SourcePermissions3-result.txt1
-rw-r--r--Tests/RunCMake/File_Generate/SourcePermissions3-stderr.txt5
-rw-r--r--Tests/RunCMake/File_Generate/SourcePermissions3.cmake5
-rw-r--r--Tests/RunCMake/File_Generate/SourcePermissions4-result.txt1
-rw-r--r--Tests/RunCMake/File_Generate/SourcePermissions4-stderr.txt4
-rw-r--r--Tests/RunCMake/File_Generate/SourcePermissions4.cmake4
-rw-r--r--Tests/RunCMake/File_Generate/SourcePermissions5-result.txt1
-rw-r--r--Tests/RunCMake/File_Generate/SourcePermissions5-stderr.txt4
-rw-r--r--Tests/RunCMake/File_Generate/SourcePermissions5.cmake4
-rw-r--r--Tests/RunCMake/File_Generate/UseSourcePermissions.cmake11
-rw-r--r--Tests/RunCMake/File_Generate/UseSourcePermissionsVerify.cmake51
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Qt5.cmake3
-rw-r--r--Tests/RunCMake/target_include_directories/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/target_include_directories/include_after.cmake18
-rw-r--r--Tests/RunCMake/target_include_directories/include_before.cmake18
-rw-r--r--Tests/RunCMake/target_include_directories/include_default.cmake18
82 files changed, 846 insertions, 113 deletions
diff --git a/Auxiliary/cmake-mode.el b/Auxiliary/cmake-mode.el
index 6137ea9..52f2d41 100644
--- a/Auxiliary/cmake-mode.el
+++ b/Auxiliary/cmake-mode.el
@@ -28,6 +28,7 @@
;;
(require 'rst)
+(require 'rx)
(defcustom cmake-mode-cmake-executable "cmake"
"*The name of the cmake executable.
@@ -190,6 +191,61 @@ the indentation. Otherwise it retains the same position on the line"
)
)
+
+;------------------------------------------------------------------------------
+
+;;
+;; Navigation / marking by function or macro
+;;
+
+(defconst cmake--regex-defun-start
+ (rx line-start
+ (zero-or-more space)
+ (or "function" "macro")
+ (zero-or-more space)
+ "("))
+
+(defconst cmake--regex-defun-end
+ (rx line-start
+ (zero-or-more space)
+ "end"
+ (or "function" "macro")
+ (zero-or-more space)
+ "(" (zero-or-more (not ")")) ")"))
+
+(defun cmake-beginning-of-defun ()
+ "Move backward to the beginning of a CMake function or macro.
+
+Return t unless search stops due to beginning of buffer."
+ (interactive)
+ (when (not (region-active-p))
+ (push-mark))
+ (let ((case-fold-search t))
+ (when (re-search-backward cmake--regex-defun-start nil 'move)
+ t)))
+
+(defun cmake-end-of-defun ()
+ "Move forward to the end of a CMake function or macro.
+
+Return t unless search stops due to end of buffer."
+ (interactive)
+ (when (not (region-active-p))
+ (push-mark))
+ (let ((case-fold-search t))
+ (when (re-search-forward cmake--regex-defun-end nil 'move)
+ (forward-line)
+ t)))
+
+(defun cmake-mark-defun ()
+ "Mark the current CMake function or macro.
+
+This puts the mark at the end, and point at the beginning."
+ (interactive)
+ (cmake-end-of-defun)
+ (push-mark nil :nomsg :activate)
+ (cmake-beginning-of-defun))
+
+
;------------------------------------------------------------------------------
;;
@@ -242,6 +298,12 @@ the indentation. Otherwise it retains the same position on the line"
; Setup comment syntax.
(set (make-local-variable 'comment-start) "#"))
+;; Default cmake-mode key bindings
+(define-key cmake-mode-map "\e\C-a" #'cmake-beginning-of-defun)
+(define-key cmake-mode-map "\e\C-e" #'cmake-end-of-defun)
+(define-key cmake-mode-map "\e\C-h" #'cmake-mark-defun)
+
+
; Help mode starts here
diff --git a/Help/command/add_test.rst b/Help/command/add_test.rst
index 832d8db..95cd037 100644
--- a/Help/command/add_test.rst
+++ b/Help/command/add_test.rst
@@ -57,7 +57,7 @@ Example usage:
.. code-block:: cmake
add_test(NAME mytest
- COMMAND testDriver --config $<CONFIGURATION>
+ COMMAND testDriver --config $<CONFIG>
--exe $<TARGET_FILE:myexe>)
This creates a test ``mytest`` whose command runs a ``testDriver`` tool
diff --git a/Help/command/file.rst b/Help/command/file.rst
index 6837672..76a07f9 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -479,7 +479,9 @@ modified.
file(GENERATE OUTPUT output-file
<INPUT input-file|CONTENT content>
- [CONDITION expression] [TARGET target])
+ [CONDITION expression] [TARGET target]
+ [FILE_PERMISSIONS <permissions>...]
+ [NO_SOURCE_PERMISSIONS] [USE_SOURCE_PERMISSIONS])
Generate an output file for each build configuration supported by the current
:manual:`CMake Generator <cmake-generators(7)>`. Evaluate
@@ -520,6 +522,17 @@ from the input content to produce the output content. The options are:
require a target for evaluation (e.g. ``$<COMPILE_FEATURES:...>``,
``$<TARGET_PROPERTY:prop>``).
+``FILE_PERMISSIONS <permissions>...``
+ Use user provided permissions for the generated file.
+
+``NO_SOURCE_PERMISSIONS``
+ The generated file permissions default to the standard 644 value
+ (-rw-r--r--).
+
+``USE_SOURCE_PERMISSIONS``
+ Transfer the file permissions of the original file to the generated file.
+ This option expects INPUT option.
+
Exactly one ``CONTENT`` or ``INPUT`` option must be given. A specific
``OUTPUT`` file may be named by at most one invocation of ``file(GENERATE)``.
Generated files are modified and their timestamp updated on subsequent cmake
diff --git a/Help/command/target_include_directories.rst b/Help/command/target_include_directories.rst
index a8a5c83..3e53b2e 100644
--- a/Help/command/target_include_directories.rst
+++ b/Help/command/target_include_directories.rst
@@ -5,7 +5,7 @@ Add include directories to a target.
.. code-block:: cmake
- target_include_directories(<target> [SYSTEM] [BEFORE]
+ target_include_directories(<target> [SYSTEM] [AFTER|BEFORE]
<INTERFACE|PUBLIC|PRIVATE> [items1...]
[<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
@@ -14,8 +14,8 @@ The named ``<target>`` must have been created by a command such
as :command:`add_executable` or :command:`add_library` and must not be an
:ref:`ALIAS target <Alias Targets>`.
-If ``BEFORE`` is specified, the content will be prepended to the property
-instead of being appended.
+By using ``AFTER`` or ``BEFORE`` explicitly, you can select between appending
+and prepending, independent of the default.
The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to specify
the scope of the following arguments. ``PRIVATE`` and ``PUBLIC`` items will
diff --git a/Help/manual/cmake-qt.7.rst b/Help/manual/cmake-qt.7.rst
index d8d6172..f156f95 100644
--- a/Help/manual/cmake-qt.7.rst
+++ b/Help/manual/cmake-qt.7.rst
@@ -48,6 +48,8 @@ and ``rcc`` for virtual file system content generation. These tools may be
automatically invoked by :manual:`cmake(1)` if the appropriate conditions
are met. The automatic tool invocation may be used with both Qt 4 and Qt 5.
+.. _`Qt AUTOMOC`:
+
AUTOMOC
^^^^^^^
@@ -77,8 +79,9 @@ automatically added to the target's :prop_tgt:`INCLUDE_DIRECTORIES`.
Not included ``moc_<basename>.cpp`` files will be generated in custom
folders to avoid name collisions and included in a separate
-``<AUTOGEN_BUILD_DIR>/mocs_compilation.cpp`` file which is compiled
-into the target.
+file which is compiled into the target, named either
+``<AUTOGEN_BUILD_DIR>/mocs_compilation.cpp`` or
+``<AUTOGEN_BUILD_DIR>/mocs_compilation_$<CONFIG>.cpp``.
* See :prop_tgt:`AUTOGEN_BUILD_DIR`.
diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst
index 00df24b..16afcec 100644
--- a/Help/manual/ctest.1.rst
+++ b/Help/manual/ctest.1.rst
@@ -324,6 +324,9 @@ Options
``--build-and-test``
See `Build and Test Mode`_.
+``--test-dir <dir>``
+Specify the directory in which to look for tests.
+
``--test-output-size-passed <size>``
Limit the output for passed tests to ``<size>`` bytes.
diff --git a/Help/prop_tgt/AUTOMOC.rst b/Help/prop_tgt/AUTOMOC.rst
index c18859b..52d96e0 100644
--- a/Help/prop_tgt/AUTOMOC.rst
+++ b/Help/prop_tgt/AUTOMOC.rst
@@ -137,7 +137,8 @@ parent directory path of the ``moc`` input file. This scheme allows to have
All not included ``moc`` output files will be included automatically by the
CMake generated file
-- ``<AUTOGEN_BUILD_DIR>/mocs_compilation.cpp``,
+- ``<AUTOGEN_BUILD_DIR>/mocs_compilation.cpp``, or
+- ``<AUTOGEN_BUILD_DIR>/mocs_compilation_$<CONFIG>.cpp``,
which is added to the target's sources.
diff --git a/Help/prop_tgt/XCODE_LINK_BUILD_PHASE_MODE.rst b/Help/prop_tgt/XCODE_LINK_BUILD_PHASE_MODE.rst
index 2a79bca..836cc6b 100644
--- a/Help/prop_tgt/XCODE_LINK_BUILD_PHASE_MODE.rst
+++ b/Help/prop_tgt/XCODE_LINK_BUILD_PHASE_MODE.rst
@@ -31,6 +31,7 @@ Possible values are:
* ``KNOWN_LOCATION``
The "Link Binary With Libraries" build phase will be used to link to another
target under the same conditions as with ``BUILT_ONLY`` and also:
+
- Imported library targets except those of type ``UNKNOWN``.
- Any non-target library specified directly with a path.
diff --git a/Help/release/dev/after-option-in-target_include-directories.rst b/Help/release/dev/after-option-in-target_include-directories.rst
new file mode 100644
index 0000000..f61026c
--- /dev/null
+++ b/Help/release/dev/after-option-in-target_include-directories.rst
@@ -0,0 +1,5 @@
+after-option-in-target_include-directories.rst
+----------------------------------------------
+
+* The :command:`target_include_directories` command gained a new option
+ ``AFTER``.
diff --git a/Help/release/dev/ctest-test-dir.rst b/Help/release/dev/ctest-test-dir.rst
new file mode 100644
index 0000000..ab8d618
--- /dev/null
+++ b/Help/release/dev/ctest-test-dir.rst
@@ -0,0 +1,5 @@
+ctest-test-dir.rst
+------------------
+
+* :manual:`ctest(1)` gained a ``--test-dir`` option to specify the directory
+ in which to look for tests.
diff --git a/Help/release/dev/file-generate-permissions.rst b/Help/release/dev/file-generate-permissions.rst
new file mode 100644
index 0000000..d1a4d42
--- /dev/null
+++ b/Help/release/dev/file-generate-permissions.rst
@@ -0,0 +1,6 @@
+file-generate-permissions
+-------------------------
+
+* The :command:`file(GENERATE)` command gained ``NO_SOURCE_PERMISSIONS``,
+ ``USE_SOURCE_PERMISSIONS``, and ``FILE_PERMISSIONS`` options to support
+ permissions of the generated file.
diff --git a/Help/release/dev/qt-autogen-per-config.rst b/Help/release/dev/qt-autogen-per-config.rst
new file mode 100644
index 0000000..6ba929d
--- /dev/null
+++ b/Help/release/dev/qt-autogen-per-config.rst
@@ -0,0 +1,4 @@
+qt-autogen-per-config
+---------------------
+
+* The :ref:`Qt AUTOMOC` feature now works with per-config sources.
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index 8cf161f..d07db70 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -911,12 +911,12 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file)
# # COFF (.exe) files start with "MZ"
# if("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "4d5a....")
-# set(CMAKE_EXECUTABLE_FORMAT "COFF" CACHE STRING "Executable file format")
+# set(CMAKE_EXECUTABLE_FORMAT "COFF" CACHE INTERNAL "Executable file format")
# endif()
#
# Mach-O files start with MH_MAGIC or MH_CIGAM
if("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "feedface|cefaedfe|feedfacf|cffaedfe")
- set(CMAKE_EXECUTABLE_FORMAT "MACHO" CACHE STRING "Executable file format")
+ set(CMAKE_EXECUTABLE_FORMAT "MACHO" CACHE INTERNAL "Executable file format")
endif()
endif()
diff --git a/Modules/FindOpenSSL.cmake b/Modules/FindOpenSSL.cmake
index 03b699b..d574790 100644
--- a/Modules/FindOpenSSL.cmake
+++ b/Modules/FindOpenSSL.cmake
@@ -141,16 +141,30 @@ if (WIN32)
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1;Inno Setup: App Path]"
ENV OPENSSL_ROOT_DIR
)
- file(TO_CMAKE_PATH "$ENV{PROGRAMFILES}" _programfiles)
+
+ if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
+ set(_arch "Win64")
+ file(TO_CMAKE_PATH "$ENV{PROGRAMFILES}" _programfiles)
+ else()
+ set(_arch "Win32")
+ set(_progfiles_x86 "ProgramFiles(x86)")
+ if(NOT "$ENV{${_progfiles_x86}}" STREQUAL "")
+ # under windows 64 bit machine
+ file(TO_CMAKE_PATH "$ENV{${_progfiles_x86}}" _programfiles)
+ else()
+ # under windows 32 bit machine
+ file(TO_CMAKE_PATH "$ENV{ProgramFiles}" _programfiles)
+ endif()
+ endif()
+
set(_OPENSSL_ROOT_PATHS
"${_programfiles}/OpenSSL"
- "${_programfiles}/OpenSSL-Win32"
- "${_programfiles}/OpenSSL-Win64"
+ "${_programfiles}/OpenSSL-${_arch}"
"C:/OpenSSL/"
- "C:/OpenSSL-Win32/"
- "C:/OpenSSL-Win64/"
+ "C:/OpenSSL-${_arch}/"
)
unset(_programfiles)
+ unset(_arch)
else ()
set(_OPENSSL_ROOT_HINTS
${OPENSSL_ROOT_DIR}
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 61645f2..49c60e6 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 19)
-set(CMake_VERSION_PATCH 20201216)
+set(CMake_VERSION_PATCH 20201222)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 8479458..014ce4e 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -4,6 +4,7 @@
#include <algorithm>
#include <cctype>
+#include <cerrno>
#include <chrono>
#include <cstdio>
#include <cstdlib>
@@ -179,6 +180,7 @@ struct cmCTest::Private
// information for the --build-and-test options
std::string BinaryDir;
+ std::string TestDir;
std::string NotesFiles;
@@ -2059,6 +2061,13 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
i++;
this->SetNotesFiles(args[i]);
return true;
+ } else if (this->CheckArgument(arg, "--test-dir"_s)) {
+ if (i >= args.size() - 1) {
+ errormsg = "'--test-dir' requires an argument";
+ return false;
+ }
+ i++;
+ this->Impl->TestDir = std::string(args[i]);
}
cm::string_view noTestsPrefix = "--no-tests=";
@@ -2467,8 +2476,26 @@ int cmCTest::ExecuteTests()
handler->SetVerbose(this->Impl->Verbose);
handler->SetSubmitIndex(this->Impl->SubmitIndex);
}
- std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
- if (!this->Initialize(cwd.c_str(), nullptr)) {
+
+ const std::string currDir = cmSystemTools::GetCurrentWorkingDirectory();
+ std::string workDir = currDir;
+ if (!this->Impl->TestDir.empty()) {
+ workDir = cmSystemTools::CollapseFullPath(this->Impl->TestDir);
+ }
+
+ if (currDir != workDir) {
+ cmCTestLog(this, OUTPUT,
+ "Internal ctest changing into directory: " << workDir
+ << std::endl);
+ if (cmSystemTools::ChangeDirectory(workDir) != 0) {
+ auto msg = "Failed to change working directory to \"" + workDir +
+ "\" : " + std::strerror(errno) + "\n";
+ cmCTestLog(this, ERROR_MESSAGE, msg);
+ return 1;
+ }
+ }
+
+ if (!this->Initialize(workDir.c_str(), nullptr)) {
res = 12;
cmCTestLog(this, ERROR_MESSAGE,
"Problem initializing the dashboard." << std::endl);
@@ -2476,6 +2503,10 @@ int cmCTest::ExecuteTests()
res = this->ProcessSteps();
}
this->Finalize();
+
+ if (currDir != workDir) {
+ cmSystemTools::ChangeDirectory(currDir);
+ }
}
if (res != 0) {
cmCTestLog(this, DEBUG,
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index 201a9d9..6e1fac0 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -699,9 +699,13 @@ void cmComputeLinkInformation::AddItem(BT<std::string> const& item,
} else {
// This is not a CMake target. Use the name given.
if (cmSystemTools::FileIsFullPath(item.Value)) {
- if (cmSystemTools::FileIsDirectory(item.Value)) {
+ if (cmSystemTools::IsPathToFramework(item.Value) &&
+ this->Makefile->IsOn("APPLE")) {
+ // This is a framework.
+ this->AddFrameworkItem(item.Value);
+ } else if (cmSystemTools::FileIsDirectory(item.Value)) {
// This is a directory.
- this->AddDirectoryItem(item.Value);
+ this->DropDirectoryItem(item.Value);
} else {
// Use the full path given to the library file.
this->Depends.push_back(item.Value);
@@ -1306,16 +1310,6 @@ void cmComputeLinkInformation::AddFrameworkItem(std::string const& item)
}
}
-void cmComputeLinkInformation::AddDirectoryItem(std::string const& item)
-{
- if (this->Makefile->IsOn("APPLE") &&
- cmSystemTools::IsPathToFramework(item)) {
- this->AddFrameworkItem(item);
- } else {
- this->DropDirectoryItem(item);
- }
-}
-
void cmComputeLinkInformation::DropDirectoryItem(std::string const& item)
{
// A full path to a directory was found as a link item. Warn the
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
index 543b6d7..ec8d73c 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -155,7 +155,6 @@ private:
void AddFullItem(BT<std::string> const& item);
bool CheckImplicitDirItem(std::string const& item);
void AddUserItem(BT<std::string> const& item, bool pathNotKnown);
- void AddDirectoryItem(std::string const& item);
void AddFrameworkItem(std::string const& item);
void DropDirectoryItem(std::string const& item);
bool CheckSharedLibNoSOName(std::string const& item);
diff --git a/Source/cmCreateTestSourceList.cxx b/Source/cmCreateTestSourceList.cxx
index 9d492ba..3001ae0 100644
--- a/Source/cmCreateTestSourceList.cxx
+++ b/Source/cmCreateTestSourceList.cxx
@@ -125,7 +125,7 @@ bool cmCreateTestSourceList(std::vector<std::string> const& args,
mf.AddDefinition("CMAKE_TESTDRIVER_ARGVC_FUNCTION", function);
}
mf.AddDefinition("CMAKE_FORWARD_DECLARE_TESTS", forwardDeclareCode);
- mf.AddDefinition("CMAKE_FUNCTION_TABLE_ENTIRES", functionMapCode);
+ mf.AddDefinition("CMAKE_FUNCTION_TABLE_ENTRIES", functionMapCode);
bool res = true;
if (!mf.ConfigureFile(configFile, driver, false, true, false)) {
res = false;
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 9467c03..9815d9d 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -2291,7 +2291,7 @@ void AddEvaluationFile(const std::string& inputName,
const std::string& targetName,
const std::string& outputExpr,
const std::string& condition, bool inputIsContent,
- cmExecutionStatus& status)
+ mode_t permissions, cmExecutionStatus& status)
{
cmListFileBacktrace lfbt = status.GetMakefile().GetBacktrace();
@@ -2305,7 +2305,7 @@ void AddEvaluationFile(const std::string& inputName,
status.GetMakefile().AddEvaluationFile(
inputName, targetName, std::move(outputCge), std::move(conditionCge),
- inputIsContent);
+ permissions, inputIsContent);
}
bool HandleGenerateCommand(std::vector<std::string> const& args,
@@ -2323,14 +2323,21 @@ bool HandleGenerateCommand(std::vector<std::string> const& args,
std::string Content;
std::string Condition;
std::string Target;
+ bool NoSourcePermissions = false;
+ bool UseSourcePermissions = false;
+ std::vector<std::string> FilePermissions;
};
- static auto const parser = cmArgumentParser<Arguments>{}
- .Bind("OUTPUT"_s, &Arguments::Output)
- .Bind("INPUT"_s, &Arguments::Input)
- .Bind("CONTENT"_s, &Arguments::Content)
- .Bind("CONDITION"_s, &Arguments::Condition)
- .Bind("TARGET"_s, &Arguments::Target);
+ static auto const parser =
+ cmArgumentParser<Arguments>{}
+ .Bind("OUTPUT"_s, &Arguments::Output)
+ .Bind("INPUT"_s, &Arguments::Input)
+ .Bind("CONTENT"_s, &Arguments::Content)
+ .Bind("CONDITION"_s, &Arguments::Condition)
+ .Bind("TARGET"_s, &Arguments::Target)
+ .Bind("NO_SOURCE_PERMISSIONS"_s, &Arguments::NoSourcePermissions)
+ .Bind("USE_SOURCE_PERMISSIONS"_s, &Arguments::UseSourcePermissions)
+ .Bind("FILE_PERMISSIONS"_s, &Arguments::FilePermissions);
std::vector<std::string> unparsedArguments;
std::vector<std::string> keywordsMissingValues;
@@ -2399,8 +2406,65 @@ bool HandleGenerateCommand(std::vector<std::string> const& args,
input = arguments.Content;
}
+ if (arguments.NoSourcePermissions && arguments.UseSourcePermissions) {
+ status.SetError("given both NO_SOURCE_PERMISSIONS and "
+ "USE_SOURCE_PERMISSIONS. Only one option allowed.");
+ return false;
+ }
+
+ if (!arguments.FilePermissions.empty()) {
+ if (arguments.NoSourcePermissions) {
+ status.SetError("given both NO_SOURCE_PERMISSIONS and "
+ "FILE_PERMISSIONS. Only one option allowed.");
+ return false;
+ }
+ if (arguments.UseSourcePermissions) {
+ status.SetError("given both USE_SOURCE_PERMISSIONS and "
+ "FILE_PERMISSIONS. Only one option allowed.");
+ return false;
+ }
+ }
+
+ if (arguments.UseSourcePermissions) {
+ if (inputIsContent) {
+ status.SetError("given USE_SOURCE_PERMISSIONS without a file INPUT.");
+ return false;
+ }
+ }
+
+ mode_t permisiions = 0;
+ if (arguments.NoSourcePermissions) {
+ permisiions |= cmFSPermissions::mode_owner_read;
+ permisiions |= cmFSPermissions::mode_owner_write;
+ permisiions |= cmFSPermissions::mode_group_read;
+ permisiions |= cmFSPermissions::mode_world_read;
+ }
+
+ if (!arguments.FilePermissions.empty()) {
+ std::vector<std::string> invalidOptions;
+ for (auto const& e : arguments.FilePermissions) {
+ if (!cmFSPermissions::stringToModeT(e, permisiions)) {
+ invalidOptions.push_back(e);
+ }
+ }
+ if (!invalidOptions.empty()) {
+ std::ostringstream oss;
+ oss << "given invalid permission ";
+ for (auto i = 0u; i < invalidOptions.size(); i++) {
+ if (i == 0u) {
+ oss << "\"" << invalidOptions[i] << "\"";
+ } else {
+ oss << ",\"" << invalidOptions[i] << "\"";
+ }
+ }
+ oss << ".";
+ status.SetError(oss.str());
+ return false;
+ }
+ }
+
AddEvaluationFile(input, arguments.Target, arguments.Output,
- arguments.Condition, inputIsContent, status);
+ arguments.Condition, inputIsContent, permisiions, status);
return true;
}
diff --git a/Source/cmGeneratorExpressionEvaluationFile.cxx b/Source/cmGeneratorExpressionEvaluationFile.cxx
index 3c17b54..af129d3 100644
--- a/Source/cmGeneratorExpressionEvaluationFile.cxx
+++ b/Source/cmGeneratorExpressionEvaluationFile.cxx
@@ -21,13 +21,15 @@ cmGeneratorExpressionEvaluationFile::cmGeneratorExpressionEvaluationFile(
std::string input, std::string target,
std::unique_ptr<cmCompiledGeneratorExpression> outputFileExpr,
std::unique_ptr<cmCompiledGeneratorExpression> condition,
- bool inputIsContent, cmPolicies::PolicyStatus policyStatusCMP0070)
+ bool inputIsContent, mode_t permissions,
+ cmPolicies::PolicyStatus policyStatusCMP0070)
: Input(std::move(input))
, Target(std::move(target))
, OutputFileExpr(std::move(outputFileExpr))
, Condition(std::move(condition))
, InputIsContent(inputIsContent)
, PolicyStatusCMP0070(policyStatusCMP0070)
+ , Permissions(permissions)
{
}
@@ -111,14 +113,15 @@ void cmGeneratorExpressionEvaluationFile::CreateOutputFile(
void cmGeneratorExpressionEvaluationFile::Generate(cmLocalGenerator* lg)
{
- mode_t perm = 0;
std::string inputContent;
if (this->InputIsContent) {
inputContent = this->Input;
} else {
const std::string inputFileName = this->GetInputFileName(lg);
lg->GetMakefile()->AddCMakeDependFile(inputFileName);
- cmSystemTools::GetPermissions(inputFileName.c_str(), perm);
+ if (!this->Permissions) {
+ cmSystemTools::GetPermissions(inputFileName.c_str(), this->Permissions);
+ }
cmsys::ifstream fin(inputFileName.c_str());
if (!fin) {
std::ostringstream e;
@@ -152,7 +155,8 @@ void cmGeneratorExpressionEvaluationFile::Generate(cmLocalGenerator* lg)
for (std::string const& le : enabledLanguages) {
for (std::string const& li : allConfigs) {
- this->Generate(lg, li, le, inputExpression.get(), outputFiles, perm);
+ this->Generate(lg, li, le, inputExpression.get(), outputFiles,
+ this->Permissions);
if (cmSystemTools::GetFatalErrorOccured()) {
return;
}
diff --git a/Source/cmGeneratorExpressionEvaluationFile.h b/Source/cmGeneratorExpressionEvaluationFile.h
index 2cd35ae..5ad5e23 100644
--- a/Source/cmGeneratorExpressionEvaluationFile.h
+++ b/Source/cmGeneratorExpressionEvaluationFile.h
@@ -24,7 +24,8 @@ public:
std::string input, std::string target,
std::unique_ptr<cmCompiledGeneratorExpression> outputFileExpr,
std::unique_ptr<cmCompiledGeneratorExpression> condition,
- bool inputIsContent, cmPolicies::PolicyStatus policyStatusCMP0070);
+ bool inputIsContent, mode_t permissions,
+ cmPolicies::PolicyStatus policyStatusCMP0070);
void Generate(cmLocalGenerator* lg);
@@ -59,4 +60,5 @@ private:
std::vector<std::string> Files;
const bool InputIsContent;
cmPolicies::PolicyStatus PolicyStatusCMP0070;
+ mode_t Permissions;
};
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index dfeb029..e2943d6 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -7039,7 +7039,7 @@ const cmLinkImplementation* cmGeneratorTarget::GetLinkImplementation(
return &impl;
}
-bool cmGeneratorTarget::GetConfigCommonSourceFiles(
+bool cmGeneratorTarget::GetConfigCommonSourceFilesForXcode(
std::vector<cmSourceFile*>& files) const
{
std::vector<std::string> const& configs =
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index cb312ad..51369c2 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -430,8 +430,9 @@ public:
/** Get source files common to all configurations and diagnose cases
with per-config sources. Excludes sources added by a TARGET_OBJECTS
- generator expression. */
- bool GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const;
+ generator expression. Do not use outside the Xcode generator. */
+ bool GetConfigCommonSourceFilesForXcode(
+ std::vector<cmSourceFile*>& files) const;
bool HaveBuildTreeRPATH(const std::string& config) const;
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 70aa052..b6fedaf 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1384,7 +1384,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
// organize the sources
std::vector<cmSourceFile*> commonSourceFiles;
- if (!gtgt->GetConfigCommonSourceFiles(commonSourceFiles)) {
+ if (!gtgt->GetConfigCommonSourceFilesForXcode(commonSourceFiles)) {
return false;
}
@@ -1748,7 +1748,7 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(
this->CreateRunScriptBuildPhase("CMake PostBuild Rules", postbuild);
} else {
std::vector<cmSourceFile*> classes;
- if (!gtgt->GetConfigCommonSourceFiles(classes)) {
+ if (!gtgt->GetConfigCommonSourceFilesForXcode(classes)) {
return;
}
// add all the sources
@@ -1821,7 +1821,7 @@ void cmGlobalXCodeGenerator::CreateRunScriptBuildPhases(
cmXCodeObject* buildPhases, cmGeneratorTarget const* gt)
{
std::vector<cmSourceFile*> sources;
- if (!gt->GetConfigCommonSourceFiles(sources)) {
+ if (!gt->GetConfigCommonSourceFilesForXcode(sources)) {
return;
}
auto& visited = this->CommandsVisited[gt];
@@ -2964,7 +2964,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateUtilityTarget(
if (gtgt->GetType() != cmStateEnums::GLOBAL_TARGET &&
gtgt->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
std::vector<cmSourceFile*> sources;
- if (!gtgt->GetConfigCommonSourceFiles(sources)) {
+ if (!gtgt->GetConfigCommonSourceFilesForXcode(sources)) {
return nullptr;
}
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 028688d..9d37d61 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -865,13 +865,14 @@ void cmMakefile::EnforceDirectoryLevelRules() const
void cmMakefile::AddEvaluationFile(
const std::string& inputFile, const std::string& targetName,
std::unique_ptr<cmCompiledGeneratorExpression> outputName,
- std::unique_ptr<cmCompiledGeneratorExpression> condition,
+ std::unique_ptr<cmCompiledGeneratorExpression> condition, mode_t permissions,
bool inputIsContent)
{
this->EvaluationFiles.push_back(
cm::make_unique<cmGeneratorExpressionEvaluationFile>(
inputFile, targetName, std::move(outputName), std::move(condition),
- inputIsContent, this->GetPolicyStatus(cmPolicies::CMP0070)));
+ inputIsContent, permissions,
+ this->GetPolicyStatus(cmPolicies::CMP0070)));
}
const std::vector<std::unique_ptr<cmGeneratorExpressionEvaluationFile>>&
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index f18f70c..1617793 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -899,7 +899,7 @@ public:
const std::string& inputFile, const std::string& targetName,
std::unique_ptr<cmCompiledGeneratorExpression> outputName,
std::unique_ptr<cmCompiledGeneratorExpression> condition,
- bool inputIsContent);
+ mode_t permissions, bool inputIsContent);
const std::vector<std::unique_ptr<cmGeneratorExpressionEvaluationFile>>&
GetEvaluationFiles() const;
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 67834f1..1f74578 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -17,6 +17,7 @@
#include <cm/iterator>
#include <cm/memory>
#include <cmext/algorithm>
+#include <cmext/string_view>
#include <cm3p/json/value.h>
#include <cm3p/json/writer.h>
@@ -564,8 +565,22 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
bool cmQtAutoGenInitializer::InitMoc()
{
// Mocs compilation file
- this->Moc.CompilationFile =
- cmStrCat(this->Dir.Build, "/mocs_compilation.cpp");
+ if (this->GlobalGen->IsXcode()) {
+ // XXX(xcode-per-cfg-src): Drop this Xcode-specific code path
+ // when the Xcode generator supports per-config sources.
+ this->Moc.CompilationFile.Default =
+ cmStrCat(this->Dir.Build, "/mocs_compilation.cpp");
+ this->Moc.CompilationFileGenex = this->Moc.CompilationFile.Default;
+ } else {
+ ConfigFileNames(this->Moc.CompilationFile,
+ cmStrCat(this->Dir.Build, "/mocs_compilation"), ".cpp");
+ if (this->MultiConfig) {
+ this->Moc.CompilationFileGenex =
+ cmStrCat(this->Dir.Build, "/mocs_compilation_$<CONFIG>.cpp"_s);
+ } else {
+ this->Moc.CompilationFileGenex = this->Moc.CompilationFile.Default;
+ }
+ }
// Moc predefs
if (this->GenTarget->GetPropertyAsBool("AUTOMOC_COMPILER_PREDEFINES") &&
@@ -731,10 +746,14 @@ bool cmQtAutoGenInitializer::InitScanFiles()
auto const& kw = this->GlobalInitializer->kw();
auto makeMUFile = [this, &kw](cmSourceFile* sf, std::string const& fullPath,
+ std::vector<size_t> const& configs,
bool muIt) -> MUFileHandle {
MUFileHandle muf = cm::make_unique<MUFile>();
muf->FullPath = fullPath;
muf->SF = sf;
+ if (!configs.empty() && configs.size() != this->ConfigsList.size()) {
+ muf->Configs = configs;
+ }
muf->Generated = sf->GetIsGenerated();
bool const skipAutogen = sf->GetPropertyAsBool(kw.SKIP_AUTOGEN);
muf->SkipMoc = this->Moc.Enabled &&
@@ -773,42 +792,37 @@ bool cmQtAutoGenInitializer::InitScanFiles()
// Scan through target files
{
// Scan through target files
- std::vector<cmSourceFile*> srcFiles;
- this->GenTarget->GetConfigCommonSourceFiles(srcFiles);
- for (cmSourceFile* sf : srcFiles) {
- // sf->GetExtension() is only valid after sf->ResolveFullPath() ...
- // Since we're iterating over source files that might be not in the
- // target we need to check for path errors (not existing files).
- std::string pathError;
- std::string const& fullPath = sf->ResolveFullPath(&pathError);
- if (!pathError.empty() || fullPath.empty()) {
- continue;
- }
+ for (cmGeneratorTarget::AllConfigSource const& acs :
+ this->GenTarget->GetAllConfigSources()) {
+ std::string const& fullPath = acs.Source->GetFullPath();
std::string const& extLower =
- cmSystemTools::LowerCase(sf->GetExtension());
+ cmSystemTools::LowerCase(acs.Source->GetExtension());
// Register files that will be scanned by moc or uic
if (this->MocOrUicEnabled()) {
if (cm->IsAHeaderExtension(extLower)) {
- addMUHeader(makeMUFile(sf, fullPath, true), extLower);
+ addMUHeader(makeMUFile(acs.Source, fullPath, acs.Configs, true),
+ extLower);
} else if (cm->IsACLikeSourceExtension(extLower)) {
- addMUSource(makeMUFile(sf, fullPath, true));
+ addMUSource(makeMUFile(acs.Source, fullPath, acs.Configs, true));
}
}
// Register rcc enabled files
if (this->Rcc.Enabled) {
- if ((extLower == kw.qrc) && !sf->GetPropertyAsBool(kw.SKIP_AUTOGEN) &&
- !sf->GetPropertyAsBool(kw.SKIP_AUTORCC)) {
+ if ((extLower == kw.qrc) &&
+ !acs.Source->GetPropertyAsBool(kw.SKIP_AUTOGEN) &&
+ !acs.Source->GetPropertyAsBool(kw.SKIP_AUTORCC)) {
// Register qrc file
Qrc qrc;
qrc.QrcFile = fullPath;
qrc.QrcName =
cmSystemTools::GetFilenameWithoutLastExtension(qrc.QrcFile);
- qrc.Generated = sf->GetIsGenerated();
+ qrc.Generated = acs.Source->GetIsGenerated();
// RCC options
{
- std::string const& opts = sf->GetSafeProperty(kw.AUTORCC_OPTIONS);
+ std::string const& opts =
+ acs.Source->GetSafeProperty(kw.AUTORCC_OPTIONS);
if (!opts.empty()) {
cmExpandList(opts, qrc.Options);
}
@@ -818,7 +832,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
}
}
}
- // cmGeneratorTarget::GetConfigCommonSourceFiles computes the target's
+ // cmGeneratorTarget::GetAllConfigSources computes the target's
// sources meta data cache. Clear it so that OBJECT library targets that
// are AUTOGEN initialized after this target get their added
// mocs_compilation.cpp source acknowledged by this target.
@@ -862,7 +876,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
}
if (sf != nullptr) {
- auto eMuf = makeMUFile(sf, fullPath, true);
+ auto eMuf = makeMUFile(sf, fullPath, muf.Configs, true);
// Only process moc/uic when the parent is processed as well
if (!muf.MocIt) {
eMuf->MocIt = false;
@@ -897,14 +911,14 @@ bool cmQtAutoGenInitializer::InitScanFiles()
if (cm->IsAHeaderExtension(extLower)) {
if (!cm::contains(this->AutogenTarget.Headers, sf.get())) {
- auto muf = makeMUFile(sf.get(), fullPath, false);
+ auto muf = makeMUFile(sf.get(), fullPath, {}, false);
if (muf->SkipMoc || muf->SkipUic) {
addMUHeader(std::move(muf), extLower);
}
}
} else if (cm->IsACLikeSourceExtension(extLower)) {
if (!cm::contains(this->AutogenTarget.Sources, sf.get())) {
- auto muf = makeMUFile(sf.get(), fullPath, false);
+ auto muf = makeMUFile(sf.get(), fullPath, {}, false);
if (muf->SkipMoc || muf->SkipUic) {
addMUSource(std::move(muf));
}
@@ -1067,10 +1081,10 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
this->Makefile->AddCMakeOutputFile(this->AutogenTarget.InfoFile);
// Files provided by the autogen target
- std::vector<std::string> autogenProvides;
+ std::vector<std::string> autogenByproducts;
if (this->Moc.Enabled) {
this->AddGeneratedSource(this->Moc.CompilationFile, this->Moc, true);
- autogenProvides.push_back(this->Moc.CompilationFile);
+ autogenByproducts.push_back(this->Moc.CompilationFileGenex);
}
// Compose target comment
@@ -1091,8 +1105,8 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
}
// Compose command lines
- // TODO: Refactor autogen to output a per-config mocs_compilation.cpp instead
- // of fiddling with the include directories
+ // FIXME: Take advantage of our per-config mocs_compilation_$<CONFIG>.cpp
+ // instead of fiddling with the include directories
std::vector<std::string> configs;
this->GlobalGen->GetQtAutoGenConfigs(configs);
bool stdPipesUTF8 = true;
@@ -1138,7 +1152,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
// PRE_BUILD does not support file dependencies!
const std::vector<std::string> no_output;
const std::vector<std::string> no_deps;
- cmCustomCommand cc(no_output, autogenProvides, no_deps, commandLines,
+ cmCustomCommand cc(no_output, autogenByproducts, no_deps, commandLines,
this->Makefile->GetBacktrace(), autogenComment.c_str(),
this->Dir.Work.c_str(), stdPipesUTF8);
cc.SetEscapeOldStyle(false);
@@ -1283,7 +1297,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
// Create autogen target
cmTarget* autogenTarget = this->LocalGen->AddUtilityCommand(
this->AutogenTarget.Name, true, this->Dir.Work.c_str(),
- /*byproducts=*/autogenProvides,
+ /*byproducts=*/autogenByproducts,
/*depends=*/dependencies, commandLines, false, autogenComment.c_str());
// Create autogen generator target
this->LocalGen->AddGeneratorTarget(
@@ -1533,18 +1547,31 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
info.SetArray("CMAKE_LIST_FILES", this->Makefile->GetListFiles());
info.SetArray("HEADER_EXTENSIONS",
this->Makefile->GetCMakeInstance()->GetHeaderExtensions());
+ auto cfgArray = [this](std::vector<size_t> const& configs) -> Json::Value {
+ Json::Value value;
+ if (!configs.empty()) {
+ value = Json::arrayValue;
+ for (size_t ci : configs) {
+ value.append(this->ConfigsList[ci]);
+ }
+ }
+ return value;
+ };
+ info.SetArrayArray("HEADERS", headers,
+ [this, &cfgArray](Json::Value& jval, MUFile const* muf) {
+ jval.resize(4u);
+ jval[0u] = muf->FullPath;
+ jval[1u] = cmStrCat(muf->MocIt ? 'M' : 'm',
+ muf->UicIt ? 'U' : 'u');
+ jval[2u] = cfgArray(muf->Configs);
+ jval[3u] = this->GetMocBuildPath(*muf);
+ });
info.SetArrayArray(
- "HEADERS", headers, [this](Json::Value& jval, MUFile const* muf) {
+ "SOURCES", sources, [&cfgArray](Json::Value& jval, MUFile const* muf) {
jval.resize(3u);
jval[0u] = muf->FullPath;
jval[1u] = cmStrCat(muf->MocIt ? 'M' : 'm', muf->UicIt ? 'U' : 'u');
- jval[2u] = this->GetMocBuildPath(*muf);
- });
- info.SetArrayArray(
- "SOURCES", sources, [](Json::Value& jval, MUFile const* muf) {
- jval.resize(2u);
- jval[0u] = muf->FullPath;
- jval[1u] = cmStrCat(muf->MocIt ? 'M' : 'm', muf->UicIt ? 'U' : 'u');
+ jval[2u] = cfgArray(muf->Configs);
});
// Write moc settings
@@ -1563,7 +1590,7 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
jval[0u] = pair.first;
jval[1u] = pair.second;
});
- info.Set("MOC_COMPILATION_FILE", this->Moc.CompilationFile);
+ info.SetConfig("MOC_COMPILATION_FILE", this->Moc.CompilationFile);
info.SetArray("MOC_PREDEFS_CMD", this->Moc.PredefsCmd);
info.SetConfig("MOC_PREDEFS_FILE", this->Moc.PredefsFile);
}
@@ -1656,6 +1683,28 @@ cmSourceFile* cmQtAutoGenInitializer::AddGeneratedSource(
return gFile;
}
+void cmQtAutoGenInitializer::AddGeneratedSource(ConfigString const& filename,
+ GenVarsT const& genVars,
+ bool prepend)
+{
+ // XXX(xcode-per-cfg-src): Drop the Xcode-specific part of the condition
+ // when the Xcode generator supports per-config sources.
+ if (!this->MultiConfig || this->GlobalGen->IsXcode()) {
+ this->AddGeneratedSource(filename.Default, genVars, prepend);
+ return;
+ }
+ for (auto const& cfg : this->ConfigsList) {
+ std::string const& filenameCfg = filename.Config.at(cfg);
+ // Register source at makefile
+ this->RegisterGeneratedSource(filenameCfg);
+ // Add source file to target for this configuration.
+ this->GenTarget->AddSource(
+ cmStrCat("$<$<CONFIG:"_s, cfg, ">:"_s, filenameCfg, ">"_s), prepend);
+ // Add source file to source group
+ this->AddToSourceGroup(filenameCfg, genVars.GenNameUpper);
+ }
+}
+
void cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName,
cm::string_view genNameUpper)
{
diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h
index 3ab303a..e0e66f1 100644
--- a/Source/cmQtAutoGenInitializer.h
+++ b/Source/cmQtAutoGenInitializer.h
@@ -4,6 +4,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <cstddef>
#include <memory>
#include <set>
#include <string>
@@ -70,6 +71,7 @@ public:
{
std::string FullPath;
cmSourceFile* SF = nullptr;
+ std::vector<size_t> Configs;
bool Generated = false;
bool SkipMoc = false;
bool SkipUic = false;
@@ -132,6 +134,8 @@ private:
cmSourceFile* AddGeneratedSource(std::string const& filename,
GenVarsT const& genVars,
bool prepend = false);
+ void AddGeneratedSource(ConfigString const& filename,
+ GenVarsT const& genVars, bool prepend = false);
void AddToSourceGroup(std::string const& fileName,
cm::string_view genNameUpper);
void AddCleanFile(std::string const& fileName);
@@ -207,7 +211,8 @@ private:
bool RelaxedMode = false;
bool PathPrefix = false;
- std::string CompilationFile;
+ ConfigString CompilationFile;
+ std::string CompilationFileGenex;
// Compiler implicit pre defines
std::vector<std::string> PredefsCmd;
ConfigString PredefsFile;
diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx
index b27bb88..c9d4268 100644
--- a/Source/cmQtAutoMocUic.cxx
+++ b/Source/cmQtAutoMocUic.cxx
@@ -2452,17 +2452,20 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
Json::Value const& entry = val[ii];
if (testEntry(entry.isArray(), "JSON value is not an array.") ||
- testEntry(entry.size() == 3, "JSON array size invalid.")) {
+ testEntry(entry.size() == 4, "JSON array size invalid.")) {
return false;
}
Json::Value const& entryName = entry[0u];
Json::Value const& entryFlags = entry[1u];
- Json::Value const& entryBuild = entry[2u];
+ Json::Value const& entryConfigs = entry[2u];
+ Json::Value const& entryBuild = entry[3u];
if (testEntry(entryName.isString(),
"JSON value for name is not a string.") ||
testEntry(entryFlags.isString(),
"JSON value for flags is not a string.") ||
+ testEntry(entryConfigs.isNull() || entryConfigs.isArray(),
+ "JSON value for configs is not null or array.") ||
testEntry(entryBuild.isString(),
"JSON value for build path is not a string.")) {
return false;
@@ -2475,6 +2478,22 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
return false;
}
+ if (entryConfigs.isArray()) {
+ bool configFound = false;
+ Json::ArrayIndex const configArraySize = entryConfigs.size();
+ for (Json::ArrayIndex ci = 0; ci != configArraySize; ++ci) {
+ Json::Value const& config = entryConfigs[ci];
+ if (testEntry(config.isString(),
+ "JSON value in config array is not a string.")) {
+ return false;
+ }
+ configFound = configFound || config.asString() == this->InfoConfig();
+ }
+ if (!configFound) {
+ continue;
+ }
+ }
+
cmFileTime fileTime;
if (!fileTime.Load(name)) {
return info.LogError(cmStrCat(
@@ -2515,16 +2534,19 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
Json::Value const& entry = val[ii];
if (testEntry(entry.isArray(), "JSON value is not an array.") ||
- testEntry(entry.size() == 2, "JSON array size invalid.")) {
+ testEntry(entry.size() == 3, "JSON array size invalid.")) {
return false;
}
Json::Value const& entryName = entry[0u];
Json::Value const& entryFlags = entry[1u];
+ Json::Value const& entryConfigs = entry[2u];
if (testEntry(entryName.isString(),
"JSON value for name is not a string.") ||
testEntry(entryFlags.isString(),
- "JSON value for flags is not a string.")) {
+ "JSON value for flags is not a string.") ||
+ testEntry(entryConfigs.isNull() || entryConfigs.isArray(),
+ "JSON value for configs is not null or array.")) {
return false;
}
@@ -2534,6 +2556,22 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
return false;
}
+ if (entryConfigs.isArray()) {
+ bool configFound = false;
+ Json::ArrayIndex const configArraySize = entryConfigs.size();
+ for (Json::ArrayIndex ci = 0; ci != configArraySize; ++ci) {
+ Json::Value const& config = entryConfigs[ci];
+ if (testEntry(config.isString(),
+ "JSON value in config array is not a string.")) {
+ return false;
+ }
+ configFound = configFound || config.asString() == this->InfoConfig();
+ }
+ if (!configFound) {
+ continue;
+ }
+ }
+
cmFileTime fileTime;
if (!fileTime.Load(name)) {
return info.LogError(cmStrCat(
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 97440d2..6a705f4 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -952,9 +952,8 @@ bool cmMoveFile(std::wstring const& oldname, std::wstring const& newname)
SetLastError(0);
// Use MOVEFILE_REPLACE_EXISTING to replace an existing destination file.
- // Use MOVEFILE_WRITE_THROUGH to flush the change to disk before returning.
return MoveFileExW(oldname.c_str(), newname.c_str(),
- MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH);
+ MOVEFILE_REPLACE_EXISTING);
}
}
#endif
diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx
index 35635b9..bf4cc09 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.cxx
+++ b/Source/cmTargetIncludeDirectoriesCommand.cxx
@@ -101,5 +101,6 @@ bool cmTargetIncludeDirectoriesCommand(std::vector<std::string> const& args,
args, "INCLUDE_DIRECTORIES",
TargetIncludeDirectoriesImpl::ArgumentFlags(
TargetIncludeDirectoriesImpl::PROCESS_BEFORE |
+ TargetIncludeDirectoriesImpl::PROCESS_AFTER |
TargetIncludeDirectoriesImpl::PROCESS_SYSTEM));
}
diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx
index b050a58..e41714a 100644
--- a/Source/cmTargetPropCommandBase.cxx
+++ b/Source/cmTargetPropCommandBase.cxx
@@ -87,6 +87,13 @@ bool cmTargetPropCommandBase::HandleArguments(
}
prepend = true;
++argIndex;
+ } else if ((flags & PROCESS_AFTER) && args[argIndex] == "AFTER") {
+ if (args.size() < 3) {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+ prepend = false;
+ ++argIndex;
}
if ((flags & PROCESS_REUSE_FROM) && args[argIndex] == "REUSE_FROM") {
diff --git a/Source/cmTargetPropCommandBase.h b/Source/cmTargetPropCommandBase.h
index 50ac1aa..fc24fe8 100644
--- a/Source/cmTargetPropCommandBase.h
+++ b/Source/cmTargetPropCommandBase.h
@@ -23,8 +23,9 @@ public:
{
NO_FLAGS = 0x0,
PROCESS_BEFORE = 0x1,
- PROCESS_SYSTEM = 0x2,
- PROCESS_REUSE_FROM = 0x3
+ PROCESS_AFTER = 0x2,
+ PROCESS_SYSTEM = 0x3,
+ PROCESS_REUSE_FROM = 0x4
};
bool HandleArguments(std::vector<std::string> const& args,
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index d0bc061..600df1d 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -111,6 +111,7 @@ static const char* cmDocumentationOptions[][2] = {
{ "--no-subproject-summary",
"Disable timing summary information for "
"subprojects." },
+ { "--test-dir <dir>", "Specify the directory in which to look for tests." },
{ "--build-and-test", "Configure, build and run a test." },
{ "--build-target", "Specify a specific target to build." },
{ "--build-nocmake", "Run the build without running cmake first." },
diff --git a/Templates/TestDriver.cxx.in b/Templates/TestDriver.cxx.in
index 053f1ee..3e47d6a 100644
--- a/Templates/TestDriver.cxx.in
+++ b/Templates/TestDriver.cxx.in
@@ -34,7 +34,7 @@ typedef struct /* NOLINT */
} functionMapEntry;
static functionMapEntry cmakeGeneratedFunctionMapEntries[] = {
- @CMAKE_FUNCTION_TABLE_ENTIRES@
+ @CMAKE_FUNCTION_TABLE_ENTRIES@
{ CM_NULL, CM_NULL } /* NOLINT */
};
diff --git a/Tests/Framework/CMakeLists.txt b/Tests/Framework/CMakeLists.txt
index a313c2c..f741ec2 100644
--- a/Tests/Framework/CMakeLists.txt
+++ b/Tests/Framework/CMakeLists.txt
@@ -84,3 +84,19 @@ if(NOT XCODE OR NOT XCODE_VERSION VERSION_LESS 5)
endif()
include(CPack)
+
+if(APPLE)
+ set(ExternalFramework_INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/External")
+ file(REMOVE_RECURSE "${ExternalFramework_INSTALL_DIR}")
+
+ include(ExternalProject)
+ ExternalProject_Add(ExternalFramework
+ SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/External"
+ INSTALL_DIR "${ExternalFramework_INSTALL_DIR}"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
+ )
+
+ add_executable(useExternal useExternal.c)
+ target_link_libraries(useExternal PRIVATE "${ExternalFramework_INSTALL_DIR}/lib/External.framework")
+ add_dependencies(useExternal ExternalFramework)
+endif()
diff --git a/Tests/Framework/External/CMakeLists.txt b/Tests/Framework/External/CMakeLists.txt
new file mode 100644
index 0000000..b9128fd
--- /dev/null
+++ b/Tests/Framework/External/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.19)
+project(ExternalFramework C)
+add_library(External SHARED external.c)
+set_property(TARGET External PROPERTY FRAMEWORK 1)
+install(TARGETS External DESTINATION lib)
diff --git a/Tests/Framework/External/external.c b/Tests/Framework/External/external.c
new file mode 100644
index 0000000..8441e71
--- /dev/null
+++ b/Tests/Framework/External/external.c
@@ -0,0 +1,4 @@
+int external(void)
+{
+ return 0;
+}
diff --git a/Tests/Framework/useExternal.c b/Tests/Framework/useExternal.c
new file mode 100644
index 0000000..8494b15
--- /dev/null
+++ b/Tests/Framework/useExternal.c
@@ -0,0 +1,6 @@
+extern int external(void);
+
+int main(void)
+{
+ return external();
+}
diff --git a/Tests/QtAutogen/AutogenOriginDependsOff/CMakeLists.txt b/Tests/QtAutogen/AutogenOriginDependsOff/CMakeLists.txt
index d9fc2b0..17855ff 100644
--- a/Tests/QtAutogen/AutogenOriginDependsOff/CMakeLists.txt
+++ b/Tests/QtAutogen/AutogenOriginDependsOff/CMakeLists.txt
@@ -2,6 +2,15 @@ cmake_minimum_required(VERSION 3.11)
project(AutogenOriginDependsOff)
include("../AutogenCoreTest.cmake")
+get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+# XXX(xcode-per-cfg-src): Enable multi-config code path for Xcode
+# when the Xcode generator supports per-config sources.
+if(_isMultiConfig AND NOT CMAKE_GENERATOR STREQUAL "Xcode")
+ set(mocs_compilation_cpp "mocs_compilation_$<CONFIG>.cpp")
+else()
+ set(mocs_compilation_cpp "mocs_compilation.cpp")
+endif()
+
set(CSD ${CMAKE_CURRENT_SOURCE_DIR})
set(CBD ${CMAKE_CURRENT_BINARY_DIR})
include_directories(${CSD})
@@ -19,7 +28,7 @@ add_custom_command (
add_custom_target ( a_mc
COMMAND ${CMAKE_COMMAND} -E sleep 2
COMMAND ${CMAKE_COMMAND}
- "-DMCF=${CBD}/a_qt_autogen/mocs_compilation.cpp"
+ "-DMCF=${CBD}/a_qt_autogen/${mocs_compilation_cpp}"
"-DCF_IN=${CSD}/a_mc.hpp.in"
"-DCF_OUT=${CBD}/a_mc.hpp"
-P ${CSD}/configure_content.cmake
@@ -51,7 +60,7 @@ add_custom_command (
DEPENDS b_qt_autogen
COMMAND ${CMAKE_COMMAND} -E sleep 2
COMMAND ${CMAKE_COMMAND}
- "-DMCF=${CBD}/b_qt_autogen/mocs_compilation.cpp"
+ "-DMCF=${CBD}/b_qt_autogen/${mocs_compilation_cpp}"
"-DCF_IN=${CSD}/b_mc.cpp.in"
"-DCF_OUT=${CBD}/b_mc.cpp"
-P ${CSD}/configure_content.cmake
diff --git a/Tests/QtAutogen/GlobalAutogenTarget/CMakeLists.txt b/Tests/QtAutogen/GlobalAutogenTarget/CMakeLists.txt
index 81fd8db..e95c626 100644
--- a/Tests/QtAutogen/GlobalAutogenTarget/CMakeLists.txt
+++ b/Tests/QtAutogen/GlobalAutogenTarget/CMakeLists.txt
@@ -13,10 +13,10 @@ include("../AutogenCoreTest.cmake")
set(GAT_SDIR "${CMAKE_CURRENT_SOURCE_DIR}/GAT")
set(GAT_BDIR "${CMAKE_CURRENT_BINARY_DIR}/GAT")
# Files
-set(MCA "sda/sda_autogen/mocs_compilation.cpp")
-set(MCB "sdb/sdb_autogen/mocs_compilation.cpp")
-set(MCC "sdc/sdc_autogen/mocs_compilation.cpp")
-set(MCG "gat_autogen/mocs_compilation.cpp")
+set(MCA "sda/sda_autogen/mocs_compilation*.cpp")
+set(MCB "sdb/sdb_autogen/mocs_compilation*.cpp")
+set(MCC "sdc/sdc_autogen/mocs_compilation*.cpp")
+set(MCG "gat_autogen/mocs_compilation*.cpp")
set(DRA "sda/sda_autogen/*qrc_data.cpp")
set(DRB "sdb/sdb_autogen/*qrc_data.cpp")
diff --git a/Tests/QtAutogen/MocOnly/CMakeLists.txt b/Tests/QtAutogen/MocOnly/CMakeLists.txt
index e109154..f4fde58 100644
--- a/Tests/QtAutogen/MocOnly/CMakeLists.txt
+++ b/Tests/QtAutogen/MocOnly/CMakeLists.txt
@@ -11,6 +11,18 @@ add_executable(mocOnly
IncA.cpp
IncB.cpp
)
+# XXX(xcode-per-cfg-src): Drop the NO_PER_CONFIG_SOURCES exclusion
+# when the Xcode generator supports per-config sources.
+if(NOT NO_PER_CONFIG_SOURCES)
+ target_sources(mocOnly PRIVATE
+ "$<$<CONFIG:Debug>:${CMAKE_CURRENT_SOURCE_DIR}/CfgDebug.cpp>"
+ "$<$<NOT:$<CONFIG:Debug>>:${CMAKE_CURRENT_SOURCE_DIR}/CfgOther.cpp>"
+ )
+ target_compile_definitions(mocOnly PRIVATE
+ "$<$<CONFIG:Debug>:HAVE_CFG_DEBUG>"
+ "$<$<NOT:$<CONFIG:Debug>>:HAVE_CFG_OTHER>"
+ )
+endif()
set_property(TARGET mocOnly PROPERTY AUTOMOC ON)
target_link_libraries(mocOnly ${QT_LIBRARIES})
# Add compile definitions with unusual characters
diff --git a/Tests/QtAutogen/MocOnly/CfgDebug.cpp b/Tests/QtAutogen/MocOnly/CfgDebug.cpp
new file mode 100644
index 0000000..07ca3fb
--- /dev/null
+++ b/Tests/QtAutogen/MocOnly/CfgDebug.cpp
@@ -0,0 +1,5 @@
+#include "CfgDebug.hpp"
+
+CfgDebug::CfgDebug()
+{
+}
diff --git a/Tests/QtAutogen/MocOnly/CfgDebug.hpp b/Tests/QtAutogen/MocOnly/CfgDebug.hpp
new file mode 100644
index 0000000..3cd90a4
--- /dev/null
+++ b/Tests/QtAutogen/MocOnly/CfgDebug.hpp
@@ -0,0 +1,15 @@
+#ifndef CFGDEBUG_HPP
+#define CFGDEBUG_HPP
+
+#include <QObject>
+
+/* clang-format off */
+class CfgDebug : public QObject
+{
+ Q_OBJECT
+public:
+ CfgDebug();
+};
+/* clang-format on */
+
+#endif
diff --git a/Tests/QtAutogen/MocOnly/CfgOther.cpp b/Tests/QtAutogen/MocOnly/CfgOther.cpp
new file mode 100644
index 0000000..0ccd433
--- /dev/null
+++ b/Tests/QtAutogen/MocOnly/CfgOther.cpp
@@ -0,0 +1,5 @@
+#include "CfgOther.hpp"
+
+CfgOther::CfgOther()
+{
+}
diff --git a/Tests/QtAutogen/MocOnly/CfgOther.hpp b/Tests/QtAutogen/MocOnly/CfgOther.hpp
new file mode 100644
index 0000000..7cacd52
--- /dev/null
+++ b/Tests/QtAutogen/MocOnly/CfgOther.hpp
@@ -0,0 +1,15 @@
+#ifndef CFGOTHER_HPP
+#define CFGOTHER_HPP
+
+#include <QObject>
+
+/* clang-format off */
+class CfgOther : public QObject
+{
+ Q_OBJECT
+public:
+ CfgOther();
+};
+/* clang-format on */
+
+#endif
diff --git a/Tests/QtAutogen/MocOnly/main.cpp b/Tests/QtAutogen/MocOnly/main.cpp
index ec8da21..6c0f6f2 100644
--- a/Tests/QtAutogen/MocOnly/main.cpp
+++ b/Tests/QtAutogen/MocOnly/main.cpp
@@ -5,6 +5,14 @@
#include "StyleA.hpp"
#include "StyleB.hpp"
+#ifdef HAVE_CFG_DEBUG
+# include "CfgDebug.hpp"
+#endif
+
+#ifdef HAVE_CFG_OTHER
+# include "CfgOther.hpp"
+#endif
+
int main(int argv, char** args)
{
StyleA styleA;
diff --git a/Tests/QtAutogen/TestMacros.cmake b/Tests/QtAutogen/TestMacros.cmake
index 0e27188..1024996 100644
--- a/Tests/QtAutogen/TestMacros.cmake
+++ b/Tests/QtAutogen/TestMacros.cmake
@@ -1,12 +1,19 @@
# Autogen build options
set(Autogen_BUILD_OPTIONS "-DQT_TEST_VERSION=${QT_TEST_VERSION}")
-if(NOT _isMultiConfig) # Set in Tests/CMakeLists.txt
+if(_isMultiConfig) # Set in Tests/CMakeLists.txt
+ list(APPEND Autogen_CTEST_OPTIONS --build-config $<CONFIGURATION>)
+else()
list(APPEND Autogen_BUILD_OPTIONS "-DCMAKE_BUILD_TYPE=$<CONFIGURATION>")
endif()
list(APPEND Autogen_BUILD_OPTIONS
"-DCMAKE_AUTOGEN_VERBOSE=1"
"-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
)
+# XXX(xcode-per-cfg-src): Drop the NO_PER_CONFIG_SOURCES exclusion
+# when the Xcode generator supports per-config sources.
+if(CMAKE_GENERATOR STREQUAL "Xcode")
+ list(APPEND Autogen_BUILD_OPTIONS -DNO_PER_CONFIG_SOURCES=1)
+endif()
# A macro to add a QtAutogen test
macro(ADD_AUTOGEN_TEST NAME)
@@ -30,6 +37,7 @@ macro(ADD_AUTOGEN_TEST NAME)
"${_BuildDir}"
${build_generator_args}
--build-project ${NAME}
+ ${Autogen_CTEST_OPTIONS}
--build-exe-dir "${_BuildDir}"
--force-new-ctest-process
--build-options ${build_options} ${Autogen_BUILD_OPTIONS}
diff --git a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
index e05ad79..6cf1476 100644
--- a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
@@ -380,3 +380,20 @@ run_MemCheckSan(Leak "simulate_sanitizer=1:report_bugs=1:history_size=5:exitcode
run_MemCheckSan(Memory "simulate_sanitizer=1:report_bugs=1:history_size=5:exitcode=55")
run_MemCheckSan(Thread "report_bugs=1:history_size=5:exitcode=55")
run_MemCheckSan(UndefinedBehavior "simulate_sanitizer=1")
+
+run_cmake_command(test-dir-invalid-arg ${CMAKE_CTEST_COMMAND} --test-dir)
+run_cmake_command(test-dir-non-existing-dir ${CMAKE_CTEST_COMMAND} --test-dir non-existing-dir)
+
+function(run_testDir)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/testDir)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}/sub")
+ file(WRITE "${RunCMake_TEST_BINARY_DIR}/sub/CTestTestfile.cmake" "
+ add_test(Test1 \"${CMAKE_COMMAND}\" -E true)
+ add_test(Test2 \"${CMAKE_COMMAND}\" -E true)
+ ")
+ run_cmake_command(testDir ${CMAKE_CTEST_COMMAND} --test-dir "${RunCMake_TEST_BINARY_DIR}/sub")
+endfunction()
+run_testDir()
diff --git a/Tests/RunCMake/CTestCommandLine/test-dir-invalid-arg-result.txt b/Tests/RunCMake/CTestCommandLine/test-dir-invalid-arg-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/test-dir-invalid-arg-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CTestCommandLine/test-dir-invalid-arg-stderr.txt b/Tests/RunCMake/CTestCommandLine/test-dir-invalid-arg-stderr.txt
new file mode 100644
index 0000000..15908a7
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/test-dir-invalid-arg-stderr.txt
@@ -0,0 +1 @@
+CMake Error: '--test-dir' requires an argument
diff --git a/Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-result.txt b/Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-stderr.txt b/Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-stderr.txt
new file mode 100644
index 0000000..017ccb0
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-stderr.txt
@@ -0,0 +1 @@
+Failed to change working directory to ".*/non-existing-dir" : No such file or directory
diff --git a/Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-stdout.txt b/Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-stdout.txt
new file mode 100644
index 0000000..ddcd238
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-stdout.txt
@@ -0,0 +1 @@
+Internal ctest changing into directory: .*/non-existing-dir
diff --git a/Tests/RunCMake/File_Generate/CustomFilePermissions.cmake b/Tests/RunCMake/File_Generate/CustomFilePermissions.cmake
new file mode 100644
index 0000000..0000ef9
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/CustomFilePermissions.cmake
@@ -0,0 +1,15 @@
+file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/customfilepermissions.txt")
+
+file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$<LOWER_CASE:$<CONFIG>>/customfilepermissions.txt"
+ INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt"
+ FILE_PERMISSIONS
+ OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_EXECUTE
+ WORLD_EXECUTE
+ )
+
+add_custom_target(checkCustomFilePermissions ALL
+ COMMAND ${CMAKE_COMMAND}
+ -DgeneratedFile=${CMAKE_CURRENT_BINARY_DIR}/$<LOWER_CASE:$<CONFIG>>/customfilepermissions.txt
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/CustomFilePermissionsVerify.cmake"
+ )
diff --git a/Tests/RunCMake/File_Generate/CustomFilePermissionsVerify.cmake b/Tests/RunCMake/File_Generate/CustomFilePermissionsVerify.cmake
new file mode 100644
index 0000000..a87e916
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/CustomFilePermissionsVerify.cmake
@@ -0,0 +1,36 @@
+if(NOT EXISTS "${generatedFile}")
+ message(SEND_ERROR "Missing file:\n ${generatedFile}")
+endif()
+
+if (UNIX)
+ find_program(STAT_EXECUTABLE NAMES stat)
+ if(NOT STAT_EXECUTABLE)
+ return()
+ endif()
+
+ if (CMAKE_HOST_SYSTEM_NAME MATCHES "FreeBSD")
+ execute_process(COMMAND "${STAT_EXECUTABLE}" -f %Lp "${generatedFile}"
+ OUTPUT_VARIABLE output
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ COMMAND_ERROR_IS_FATAL ANY
+ )
+ elseif (CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin")
+ execute_process(COMMAND "${STAT_EXECUTABLE}" -f %A "${generatedFile}"
+ OUTPUT_VARIABLE output
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ COMMAND_ERROR_IS_FATAL ANY
+ )
+ else()
+ execute_process(COMMAND "${STAT_EXECUTABLE}" -c %a "${generatedFile}"
+ OUTPUT_VARIABLE output
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ COMMAND_ERROR_IS_FATAL ANY
+ )
+ endif()
+
+ if (NOT output EQUAL "711")
+ message(SEND_ERROR "file generate has different permissions source "
+ "permissions: \"${output}\" desired permissions: \"711\"")
+ endif()
+
+endif()
diff --git a/Tests/RunCMake/File_Generate/NoSourcePermissions.cmake b/Tests/RunCMake/File_Generate/NoSourcePermissions.cmake
new file mode 100644
index 0000000..868a045
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/NoSourcePermissions.cmake
@@ -0,0 +1,10 @@
+file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$<LOWER_CASE:$<CONFIG>>/nosourcepermissions.txt"
+ INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt"
+ NO_SOURCE_PERMISSIONS
+ )
+
+add_custom_target(checkNoSourcePermission ALL
+ COMMAND ${CMAKE_COMMAND}
+ -DgeneratedFile=${CMAKE_CURRENT_BINARY_DIR}/$<LOWER_CASE:$<CONFIG>>/nosourcepermissions.txt
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/NoSourcePermissionsVerify.cmake"
+ )
diff --git a/Tests/RunCMake/File_Generate/NoSourcePermissionsVerify.cmake b/Tests/RunCMake/File_Generate/NoSourcePermissionsVerify.cmake
new file mode 100644
index 0000000..7981ccc
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/NoSourcePermissionsVerify.cmake
@@ -0,0 +1,36 @@
+if(NOT EXISTS "${generatedFile}")
+ message(SEND_ERROR "Missing generated file:\n ${generatedFile}")
+endif()
+
+if (UNIX)
+ find_program(STAT_EXECUTABLE NAMES stat)
+ if(NOT STAT_EXECUTABLE)
+ return()
+ endif()
+
+ if (CMAKE_HOST_SYSTEM_NAME MATCHES "FreeBSD")
+ execute_process(COMMAND "${STAT_EXECUTABLE}" -f %Lp "${generatedFile}"
+ OUTPUT_VARIABLE output
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ COMMAND_ERROR_IS_FATAL ANY
+ )
+ elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin")
+ execute_process(COMMAND "${STAT_EXECUTABLE}" -f %A "${generatedFile}"
+ OUTPUT_VARIABLE output
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ COMMAND_ERROR_IS_FATAL ANY
+ )
+ else()
+ execute_process(COMMAND "${STAT_EXECUTABLE}" -c %a "${generatedFile}"
+ OUTPUT_VARIABLE output
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ COMMAND_ERROR_IS_FATAL ANY
+ )
+ endif()
+
+ if (NOT output EQUAL "644")
+ message(SEND_ERROR "generated file has different permissions than "
+ "desired, generated permissions: \"${output}\"")
+ endif()
+
+endif()
diff --git a/Tests/RunCMake/File_Generate/RunCMakeTest.cmake b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake
index 48fb71c..51491af 100644
--- a/Tests/RunCMake/File_Generate/RunCMakeTest.cmake
+++ b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake
@@ -123,3 +123,24 @@ set(RunCMake_TEST_NO_CLEAN 1)
run_cmake_command(AdjacentInOut-nowork ${CMAKE_COMMAND} --build .)
unset(RunCMake_TEST_BINARY_DIR)
unset(RunCMake_TEST_NO_CLEAN)
+
+run_cmake(SourcePermissions1)
+run_cmake(SourcePermissions2)
+run_cmake(SourcePermissions3)
+run_cmake(SourcePermissions4)
+run_cmake(SourcePermissions5)
+
+function(run_cmake_and_verify_after_build case)
+ set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${case}-build")
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ set(RunCMake_TEST_NO_CLEAN 1)
+ run_cmake(${case})
+ run_cmake_command("${case}-build" ${CMAKE_COMMAND} --build .)
+ unset(RunCMake_TEST_NO_CLEAN)
+ unset(RunCMake_TEST_BINARY_DIR)
+endfunction()
+
+run_cmake_and_verify_after_build(NoSourcePermissions)
+run_cmake_and_verify_after_build(UseSourcePermissions)
+run_cmake_and_verify_after_build(CustomFilePermissions)
diff --git a/Tests/RunCMake/File_Generate/SourcePermissions1-result.txt b/Tests/RunCMake/File_Generate/SourcePermissions1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/SourcePermissions1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/File_Generate/SourcePermissions1-stderr.txt b/Tests/RunCMake/File_Generate/SourcePermissions1-stderr.txt
new file mode 100644
index 0000000..730800d
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/SourcePermissions1-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at SourcePermissions1.cmake:[0-9]+ \(file\):
+ file given both NO_SOURCE_PERMISSIONS and USE_SOURCE_PERMISSIONS. Only one
+ option allowed.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/File_Generate/SourcePermissions1.cmake b/Tests/RunCMake/File_Generate/SourcePermissions1.cmake
new file mode 100644
index 0000000..d25e66a
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/SourcePermissions1.cmake
@@ -0,0 +1,5 @@
+file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output-sourcepermission1.txt"
+ INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt"
+ NO_SOURCE_PERMISSIONS
+ USE_SOURCE_PERMISSIONS
+ )
diff --git a/Tests/RunCMake/File_Generate/SourcePermissions2-result.txt b/Tests/RunCMake/File_Generate/SourcePermissions2-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/SourcePermissions2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/File_Generate/SourcePermissions2-stderr.txt b/Tests/RunCMake/File_Generate/SourcePermissions2-stderr.txt
new file mode 100644
index 0000000..e8184cc
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/SourcePermissions2-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at SourcePermissions2.cmake:[0-9]+ \(file\):
+ file given both NO_SOURCE_PERMISSIONS and FILE_PERMISSIONS. Only one
+ option allowed.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/File_Generate/SourcePermissions2.cmake b/Tests/RunCMake/File_Generate/SourcePermissions2.cmake
new file mode 100644
index 0000000..2a1e3ea
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/SourcePermissions2.cmake
@@ -0,0 +1,5 @@
+file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output-sourcepermission2.txt"
+ INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt"
+ NO_SOURCE_PERMISSIONS
+ FILE_PERMISSIONS OWNER_READ
+ )
diff --git a/Tests/RunCMake/File_Generate/SourcePermissions3-result.txt b/Tests/RunCMake/File_Generate/SourcePermissions3-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/SourcePermissions3-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/File_Generate/SourcePermissions3-stderr.txt b/Tests/RunCMake/File_Generate/SourcePermissions3-stderr.txt
new file mode 100644
index 0000000..1143c78
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/SourcePermissions3-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at SourcePermissions3.cmake:[0-9]+ \(file\):
+ file given both USE_SOURCE_PERMISSIONS and FILE_PERMISSIONS. Only one
+ option allowed.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/File_Generate/SourcePermissions3.cmake b/Tests/RunCMake/File_Generate/SourcePermissions3.cmake
new file mode 100644
index 0000000..97e0deb
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/SourcePermissions3.cmake
@@ -0,0 +1,5 @@
+file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output-sourcepermission3.txt"
+ INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt"
+ USE_SOURCE_PERMISSIONS
+ FILE_PERMISSIONS OWNER_READ
+ )
diff --git a/Tests/RunCMake/File_Generate/SourcePermissions4-result.txt b/Tests/RunCMake/File_Generate/SourcePermissions4-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/SourcePermissions4-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/File_Generate/SourcePermissions4-stderr.txt b/Tests/RunCMake/File_Generate/SourcePermissions4-stderr.txt
new file mode 100644
index 0000000..84368cd
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/SourcePermissions4-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at SourcePermissions4.cmake:[0-9]+ \(file\):
+ file given USE_SOURCE_PERMISSIONS without a file INPUT.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/File_Generate/SourcePermissions4.cmake b/Tests/RunCMake/File_Generate/SourcePermissions4.cmake
new file mode 100644
index 0000000..f4127a6
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/SourcePermissions4.cmake
@@ -0,0 +1,4 @@
+file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output-sourcepermission4.txt"
+ CONTENT "Input is content"
+ USE_SOURCE_PERMISSIONS
+ )
diff --git a/Tests/RunCMake/File_Generate/SourcePermissions5-result.txt b/Tests/RunCMake/File_Generate/SourcePermissions5-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/SourcePermissions5-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/File_Generate/SourcePermissions5-stderr.txt b/Tests/RunCMake/File_Generate/SourcePermissions5-stderr.txt
new file mode 100644
index 0000000..d66d488
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/SourcePermissions5-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at SourcePermissions5.cmake:[0-9]+ \(file\):
+ file given invalid permission "GROUP_RWX","USER_ALL".
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/File_Generate/SourcePermissions5.cmake b/Tests/RunCMake/File_Generate/SourcePermissions5.cmake
new file mode 100644
index 0000000..4eb4c36
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/SourcePermissions5.cmake
@@ -0,0 +1,4 @@
+file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output-sourcepermission5.txt"
+ INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt"
+ FILE_PERMISSIONS OWNER_READ GROUP_RWX USER_ALL
+ )
diff --git a/Tests/RunCMake/File_Generate/UseSourcePermissions.cmake b/Tests/RunCMake/File_Generate/UseSourcePermissions.cmake
new file mode 100644
index 0000000..7cca9bf
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/UseSourcePermissions.cmake
@@ -0,0 +1,11 @@
+file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$<LOWER_CASE:$<CONFIG>>/usesourcepermissions.txt"
+ INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt"
+ USE_SOURCE_PERMISSIONS
+ )
+
+add_custom_target(checkUseSourcePermissions ALL
+ COMMAND ${CMAKE_COMMAND}
+ -DsourceFile=${CMAKE_CURRENT_SOURCE_DIR}/input.txt
+ -DgeneratedFile=${CMAKE_CURRENT_BINARY_DIR}/$<LOWER_CASE:$<CONFIG>>/usesourcepermissions.txt
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/UseSourcePermissionsVerify.cmake"
+ )
diff --git a/Tests/RunCMake/File_Generate/UseSourcePermissionsVerify.cmake b/Tests/RunCMake/File_Generate/UseSourcePermissionsVerify.cmake
new file mode 100644
index 0000000..8b30f96
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/UseSourcePermissionsVerify.cmake
@@ -0,0 +1,51 @@
+if(NOT EXISTS "${generatedFile}")
+ message(SEND_ERROR "Missing generated file:\n ${generatedFile}")
+endif()
+
+if (UNIX)
+ find_program(STAT_EXECUTABLE NAMES stat)
+ if(NOT STAT_EXECUTABLE)
+ return()
+ endif()
+
+ if (CMAKE_HOST_SYSTEM_NAME MATCHES "FreeBSD")
+ execute_process(COMMAND "${STAT_EXECUTABLE}" -f %Lp "${sourceFile}"
+ OUTPUT_VARIABLE output1
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ COMMAND_ERROR_IS_FATAL ANY
+ )
+ execute_process(COMMAND "${STAT_EXECUTABLE}" -f %Lp "${generatedFile}"
+ OUTPUT_VARIABLE output2
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ COMMAND_ERROR_IS_FATAL ANY
+ )
+ elseif (CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin")
+ execute_process(COMMAND "${STAT_EXECUTABLE}" -f %A "${sourceFile}"
+ OUTPUT_VARIABLE output1
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ COMMAND_ERROR_IS_FATAL ANY
+ )
+ execute_process(COMMAND "${STAT_EXECUTABLE}" -f %A "${generatedFile}"
+ OUTPUT_VARIABLE output2
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ COMMAND_ERROR_IS_FATAL ANY
+ )
+ else()
+ execute_process(COMMAND "${STAT_EXECUTABLE}" -c %a "${sourceFile}"
+ OUTPUT_VARIABLE output1
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ COMMAND_ERROR_IS_FATAL ANY
+ )
+ execute_process(COMMAND "${STAT_EXECUTABLE}" -c %a "${generatedFile}"
+ OUTPUT_VARIABLE output2
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ COMMAND_ERROR_IS_FATAL ANY
+ )
+ endif()
+
+ if (NOT output1 EQUAL output2)
+ message(SEND_ERROR "generated file has a different permissions source "
+ "permissions: \"${output1}\" generated permissions: \"${output2}\"")
+ endif()
+
+endif()
diff --git a/Tests/RunCMake/NinjaMultiConfig/Qt5.cmake b/Tests/RunCMake/NinjaMultiConfig/Qt5.cmake
index 3a1c7f5..578256a 100644
--- a/Tests/RunCMake/NinjaMultiConfig/Qt5.cmake
+++ b/Tests/RunCMake/NinjaMultiConfig/Qt5.cmake
@@ -16,12 +16,13 @@ if(Qt5Core_VERSION VERSION_GREATER_EQUAL "5.15.0")
set(moc_writes_depfiles 1)
endif()
-set(autogen_files "${CMAKE_BINARY_DIR}/exe_autogen/mocs_compilation.cpp")
+set(autogen_files)
if(moc_writes_depfiles)
list(APPEND autogen_files "${CMAKE_BINARY_DIR}/exe_autogen/deps")
list(APPEND autogen_files "${CMAKE_BINARY_DIR}/exe_autogen/timestamp")
endif()
foreach(c IN LISTS CMAKE_CONFIGURATION_TYPES)
+ list(APPEND autogen_files "${CMAKE_BINARY_DIR}/exe_autogen/mocs_compilation_${c}.cpp")
list(APPEND autogen_files "${CMAKE_BINARY_DIR}/exe_autogen/include_${c}/moc_qt5.cpp")
if(moc_writes_depfiles)
list(APPEND autogen_files "${CMAKE_BINARY_DIR}/exe_autogen/include_${c}/moc_qt5.cpp.d")
diff --git a/Tests/RunCMake/target_include_directories/RunCMakeTest.cmake b/Tests/RunCMake/target_include_directories/RunCMakeTest.cmake
index b67c598..48a750d 100644
--- a/Tests/RunCMake/target_include_directories/RunCMakeTest.cmake
+++ b/Tests/RunCMake/target_include_directories/RunCMakeTest.cmake
@@ -1,3 +1,6 @@
include(RunCMake)
run_cmake(empty_keyword_args)
+run_cmake(include_before)
+run_cmake(include_after)
+run_cmake(include_default)
diff --git a/Tests/RunCMake/target_include_directories/include_after.cmake b/Tests/RunCMake/target_include_directories/include_after.cmake
new file mode 100644
index 0000000..68a08a7
--- /dev/null
+++ b/Tests/RunCMake/target_include_directories/include_after.cmake
@@ -0,0 +1,18 @@
+enable_language(C)
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.c" "int main() { return 0;}")
+
+set(include_dir "${CMAKE_CURRENT_BINARY_DIR}/dir")
+set(after_include_dir "${CMAKE_CURRENT_BINARY_DIR}/dirAfter")
+file(MAKE_DIRECTORY "${include_dir}")
+file(MAKE_DIRECTORY "${after_include_dir}")
+
+add_executable(main "${CMAKE_CURRENT_BINARY_DIR}/main.c")
+include_directories("${include_dir}")
+target_include_directories(main AFTER PRIVATE "${after_include_dir}")
+
+get_target_property(actual_include_dirs main INCLUDE_DIRECTORIES)
+set(desired_include_dirs "${include_dir}" "${after_include_dir}")
+
+if (NOT "${actual_include_dirs}" MATCHES "${desired_include_dirs}")
+ message(SEND_ERROR "include after does not work")
+endif()
diff --git a/Tests/RunCMake/target_include_directories/include_before.cmake b/Tests/RunCMake/target_include_directories/include_before.cmake
new file mode 100644
index 0000000..9bebecd
--- /dev/null
+++ b/Tests/RunCMake/target_include_directories/include_before.cmake
@@ -0,0 +1,18 @@
+enable_language(C)
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.c" "int main() { return 0;}")
+
+set(include_dir "${CMAKE_CURRENT_BINARY_DIR}/dir")
+set(before_include_dir "${CMAKE_CURRENT_BINARY_DIR}/dirBefore")
+file(MAKE_DIRECTORY "${include_dir}")
+file(MAKE_DIRECTORY "${before_include_dir}")
+
+add_executable(main "${CMAKE_CURRENT_BINARY_DIR}/main.c")
+include_directories("${include_dir}")
+target_include_directories(main BEFORE PRIVATE "${before_include_dir}")
+
+get_target_property(actual_include_dirs main INCLUDE_DIRECTORIES)
+set(desired_include_dirs "${before_include_dir}" "${include_dir}")
+
+if (NOT "${actual_include_dirs}" MATCHES "${desired_include_dirs}")
+ message(SEND_ERROR "include before does not work")
+endif()
diff --git a/Tests/RunCMake/target_include_directories/include_default.cmake b/Tests/RunCMake/target_include_directories/include_default.cmake
new file mode 100644
index 0000000..88b2502
--- /dev/null
+++ b/Tests/RunCMake/target_include_directories/include_default.cmake
@@ -0,0 +1,18 @@
+enable_language(C)
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.c" "int main() { return 0;}")
+
+set(include_dir "${CMAKE_CURRENT_BINARY_DIR}/dir")
+set(default_include_dir "${CMAKE_CURRENT_BINARY_DIR}/dirDefault")
+file(MAKE_DIRECTORY "${include_dir}")
+file(MAKE_DIRECTORY "${default_include_dir}")
+
+add_executable(main "${CMAKE_CURRENT_BINARY_DIR}/main.c")
+include_directories("${include_dir}")
+target_include_directories(main AFTER PRIVATE "${default_include_dir}")
+
+get_target_property(actual_include_dirs main INCLUDE_DIRECTORIES)
+set(desired_include_dirs "${include_dir}" "${default_include_dir}")
+
+if (NOT "${actual_include_dirs}" MATCHES "${desired_include_dirs}")
+ message(SEND_ERROR "include default does not work")
+endif()