Autogen
-------
-* When using :prop_tgt:`AUTOMOC`, CMake now generates the ``-p`` path prefix
+* When using :prop_tgt:`AUTOMOC`, the new :variable:`CMAKE_AUTOMOC_PATH_PREFIX`
+ variable or :prop_tgt:`AUTOMOC_PATH_PREFIX` target property may be enabled
+ to generate the ``-p`` path prefix
option for ``moc``. This ensures that ``moc`` output files are identical
on different build setups (given, that the headers compiled by ``moc`` are
in an :command:`include directory <target_include_directories>`).
Also it ensures that ``moc`` output files will compile correctly when the
source and/or build directory is a symbolic link.
- The ``moc`` path prefix generation behavior can be configured by setting
- the new :variable:`CMAKE_AUTOMOC_PATH_PREFIX` variable and/or
- :prop_tgt:`AUTOMOC_PATH_PREFIX` target property.
-
CTest
-----
:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` target properties.
Previously they would be places in ``*_CFLAGS_OTHER`` variables and
:prop_tgt:`INTERFACE_COMPILE_OPTIONS` target properties.
+
+3.16.9
+------
+
+* The default value of :variable:`CMAKE_AUTOMOC_PATH_PREFIX` was changed to
+ ``OFF`` because this feature can break existing projects that have
+ identically named header files in different include directories.
+ This restores compatibility with behavior of CMake 3.15 and below.
:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` target properties.
Previously they would be places in ``*_CFLAGS_OTHER`` variables and
:prop_tgt:`INTERFACE_COMPILE_OPTIONS` target properties.
+
+3.17.5
+------
+
+* The default value of :variable:`CMAKE_AUTOMOC_PATH_PREFIX` was changed to
+ ``OFF`` because this feature can break existing projects that have
+ identically named header files in different include directories.
+ This restores compatibility with behavior of CMake 3.15 and below.
+ The default was also changed to ``OFF`` in 3.16.9.
environment variable to customize colors.
* The :manual:`Compile Features <cmake-compile-features(7)>` functionality
- is now aware of the availability of C11 features in MSVC 19.27 and above,
- including support for the ``c_restrict`` feature and the ``-std:c11`` flag.
+ is now aware of the availability of C11 features in MSVC 19.27 and 19.28,
+ including support for the ``c_restrict``, ``c_static_assert`` features and
+ the ``-std:c11`` flag.
Deprecated and Removed Features
===============================
``OFF`` because this feature can break existing projects that have
identically named header files in different include directories.
This restores compatibility with behavior of CMake 3.15 and below.
+ The default was also changed to ``OFF`` in 3.16.9 and 3.17.5.
* The :manual:`Compile Features <cmake-compile-features(7)>` functionality
- was updated for MSVC 19.27 as mentioned above.
+ was updated for MSVC 19.27 as mentioned above (``c_restrict``).
+
+3.18.3
+------
+
+* The :manual:`Compile Features <cmake-compile-features(7)>` functionality
+ was updated for MSVC 19.28 as mentioned above (``c_static_assert``).
# compile an Objective-C++ file into an object file
if(NOT CMAKE_OBJCXX_COMPILE_OBJECT)
set(CMAKE_OBJCXX_COMPILE_OBJECT
- "<CMAKE_OBJCXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -x objective-c++ -o <OBJECT> -c <SOURCE>")
+ "<CMAKE_OBJCXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
endif()
if(NOT CMAKE_OBJCXX_LINK_EXECUTABLE)
foreach(v IN LISTS _locale_vars)
set(ENV{${v}} ${_locale_vars_saved_${v}})
endforeach()
- set(${_var} "${${_var}}" PARENT_SCOPE)
endfunction()
foreach(v IN LISTS _locale_vars)
set(ENV{${v}} ${_locale_vars_saved_${v}})
endforeach()
- set(${_var} "${${_var}}" PARENT_SCOPE)
endfunction()
endif()
if(__CMAKE_ARMClang_USING_armlink)
+ unset(CMAKE_${lang}_LINKER_WRAPPER_FLAG)
set(__CMAKE_ARMClang_USING_armlink_WRAPPER "")
else()
- set(__CMAKE_ARMClang_USING_armlink_WRAPPER ${CMAKE_${lang}_LINKER_WRAPPER_FLAG})
+ set(__CMAKE_ARMClang_USING_armlink_WRAPPER "-Xlinker")
endif()
- set(CMAKE_${lang}_LINK_EXECUTABLE "<CMAKE_LINKER> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> <OBJECTS> -o <TARGET> ${__CMAKE_ARMClang_USING_armlink_WRAPPER} --list <TARGET_BASE>.map")
+ set(CMAKE_${lang}_LINK_EXECUTABLE "<CMAKE_LINKER> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> <OBJECTS> -o <TARGET> ${__CMAKE_ARMClang_USING_armlink_WRAPPER} --list=<TARGET_BASE>.map")
set(CMAKE_${lang}_CREATE_STATIC_LIBRARY "<CMAKE_AR> --create -cr <TARGET> <LINK_FLAGS> <OBJECTS>")
set(CMAKE_${lang}_ARCHIVE_CREATE "<CMAKE_AR> --create -cr <TARGET> <LINK_FLAGS> <OBJECTS>")
set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "${__CMAKE_ARMClang_USING_armlink_WRAPPER} --via=")
include(Compiler/CMakeCommonCompilerMacros)
+set(__pch_header_C "c-header")
+set(__pch_header_CXX "c++-header")
+set(__pch_header_OBJC "objective-c-header")
+set(__pch_header_OBJCXX "objective-c++-header")
+
if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC"
OR "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC"
OR "x${CMAKE_Fortran_SIMULATE_ID}" STREQUAL "xMSVC")
set(CMAKE_PCH_PROLOGUE "#pragma clang system_header")
endif()
set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Xclang -include-pch -Xclang <PCH_FILE> -Xclang -include -Xclang <PCH_HEADER>)
- set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Xclang -emit-pch -Xclang -include -Xclang <PCH_HEADER>)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Xclang -emit-pch -Xclang -include -Xclang <PCH_HEADER> -x ${__pch_header_${lang}})
endmacro()
endif()
set(_cmake_oldestSupported "_MSC_VER >= 1600")
-# Not yet supported:
-#set(_cmake_feature_test_c_static_assert "")
-
set(_cmake_feature_test_c_restrict "_MSC_VER >= 1927")
+set(_cmake_feature_test_c_static_assert "_MSC_VER >= 1928")
set(_cmake_feature_test_c_variadic_macros "${_cmake_oldestSupported}")
set(_cmake_feature_test_c_function_prototypes "${_cmake_oldestSupported}")
list(APPEND CMAKE_C_COMPILE_FEATURES c_restrict)
list(APPEND CMAKE_C99_COMPILE_FEATURES c_restrict)
endif()
+ if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.28)
+ list(APPEND CMAKE_C_COMPILE_FEATURES c_static_assert)
+ list(APPEND CMAKE_C11_COMPILE_FEATURES c_static_assert)
+ endif()
set(_result 0) # expected by cmake_determine_compile_features
endmacro()
endif()
if("x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC")
+ # MSVC requires c++14 as the minimum level
set(CMAKE_CUDA03_STANDARD_COMPILE_OPTION "")
set(CMAKE_CUDA03_EXTENSION_COMPILE_OPTION "")
+ # MSVC requires c++14 as the minimum level
set(CMAKE_CUDA11_STANDARD_COMPILE_OPTION "")
set(CMAKE_CUDA11_EXTENSION_COMPILE_OPTION "")
if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 9.0)
- set(CMAKE_CUDA14_STANDARD_COMPILE_OPTION "")
- set(CMAKE_CUDA14_EXTENSION_COMPILE_OPTION "")
+ set(CMAKE_CUDA14_STANDARD_COMPILE_OPTION "-std=c++14")
+ set(CMAKE_CUDA14_EXTENSION_COMPILE_OPTION "-std=c++14")
endif()
if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 11.0)
- set(CMAKE_CUDA17_STANDARD_COMPILE_OPTION "")
- set(CMAKE_CUDA17_EXTENSION_COMPILE_OPTION "")
+ set(CMAKE_CUDA17_STANDARD_COMPILE_OPTION "-std=c++17")
+ set(CMAKE_CUDA17_EXTENSION_COMPILE_OPTION "-std=c++17")
endif()
else()
endif()
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^i.86$")
set(_java_libarch "i386")
+ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64")
+ set(_java_libarch "arm64")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^alpha")
set(_java_libarch "alpha")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm")
endif()
set(MATLAB_VERSIONS_MAPPING
+ "R2020b=9.9"
"R2020a=9.8"
"R2019b=9.7"
"R2019a=9.6"
# Initial configuration
#
+cmake_policy(PUSH)
+# numbers and boolean constants
+cmake_policy (SET CMP0012 NEW)
# IN_LIST operator
cmake_policy (SET CMP0057 NEW)
set (${_PYTHON_PREFIX}_FOUND FALSE)
string (TOUPPER "${_PYTHON_PREFIX}" _${_PYTHON_PREFIX}_UPPER_PREFIX)
set (${_PYTHON_UPPER_PREFIX}_FOUND FALSE)
- return()
endmacro()
# ABI not used on Windows
set (abi "")
else()
- if (config MATCHES "#[ ]*define[ ]+Py_DEBUG[ ]+1")
- string (APPEND abi "d")
- endif()
- if (config MATCHES "#[ ]*define[ ]+WITH_PYMALLOC[ ]+1")
- string (APPEND abi "m")
- endif()
- if (config MATCHES "#[ ]*define[ ]+Py_UNICODE_SIZE[ ]+4")
- string (APPEND abi "u")
+ if (NOT config)
+ # pyconfig.h can be a wrapper to a platform specific pyconfig.h
+ # In this case, try to identify ABI from include directory
+ if (_${_PYTHON_PREFIX}_INCLUDE_DIR MATCHES "python${version_major}\.${version_minor}+([dmu]*)")
+ set (abi "${CMAKE_MATCH_1}")
+ else()
+ set (abi "")
+ endif()
+ else()
+ if (config MATCHES "#[ ]*define[ ]+Py_DEBUG[ ]+1")
+ string (APPEND abi "d")
+ endif()
+ if (config MATCHES "#[ ]*define[ ]+WITH_PYMALLOC[ ]+1")
+ string (APPEND abi "m")
+ endif()
+ if (config MATCHES "#[ ]*define[ ]+Py_UNICODE_SIZE[ ]+4")
+ string (APPEND abi "u")
+ endif()
endif()
set (${_PGV_PREFIX}ABI "${abi}" PARENT_SCOPE)
endif()
if (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR
AND NOT ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
_python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Wrong major version specified is \"${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}\", but expected major version is \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"")
+
+ cmake_policy(POP)
+ return()
endif()
if (${_PYTHON_PREFIX}_VERSION_MAJOR AND
NOT ${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
_python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Found unsuitable major version \"${${_PYTHON_PREFIX}_VERSION_MAJOR}\", but required major version is exact version \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"")
+
+ cmake_policy(POP)
+ return()
endif()
unset (_${_PYTHON_PREFIX}_REASON_FAILURE)
else()
unset (CMAKE_FIND_FRAMEWORK)
endif()
+
+cmake_policy(POP)
endif()
set(__WINDOWS_CLANG 1)
+set(__pch_header_C "c-header")
+set(__pch_header_CXX "c++-header")
+set(__pch_header_OBJC "objective-c-header")
+set(__pch_header_OBJCXX "objective-c++-header")
+
macro(__windows_compiler_clang_gnu lang)
set(CMAKE_LIBRARY_PATH_FLAG "-L")
set(CMAKE_LINK_LIBRARY_FLAG "-l")
set(CMAKE_PCH_EXTENSION .pch)
set(CMAKE_PCH_PROLOGUE "#pragma clang system_header")
set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Xclang -include-pch -Xclang <PCH_FILE> -Xclang -include -Xclang <PCH_HEADER>)
- set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Xclang -emit-pch -Xclang -include -Xclang <PCH_HEADER>)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Xclang -emit-pch -Xclang -include -Xclang <PCH_HEADER> -x ${__pch_header_${lang}})
unset(__ADDED_FLAGS)
unset(__ADDED_FLAGS_DEBUG)
set(BORLAND 1)
+set(__pch_header_C "c-header")
+set(__pch_header_CXX "c++-header")
+set(__pch_header_OBJC "objective-c-header")
+set(__pch_header_OBJCXX "objective-c++-header")
+
if("${CMAKE_${_lang}_COMPILER_VERSION}" VERSION_LESS 6.30)
# Borland target type flags (bcc32 -h -t):
set(_tW "-tW") # -tW GUI App (implies -U__CONSOLE__)
if (EMBARCADERO)
set(CMAKE_PCH_EXTENSION .pch)
set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Xclang -include-pch -Xclang <PCH_FILE> -Xclang -include -Xclang <PCH_HEADER>)
- set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Xclang -emit-pch -Xclang -include -Xclang <PCH_HEADER>)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Xclang -emit-pch -Xclang -include -Xclang <PCH_HEADER> -x ${__pch_header_${lang}})
endif()
# Initial configuration flags.
endif()
endif()
if (SWIG_MODULE_${name}_LANGUAGE STREQUAL "PYTHON" AND NOT SWIG_MODULE_${name}_NOPROXY)
- if(NOT ("-interface" IN_LIST swig_source_file_flags OR "-interface" IN_LIST SWIG_MODULE_${name}_EXTRA_FLAGS))
+ if(SWIG_USE_INTERFACE AND
+ NOT ("-interface" IN_LIST swig_source_file_flags OR "-interface" IN_LIST SWIG_MODULE_${name}_EXTRA_FLAGS))
# This makes sure that the name used in the proxy code
# matches the library name created by CMake
list (APPEND SWIG_MODULE_${name}_EXTRA_FLAGS "-interface" "$<TARGET_FILE_PREFIX:${target_name}>$<TARGET_FILE_BASE_NAME:${target_name}>")
set(swig_generated_sources)
set(swig_generated_timestamps)
+ list(LENGTH swig_dot_i_sources swig_sources_count)
+ if (swig_sources_count GREATER "1")
+ # option -interface cannot be used
+ set(SWIG_USE_INTERFACE FALSE)
+ else()
+ set(SWIG_USE_INTERFACE TRUE)
+ endif()
foreach(swig_it IN LISTS swig_dot_i_sources)
SWIG_ADD_SOURCE_TO_MODULE(${name} swig_generated_source "${swig_it}")
list (APPEND swig_generated_sources "${swig_generated_source}")
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 18)
-set(CMake_VERSION_PATCH 2)
+set(CMake_VERSION_PATCH 3)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
if(NOT CMake_VERSION_NO_GIT)
# If this source was exported by 'git archive', use its commit info.
- set(git_info [==[aaa5eab410 CMake 3.18.2]==])
+ set(git_info [==[177fc02073 CMake 3.18.3]==])
# Otherwise, try to identify the current development source version.
if(NOT git_info MATCHES "^([0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]?[0-9a-f]?)[0-9a-f]* "
status.SetError(e.str());
cmSystemTools::SetFatalErrorOccured();
return false;
+ } catch (std::out_of_range&) {
+ std::ostringstream e;
+ e << "Integer out of range: '" << str << "'";
+ status.SetError(e.str());
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
}
return true;
{
for (const auto& lg : this->LocalGenerators) {
lg->CreateEvaluationFileOutputs();
+ }
+ for (const auto& lg : this->LocalGenerators) {
for (const auto& gt : lg->GetGeneratorTargets()) {
if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
gt->GetType() == cmStateEnums::UTILITY ||
for (auto const& dep_target : this->GetTargetDirectDepends(target)) {
if (dep_target->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
- (this->EnableCrossConfigBuild() && !dep_target.IsCross())) {
+ (target->GetType() != cmStateEnums::UTILITY &&
+ dep_target->GetType() != cmStateEnums::UTILITY &&
+ this->EnableCrossConfigBuild() && !dep_target.IsCross())) {
continue;
}
byproducts.push_back(
this->BuildAlias(GetByproductsForCleanTargetName(), config));
}
+ byproducts.emplace_back(GetByproductsForCleanTargetName());
build.Variables["TARGETS"] = cmJoin(byproducts, " ");
for (auto const& fileConfig : configs) {
this->Makefile->GetSafeDefinition(
cmStrCat("CMAKE_", lang, "_FLAGS_", configUpper));
+ bool editAndContinueDebugInfo =
+ langFlags.find("/ZI") != std::string::npos ||
+ langFlags.find("-ZI") != std::string::npos;
+
+ bool enableDebuggingInformation =
+ langFlags.find("/Zi") != std::string::npos ||
+ langFlags.find("-Zi") != std::string::npos;
+
// MSVC 2008 is producing both .pdb and .idb files with /Zi.
- if ((langFlags.find("/ZI") != std::string::npos ||
- langFlags.find("-ZI") != std::string::npos) ||
- (cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
- compilerVersion.c_str(),
- "16.0") &&
- compilerId == "MSVC")) {
+ bool msvc2008OrLess =
+ cmSystemTools::VersionCompare(
+ cmSystemTools::OP_LESS, compilerVersion.c_str(), "16.0") &&
+ compilerId == "MSVC";
+ // but not when used via toolset -Tv90
+ if (this->Makefile->GetSafeDefinition(
+ "CMAKE_VS_PLATFORM_TOOLSET") == "v90") {
+ msvc2008OrLess = false;
+ }
+
+ if (editAndContinueDebugInfo || msvc2008OrLess) {
CopyPchCompilePdb(config, target, *ReuseFrom, reuseTarget,
{ ".pdb", ".idb" });
- } else if ((langFlags.find("/Zi") != std::string::npos ||
- langFlags.find("-Zi") != std::string::npos)) {
+ } else if (enableDebuggingInformation) {
CopyPchCompilePdb(config, target, *ReuseFrom, reuseTarget,
{ ".pdb" });
}
if (genTarget->Target->GetType() != cmStateEnums::GLOBAL_TARGET) {
lg->AppendTargetOutputs(genTarget, gg->GetByproductsForCleanTarget(),
config);
+ std::copy(util_outputs.begin(), util_outputs.end(),
+ std::back_inserter(gg->GetByproductsForCleanTarget()));
}
lg->AppendTargetDepends(genTarget, deps, config, config);
if (this->Moc.ExecutableTarget != nullptr) {
dependencies.push_back(this->Moc.ExecutableTarget->Target->GetName());
+ } else if (!this->Moc.Executable.empty()) {
+ dependencies.push_back(this->Moc.Executable);
}
if (this->Uic.ExecutableTarget != nullptr) {
dependencies.push_back(this->Uic.ExecutableTarget->Target->GetName());
+ } else if (!this->Uic.Executable.empty()) {
+ dependencies.push_back(this->Uic.Executable);
}
// Create the custom command that outputs the timestamp file.
info.SetConfig("PARSE_CACHE_FILE", this->AutogenTarget.ParseCacheFile);
info.Set("DEP_FILE", this->AutogenTarget.DepFile);
info.Set("DEP_FILE_RULE_NAME", this->AutogenTarget.DepFileRuleName);
+ info.SetArray("CMAKE_LIST_FILES", this->Makefile->GetListFiles());
info.SetArray("HEADER_EXTENSIONS",
this->Makefile->GetCMakeInstance()->GetHeaderExtensions());
info.SetArrayArray(
std::string DepFile;
std::string DepFileRuleName;
std::vector<std::string> HeaderExtensions;
+ std::vector<std::string> ListFiles;
};
/** Shared common variables. */
{
public:
// -- Parse Cache
- bool ParseCacheChanged = false;
+ std::atomic<bool> ParseCacheChanged = ATOMIC_VAR_INIT(false);
cmFileTime ParseCacheTime;
ParseCacheT ParseCache;
{
// Check dependency timestamps
std::string const sourceDir = SubDirPrefix(sourceFile);
- for (std::string const& dep : mapping.SourceFile->ParseData->Moc.Depends) {
+ auto& dependencies = mapping.SourceFile->ParseData->Moc.Depends;
+ for (auto it = dependencies.begin(); it != dependencies.end(); ++it) {
+ auto& dep = *it;
+
// Find dependency file
auto const depMatch = FindDependency(sourceDir, dep);
if (depMatch.first.empty()) {
- Log().Warning(GenT::MOC,
- cmStrCat(MessagePath(sourceFile), " depends on ",
- MessagePath(dep),
- " but the file does not exist."));
- continue;
+ if (reason != nullptr) {
+ *reason =
+ cmStrCat("Generating ", MessagePath(outputFile), " from ",
+ MessagePath(sourceFile), ", because its dependency ",
+ MessagePath(dep), " vanished.");
+ }
+ dependencies.erase(it);
+ BaseEval().ParseCacheChanged = true;
+ return true;
}
+
// Test if dependency file is older
if (outputFileTime.Older(depMatch.second)) {
if (reason != nullptr) {
return dependenciesFromDepFile(f.c_str());
};
- std::vector<std::string> dependencies;
+ std::vector<std::string> dependencies = BaseConst().ListFiles;
ParseCacheT& parseCache = BaseEval().ParseCache;
auto processMappingEntry = [&](const MappingMapT::value_type& m) {
auto cacheEntry = parseCache.GetOrInsert(m.first);
!info.GetString("DEP_FILE_RULE_NAME", BaseConst_.DepFileRuleName,
false) ||
!info.GetStringConfig("SETTINGS_FILE", SettingsFile_, true) ||
+ !info.GetArray("CMAKE_LIST_FILES", BaseConst_.ListFiles, true) ||
!info.GetArray("HEADER_EXTENSIONS", BaseConst_.HeaderExtensions, true) ||
!info.GetString("QT_MOC_EXECUTABLE", MocConst_.Executable, false) ||
!info.GetString("QT_UIC_EXECUTABLE", UicConst_.Executable, false)) {
--- /dev/null
+# This test checks whether adding a source file to the project triggers an AUTOMOC re-run.
+
+cmake_minimum_required(VERSION 3.10)
+project(RerunMocOnAddFile)
+include("../AutogenCoreTest.cmake")
+
+# Create an executable to generate a clean target
+set(main_source "${CMAKE_CURRENT_BINARY_DIR}/generated_main.cpp")
+file(WRITE "${main_source}" "int main() {}")
+add_executable(exe "${main_source}")
+
+# Utility variables
+set(timeformat "%Y.%j.%H.%M%S")
+set(testProjectTemplateDir "${CMAKE_CURRENT_SOURCE_DIR}/MocOnAddFile")
+set(testProjectSrc "${CMAKE_CURRENT_BINARY_DIR}/MocOnAddFile")
+set(testProjectBinDir "${CMAKE_CURRENT_BINARY_DIR}/MocOnAddFile-build")
+
+# Utility macros
+macro(sleep)
+ message(STATUS "Sleeping for a few seconds.")
+ execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
+endmacro()
+
+macro(acquire_timestamp When)
+ file(TIMESTAMP "${mocBasicBin}" time${When} "${timeformat}")
+endmacro()
+
+macro(rebuild buildName)
+ message(STATUS "Starting build ${buildName}.")
+ execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${testProjectBinDir}" RESULT_VARIABLE result)
+ if (result)
+ message(FATAL_ERROR "Build ${buildName} failed.")
+ else()
+ message(STATUS "Build ${buildName} finished.")
+ endif()
+endmacro()
+
+macro(require_change)
+ if (timeAfter VERSION_GREATER timeBefore)
+ message(STATUS "As expected the file ${mocBasicBin} changed.")
+ else()
+ message(SEND_ERROR "Unexpectedly the file ${mocBasicBin} did not change!\nTimestamp pre: ${timeBefore}\nTimestamp aft: ${timeAfter}\n")
+ endif()
+endmacro()
+
+macro(require_change_not)
+ if (timeAfter VERSION_GREATER timeBefore)
+ message(SEND_ERROR "Unexpectedly the file ${mocBasicBin} changed!\nTimestamp pre: ${timeBefore}\nTimestamp aft: ${timeAfter}\n")
+ else()
+ message(STATUS "As expected the file ${mocBasicBin} did not change.")
+ endif()
+endmacro()
+
+# Create the test project from the template
+unset(additional_project_sources)
+unset(main_cpp_includes)
+configure_file("${testProjectTemplateDir}/CMakeLists.txt.in" "${testProjectSrc}/CMakeLists.txt")
+configure_file("${testProjectTemplateDir}/main.cpp.in" "${testProjectSrc}/main.cpp")
+
+# Initial build
+try_compile(MOC_RERUN
+ "${testProjectBinDir}"
+ "${testProjectSrc}"
+ MocOnAddFile
+ CMAKE_FLAGS "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
+ "-DCMAKE_AUTOGEN_VERBOSE=${CMAKE_AUTOGEN_VERBOSE}"
+ "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
+ OUTPUT_VARIABLE output
+)
+if (NOT MOC_RERUN)
+ message(FATAL_ERROR "Initial build of mocOnAddFile failed. Output: ${output}")
+endif()
+
+# Sleep to ensure new timestamps
+sleep()
+
+# Add a QObject class (defined in header) to the project and build
+set(additional_project_sources myobject.cpp)
+set(main_cpp_includes "#include \"myobject.h\"")
+configure_file("${testProjectTemplateDir}/CMakeLists.txt.in" "${testProjectSrc}/CMakeLists.txt"
+ @ONLY)
+configure_file("${testProjectTemplateDir}/main.cpp.in" "${testProjectSrc}/main.cpp" @ONLY)
+configure_file("${testProjectTemplateDir}/myobject.h" "${testProjectSrc}/myobject.h" COPYONLY)
+configure_file("${testProjectTemplateDir}/myobject.cpp" "${testProjectSrc}/myobject.cpp" COPYONLY)
+rebuild(2)
+
+# Sleep to ensure new timestamps
+sleep()
+
+# Add a QObject class (defined in source) to the project and build
+set(additional_project_sources myobject.cpp anotherobject.cpp)
+configure_file("${testProjectTemplateDir}/CMakeLists.txt.in" "${testProjectSrc}/CMakeLists.txt"
+ @ONLY)
+configure_file("${testProjectTemplateDir}/anotherobject.cpp" "${testProjectSrc}/anotherobject.cpp"
+ COPYONLY)
+rebuild(3)
--- /dev/null
+cmake_minimum_required(VERSION 3.10)
+project(MocOnAddFile)
+include("@CMAKE_CURRENT_LIST_DIR@/../AutogenCoreTest.cmake")
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTORCC ON)
+
+add_executable(mocOnAddFile main.cpp @additional_project_sources@)
+target_link_libraries(mocOnAddFile ${QT_QTCORE_TARGET})
--- /dev/null
+#include <qobject.h>
+
+class AnotherObject : public QObject
+{
+ Q_OBJECT
+public:
+ AnotherObject() {}
+};
+
+AnotherObject* createAnotherObject()
+{
+ return new AnotherObject();
+}
+
+#include "anotherobject.moc"
--- /dev/null
+@main_cpp_includes@
+
+int main(int argc, char *argv[])
+{
+ return 0;
+}
--- /dev/null
+#include "myobject.h"
+
+MyObject::MyObject(QObject* parent)
+ : QObject(parent)
+{
+}
--- /dev/null
+#ifndef MYOBJECT_H
+#define MYOBJECT_H
+
+#include <qobject.h>
+
+class MyObject : public QObject
+{
+ Q_OBJECT
+public:
+ MyObject(QObject* parent = 0);
+};
+
+#endif
--- /dev/null
+# This test checks whether a missing dependency of the moc output triggers an AUTOMOC re-run.
+
+cmake_minimum_required(VERSION 3.10)
+project(RerunMocOnMissingDependency)
+include("../AutogenCoreTest.cmake")
+
+# Create an executable to generate a clean target
+set(main_source "${CMAKE_CURRENT_BINARY_DIR}/generated_main.cpp")
+file(WRITE "${main_source}" "int main() {}")
+add_executable(exe "${main_source}")
+
+# Utility variables
+set(testProjectTemplateDir "${CMAKE_CURRENT_SOURCE_DIR}/MocOnMissingDependency")
+set(testProjectSrc "${CMAKE_CURRENT_BINARY_DIR}/MocOnMissingDependency")
+set(testProjectBinDir "${CMAKE_CURRENT_BINARY_DIR}/MocOnMissingDependency-build")
+if(DEFINED Qt5Core_VERSION AND Qt5Core_VERSION VERSION_GREATER_EQUAL "5.15.0")
+ set(moc_depfiles_supported TRUE)
+else()
+ set(moc_depfiles_supported FALSE)
+endif()
+
+# Utility macros
+macro(sleep)
+ message(STATUS "Sleeping for a few seconds.")
+ execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
+endmacro()
+
+macro(rebuild buildName)
+ message(STATUS "Starting build ${buildName}.")
+ execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${testProjectBinDir}"
+ RESULT_VARIABLE result OUTPUT_VARIABLE output)
+ if (result)
+ message(FATAL_ERROR "Build ${buildName} failed.")
+ else()
+ message(STATUS "Build ${buildName} finished.")
+ endif()
+endmacro()
+
+# Create the test project from the template
+file(COPY "${testProjectTemplateDir}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
+configure_file("${testProjectTemplateDir}/CMakeLists.txt.in" "${testProjectSrc}/CMakeLists.txt" @ONLY)
+
+# Initial build
+file(REMOVE_RECURSE "${testProjectBinDir}")
+try_compile(MOC_RERUN
+ "${testProjectBinDir}"
+ "${testProjectSrc}"
+ MocOnMissingDependency
+ CMAKE_FLAGS "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
+ "-DCMAKE_AUTOGEN_VERBOSE=ON"
+ "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
+ OUTPUT_VARIABLE output
+)
+if (NOT MOC_RERUN)
+ message(FATAL_ERROR "Initial build of mocOnMissingDependency failed. Output: ${output}")
+endif()
+
+# Sleep to ensure new timestamps
+sleep()
+
+if(moc_depfiles_supported)
+ # Remove the dependency inc1/foo.h and build again.
+ # We expect that the moc_XXX.cpp file gets re-generated. But only if we have depfile support.
+ file(REMOVE_RECURSE "${testProjectSrc}/inc1")
+ rebuild(2)
+ if(NOT output MATCHES "AutoMoc: Generating \"[^\"]*moc_myobject.cpp\"")
+ message(FATAL_ERROR "moc_myobject.cpp was not re-generated "
+ "after removing one of its dependencies")
+ endif()
+endif()
+
+# Sleep to ensure new timestamps
+sleep()
+
+# The next build should *not* re-renerate any moc outputs
+rebuild(3)
+if(output MATCHES "AutoMoc: Generating")
+ message(FATAL_ERROR "moc_myobject.cpp was not re-generated "
+ "after removing one of its dependencies")
+endif()
--- /dev/null
+cmake_minimum_required(VERSION 3.18)
+project(MocOnMissingDependency)
+include("@CMAKE_CURRENT_LIST_DIR@/../AutogenCoreTest.cmake")
+set(CMAKE_AUTOMOC ON)
+add_executable(MocOnMissingDependency main.cpp myobject.cpp)
+target_include_directories(MocOnMissingDependency PRIVATE inc1 inc2)
+target_link_libraries(MocOnMissingDependency PRIVATE ${QT_QTCORE_TARGET})
--- /dev/null
+
+#include <qobject.h>
--- /dev/null
+
+#include <qobject.h>
--- /dev/null
+#include <iostream>
+
+#include "myobject.h"
+
+int main(int argc, char* argv[])
+{
+ MyObject obj;
+ return 0;
+}
--- /dev/null
+#include "myobject.h"
+
+MyObject::MyObject(QObject* parent)
+ : QObject(parent)
+{
+}
--- /dev/null
+#pragma once
+
+#include <foo.h>
+
+class MyObject : public QObject
+{
+ Q_OBJECT
+public:
+ MyObject(QObject* parent = 0);
+};
ADD_AUTOGEN_TEST(RccOnly rccOnly)
ADD_AUTOGEN_TEST(RccSkipSource)
ADD_AUTOGEN_TEST(RerunMocBasic)
+ADD_AUTOGEN_TEST(RerunMocOnAddFile)
+ADD_AUTOGEN_TEST(RerunMocOnMissingDependency)
ADD_AUTOGEN_TEST(RerunRccConfigChange)
ADD_AUTOGEN_TEST(RerunRccDepends)
ADD_AUTOGEN_TEST(SameName sameName)
list(APPEND Ninja_ARGS -DTEST_Fortran=1)
endif()
if(CMake_TEST_Qt5 AND Qt5Core_FOUND)
- list(APPEND Ninja_ARGS -DCMake_TEST_Qt5=1 -DCMAKE_TEST_Qt5Core_Version=${Qt5Core_VERSION})
+ list(APPEND Ninja_ARGS -DCMake_TEST_Qt5=1 -DQt5Core_DIR=${Qt5Core_DIR} -DCMAKE_TEST_Qt5Core_Version=${Qt5Core_VERSION})
endif()
add_RunCMake_test(Ninja)
set(NinjaMultiConfig_ARGS
-DCYGWIN=${CYGWIN}
)
if(CMake_TEST_Qt5 AND Qt5Core_FOUND)
- list(APPEND NinjaMultiConfig_ARGS -DCMake_TEST_Qt5=1)
+ list(APPEND NinjaMultiConfig_ARGS -DCMake_TEST_Qt5=1 -DQt5Core_DIR=${Qt5Core_DIR} -DCMAKE_TEST_Qt5Core_Version=${Qt5Core_VERSION})
endif()
if(DEFINED CMake_TEST_CUDA)
list(APPEND NinjaMultiConfig_ARGS -DCMake_TEST_CUDA=${CMake_TEST_CUDA})
function(run_Qt5AutoMocDeps)
if(CMake_TEST_Qt5 AND CMAKE_TEST_Qt5Core_Version VERSION_GREATER_EQUAL 5.15.0)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Qt5AutoMocDeps-build)
+ set(RunCMake_TEST_OPTIONS "-DQt5Core_DIR=${Qt5Core_DIR}")
run_cmake(Qt5AutoMocDeps)
unset(RunCMake_TEST_OPTIONS)
# Build the project.
--- /dev/null
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ )
--- /dev/null
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${TARGET_BYPRODUCTS_LeafExe}
+ ${TARGET_BYPRODUCTS_RootCustom}
+ )
--- /dev/null
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${TARGET_BYPRODUCTS_LeafCustom}
+ ${TARGET_BYPRODUCTS_RootCustom}
+ ${TARGET_FILE_RootExe_Release}
+ )
--- /dev/null
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${TARGET_FILE_LeafExe_Release}
+ ${TARGET_BYPRODUCTS_LeafExe}
+ ${TARGET_BYPRODUCTS_RootCustom}
+ ${TARGET_FILE_RootExe_Release}
+ )
create_targets(Top)
+add_executable(RootExe main.c)
+add_custom_target(RootCustom COMMAND ${CMAKE_COMMAND} -E touch RootCustom.txt BYPRODUCTS RootCustom.txt)
+add_custom_command(OUTPUT main.c COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/main.c ${CMAKE_CURRENT_BINARY_DIR}/main.c DEPENDS RootCustom)
+add_executable(LeafExe ${CMAKE_CURRENT_BINARY_DIR}/main.c)
+add_custom_target(LeafCustom COMMAND ${CMAKE_COMMAND} -E touch LeafCustom.txt BYPRODUCTS LeafCustom.txt DEPENDS RootCustom RootExe)
+add_dependencies(LeafExe RootExe)
+file(APPEND "${CMAKE_BINARY_DIR}/target_files_custom.cmake"
+"set(TARGET_BYPRODUCTS_LeafCustom [==[${CMAKE_CURRENT_BINARY_DIR}/LeafCustom.txt]==])
+set(TARGET_BYPRODUCTS_LeafExe [==[${CMAKE_CURRENT_BINARY_DIR}/main.c]==])
+set(TARGET_BYPRODUCTS_RootCustom [==[${CMAKE_CURRENT_BINARY_DIR}/RootCustom.txt]==])
+")
+
include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake)
-generate_output_files(TopPostBuild SubdirPostBuild)
+generate_output_files(TopPostBuild SubdirPostBuild RootExe LeafExe)
file(APPEND "${CMAKE_BINARY_DIR}/target_files.cmake" "include(\${CMAKE_CURRENT_LIST_DIR}/target_files_custom.cmake)\n")
--- /dev/null
+ input: CUSTOM_COMMAND(
+ [^
+]*)*
+ \|\| exe_autogen_timestamp_deps:Debug(
+ [^
+]*)*
+ outputs:
run_ninja(CustomCommandsAndTargets release-postbuild build-Release.ninja SubdirPostBuild)
run_cmake_build(CustomCommandsAndTargets debug-targetpostbuild Debug TopTargetPostBuild)
run_ninja(CustomCommandsAndTargets release-targetpostbuild build-Release.ninja SubdirTargetPostBuild)
+run_cmake_build(CustomCommandsAndTargets release-clean Release clean:all)
+run_ninja(CustomCommandsAndTargets release-leaf-custom build-Release.ninja LeafCustom.txt)
+run_cmake_build(CustomCommandsAndTargets release-clean Release clean:all)
+run_ninja(CustomCommandsAndTargets release-leaf-exe build-Release.ninja LeafExe)
+run_cmake_build(CustomCommandsAndTargets release-clean Release clean:all)
+run_ninja(CustomCommandsAndTargets release-leaf-byproduct build-Release.ninja main.c)
unset(RunCMake_TEST_BINARY_DIR)
if(CMake_TEST_Qt5)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Qt5-build)
- set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all")
+ set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all" "-DQt5Core_DIR=${Qt5Core_DIR}")
run_cmake_configure(Qt5)
unset(RunCMake_TEST_OPTIONS)
include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
run_cmake_build(Qt5 debug-in-release-graph Release exe:Debug)
+ if(CMAKE_TEST_Qt5Core_Version VERSION_GREATER_EQUAL 5.15.0)
+ run_ninja(Qt5 automoc-check build-Debug.ninja -t query exe_autogen/timestamp)
+ endif()
endif()
run_cmake(foreach-RANGE-non-int-test-3-2)
run_cmake(foreach-RANGE-non-int-test-3-3)
run_cmake(foreach-RANGE-invalid-test)
+run_cmake(foreach-RANGE-out-of-range-test)
--- /dev/null
+^CMake Error at foreach-RANGE-out-of-range-test\.cmake:[0-9]+ \(foreach\):
+ foreach Integer out of range: '10000000000000000000'
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)$
--- /dev/null
+foreach(a RANGE 10000000000000000000)
+ break()
+endforeach()
--build-options ${build_options}
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
+add_test(NAME UseSWIG.MultipleFiles COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/UseSWIG/MultipleFiles"
+ "${CMake_BINARY_DIR}/Tests/UseSWIG/MultipleFiles"
+ ${build_generator_args}
+ --build-project TestMultipleFiles
+ --build-options ${build_options}
+ )
add_test(NAME UseSWIG.ModuleVersion2 COMMAND
--- /dev/null
+cmake_minimum_required(VERSION 3.18)
+
+project(TestMultipleFiles CXX)
+
+find_package(SWIG REQUIRED)
+include(UseSWIG)
+
+unset(SWIG_LANG_TYPE)
+unset(SWIG_LANG_INCLUDE_DIRECTORIES)
+unset(SWIG_LANG_DEFINITIONS)
+unset(SWIG_LANG_OPTIONS)
+unset(SWIG_LANG_LIBRARIES)
+
+find_package(Python3 REQUIRED COMPONENTS Development)
+
+set_property(SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/add.i" PROPERTY CPLUSPLUS ON)
+set_property(SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/sub.i" PROPERTY CPLUSPLUS ON)
+set_property(SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/add.i" PROPERTY SWIG_MODULE_NAME _add)
+set_property(SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/sub.i" PROPERTY SWIG_MODULE_NAME _sub)
+
+
+swig_add_library(example
+ LANGUAGE python
+ TYPE MODULE
+ SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/add.i"
+ "${CMAKE_CURRENT_SOURCE_DIR}/sub.i"
+ "${CMAKE_CURRENT_SOURCE_DIR}/add.cxx"
+ "${CMAKE_CURRENT_SOURCE_DIR}/sub.cxx")
+target_include_directories(example PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
+target_link_libraries(example PRIVATE Python3::Module)
--- /dev/null
+#include "add.h"
+
+int add(int a, int b)
+{
+ return a + b;
+}
--- /dev/null
+int add(int a, int b);
--- /dev/null
+%{
+#include "add.h"
+%}
+%include "add.h"
--- /dev/null
+#include "sub.h"
+
+int sub(int a, int b)
+{
+ return a - b;
+}
--- /dev/null
+int sub(int a, int b);
--- /dev/null
+%{
+#include "sub.h"
+%}
+
+%include "sub.h"