Try building a project. The success or failure of the ``try_compile``,
i.e. ``TRUE`` or ``FALSE`` respectively, is returned in ``<resultVar>``.
-.. versionadded:: 3.14
- The name of the ``<resultVar>`` is defined by the user. Previously, it had
- a fixed name ``RESULT_VAR``.
-
In this form, ``<srcdir>`` should contain a complete CMake project with a
``CMakeLists.txt`` file and all sources. The ``<bindir>`` and ``<srcdir>``
will not be deleted after this command is run. Specify ``<targetName>`` to
variable). The success or failure of the ``try_compile``, i.e. ``TRUE`` or
``FALSE`` respectively, is returned in ``<resultVar>``.
-.. versionadded:: 3.14
- The name of the ``<resultVar>`` is defined by the user. Previously, it had
- a fixed name ``RESULT_VAR``.
-
In this form, one or more source files must be provided. If
:variable:`CMAKE_TRY_COMPILE_TARGET_TYPE` is unset or is set to ``EXECUTABLE``,
the sources must include a definition for ``main`` and CMake will create a
set to ``FAILED_TO_RUN``. See the :command:`try_compile` command for
information on how the test project is constructed to build the source file.
-.. versionadded:: 3.14
- The names of the result variables ``<runResultVar>`` and
- ``<compileResultVar>`` are defined by the user. Previously, they had
- fixed names ``RUN_RESULT_VAR`` and ``COMPILE_RESULT_VAR``.
-
The options are:
``CMAKE_FLAGS <flags>...``
* The :generator:`Visual Studio 17 2022` generator is now based on the
"Visual Studio 2022" release candidates. Previously it was based on
preview versions.
+
+3.21.5, 3.21.6
+--------------
+
+These versions made no changes to documented features or interfaces.
+Some implementation updates were made to support ecosystem changes
+and/or fix regressions.
* The ``OLD`` behavior of :policy:`CMP0128` was fixed to add flags even when
the specified standard matches the compiler default.
+
+3.22.3
+------
+
+* The :command:`while` command again ignores errors in condition evaluation
+ as CMake 3.21 and below did. This bug was fixed in 3.22.0, but exposed
+ errors in existing projects. The fix has been reverted to restore
+ compatibility. The fix may be restored in a future version of CMake
+ via a policy.
140 = VS 2015 (14.0)
141 = VS 2017 (15.0)
142 = VS 2019 (16.0)
+ 143 = VS 2022 (17.0)
Compiler versions newer than those known to CMake will be reported
as the latest known toolset version.
"INFO" ":" "standard_default[" C_VERSION "]";
const char* info_language_extensions_default = "INFO" ":" "extensions_default["
-/* !defined(_MSC_VER) to exclude Clang's MSVC compatibility mode. */
#if (defined(__clang__) || defined(__GNUC__) || defined(__xlC__) || \
defined(__TI_COMPILER_VERSION__)) && \
- !defined(__STRICT_ANSI__) && !defined(_MSC_VER)
+ !defined(__STRICT_ANSI__)
"ON"
#else
"OFF"
"]";
const char* info_language_extensions_default = "INFO" ":" "extensions_default["
-/* !defined(_MSC_VER) to exclude Clang's MSVC compatibility mode. */
-#if (defined(__clang__) || defined(__GNUC__)) && !defined(__STRICT_ANSI__) && \
- !defined(_MSC_VER)
+#if (defined(__clang__) || defined(__GNUC__)) && \
+ !defined(__STRICT_ANSI__)
"ON"
#else
"OFF"
"]";
const char* info_language_extensions_default = "INFO" ":" "extensions_default["
-/* !defined(_MSC_VER) to exclude Clang's MSVC compatibility mode. */
#if (defined(__clang__) || defined(__GNUC__) || defined(__xlC__) || \
defined(__TI_COMPILER_VERSION__)) && \
- !defined(__STRICT_ANSI__) && !defined(_MSC_VER)
+ !defined(__STRICT_ANSI__)
"ON"
#else
"OFF"
else()
list(PREPEND _CMAKE_LINKER_NAMES "ld.lld")
endif()
- list(PREPEND _CMAKE_AR_NAMES "llvm-ar")
+ if(NOT APPLE)
+ # llvm-ar does not generate a symbol table that the Apple ld64 linker accepts.
+ list(PREPEND _CMAKE_AR_NAMES "llvm-ar")
+ endif()
list(PREPEND _CMAKE_RANLIB_NAMES "llvm-ranlib")
if("${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_VERSION}" VERSION_GREATER_EQUAL 11)
# llvm-strip versions prior to 11 require additional flags we do not yet add.
# Whenever needed, override this default behavior using CMAKE_IAR_CXX_FLAG in your toolchain file.
if(NOT CMAKE_IAR_CXX_FLAG)
- set(_CMAKE_IAR_MODERNCXX_LIST 14 17)
- if(${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT} IN_LIST _CMAKE_IAR_MODERNCXX_LIST OR
+ cmake_policy(PUSH)
+ cmake_policy(SET CMP0057 NEW) # if IN_LIST
+
+ if(${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT} IN_LIST "14;17" OR
("${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "ARM" AND ${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT} EQUAL 98))
string(PREPEND CMAKE_CXX_FLAGS "--c++ ")
else()
string(PREPEND CMAKE_CXX_FLAGS "--eec++ ")
endif()
- unset(_CMAKE_IAR_MODERNCXX_LIST)
+
+ cmake_policy(POP)
endif()
set(CMAKE_CXX_STANDARD_COMPILE_OPTION "")
if(GLUT_LIBRARIES)
target_link_libraries(GLUT::GLUT INTERFACE ${GLUT_LIBRARIES})
endif()
+ if(GLUT_LIBRARY_DIRS)
+ target_link_directories(GLUT::GLUT INTERFACE ${GLUT_LIBRARY_DIRS})
+ endif()
if(GLUT_LDFLAGS)
target_link_options(GLUT::GLUT INTERFACE ${GLUT_LDFLAGS})
endif()
# 2. If gsl-config is not available, try looking in gsl/gsl_version.h
if( NOT GSL_VERSION AND EXISTS "${GSL_INCLUDE_DIRS}/gsl/gsl_version.h" )
file( STRINGS "${GSL_INCLUDE_DIRS}/gsl/gsl_version.h" gsl_version_h_contents REGEX "define GSL_VERSION" )
- string( REGEX REPLACE ".*([0-9]\\.[0-9][0-9]?).*" "\\1" GSL_VERSION ${gsl_version_h_contents} )
+ string( REGEX REPLACE ".*define[ ]+GSL_VERSION[ ]+\"([^\"]*)\".*" "\\1" GSL_VERSION ${gsl_version_h_contents} )
endif()
# might also try scraping the directory name for a regex match "gsl-X.X"
#endif
#if defined(MPI_VERSION) && defined(MPI_SUBVERSION)
-const static char mpiver_str[] = { 'I', 'N',
+static const char mpiver_str[] = { 'I', 'N',
'F', 'O',
':', 'M',
'P', 'I',
${versioninfo_string}
)
- if(CMAKE_MATCH_1 MATCHES "(([0-9])\\.([0-9]))[\\.0-9]*")
+ if(CMAKE_MATCH_1 MATCHES "(([0-9]+)\\.([0-9]+))[\\.0-9]*")
set(_matlab_version_tmp "${CMAKE_MATCH_1}")
endif()
endif()
include(Platform/Windows-Intel)
__windows_compiler_intel(C)
-set(CMAKE_DEPFILE_FLAGS_C "-QMMD -QMT <DEP_TARGET> -QMF <DEP_FILE>")
+set(CMAKE_DEPFILE_FLAGS_C "-QMD -QMT <DEP_TARGET> -QMF <DEP_FILE>")
set(CMAKE_C_DEPFILE_FORMAT gcc)
if(CMAKE_GENERATOR MATCHES "^Ninja")
set(_COMPILE_CXX " /TP")
__windows_compiler_intel(CXX)
-set(CMAKE_DEPFILE_FLAGS_CXX "-QMMD -QMT <DEP_TARGET> -QMF <DEP_FILE>")
+set(CMAKE_DEPFILE_FLAGS_CXX "-QMD -QMT <DEP_TARGET> -QMF <DEP_FILE>")
set(CMAKE_CXX_DEPFILE_FORMAT gcc)
if(CMAKE_GENERATOR MATCHES "^Ninja")
macro(__windows_compiler_intel lang)
__windows_compiler_msvc(${lang})
- set(CMAKE_DEPFILE_FLAGS_${lang} "-QMMD -QMT <DEP_TARGET> -QMF <DEP_FILE>")
+ set(CMAKE_DEPFILE_FLAGS_${lang} "-QMD -QMT <DEP_TARGET> -QMF <DEP_FILE>")
set(CMAKE_${lang}_DEPFILE_FORMAT gcc)
endmacro()
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 22)
-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 [==[8428e39ed9 CMake 3.22.2]==])
+ set(git_info [==[6e9eaf209d CMake 3.22.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]* "
void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
cmGeneratorTarget const* target,
cmGeneratorExpression::PreprocessContext preprocessRule,
- ImportPropertyMap& properties, std::vector<std::string>& missingTargets)
+ ImportPropertyMap& properties, std::vector<std::string>& missingTargets,
+ cmTargetExport const& te)
{
assert(preprocessRule == cmGeneratorExpression::InstallInterface);
cmGeneratorExpression ge;
std::string dirs = cmGeneratorExpression::Preprocess(
- cmJoin(target->Target->GetInstallIncludeDirectoriesEntries(), ";"),
+ cmJoin(target->Target->GetInstallIncludeDirectoriesEntries(te), ";"),
preprocessRule, true);
this->ReplaceInstallPrefix(dirs);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(dirs);
#include "cmVersionConfig.h"
class cmGeneratorTarget;
+class cmTargetExport;
#define STRINGIFY_HELPER(X) #X
#define STRINGIFY(X) STRINGIFY_HELPER(X)
void PopulateIncludeDirectoriesInterface(
cmGeneratorTarget const* target,
cmGeneratorExpression::PreprocessContext preprocessRule,
- ImportPropertyMap& properties, std::vector<std::string>& missingTargets);
+ ImportPropertyMap& properties, std::vector<std::string>& missingTargets,
+ cmTargetExport const& te);
void PopulateSourcesInterface(
cmGeneratorTarget const* target,
cmGeneratorExpression::PreprocessContext preprocessRule,
ImportPropertyMap properties;
this->PopulateIncludeDirectoriesInterface(
- gt, cmGeneratorExpression::InstallInterface, properties, missingTargets);
+ gt, cmGeneratorExpression::InstallInterface, properties, missingTargets,
+ *te);
this->PopulateSourcesInterface(gt, cmGeneratorExpression::InstallInterface,
properties, missingTargets);
this->PopulateInterfaceProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", gt,
te->RuntimeGenerator = runtimeGenerator.get();
te->ObjectsGenerator = objectGenerator.get();
target.AddInstallIncludeDirectories(
- cmMakeRange(includesArgs.GetIncludeDirs()));
+ *te, cmMakeRange(includesArgs.GetIncludeDirs()));
te->NamelinkOnly = namelinkOnly;
helper.Makefile->GetGlobalGenerator()
->GetExportSets()[exports]
#include <cmext/algorithm>
#include <cmext/string_view>
+#include "cm_codecvt.hxx"
+
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
const char* name, std::string const& options,
std::vector<std::string>& makefile_depends)
{
+ // FIXME: Find a better way to determine the response file encoding,
+ // perhaps using tool-specific platform information variables.
+ // For now, use the makefile encoding as a heuristic.
+ codecvt::Encoding responseEncoding =
+ this->GlobalGenerator->GetMakefileEncoding();
+ // Non-MSVC tooling may not understand a BOM.
+ if (responseEncoding == codecvt::UTF8_WITH_BOM &&
+ !this->Makefile->IsOn("MSVC")) {
+ responseEncoding = codecvt::UTF8;
+ }
+
// Create the response file.
std::string responseFileNameFull =
cmStrCat(this->TargetBuildDirectoryFull, '/', name);
- cmGeneratedFileStream responseStream(
- responseFileNameFull, false, this->GlobalGenerator->GetMakefileEncoding());
+ cmGeneratedFileStream responseStream(responseFileNameFull, false,
+ responseEncoding);
responseStream.SetCopyIfDifferent(true);
responseStream << options << "\n";
cmTarget::LinkLibraryVectorType OriginalLinkLibraries;
std::map<std::string, BTs<std::string>> LanguageStandardProperties;
std::vector<BT<std::string>> IncludeDirectoriesEntries;
- std::vector<std::string> InstallIncludeDirectoriesEntries;
+ std::map<cmTargetExport const*, std::vector<std::string>>
+ InstallIncludeDirectoriesEntries;
std::vector<BT<std::string>> CompileOptionsEntries;
std::vector<BT<std::string>> CompileFeaturesEntries;
std::vector<BT<std::string>> CompileDefinitionsEntries;
return this->impl->SystemIncludeDirectories;
}
-void cmTarget::AddInstallIncludeDirectories(cmStringRange const& incs)
+void cmTarget::AddInstallIncludeDirectories(cmTargetExport const& te,
+ cmStringRange const& incs)
{
- std::copy(incs.begin(), incs.end(),
- std::back_inserter(this->impl->InstallIncludeDirectoriesEntries));
+ std::copy(
+ incs.begin(), incs.end(),
+ std::back_inserter(this->impl->InstallIncludeDirectoriesEntries[&te]));
}
-cmStringRange cmTarget::GetInstallIncludeDirectoriesEntries() const
+cmStringRange cmTarget::GetInstallIncludeDirectoriesEntries(
+ cmTargetExport const& te) const
{
- return cmMakeRange(this->impl->InstallIncludeDirectoriesEntries);
+ return cmMakeRange(this->impl->InstallIncludeDirectoriesEntries[&te]);
}
cmBTStringRange cmTarget::GetIncludeDirectoriesEntries() const
class cmMessenger;
class cmPropertyMap;
class cmSourceFile;
+class cmTargetExport;
class cmTargetInternals;
/** \class cmTarget
void AddSystemIncludeDirectories(std::set<std::string> const& incs);
std::set<std::string> const& GetSystemIncludeDirectories() const;
- void AddInstallIncludeDirectories(cmStringRange const& incs);
- cmStringRange GetInstallIncludeDirectoriesEntries() const;
+ void AddInstallIncludeDirectories(cmTargetExport const& te,
+ cmStringRange const& incs);
+ cmStringRange GetInstallIncludeDirectoriesEntries(
+ cmTargetExport const& te) const;
BTs<std::string> const* GetLanguageStandardProperty(
const std::string& propertyName) const;
return out;
};
+ // FIXME(#23296): For compatibility with older versions of CMake, we
+ // tolerate condition errors that evaluate to false. We should add
+ // a policy to enforce such errors.
+ bool enforceError = true;
std::string errorString;
MessageType messageType;
for (cmConditionEvaluator conditionEvaluator(mf, whileBT);
- conditionEvaluator.IsTrue(expandArgs(this->Args, expandedArguments),
- errorString, messageType);) {
+ (enforceError = /* enforce condition errors that evaluate to true */
+ conditionEvaluator.IsTrue(expandArgs(this->Args, expandedArguments),
+ errorString, messageType));) {
// Invoke all the functions that were collected in the block.
for (cmListFileFunction const& fn : functions) {
cmExecutionStatus status(mf);
}
}
- if (!errorString.empty()) {
+ if (!errorString.empty() && enforceError) {
std::string err = "had incorrect arguments:\n ";
for (auto const& i : expandedArguments) {
err += " ";
// cannot use it to print messages. Another implementation will
// be needed to print colored messages on Windows.
static_cast<void>(md);
- std::cerr << m << cmakemainGetStack(cm) << "\n";
+ std::cerr << m << cmakemainGetStack(cm) << '\n' << std::flush;
#else
cmsysTerminal_cfprintf(md.desiredColor, stderr, "%s", m.c_str());
fflush(stderr); // stderr is buffered in some cases.
- std::cerr << cmakemainGetStack(cm) << "\n";
+ std::cerr << cmakemainGetStack(cm) << '\n' << std::flush;
#endif
}
add_RunCMake_test(SymlinkTrees)
endif ()
-find_package(Qt4 QUIET)
-find_package(Qt5Core QUIET)
-if (QT4_FOUND AND Qt5Core_FOUND AND NOT Qt5Core_VERSION VERSION_LESS 5.1.0)
+if(CMake_TEST_Qt4)
+ find_package(Qt4 QUIET)
+endif()
+if(CMake_TEST_Qt5)
+ find_package(Qt5Core QUIET)
+endif()
+if (CMake_TEST_Qt4 AND CMake_TEST_Qt5 AND QT4_FOUND AND Qt5Core_FOUND AND NOT Qt5Core_VERSION VERSION_LESS 5.1.0)
add_RunCMake_test(IncompatibleQt)
endif()
-if (QT4_FOUND)
+if (CMake_TEST_Qt4 AND QT4_FOUND)
add_RunCMake_test(ObsoleteQtMacros -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE})
endif()
CMake Error at unbalanced-parenthesis\.cmake:[0-9]+ \(if\):
if given arguments:
- "NOT" "\(" "IN_LIST" "some_list"
+ "\("
mismatched parenthesis in condition
Call Stack \(most recent call first\):
-set(var_with_paren "(")
-set(some_list "")
-
-if(NOT ${var_with_paren} IN_LIST some_list)
- message(STATUS "Never prints")
-else()
- message(STATUS "Never prints")
+set(paren "(")
+if(${paren})
+ message(STATUS "Condition incorrectly true")
endif()
+message(STATUS "Code incorrectly accepted")
--- /dev/null
+set(pkg1_cmake "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/Export/pkg1/pkg1.cmake")
+file(STRINGS "${pkg1_cmake}" pkg1_includes REGEX INTERFACE_INCLUDE_DIRECTORIES)
+set(pkg1_expect [[INTERFACE_INCLUDE_DIRECTORIES "\${_IMPORT_PREFIX}/pkg1/inc"]])
+if(NOT pkg1_includes MATCHES "${pkg1_expect}")
+ set(RunCMake_TEST_FAILED "pkg1 has unexpected INTERFACE_INCLUDE_DIRECTORIES line:
+ ${pkg1_includes}
+It does not match:
+ ${pkg1_expect}")
+endif()
+
+set(pkg2_cmake "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/Export/pkg2/pkg2.cmake")
+file(STRINGS "${pkg2_cmake}" pkg2_includes REGEX INTERFACE_INCLUDE_DIRECTORIES)
+set(pkg2_expect [[INTERFACE_INCLUDE_DIRECTORIES "\${_IMPORT_PREFIX}/pkg2/inc"]])
+if(NOT pkg2_includes MATCHES "${pkg2_expect}")
+ set(RunCMake_TEST_FAILED "pkg2 has unexpected INTERFACE_INCLUDE_DIRECTORIES line:
+ ${pkg2_includes}
+It does not match:
+ ${pkg2_expect}")
+endif()
--- /dev/null
+.+
+set_target_properties\(pkg1::foo PROPERTIES
+.+INTERFACE_INCLUDE_DIRECTORIES "\${_IMPORT_PREFIX}/pkg1/inc"
+\)
+.+
--- /dev/null
+.+
+set_target_properties\(pkg2::foo PROPERTIES
+.+INTERFACE_INCLUDE_DIRECTORIES "\${_IMPORT_PREFIX}/pkg2/inc"
+\)
+.+
--- /dev/null
+enable_language(C)
+
+add_library(foo STATIC empty.c)
+
+install(TARGETS foo
+ EXPORT pkg1
+ ARCHIVE DESTINATION pkg1/lib
+ INCLUDES DESTINATION pkg1/inc
+ )
+install(EXPORT pkg1 DESTINATION pkg1)
+
+install(TARGETS foo
+ EXPORT pkg2
+ ARCHIVE DESTINATION pkg2/lib
+ INCLUDES DESTINATION pkg2/inc
+ )
+install(EXPORT pkg2 DESTINATION pkg2)
run_cmake(EXPORT-UnknownExport)
run_cmake(EXPORT-NamelinkOnly)
run_cmake(EXPORT-SeparateNamelink)
+run_cmake(EXPORT-TargetTwice)
run_cmake(CMP0062-OLD)
run_cmake(CMP0062-NEW)
run_cmake(CMP0062-WARN)
+++ /dev/null
-CMake Error at unbalanced-parenthesis.cmake:[0-9]+ \(while\):
- had incorrect arguments:
-
- "NOT" "\(" "IN_LIST" "some_list"
-
- mismatched parenthesis in condition
-Call Stack \(most recent call first\):
- CMakeLists\.txt:[0-9]+ \(include\)
--- /dev/null
+-- Code incorrectly accepted
-set(var_with_paren "(")
-set(some_list "")
-
-while(NOT ${var_with_paren} IN_LIST some_list)
- message(STATUS "Never prints")
+set(paren "(")
+while(${paren})
+ message(STATUS "Condition incorrectly true")
+ break()
endwhile()
-
-message(STATUS "Never prints")
+# FIXME(#23296): The above condition error is tolerated for compatibility.
+message(STATUS "Code incorrectly accepted")