summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeVersion.cmake4
-rw-r--r--Source/CPack/cmCPackExternalGenerator.cxx6
-rw-r--r--Source/CPack/cmCPackGenerator.cxx50
-rw-r--r--Source/CursesDialog/ccmake.cxx16
-rw-r--r--Source/QtDialog/CMakeLists.txt179
-rw-r--r--Source/QtDialog/CMakeSetup.cxx8
-rw-r--r--Source/QtDialog/QCMake.cxx6
-rw-r--r--Source/QtDialog/QCMakeCacheView.cxx33
-rw-r--r--Source/QtDialog/QCMakeCacheView.h1
-rw-r--r--Source/QtDialog/QCMakeWidgets.cxx18
-rw-r--r--Source/cmAuxSourceDirectoryCommand.cxx2
-rw-r--r--Source/cmCoreTryCompile.cxx613
-rw-r--r--Source/cmCoreTryCompile.h4
-rw-r--r--Source/cmExtraCodeBlocksGenerator.cxx2
-rw-r--r--Source/cmExtraCodeLiteGenerator.cxx3
-rw-r--r--Source/cmExtraSublimeTextGenerator.cxx7
-rw-r--r--Source/cmFileAPI.cxx2
-rw-r--r--Source/cmFileAPICodemodel.cxx36
-rw-r--r--Source/cmFileCommand.cxx18
-rw-r--r--Source/cmFindProgramCommand.cxx61
-rw-r--r--Source/cmGeneratorExpressionNode.cxx34
-rw-r--r--Source/cmGeneratorTarget.cxx114
-rw-r--r--Source/cmGeneratorTarget.h20
-rw-r--r--Source/cmGetFilenameComponentCommand.cxx2
-rw-r--r--Source/cmGlobalGenerator.cxx30
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx103
-rw-r--r--Source/cmGlobalVisualStudio10Generator.h22
-rw-r--r--Source/cmGlobalVisualStudio14Generator.cxx6
-rw-r--r--Source/cmGlobalVisualStudio14Generator.h6
-rw-r--r--Source/cmGlobalVisualStudioVersionedGenerator.cxx38
-rw-r--r--Source/cmGlobalVisualStudioVersionedGenerator.h2
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx223
-rw-r--r--Source/cmGlobalXCodeGenerator.h3
-rw-r--r--Source/cmLinkItemGraphVisitor.cxx4
-rw-r--r--Source/cmLocalGenerator.cxx52
-rw-r--r--Source/cmLocalGenerator.h3
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx7
-rw-r--r--Source/cmMakefile.cxx219
-rw-r--r--Source/cmMakefile.h59
-rw-r--r--Source/cmMakefileTargetGenerator.cxx7
-rw-r--r--Source/cmNinjaTargetGenerator.cxx11
-rw-r--r--Source/cmPolicies.cxx30
-rw-r--r--Source/cmPolicies.h17
-rw-r--r--Source/cmQtAutoGenInitializer.cxx8
-rw-r--r--Source/cmSourceFile.cxx31
-rw-r--r--Source/cmSourceFileLocation.cxx4
-rw-r--r--Source/cmStateSnapshot.cxx2
-rw-r--r--Source/cmTarget.cxx79
-rw-r--r--Source/cmTarget.h10
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx69
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h2
-rw-r--r--Source/cmake.cxx38
-rw-r--r--Source/cmake.h39
-rw-r--r--Source/cmakemain.cxx139
-rw-r--r--Source/cmcmd.cxx4
55 files changed, 1690 insertions, 816 deletions
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 04d083b..b579c7b 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,8 +1,8 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 18)
-set(CMake_VERSION_PATCH 0)
-set(CMake_VERSION_RC 2)
+set(CMake_VERSION_PATCH 20200630)
+#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
# Start with the full version number used in tags. It has no dev info.
diff --git a/Source/CPack/cmCPackExternalGenerator.cxx b/Source/CPack/cmCPackExternalGenerator.cxx
index 11e1aec..53be4fe 100644
--- a/Source/CPack/cmCPackExternalGenerator.cxx
+++ b/Source/CPack/cmCPackExternalGenerator.cxx
@@ -75,6 +75,12 @@ int cmCPackExternalGenerator::PackageFiles()
if (cmSystemTools::GetErrorOccuredFlag() || !res) {
return 0;
}
+
+ const char* builtPackagesStr =
+ this->GetOption("CPACK_EXTERNAL_BUILT_PACKAGES");
+ if (builtPackagesStr) {
+ cmExpandList(builtPackagesStr, this->packageFileNames, false);
+ }
}
return 1;
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index 288dc58..7990504 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -264,6 +264,23 @@ int cmCPackGenerator::InstallProject()
return 0;
}
+ // Run pre-build actions
+ const char* preBuildScripts = this->GetOption("CPACK_PRE_BUILD_SCRIPTS");
+ if (preBuildScripts) {
+ const auto scripts = cmExpandedList(preBuildScripts, false);
+ for (const auto& script : scripts) {
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+ "Executing pre-build script: " << script << std::endl);
+
+ if (!this->MakefileMap->ReadListFile(script)) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "The pre-build script not found: " << script
+ << std::endl);
+ return 0;
+ }
+ }
+ }
+
if (setDestDir) {
cmSystemTools::PutEnv("DESTDIR=");
}
@@ -333,7 +350,8 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
if (installDirectoriesVector.size() % 2 != 0) {
cmCPackLogger(
cmCPackLog::LOG_ERROR,
- "CPACK_INSTALLED_DIRECTORIES should contain pairs of <directory> and "
+ "CPACK_INSTALLED_DIRECTORIES should contain pairs of <directory> "
+ "and "
"<subdirectory>. The <subdirectory> can be '.' to be installed in "
"the toplevel directory of installation."
<< std::endl);
@@ -475,10 +493,10 @@ int cmCPackGenerator::InstallProjectViaInstallScript(
"- Install script: " << installScript << std::endl);
if (setDestDir) {
- // For DESTDIR based packaging, use the *project* CMAKE_INSTALL_PREFIX
- // underneath the tempInstallDirectory. The value of the project's
- // CMAKE_INSTALL_PREFIX is sent in here as the value of the
- // CPACK_INSTALL_PREFIX variable.
+ // For DESTDIR based packaging, use the *project*
+ // CMAKE_INSTALL_PREFIX underneath the tempInstallDirectory. The
+ // value of the project's CMAKE_INSTALL_PREFIX is sent in here as the
+ // value of the CPACK_INSTALL_PREFIX variable.
std::string dir;
if (this->GetOption("CPACK_INSTALL_PREFIX")) {
@@ -1076,6 +1094,25 @@ int cmCPackGenerator::DoPackage()
return 0;
}
}
+ // Run post-build actions
+ const char* postBuildScripts = this->GetOption("CPACK_POST_BUILD_SCRIPTS");
+ if (postBuildScripts) {
+ this->MakefileMap->AddDefinition("CPACK_PACKAGE_FILES",
+ cmJoin(this->packageFileNames, ";"));
+
+ const auto scripts = cmExpandedList(postBuildScripts, false);
+ for (const auto& script : scripts) {
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+ "Executing post-build script: " << script << std::endl);
+
+ if (!this->MakefileMap->ReadListFile(script)) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "The post-build script not found: " << script
+ << std::endl);
+ return 0;
+ }
+ }
+ }
/* Prepare checksum algorithm*/
const char* algo = this->GetOption("CPACK_PACKAGE_CHECKSUM");
@@ -1378,7 +1415,8 @@ int cmCPackGenerator::PrepareGroupingKind()
<< std::endl);
}
- // if user specified packaging method, override the default packaging method
+ // if user specified packaging method, override the default packaging
+ // method
if (method != UNKNOWN_COMPONENT_PACKAGE_METHOD) {
componentPackageMethod = method;
}
diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx
index 9a26db5..85e256b 100644
--- a/Source/CursesDialog/ccmake.cxx
+++ b/Source/CursesDialog/ccmake.cxx
@@ -2,11 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include <csignal>
+#include <cstdio>
+#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>
+#include <unistd.h>
+
#include "cmsys/Encoding.hxx"
#include "cmCursesColor.h"
@@ -54,7 +58,12 @@ void onsig(int /*unused*/)
{
if (cmCursesForm::CurrentForm) {
endwin();
- initscr(); /* Initialization */
+ if (initscr() == nullptr) {
+ static const char errmsg[] = "Error: ncurses initialization failed\n";
+ auto r = write(STDERR_FILENO, errmsg, sizeof(errmsg) - 1);
+ static_cast<void>(r);
+ exit(1);
+ }
noecho(); /* Echo off */
cbreak(); /* nl- or cr not needed */
keypad(stdscr, true); /* Use key symbols as KEY_DOWN */
@@ -124,7 +133,10 @@ int main(int argc, char const* const* argv)
cmCursesForm::DebugStart();
}
- initscr(); /* Initialization */
+ if (initscr() == nullptr) {
+ fprintf(stderr, "Error: ncurses initialization failed\n");
+ exit(1);
+ }
noecho(); /* Echo off */
cbreak(); /* nl- or cr not needed */
keypad(stdscr, true); /* Use key symbols as KEY_DOWN */
diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt
index 98dd0e2..e6d6b17 100644
--- a/Source/QtDialog/CMakeLists.txt
+++ b/Source/QtDialog/CMakeLists.txt
@@ -3,111 +3,79 @@
project(QtDialog)
CMake_OPTIONAL_COMPONENT(cmake-gui)
-find_package(Qt5Widgets QUIET)
-if (Qt5Widgets_FOUND)
- include_directories(${Qt5Widgets_INCLUDE_DIRS})
- add_definitions(${Qt5Widgets_DEFINITONS})
- macro(qt4_wrap_ui)
- qt5_wrap_ui(${ARGN})
- endmacro()
- macro(qt4_wrap_cpp)
- qt5_wrap_cpp(${ARGN})
- endmacro()
- macro(qt4_add_resources)
- qt5_add_resources(${ARGN})
- endmacro()
+find_package(Qt5Widgets REQUIRED)
- set(CMake_QT_LIBRARIES ${Qt5Widgets_LIBRARIES})
- set(QT_QTMAIN_LIBRARY ${Qt5Core_QTMAIN_LIBRARIES})
+set(CMake_QT_EXTRA_LIBRARIES)
- # Try to find the package WinExtras for the task bar progress
- if(WIN32)
- find_package(Qt5WinExtras QUIET)
- if (Qt5WinExtras_FOUND)
- include_directories(${Qt5WinExtras_INCLUDE_DIRS})
- add_definitions(-DQT_WINEXTRAS)
- list(APPEND CMake_QT_LIBRARIES ${Qt5WinExtras_LIBRARIES})
- endif()
+# Try to find the package WinExtras for the task bar progress
+if(WIN32)
+ find_package(Qt5WinExtras QUIET)
+ if (Qt5WinExtras_FOUND)
+ add_definitions(-DQT_WINEXTRAS)
+ list(APPEND CMake_QT_EXTRA_LIBRARIES Qt5::WinExtras)
endif()
+endif()
- # Remove this when the minimum version of Qt is 4.6.
- add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0)
-
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
- if(CMake_QT_STATIC_QXcbIntegrationPlugin_LIBRARIES)
- list(APPEND CMake_QT_LIBRARIES ${CMake_QT_STATIC_QXcbIntegrationPlugin_LIBRARIES})
- set_property(SOURCE CMakeSetup.cxx
- PROPERTY COMPILE_DEFINITIONS USE_QXcbIntegrationPlugin)
- endif()
+if(CMake_QT_STATIC_QXcbIntegrationPlugin_LIBRARIES)
+ list(APPEND CMake_QT_EXTRA_LIBRARIES ${CMake_QT_STATIC_QXcbIntegrationPlugin_LIBRARIES})
+ set_property(SOURCE CMakeSetup.cxx
+ PROPERTY COMPILE_DEFINITIONS USE_QXcbIntegrationPlugin)
+endif()
- if(CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES)
- list(APPEND CMake_QT_LIBRARIES ${CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES})
- set_property(SOURCE CMakeSetup.cxx
- PROPERTY COMPILE_DEFINITIONS USE_QWindowsIntegrationPlugin)
- endif()
+if(CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES)
+ list(APPEND CMake_QT_EXTRA_LIBRARIES ${CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES})
+ set_property(SOURCE CMakeSetup.cxx
+ PROPERTY COMPILE_DEFINITIONS USE_QWindowsIntegrationPlugin)
+endif()
- # We need to install platform plugin and add qt.conf for Qt5 on Mac and Windows.
- # FIXME: This should be part of Qt5 CMake scripts, but unfortunately
- # Qt5 support is missing there.
- if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32))
- macro(install_qt5_plugin _qt_plugin_name _qt_plugins_var)
- get_target_property(_qt_plugin_path "${_qt_plugin_name}" LOCATION)
- if(EXISTS "${_qt_plugin_path}")
- get_filename_component(_qt_plugin_file "${_qt_plugin_path}" NAME)
- get_filename_component(_qt_plugin_type "${_qt_plugin_path}" PATH)
- get_filename_component(_qt_plugin_type "${_qt_plugin_type}" NAME)
- if(APPLE)
- set(_qt_plugin_dir "PlugIns")
- elseif(WIN32)
- set(_qt_plugin_dir "plugins")
- endif()
- set(_qt_plugin_dest "${_qt_plugin_dir}/${_qt_plugin_type}")
- install(FILES "${_qt_plugin_path}"
- DESTINATION "${_qt_plugin_dest}"
- ${COMPONENT})
- set(${_qt_plugins_var}
- "${${_qt_plugins_var}};\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${_qt_plugin_dest}/${_qt_plugin_file}")
- else()
- message(FATAL_ERROR "QT plugin ${_qt_plugin_name} not found")
+# We need to install platform plugin and add qt.conf for Qt5 on Mac and Windows.
+# FIXME: This should be part of Qt5 CMake scripts, but unfortunately
+# Qt5 support is missing there.
+if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32))
+ macro(install_qt5_plugin _qt_plugin_name _qt_plugins_var)
+ get_target_property(_qt_plugin_path "${_qt_plugin_name}" LOCATION)
+ if(EXISTS "${_qt_plugin_path}")
+ get_filename_component(_qt_plugin_file "${_qt_plugin_path}" NAME)
+ get_filename_component(_qt_plugin_type "${_qt_plugin_path}" PATH)
+ get_filename_component(_qt_plugin_type "${_qt_plugin_type}" NAME)
+ if(APPLE)
+ set(_qt_plugin_dir "PlugIns")
+ elseif(WIN32)
+ set(_qt_plugin_dir "plugins")
endif()
- endmacro()
- if(APPLE)
- install_qt5_plugin("Qt5::QCocoaIntegrationPlugin" QT_PLUGINS)
- file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
- "[Paths]\nPlugins = ${_qt_plugin_dir}\n")
- install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
- DESTINATION "${CMAKE_INSTALL_PREFIX}/Resources"
+ set(_qt_plugin_dest "${_qt_plugin_dir}/${_qt_plugin_type}")
+ install(FILES "${_qt_plugin_path}"
+ DESTINATION "${_qt_plugin_dest}"
${COMPONENT})
- elseif(WIN32 AND NOT CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES)
- install_qt5_plugin("Qt5::QWindowsIntegrationPlugin" QT_PLUGINS)
- file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
- "[Paths]\nPlugins = ../${_qt_plugin_dir}\n")
- install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
- DESTINATION bin
- ${COMPONENT})
- endif()
- endif()
-
- if(TARGET Qt5::Core)
- get_property(_Qt5_Core_LOCATION TARGET Qt5::Core PROPERTY LOCATION)
- get_filename_component(Qt_BIN_DIR "${_Qt5_Core_LOCATION}" PATH)
- if(APPLE)
- get_filename_component(Qt_BIN_DIR "${Qt_BIN_DIR}" PATH)
+ set(${_qt_plugins_var}
+ "${${_qt_plugins_var}};\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${_qt_plugin_dest}/${_qt_plugin_file}")
+ else()
+ message(FATAL_ERROR "QT plugin ${_qt_plugin_name} not found")
endif()
+ endmacro()
+ if(APPLE)
+ install_qt5_plugin("Qt5::QCocoaIntegrationPlugin" QT_PLUGINS)
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+ "[Paths]\nPlugins = ${_qt_plugin_dir}\n")
+ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+ DESTINATION "${CMAKE_INSTALL_PREFIX}/Resources"
+ ${COMPONENT})
+ elseif(WIN32 AND NOT CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES)
+ install_qt5_plugin("Qt5::QWindowsIntegrationPlugin" QT_PLUGINS)
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+ "[Paths]\nPlugins = ../${_qt_plugin_dir}\n")
+ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+ DESTINATION bin
+ ${COMPONENT})
endif()
-else()
- set(QT_MIN_VERSION "4.4.0")
- find_package(Qt4 REQUIRED)
- if(NOT QT4_FOUND)
- message(SEND_ERROR "Failed to find Qt 4.4 or greater.")
- return()
- endif()
-
- include(${QT_USE_FILE})
-
- set(CMake_QT_LIBRARIES ${QT_LIBRARIES})
+endif()
+get_property(_Qt5_Core_LOCATION TARGET Qt5::Core PROPERTY LOCATION)
+get_filename_component(Qt_BIN_DIR "${_Qt5_Core_LOCATION}" PATH)
+if(APPLE)
+ get_filename_component(Qt_BIN_DIR "${Qt_BIN_DIR}" PATH)
endif()
set(SRCS
@@ -116,6 +84,7 @@ set(SRCS
CMakeSetup.cxx
CMakeSetupDialog.cxx
CMakeSetupDialog.h
+ Compilers.h
FirstConfigure.cxx
FirstConfigure.h
QCMake.cxx
@@ -129,7 +98,7 @@ set(SRCS
WarningMessagesDialog.cxx
WarningMessagesDialog.h
)
-QT4_WRAP_UI(UI_SRCS
+qt5_wrap_ui(UI_SRCS
CMakeSetupDialog.ui
Compilers.ui
CrossCompiler.ui
@@ -137,7 +106,7 @@ QT4_WRAP_UI(UI_SRCS
RegexExplorer.ui
WarningMessagesDialog.ui
)
-QT4_WRAP_CPP(MOC_SRCS
+qt5_wrap_cpp(MOC_SRCS
AddCacheEntry.h
Compilers.h
CMakeSetupDialog.h
@@ -148,14 +117,24 @@ QT4_WRAP_CPP(MOC_SRCS
RegexExplorer.h
WarningMessagesDialog.h
)
-QT4_ADD_RESOURCES(RC_SRCS CMakeSetup.qrc)
+qt5_add_resources(RC_SRCS CMakeSetup.qrc)
+
+if (FALSE) # CMake's bootstrap binary does not support automoc
+ set(CMAKE_AUTOMOC 1)
+ set(CMAKE_AUTORCC 1)
+ set(CMAKE_AUTOUIC 1)
+else ()
+ list(APPEND SRCS
+ ${UI_SRCS}
+ ${MOC_SRCS}
+ ${RC_SRCS})
+endif ()
-set(SRCS ${SRCS} ${UI_SRCS} ${MOC_SRCS} ${RC_SRCS})
if(WIN32)
- set(SRCS ${SRCS} CMakeSetup.rc)
+ list(APPEND SRCS CMakeSetup.rc)
endif()
if(APPLE)
- set(SRCS ${SRCS} CMakeSetup.icns)
+ list(APPEND SRCS CMakeSetup.icns)
set(MACOSX_BUNDLE_ICON_FILE CMakeSetup.icns)
set_source_files_properties(CMakeSetup.icns PROPERTIES
MACOSX_PACKAGE_LOCATION Resources)
@@ -172,7 +151,7 @@ endif()
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(cmake-gui WIN32 MACOSX_BUNDLE ${SRCS} ${MANIFEST_FILE})
-target_link_libraries(cmake-gui CMakeLib ${QT_QTMAIN_LIBRARY} ${CMake_QT_LIBRARIES})
+target_link_libraries(cmake-gui CMakeLib Qt5::Core Qt5::Widgets ${CMake_QT_EXTRA_LIBRARIES})
if(WIN32)
target_sources(cmake-gui PRIVATE $<TARGET_OBJECTS:CMakeVersion>)
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx
index 9d928b2..7ef5a72 100644
--- a/Source/QtDialog/CMakeSetup.cxx
+++ b/Source/QtDialog/CMakeSetup.cxx
@@ -115,14 +115,6 @@ int main(int argc, char** argv)
QTextCodec* utf8_codec = QTextCodec::codecForName("UTF-8");
QTextCodec::setCodecForLocale(utf8_codec);
-#if QT_VERSION < 0x050000
- // clean out standard Qt paths for plugins, which we don't use anyway
- // when creating Mac bundles, it potentially causes problems
- foreach (QString p, QApplication::libraryPaths()) {
- QApplication::removeLibraryPath(p);
- }
-#endif
-
// tell the cmake library where cmake is
QDir cmExecDir(QApplication::applicationDirPath());
#if defined(Q_OS_MAC)
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx
index 776af81..f0b967b 100644
--- a/Source/QtDialog/QCMake.cxx
+++ b/Source/QtDialog/QCMake.cxx
@@ -340,10 +340,10 @@ void QCMake::interrupt()
bool QCMake::interruptCallback()
{
-#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
- return this->InterruptFlag;
-#else
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
return this->InterruptFlag.load();
+#else
+ return this->InterruptFlag.loadRelaxed();
#endif
}
diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx
index 541d3e9..928494b 100644
--- a/Source/QtDialog/QCMakeCacheView.cxx
+++ b/Source/QtDialog/QCMakeCacheView.cxx
@@ -155,11 +155,7 @@ QModelIndex QCMakeCacheView::moveCursor(CursorAction act,
void QCMakeCacheView::setShowAdvanced(bool s)
{
-#if QT_VERSION >= 040300
- // new 4.3 API that needs to be called. what about an older Qt?
this->SearchFilter->invalidate();
-#endif
-
this->AdvancedFilter->setShowAdvanced(s);
}
@@ -209,9 +205,7 @@ void QCMakeCacheModel::clear()
void QCMakeCacheModel::setProperties(const QCMakePropertyList& props)
{
-#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
this->beginResetModel();
-#endif
QSet<QCMakeProperty> newProps;
QSet<QCMakeProperty> newProps2;
@@ -334,11 +328,7 @@ void QCMakeCacheModel::setProperties(const QCMakePropertyList& props)
}
this->blockSignals(b);
-#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
this->endResetModel();
-#else
- this->reset();
-#endif
}
QCMakeCacheModel::ViewType QCMakeCacheModel::viewType() const
@@ -348,9 +338,7 @@ QCMakeCacheModel::ViewType QCMakeCacheModel::viewType() const
void QCMakeCacheModel::setViewType(QCMakeCacheModel::ViewType t)
{
-#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
this->beginResetModel();
-#endif
this->View = t;
@@ -367,11 +355,7 @@ void QCMakeCacheModel::setViewType(QCMakeCacheModel::ViewType t)
this->setProperties(oldProps);
this->setProperties(props);
this->blockSignals(b);
-#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
this->endResetModel();
-#else
- this->reset();
-#endif
}
void QCMakeCacheModel::setPropertyData(const QModelIndex& idx1,
@@ -497,8 +481,7 @@ QCMakePropertyList QCMakeCacheModel::properties() const
// go to the next in the tree
while (!idxs.isEmpty() &&
(
-#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) && \
- QT_VERSION < QT_VERSION_CHECK(5, 1, 0)
+#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0)
(idxs.last().row() + 1) >= rowCount(idxs.last().parent()) ||
#endif
!idxs.last().sibling(idxs.last().row() + 1, 0).isValid())) {
@@ -658,20 +641,6 @@ bool QCMakeCacheModelDelegate::editorEvent(QEvent* e,
return success;
}
-// Issue 205903 fixed in Qt 4.5.0.
-// Can remove this function and FileDialogFlag when minimum Qt version is 4.5
-bool QCMakeCacheModelDelegate::eventFilter(QObject* object, QEvent* evt)
-{
- // workaround for what looks like a bug in Qt on macOS
- // where it doesn't create a QWidget wrapper for the native file dialog
- // so the Qt library ends up assuming the focus was lost to something else
-
- if (evt->type() == QEvent::FocusOut && this->FileDialogFlag) {
- return false;
- }
- return QItemDelegate::eventFilter(object, evt);
-}
-
void QCMakeCacheModelDelegate::setModelData(QWidget* editor,
QAbstractItemModel* model,
const QModelIndex& index) const
diff --git a/Source/QtDialog/QCMakeCacheView.h b/Source/QtDialog/QCMakeCacheView.h
index bea1965..a252708 100644
--- a/Source/QtDialog/QCMakeCacheView.h
+++ b/Source/QtDialog/QCMakeCacheView.h
@@ -144,7 +144,6 @@ public:
bool editorEvent(QEvent* event, QAbstractItemModel* model,
const QStyleOptionViewItem& option,
const QModelIndex& index);
- bool eventFilter(QObject* object, QEvent* event);
void setModelData(QWidget* editor, QAbstractItemModel* model,
const QModelIndex& index) const;
QSize sizeHint(const QStyleOptionViewItem& option,
diff --git a/Source/QtDialog/QCMakeWidgets.cxx b/Source/QtDialog/QCMakeWidgets.cxx
index 332a770..d16ea58 100644
--- a/Source/QtDialog/QCMakeWidgets.cxx
+++ b/Source/QtDialog/QCMakeWidgets.cxx
@@ -4,9 +4,9 @@
#include <utility>
-#include <QDirModel>
#include <QFileDialog>
#include <QFileInfo>
+#include <QFileSystemModel>
#include <QResizeEvent>
#include <QToolButton>
@@ -88,20 +88,20 @@ void QCMakePathEditor::chooseFile()
}
}
-// use same QDirModel for all completers
-static QDirModel* fileDirModel()
+// use same QFileSystemModel for all completers
+static QFileSystemModel* fileDirModel()
{
- static QDirModel* m = nullptr;
+ static QFileSystemModel* m = nullptr;
if (!m) {
- m = new QDirModel();
+ m = new QFileSystemModel();
}
return m;
}
-static QDirModel* pathDirModel()
+static QFileSystemModel* pathDirModel()
{
- static QDirModel* m = nullptr;
+ static QFileSystemModel* m = nullptr;
if (!m) {
- m = new QDirModel();
+ m = new QFileSystemModel();
m->setFilter(QDir::AllDirs | QDir::Drives | QDir::NoDotAndDotDot);
}
return m;
@@ -110,7 +110,7 @@ static QDirModel* pathDirModel()
QCMakeFileCompleter::QCMakeFileCompleter(QObject* o, bool dirs)
: QCompleter(o)
{
- QDirModel* m = dirs ? pathDirModel() : fileDirModel();
+ QFileSystemModel* m = dirs ? pathDirModel() : fileDirModel();
this->setModel(m);
}
diff --git a/Source/cmAuxSourceDirectoryCommand.cxx b/Source/cmAuxSourceDirectoryCommand.cxx
index d6f7500e..53d4cb4 100644
--- a/Source/cmAuxSourceDirectoryCommand.cxx
+++ b/Source/cmAuxSourceDirectoryCommand.cxx
@@ -55,7 +55,7 @@ bool cmAuxSourceDirectoryCommand(std::vector<std::string> const& args,
auto ext = cm::string_view(file).substr(dotpos + 1);
// Process only source files
auto cm = mf.GetCMakeInstance();
- if (dotpos > 0 && cm->IsSourceExtension(ext)) {
+ if (dotpos > 0 && cm->IsACLikeSourceExtension(ext)) {
std::string fullname = cmStrCat(templateDirectory, '/', file);
// add the file as a class file so
// depends can be done
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index a7acadc..7fbe90e 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -25,77 +25,205 @@
#include "cmVersion.h"
#include "cmake.h"
-static std::string const kCMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN =
- "CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN";
-static std::string const kCMAKE_C_COMPILER_TARGET = "CMAKE_C_COMPILER_TARGET";
-static std::string const kCMAKE_C_LINK_NO_PIE_SUPPORTED =
- "CMAKE_C_LINK_NO_PIE_SUPPORTED";
-static std::string const kCMAKE_C_LINK_PIE_SUPPORTED =
- "CMAKE_C_LINK_PIE_SUPPORTED";
-static std::string const kCMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN =
- "CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN";
-static std::string const kCMAKE_CXX_COMPILER_TARGET =
- "CMAKE_CXX_COMPILER_TARGET";
-static std::string const kCMAKE_CXX_LINK_NO_PIE_SUPPORTED =
- "CMAKE_CXX_LINK_NO_PIE_SUPPORTED";
-static std::string const kCMAKE_CXX_LINK_PIE_SUPPORTED =
- "CMAKE_CXX_LINK_PIE_SUPPORTED";
-static std::string const kCMAKE_CUDA_ARCHITECTURES =
- "CMAKE_CUDA_ARCHITECTURES";
-static std::string const kCMAKE_CUDA_COMPILER_TARGET =
- "CMAKE_CUDA_COMPILER_TARGET";
-static std::string const kCMAKE_CUDA_RUNTIME_LIBRARY =
- "CMAKE_CUDA_RUNTIME_LIBRARY";
-static std::string const kCMAKE_ENABLE_EXPORTS = "CMAKE_ENABLE_EXPORTS";
-static std::string const kCMAKE_LINK_SEARCH_END_STATIC =
+namespace {
+class LanguageStandardState
+{
+public:
+ LanguageStandardState(std::string&& lang)
+ : IsEnabled(false)
+ , DidStandard(false)
+ , DidStandardRequired(false)
+ , DidExtensions(false)
+ , StandardFlag(lang + "_STANDARD")
+ , RequiredFlag(lang + "_STANDARD_REQUIRED")
+ , ExtensionFlag(lang + "_EXTENSIONS")
+ {
+ }
+
+ void Enabled(bool isEnabled) { this->IsEnabled = isEnabled; }
+
+ bool UpdateIfMatches(std::vector<std::string> const& argv, size_t& index)
+ {
+ bool updated = false;
+ if (argv[index] == this->StandardFlag) {
+ this->DidStandard = true;
+ this->StandardValue = argv[++index];
+ updated = true;
+ } else if (argv[index] == this->RequiredFlag) {
+ this->DidStandardRequired = true;
+ this->RequiredValue = argv[++index];
+ updated = true;
+ } else if (argv[index] == this->ExtensionFlag) {
+ this->DidExtensions = true;
+ this->ExtensionValue = argv[++index];
+ updated = true;
+ }
+ return updated;
+ }
+
+ bool Validate(cmMakefile* const makefile) const
+ {
+ if (this->DidStandard) {
+ makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(this->StandardFlag,
+ " allowed only in source file signature."));
+ return false;
+ }
+ if (this->DidStandardRequired) {
+ makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(this->RequiredFlag,
+ " allowed only in source file signature."));
+ return false;
+ }
+ if (this->DidExtensions) {
+ makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(this->ExtensionFlag,
+ " allowed only in source file signature."));
+ return false;
+ }
+
+ return true;
+ }
+
+ bool DidNone() const
+ {
+ return !this->DidStandard && !this->DidStandardRequired &&
+ !this->DidExtensions;
+ }
+
+ void LoadUnsetPropertyValues(cmMakefile* const makefile, bool honorStandard,
+ bool warnCMP0067,
+ std::vector<std::string>& warnCMP0067Variables)
+ {
+ if (!this->IsEnabled) {
+ return;
+ }
+
+ auto lookupStdVar = [&](std::string const& var) -> std::string {
+ std::string value = makefile->GetSafeDefinition(var);
+ if (warnCMP0067 && !value.empty()) {
+ value.clear();
+ warnCMP0067Variables.push_back(var);
+ }
+ return value;
+ };
+
+ if (honorStandard || warnCMP0067) {
+ if (!this->DidStandard) {
+ this->StandardValue =
+ lookupStdVar(cmStrCat("CMAKE_", this->StandardFlag));
+ }
+ if (!this->DidStandardRequired) {
+ this->RequiredValue =
+ lookupStdVar(cmStrCat("CMAKE_", this->RequiredFlag));
+ }
+ if (!this->DidExtensions) {
+ this->ExtensionValue =
+ lookupStdVar(cmStrCat("CMAKE_", this->ExtensionFlag));
+ }
+ }
+ }
+
+ void WriteProperties(FILE* fout, std::string const& targetName) const
+ {
+ if (!this->IsEnabled) {
+ return;
+ }
+
+ auto writeProp = [&](std::string const& prop, std::string const& value) {
+ fprintf(fout, "set_property(TARGET %s PROPERTY %s %s)\n",
+ targetName.c_str(),
+ cmOutputConverter::EscapeForCMake(prop).c_str(),
+ cmOutputConverter::EscapeForCMake(value).c_str());
+ };
+
+ if (!this->StandardValue.empty()) {
+ writeProp(this->StandardFlag, this->StandardValue);
+ }
+ if (!this->RequiredValue.empty()) {
+ writeProp(this->RequiredFlag, this->RequiredValue);
+ }
+ if (!this->ExtensionValue.empty()) {
+ writeProp(this->ExtensionFlag, this->ExtensionValue);
+ }
+ }
+
+private:
+ bool IsEnabled;
+ bool DidStandard;
+ bool DidStandardRequired;
+ bool DidExtensions;
+
+ std::string StandardFlag;
+ std::string RequiredFlag;
+ std::string ExtensionFlag;
+
+ std::string StandardValue;
+ std::string RequiredValue;
+ std::string ExtensionValue;
+};
+
+constexpr size_t lang_property_start = 0;
+constexpr size_t lang_property_size = 4;
+constexpr size_t pie_property_start = 4;
+constexpr size_t pie_property_size = 2;
+#define SETUP_LANGUAGE(name, lang) \
+ static const std::string name[lang_property_size + pie_property_size + 1] = \
+ { "CMAKE_" #lang "_COMPILER_EXTERNAL_TOOLCHAIN", \
+ "CMAKE_" #lang "_COMPILER_TARGET", \
+ "CMAKE_" #lang "_LINK_NO_PIE_SUPPORTED", \
+ "CMAKE_" #lang "_PIE_SUPPORTED", "" }
+
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(c_properties, C);
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(cxx_properties, CXX);
+
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(cuda_properties, CUDA);
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(fortran_properties, Fortran);
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(objc_properties, OBJC);
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(objcxx_properties, OBJCXX);
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(swift_properties, Swift);
+#undef SETUP_LANGUAGE
+
+std::string const kCMAKE_CUDA_ARCHITECTURES = "CMAKE_CUDA_ARCHITECTURES";
+std::string const kCMAKE_CUDA_RUNTIME_LIBRARY = "CMAKE_CUDA_RUNTIME_LIBRARY";
+std::string const kCMAKE_ENABLE_EXPORTS = "CMAKE_ENABLE_EXPORTS";
+std::string const kCMAKE_LINK_SEARCH_END_STATIC =
"CMAKE_LINK_SEARCH_END_STATIC";
-static std::string const kCMAKE_LINK_SEARCH_START_STATIC =
+std::string const kCMAKE_LINK_SEARCH_START_STATIC =
"CMAKE_LINK_SEARCH_START_STATIC";
-static std::string const kCMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT =
+std::string const kCMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT =
"CMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT";
-static std::string const kCMAKE_OSX_ARCHITECTURES = "CMAKE_OSX_ARCHITECTURES";
-static std::string const kCMAKE_OSX_DEPLOYMENT_TARGET =
- "CMAKE_OSX_DEPLOYMENT_TARGET";
-static std::string const kCMAKE_OSX_SYSROOT = "CMAKE_OSX_SYSROOT";
-static std::string const kCMAKE_APPLE_ARCH_SYSROOTS =
- "CMAKE_APPLE_ARCH_SYSROOTS";
-static std::string const kCMAKE_POSITION_INDEPENDENT_CODE =
+std::string const kCMAKE_OSX_ARCHITECTURES = "CMAKE_OSX_ARCHITECTURES";
+std::string const kCMAKE_OSX_DEPLOYMENT_TARGET = "CMAKE_OSX_DEPLOYMENT_TARGET";
+std::string const kCMAKE_OSX_SYSROOT = "CMAKE_OSX_SYSROOT";
+std::string const kCMAKE_APPLE_ARCH_SYSROOTS = "CMAKE_APPLE_ARCH_SYSROOTS";
+std::string const kCMAKE_POSITION_INDEPENDENT_CODE =
"CMAKE_POSITION_INDEPENDENT_CODE";
-static std::string const kCMAKE_SYSROOT = "CMAKE_SYSROOT";
-static std::string const kCMAKE_SYSROOT_COMPILE = "CMAKE_SYSROOT_COMPILE";
-static std::string const kCMAKE_SYSROOT_LINK = "CMAKE_SYSROOT_LINK";
-static std::string const kCMAKE_Swift_COMPILER_TARGET =
- "CMAKE_Swift_COMPILER_TARGET";
-static std::string const kCMAKE_TRY_COMPILE_OSX_ARCHITECTURES =
+std::string const kCMAKE_SYSROOT = "CMAKE_SYSROOT";
+std::string const kCMAKE_SYSROOT_COMPILE = "CMAKE_SYSROOT_COMPILE";
+std::string const kCMAKE_SYSROOT_LINK = "CMAKE_SYSROOT_LINK";
+std::string const kCMAKE_TRY_COMPILE_OSX_ARCHITECTURES =
"CMAKE_TRY_COMPILE_OSX_ARCHITECTURES";
-static std::string const kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES =
+std::string const kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES =
"CMAKE_TRY_COMPILE_PLATFORM_VARIABLES";
-static std::string const kCMAKE_WARN_DEPRECATED = "CMAKE_WARN_DEPRECATED";
+std::string const kCMAKE_WARN_DEPRECATED = "CMAKE_WARN_DEPRECATED";
/* GHS Multi platform variables */
-static std::set<std::string> ghs_platform_vars{
+std::set<std::string> const ghs_platform_vars{
"GHS_TARGET_PLATFORM", "GHS_PRIMARY_TARGET", "GHS_TOOLSET_ROOT",
"GHS_OS_ROOT", "GHS_OS_DIR", "GHS_BSP_NAME",
"GHS_OS_DIR_OPTION"
};
-
-static void writeProperty(FILE* fout, std::string const& targetName,
- std::string const& prop, std::string const& value)
-{
- fprintf(fout, "set_property(TARGET %s PROPERTY %s %s)\n", targetName.c_str(),
- cmOutputConverter::EscapeForCMake(prop).c_str(),
- cmOutputConverter::EscapeForCMake(value).c_str());
-}
-
-std::string cmCoreTryCompile::LookupStdVar(std::string const& var,
- bool warnCMP0067)
-{
- std::string value = this->Makefile->GetSafeDefinition(var);
- if (warnCMP0067 && !value.empty()) {
- value.clear();
- this->WarnCMP0067.push_back(var);
- }
- return value;
}
int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
@@ -137,21 +265,11 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
std::string outputVariable;
std::string copyFile;
std::string copyFileError;
- std::string cStandard;
- std::string objcStandard;
- std::string cxxStandard;
- std::string objcxxStandard;
- std::string cudaStandard;
- std::string cStandardRequired;
- std::string cxxStandardRequired;
- std::string objcStandardRequired;
- std::string objcxxStandardRequired;
- std::string cudaStandardRequired;
- std::string cExtensions;
- std::string cxxExtensions;
- std::string objcExtensions;
- std::string objcxxExtensions;
- std::string cudaExtensions;
+ LanguageStandardState cState("C");
+ LanguageStandardState cudaState("CUDA");
+ LanguageStandardState cxxState("CXX");
+ LanguageStandardState objcState("OBJC");
+ LanguageStandardState objcxxState("OBJCXX");
std::vector<std::string> targets;
std::vector<std::string> linkOptions;
std::string libsToLink = " ";
@@ -160,21 +278,6 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
bool didOutputVariable = false;
bool didCopyFile = false;
bool didCopyFileError = false;
- bool didCStandard = false;
- bool didCxxStandard = false;
- bool didObjCStandard = false;
- bool didObjCxxStandard = false;
- bool didCudaStandard = false;
- bool didCStandardRequired = false;
- bool didCxxStandardRequired = false;
- bool didObjCStandardRequired = false;
- bool didObjCxxStandardRequired = false;
- bool didCudaStandardRequired = false;
- bool didCExtensions = false;
- bool didCxxExtensions = false;
- bool didObjCExtensions = false;
- bool didObjCxxExtensions = false;
- bool didCudaExtensions = false;
bool useSources = argv[2] == "SOURCES";
std::vector<std::string> sources;
@@ -188,21 +291,6 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
DoingOutputVariable,
DoingCopyFile,
DoingCopyFileError,
- DoingCStandard,
- DoingCxxStandard,
- DoingObjCStandard,
- DoingObjCxxStandard,
- DoingCudaStandard,
- DoingCStandardRequired,
- DoingCxxStandardRequired,
- DoingObjCStandardRequired,
- DoingObjCxxStandardRequired,
- DoingCudaStandardRequired,
- DoingCExtensions,
- DoingCxxExtensions,
- DoingObjCExtensions,
- DoingObjCxxExtensions,
- DoingCudaExtensions,
DoingSources,
DoingCMakeInternal
};
@@ -226,51 +314,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
} else if (argv[i] == "COPY_FILE_ERROR") {
doing = DoingCopyFileError;
didCopyFileError = true;
- } else if (argv[i] == "C_STANDARD") {
- doing = DoingCStandard;
- didCStandard = true;
- } else if (argv[i] == "CXX_STANDARD") {
- doing = DoingCxxStandard;
- didCxxStandard = true;
- } else if (argv[i] == "OBJC_STANDARD") {
- doing = DoingObjCStandard;
- didObjCStandard = true;
- } else if (argv[i] == "OBJCXX_STANDARD") {
- doing = DoingObjCxxStandard;
- didObjCxxStandard = true;
- } else if (argv[i] == "CUDA_STANDARD") {
- doing = DoingCudaStandard;
- didCudaStandard = true;
- } else if (argv[i] == "C_STANDARD_REQUIRED") {
- doing = DoingCStandardRequired;
- didCStandardRequired = true;
- } else if (argv[i] == "CXX_STANDARD_REQUIRED") {
- doing = DoingCxxStandardRequired;
- didCxxStandardRequired = true;
- } else if (argv[i] == "OBJC_STANDARD_REQUIRED") {
- doing = DoingObjCStandardRequired;
- didObjCStandardRequired = true;
- } else if (argv[i] == "OBJCXX_STANDARD_REQUIRED") {
- doing = DoingObjCxxStandardRequired;
- didObjCxxStandardRequired = true;
- } else if (argv[i] == "CUDA_STANDARD_REQUIRED") {
- doing = DoingCudaStandardRequired;
- didCudaStandardRequired = true;
- } else if (argv[i] == "C_EXTENSIONS") {
- doing = DoingCExtensions;
- didCExtensions = true;
- } else if (argv[i] == "CXX_EXTENSIONS") {
- doing = DoingCxxExtensions;
- didCxxExtensions = true;
- } else if (argv[i] == "OBJC_EXTENSIONS") {
- doing = DoingObjCExtensions;
- didObjCExtensions = true;
- } else if (argv[i] == "OBJCXX_EXTENSIONS") {
- doing = DoingObjCxxExtensions;
- didObjCxxExtensions = true;
- } else if (argv[i] == "CUDA_EXTENSIONS") {
- doing = DoingCudaExtensions;
- didCudaExtensions = true;
+ } else if (cState.UpdateIfMatches(argv, i) ||
+ cxxState.UpdateIfMatches(argv, i) ||
+ cudaState.UpdateIfMatches(argv, i) ||
+ objcState.UpdateIfMatches(argv, i) ||
+ objcxxState.UpdateIfMatches(argv, i)) {
+ continue;
} else if (argv[i] == "__CMAKE_INTERNAL") {
doing = DoingCMakeInternal;
} else if (doing == DoingCMakeFlags) {
@@ -315,51 +364,6 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
} else if (doing == DoingCopyFileError) {
copyFileError = argv[i];
doing = DoingNone;
- } else if (doing == DoingCStandard) {
- cStandard = argv[i];
- doing = DoingNone;
- } else if (doing == DoingCxxStandard) {
- cxxStandard = argv[i];
- doing = DoingNone;
- } else if (doing == DoingObjCStandard) {
- objcStandard = argv[i];
- doing = DoingNone;
- } else if (doing == DoingObjCxxStandard) {
- objcxxStandard = argv[i];
- doing = DoingNone;
- } else if (doing == DoingCudaStandard) {
- cudaStandard = argv[i];
- doing = DoingNone;
- } else if (doing == DoingCStandardRequired) {
- cStandardRequired = argv[i];
- doing = DoingNone;
- } else if (doing == DoingCxxStandardRequired) {
- cxxStandardRequired = argv[i];
- doing = DoingNone;
- } else if (doing == DoingObjCStandardRequired) {
- objcStandardRequired = argv[i];
- doing = DoingNone;
- } else if (doing == DoingObjCxxStandardRequired) {
- objcxxStandardRequired = argv[i];
- doing = DoingNone;
- } else if (doing == DoingCudaStandardRequired) {
- cudaStandardRequired = argv[i];
- doing = DoingNone;
- } else if (doing == DoingCExtensions) {
- cExtensions = argv[i];
- doing = DoingNone;
- } else if (doing == DoingCxxExtensions) {
- cxxExtensions = argv[i];
- doing = DoingNone;
- } else if (doing == DoingObjCExtensions) {
- objcExtensions = argv[i];
- doing = DoingNone;
- } else if (doing == DoingObjCxxExtensions) {
- objcxxExtensions = argv[i];
- doing = DoingNone;
- } else if (doing == DoingCudaExtensions) {
- cudaExtensions = argv[i];
- doing = DoingNone;
} else if (doing == DoingSources) {
sources.push_back(argv[i]);
} else if (doing == DoingCMakeInternal) {
@@ -411,59 +415,22 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
return -1;
}
- if (didCStandard && !this->SrcFileSignature) {
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "C_STANDARD allowed only in source file signature.");
- return -1;
- }
- if (didCxxStandard && !this->SrcFileSignature) {
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "CXX_STANDARD allowed only in source file signature.");
- return -1;
- }
- if (didCudaStandard && !this->SrcFileSignature) {
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "CUDA_STANDARD allowed only in source file signature.");
- return -1;
- }
- if (didCStandardRequired && !this->SrcFileSignature) {
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "C_STANDARD_REQUIRED allowed only in source file signature.");
- return -1;
- }
- if (didCxxStandardRequired && !this->SrcFileSignature) {
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "CXX_STANDARD_REQUIRED allowed only in source file signature.");
- return -1;
- }
- if (didCudaStandardRequired && !this->SrcFileSignature) {
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "CUDA_STANDARD_REQUIRED allowed only in source file signature.");
- return -1;
- }
- if (didCExtensions && !this->SrcFileSignature) {
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "C_EXTENSIONS allowed only in source file signature.");
- return -1;
- }
- if (didCxxExtensions && !this->SrcFileSignature) {
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "CXX_EXTENSIONS allowed only in source file signature.");
- return -1;
- }
- if (didCudaExtensions && !this->SrcFileSignature) {
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "CUDA_EXTENSIONS allowed only in source file signature.");
- return -1;
+ if (!this->SrcFileSignature) {
+ if (!cState.Validate(this->Makefile)) {
+ return -1;
+ }
+ if (!cudaState.Validate(this->Makefile)) {
+ return -1;
+ }
+ if (!cxxState.Validate(this->Makefile)) {
+ return -1;
+ }
+ if (!objcState.Validate(this->Makefile)) {
+ return -1;
+ }
+ if (!objcxxState.Validate(this->Makefile)) {
+ return -1;
+ }
}
// compute the binary dir when TRY_COMPILE is called with a src file
@@ -721,12 +688,23 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
// Forward a set of variables to the inner project cache.
{
std::set<std::string> vars;
- vars.insert(kCMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN);
- vars.insert(kCMAKE_C_COMPILER_TARGET);
- vars.insert(kCMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN);
- vars.insert(kCMAKE_CXX_COMPILER_TARGET);
+ vars.insert(&c_properties[lang_property_start],
+ &c_properties[lang_property_start + lang_property_size]);
+ vars.insert(&cxx_properties[lang_property_start],
+ &cxx_properties[lang_property_start + lang_property_size]);
+ vars.insert(&cuda_properties[lang_property_start],
+ &cuda_properties[lang_property_start + lang_property_size]);
+ vars.insert(
+ &fortran_properties[lang_property_start],
+ &fortran_properties[lang_property_start + lang_property_size]);
+ vars.insert(&objc_properties[lang_property_start],
+ &objc_properties[lang_property_start + lang_property_size]);
+ vars.insert(
+ &objcxx_properties[lang_property_start],
+ &objcxx_properties[lang_property_start + lang_property_size]);
+ vars.insert(&swift_properties[lang_property_start],
+ &swift_properties[lang_property_start + lang_property_size]);
vars.insert(kCMAKE_CUDA_ARCHITECTURES);
- vars.insert(kCMAKE_CUDA_COMPILER_TARGET);
vars.insert(kCMAKE_CUDA_RUNTIME_LIBRARY);
vars.insert(kCMAKE_ENABLE_EXPORTS);
vars.insert(kCMAKE_LINK_SEARCH_END_STATIC);
@@ -739,7 +717,6 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
vars.insert(kCMAKE_SYSROOT);
vars.insert(kCMAKE_SYSROOT_COMPILE);
vars.insert(kCMAKE_SYSROOT_LINK);
- vars.insert(kCMAKE_Swift_COMPILER_TARGET);
vars.insert(kCMAKE_WARN_DEPRECATED);
vars.emplace("CMAKE_MSVC_RUNTIME_LIBRARY"_s);
@@ -753,10 +730,22 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
cmPolicies::NEW) {
// To ensure full support of PIE, propagate cache variables
// driving the link options
- vars.insert(kCMAKE_C_LINK_PIE_SUPPORTED);
- vars.insert(kCMAKE_C_LINK_NO_PIE_SUPPORTED);
- vars.insert(kCMAKE_CXX_LINK_PIE_SUPPORTED);
- vars.insert(kCMAKE_CXX_LINK_NO_PIE_SUPPORTED);
+ vars.insert(&c_properties[pie_property_start],
+ &c_properties[pie_property_start + pie_property_size]);
+ vars.insert(&cxx_properties[pie_property_start],
+ &cxx_properties[pie_property_start + pie_property_size]);
+ vars.insert(&cuda_properties[pie_property_start],
+ &cuda_properties[pie_property_start + pie_property_size]);
+ vars.insert(
+ &fortran_properties[pie_property_start],
+ &fortran_properties[pie_property_start + pie_property_size]);
+ vars.insert(&objc_properties[pie_property_start],
+ &objc_properties[pie_property_start + pie_property_size]);
+ vars.insert(
+ &objcxx_properties[pie_property_start],
+ &objcxx_properties[pie_property_start + pie_property_size]);
+ vars.insert(&swift_properties[pie_property_start],
+ &swift_properties[pie_property_start + pie_property_size]);
}
/* for the TRY_COMPILEs we want to be able to specify the architecture.
@@ -819,21 +808,17 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
}
fprintf(fout, ")\n");
- bool const testC = testLangs.find("C") != testLangs.end();
- bool const testObjC = testLangs.find("OBJC") != testLangs.end();
- bool const testCxx = testLangs.find("CXX") != testLangs.end();
- bool const testObjCxx = testLangs.find("OBJCXX") != testLangs.end();
- bool const testCuda = testLangs.find("CUDA") != testLangs.end();
+ cState.Enabled(testLangs.find("C") != testLangs.end());
+ cxxState.Enabled(testLangs.find("CXX") != testLangs.end());
+ cudaState.Enabled(testLangs.find("CUDA") != testLangs.end());
+ objcState.Enabled(testLangs.find("OBJC") != testLangs.end());
+ objcxxState.Enabled(testLangs.find("OBJCXX") != testLangs.end());
bool warnCMP0067 = false;
bool honorStandard = true;
- if (!didCStandard && !didCxxStandard && !didObjCStandard &&
- !didObjCxxStandard && !didCudaStandard && !didCStandardRequired &&
- !didCxxStandardRequired && !didObjCStandardRequired &&
- !didObjCxxStandardRequired && !didCudaStandardRequired &&
- !didCExtensions && !didCxxExtensions && !didObjCExtensions &&
- !didObjCxxExtensions && !didCudaExtensions) {
+ if (cState.DidNone() && cxxState.DidNone() && objcState.DidNone() &&
+ objcxxState.DidNone() && cudaState.DidNone()) {
switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0067)) {
case cmPolicies::WARN:
warnCMP0067 = this->Makefile->PolicyOptionalWarningEnabled(
@@ -855,46 +840,20 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
}
}
- if (honorStandard || warnCMP0067) {
+ std::vector<std::string> warnCMP0067Variables;
- auto testLanguage =
- [&](bool testLang, bool didLangStandard, bool didLangStandardRequired,
- bool didLangExtensions, std::string& langStandard,
- std::string& langStandardRequired, std::string& langExtensions,
- const std::string& lang) {
- if (testLang) {
- if (!didLangStandard) {
- langStandard = this->LookupStdVar(
- cmStrCat("CMAKE_", lang, "_STANDARD"), warnCMP0067);
- }
- if (!didLangStandardRequired) {
- langStandardRequired = this->LookupStdVar(
- cmStrCat("CMAKE_", lang, "_STANDARD_REQUIRED"), warnCMP0067);
- }
- if (!didLangExtensions) {
- langExtensions = this->LookupStdVar(
- cmStrCat("CMAKE_", lang, "_EXTENSIONS"), warnCMP0067);
- }
- }
- };
-
- testLanguage(testC, didCStandard, didCStandardRequired, didCExtensions,
- cStandard, cStandardRequired, cExtensions, "C");
- testLanguage(testObjC, didObjCStandard, didObjCStandardRequired,
- didObjCExtensions, objcStandard, objcStandardRequired,
- objcExtensions, "OBJC");
- testLanguage(testCxx, didCxxStandard, didCxxStandardRequired,
- didCxxExtensions, cxxStandard, cxxStandardRequired,
- cxxExtensions, "CXX");
- testLanguage(testObjCxx, didObjCxxStandard, didObjCxxStandardRequired,
- didObjCxxExtensions, objcxxStandard, objcxxStandardRequired,
- objcxxExtensions, "OBJCXX");
- testLanguage(testCuda, didCudaStandard, didCudaStandardRequired,
- didCudaExtensions, cudaStandard, cudaStandardRequired,
- cudaExtensions, "CUDA");
- }
+ cState.LoadUnsetPropertyValues(this->Makefile, honorStandard, warnCMP0067,
+ warnCMP0067Variables);
+ cxxState.LoadUnsetPropertyValues(this->Makefile, honorStandard,
+ warnCMP0067, warnCMP0067Variables);
+ cudaState.LoadUnsetPropertyValues(this->Makefile, honorStandard,
+ warnCMP0067, warnCMP0067Variables);
+ objcState.LoadUnsetPropertyValues(this->Makefile, honorStandard,
+ warnCMP0067, warnCMP0067Variables);
+ objcxxState.LoadUnsetPropertyValues(this->Makefile, honorStandard,
+ warnCMP0067, warnCMP0067Variables);
- if (!this->WarnCMP0067.empty()) {
+ if (!warnCMP0067Variables.empty()) {
std::ostringstream w;
/* clang-format off */
w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0067) << "\n"
@@ -902,43 +861,17 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
"is not honoring language standard variables in the test project:\n"
;
/* clang-format on */
- for (std::string const& vi : this->WarnCMP0067) {
+ for (std::string const& vi : warnCMP0067Variables) {
w << " " << vi << "\n";
}
this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
}
- auto writeLanguageProperties = [&](bool testLang,
- const std::string& langStandard,
- const std::string& langStandardRequired,
- const std::string& langExtensions,
- const std::string& lang) {
- if (testLang) {
- if (!langStandard.empty()) {
- writeProperty(fout, targetName, cmStrCat(lang, "_STANDARD"),
- langStandard);
- }
- if (!langStandardRequired.empty()) {
- writeProperty(fout, targetName, cmStrCat(lang, "_STANDARD_REQUIRED"),
- langStandardRequired);
- }
- if (!langExtensions.empty()) {
- writeProperty(fout, targetName, cmStrCat(lang, "_EXTENSIONS"),
- langExtensions);
- }
- }
- };
-
- writeLanguageProperties(testC, cStandard, cStandardRequired, cExtensions,
- "C");
- writeLanguageProperties(testObjC, objcStandard, objcStandardRequired,
- objcExtensions, "OBJC");
- writeLanguageProperties(testCxx, cxxStandard, cxxStandardRequired,
- cxxExtensions, "CXX");
- writeLanguageProperties(testObjCxx, objcxxStandard, objcxxStandardRequired,
- objcxxExtensions, "OBJCXX");
- writeLanguageProperties(testCuda, cudaStandard, cudaStandardRequired,
- cudaExtensions, "CUDA");
+ cState.WriteProperties(fout, targetName);
+ cxxState.WriteProperties(fout, targetName);
+ cudaState.WriteProperties(fout, targetName);
+ objcState.WriteProperties(fout, targetName);
+ objcxxState.WriteProperties(fout, targetName);
if (!linkOptions.empty()) {
std::vector<std::string> options;
@@ -1050,7 +983,9 @@ void cmCoreTryCompile::CleanupFiles(std::string const& binDir)
std::set<std::string> deletedFiles;
for (unsigned long i = 0; i < dir.GetNumberOfFiles(); ++i) {
const char* fileName = dir.GetFile(i);
- if (strcmp(fileName, ".") != 0 && strcmp(fileName, "..") != 0) {
+ if (strcmp(fileName, ".") != 0 && strcmp(fileName, "..") != 0 &&
+ // Do not delete NFS temporary files.
+ !cmHasPrefix(fileName, ".nfs")) {
if (deletedFiles.insert(fileName).second) {
std::string const fullPath =
std::string(binDir).append("/").append(fileName);
diff --git a/Source/cmCoreTryCompile.h b/Source/cmCoreTryCompile.h
index ae714a6..916572a 100644
--- a/Source/cmCoreTryCompile.h
+++ b/Source/cmCoreTryCompile.h
@@ -47,10 +47,6 @@ protected:
std::string OutputFile;
std::string FindErrorMessage;
bool SrcFileSignature = false;
-
-private:
- std::vector<std::string> WarnCMP0067;
- std::string LookupStdVar(std::string const& var, bool warnCMP0067);
};
#endif
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index 32b0ca9..652c041 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -370,7 +370,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
std::string lang = s->GetOrDetermineLanguage();
if (lang == "C" || lang == "CXX" || lang == "CUDA") {
std::string const& srcext = s->GetExtension();
- isCFile = cm->IsSourceExtension(srcext);
+ isCFile = cm->IsACLikeSourceExtension(srcext);
}
std::string const& fullPath = s->ResolveFullPath();
diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx
index bf7555d..95cfb0a 100644
--- a/Source/cmExtraCodeLiteGenerator.cxx
+++ b/Source/cmExtraCodeLiteGenerator.cxx
@@ -227,8 +227,7 @@ std::string cmExtraCodeLiteGenerator::CollectSourceFiles(
cmSystemTools::LowerCase(s->GetExtension());
// check whether it is a source or a include file
// then put it accordingly into one of the two containers
- if (cm->IsSourceExtension(extLower) || cm->IsCudaExtension(extLower) ||
- cm->IsFortranExtension(extLower)) {
+ if (cm->IsAKnownSourceExtension(extLower)) {
cFiles[fullPath] = s;
} else {
otherFiles.insert(fullPath);
diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx
index 613a943..3e265a0 100644
--- a/Source/cmExtraSublimeTextGenerator.cxx
+++ b/Source/cmExtraSublimeTextGenerator.cxx
@@ -349,6 +349,13 @@ std::string cmExtraSublimeTextGenerator::ComputeFlagsForObject(
if (language.empty()) {
language = "C";
}
+
+ // explicitly add the explicit language flag before any other flag
+ // this way backwards compatibility with user flags is maintained
+ if (source->GetProperty("LANGUAGE")) {
+ lg->AppendFeatureOptions(flags, language, "EXPLICIT_LANGUAGE");
+ }
+
std::string const& config =
lg->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
diff --git a/Source/cmFileAPI.cxx b/Source/cmFileAPI.cxx
index 594969b..c2ab2f1 100644
--- a/Source/cmFileAPI.cxx
+++ b/Source/cmFileAPI.cxx
@@ -665,7 +665,7 @@ std::string cmFileAPI::NoSupportedVersion(
// The "codemodel" object kind.
-static unsigned int const CodeModelV2Minor = 1;
+static unsigned int const CodeModelV2Minor = 2;
void cmFileAPI::BuildClientRequestCodeModel(
ClientRequest& r, std::vector<RequestVersion> const& versions)
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index fe331ec..21d9abb 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -277,6 +277,7 @@ struct CompileData
std::string Language;
std::string Sysroot;
+ JBT<std::string> LanguageStandard;
std::vector<JBT<std::string>> Flags;
std::vector<JBT<std::string>> Defines;
std::vector<JBT<std::string>> PrecompileHeaders;
@@ -287,6 +288,7 @@ struct CompileData
return (l.Language == r.Language && l.Sysroot == r.Sysroot &&
l.Flags == r.Flags && l.Defines == r.Defines &&
l.PrecompileHeaders == r.PrecompileHeaders &&
+ l.LanguageStandard == r.LanguageStandard &&
l.Includes == r.Includes);
}
};
@@ -320,6 +322,10 @@ struct hash<CompileData>
result = result ^ hash<std::string>()(i.Value) ^
hash<Json::ArrayIndex>()(i.Backtrace.Index);
}
+ if (!in.LanguageStandard.Value.empty()) {
+ result = result ^ hash<std::string>()(in.LanguageStandard.Value) ^
+ hash<Json::ArrayIndex>()(in.LanguageStandard.Backtrace.Index);
+ }
return result;
}
};
@@ -377,6 +383,7 @@ class Target
Json::Value DumpCompileData(CompileData const& cd);
Json::Value DumpInclude(CompileData::IncludeEntry const& inc);
Json::Value DumpPrecompileHeader(JBT<std::string> const& header);
+ Json::Value DumpLanguageStandard(JBT<std::string> const& standard);
Json::Value DumpDefine(JBT<std::string> const& def);
Json::Value DumpSources();
Json::Value DumpSource(cmGeneratorTarget::SourceAndKind const& sk,
@@ -838,6 +845,11 @@ void Target::ProcessLanguage(std::string const& lang)
for (BT<std::string> const& pch : precompileHeaders) {
cd.PrecompileHeaders.emplace_back(this->ToJBT(pch));
}
+ BT<std::string> const* languageStandard =
+ this->GT->GetLanguageStandardProperty(lang, this->Config);
+ if (languageStandard) {
+ cd.LanguageStandard = this->ToJBT(*languageStandard);
+ }
}
Json::ArrayIndex Target::AddSourceGroup(cmSourceGroup* sg, Json::ArrayIndex si)
@@ -996,6 +1008,9 @@ CompileData Target::MergeCompileData(CompileData const& fd)
// All compile groups share the precompile headers of the target.
cd.PrecompileHeaders = td.PrecompileHeaders;
+ // All compile groups share the language standard of the target.
+ cd.LanguageStandard = td.LanguageStandard;
+
// Use target-wide flags followed by source-specific flags.
cd.Flags.reserve(td.Flags.size() + fd.Flags.size());
cd.Flags.insert(cd.Flags.end(), td.Flags.begin(), td.Flags.end());
@@ -1153,6 +1168,10 @@ Json::Value Target::DumpCompileData(CompileData const& cd)
}
result["precompileHeaders"] = std::move(precompileHeaders);
}
+ if (!cd.LanguageStandard.Value.empty()) {
+ result["languageStandard"] =
+ this->DumpLanguageStandard(cd.LanguageStandard);
+ }
return result;
}
@@ -1176,6 +1195,23 @@ Json::Value Target::DumpPrecompileHeader(JBT<std::string> const& header)
return precompileHeader;
}
+Json::Value Target::DumpLanguageStandard(JBT<std::string> const& standard)
+{
+ Json::Value languageStandard = Json::objectValue;
+ languageStandard["standard"] = standard.Value;
+ if (standard.Backtrace) {
+ // Only one backtrace is currently stored for a given language standard,
+ // but we represent this as an array because it's possible for multiple
+ // compile features to set the same language standard value. Representing
+ // this as an array will allow things to just work once we support storing
+ // multiple backtraces for a language standard value.
+ Json::Value backtraces = Json::arrayValue;
+ backtraces.append(standard.Backtrace.Index);
+ languageStandard["backtraces"] = backtraces;
+ }
+ return languageStandard;
+}
+
Json::Value Target::DumpDefine(JBT<std::string> const& def)
{
Json::Value define = Json::objectValue;
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 268c5d1..3eea6f3 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -2941,7 +2941,7 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
{
std::string Output;
std::string Format;
- std::string Type;
+ std::string Compression;
std::string MTime;
bool Verbose = false;
std::vector<std::string> Files;
@@ -2951,7 +2951,7 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
static auto const parser = cmArgumentParser<Arguments>{}
.Bind("OUTPUT"_s, &Arguments::Output)
.Bind("FORMAT"_s, &Arguments::Format)
- .Bind("TYPE"_s, &Arguments::Type)
+ .Bind("COMPRESSION"_s, &Arguments::Compression)
.Bind("MTIME"_s, &Arguments::MTime)
.Bind("VERBOSE"_s, &Arguments::Verbose)
.Bind("FILES"_s, &Arguments::Files)
@@ -2970,7 +2970,7 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
}
const std::vector<std::string> LIST_ARGS = {
- "OUTPUT", "FORMAT", "TYPE", "MTIME", "FILES", "DIRECTORY",
+ "OUTPUT", "FORMAT", "COMPRESSION", "MTIME", "FILES", "DIRECTORY",
};
auto kwbegin = keywordsMissingValues.cbegin();
auto kwend = cmRemoveMatching(keywordsMissingValues, LIST_ARGS);
@@ -2994,10 +2994,10 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
}
const char* zipFileFormats[] = { "7zip", "zip" };
- if (!parsedArgs.Type.empty() &&
+ if (!parsedArgs.Compression.empty() &&
cm::contains(zipFileFormats, parsedArgs.Format)) {
status.SetError(cmStrCat("archive format ", parsedArgs.Format,
- " does not support TYPE arguments"));
+ " does not support COMPRESSION arguments"));
cmSystemTools::SetFatalErrorOccured();
return false;
}
@@ -3015,12 +3015,12 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
std::back_inserter(files));
cmSystemTools::cmTarCompression compress = cmSystemTools::TarCompressNone;
- auto typeIt = compressionTypeMap.find(parsedArgs.Type);
+ auto typeIt = compressionTypeMap.find(parsedArgs.Compression);
if (typeIt != compressionTypeMap.end()) {
compress = typeIt->second;
- } else if (!parsedArgs.Type.empty()) {
- status.SetError(
- cmStrCat("compression type ", parsedArgs.Type, " is not supported"));
+ } else if (!parsedArgs.Compression.empty()) {
+ status.SetError(cmStrCat("compression type ", parsedArgs.Compression,
+ " is not supported"));
cmSystemTools::SetFatalErrorOccured();
return false;
}
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index 4b88bea..77728ec 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -4,6 +4,7 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmPolicies.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -19,6 +20,7 @@ struct cmFindProgramHelper
cmFindProgramHelper(cmMakefile* makefile, cmFindBase const* base)
: DebugSearches("find_program", base)
, Makefile(makefile)
+ , PolicyCMP0109(makefile->GetPolicyStatus(cmPolicies::CMP0109))
{
#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
// Consider platform-specific extensions.
@@ -48,6 +50,8 @@ struct cmFindProgramHelper
cmFindBaseDebugState DebugSearches;
cmMakefile* Makefile;
+ cmPolicies::PolicyStatus PolicyCMP0109;
+
void AddName(std::string const& name) { this->Names.push_back(name); }
void SetName(std::string const& name)
{
@@ -85,7 +89,7 @@ struct cmFindProgramHelper
this->TestNameExt = cmStrCat(name, ext);
this->TestPath =
cmSystemTools::CollapseFullPath(this->TestNameExt, path);
- bool exists = cmSystemTools::FileExists(this->TestPath, true);
+ bool exists = this->FileIsExecutable(this->TestPath);
exists ? this->DebugSearches.FoundAt(this->TestPath)
: this->DebugSearches.FailedAt(this->TestPath);
if (exists) {
@@ -95,6 +99,48 @@ struct cmFindProgramHelper
}
return false;
}
+ bool FileIsExecutable(std::string const& file) const
+ {
+ switch (this->PolicyCMP0109) {
+ case cmPolicies::OLD:
+ return cmSystemTools::FileExists(file, true);
+ case cmPolicies::NEW:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ return cmSystemTools::FileIsExecutable(file);
+ default:
+ break;
+ }
+ bool const isExeOld = cmSystemTools::FileExists(file, true);
+ bool const isExeNew = cmSystemTools::FileIsExecutable(file);
+ if (isExeNew == isExeOld) {
+ return isExeNew;
+ }
+ if (isExeNew) {
+ this->Makefile->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0109),
+ "\n"
+ "The file\n"
+ " ",
+ file,
+ "\n"
+ "is executable but not readable. "
+ "CMake is ignoring it for compatibility."));
+ } else {
+ this->Makefile->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0109),
+ "\n"
+ "The file\n"
+ " ",
+ file,
+ "\n"
+ "is readable but not executable. "
+ "CMake is using it for compatibility."));
+ }
+ return isExeOld;
+ }
};
cmFindProgramCommand::cmFindProgramCommand(cmExecutionStatus& status)
@@ -266,14 +312,13 @@ std::string cmFindProgramCommand::GetBundleExecutable(
if (executableURL != nullptr) {
const int MAX_OSX_PATH_SIZE = 1024;
- char buffer[MAX_OSX_PATH_SIZE];
+ UInt8 buffer[MAX_OSX_PATH_SIZE];
- // Convert the CFString to a C string
- CFStringGetCString(CFURLGetString(executableURL), buffer,
- MAX_OSX_PATH_SIZE, kCFStringEncodingUTF8);
-
- // And finally to a c++ string
- executable = bundlePath + "/Contents/MacOS/" + std::string(buffer);
+ if (CFURLGetFileSystemRepresentation(executableURL, false, buffer,
+ MAX_OSX_PATH_SIZE)) {
+ executable = bundlePath + "/Contents/MacOS/" +
+ std::string(reinterpret_cast<char*>(buffer));
+ }
// Only release CFURLRef if it's not null
CFRelease(executableURL);
}
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index e4fb67e..b712b71 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -881,7 +881,7 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
{
ConfigurationTestNode() {} // NOLINT(modernize-use-equals-default)
- int NumExpectedParameters() const override { return OneOrZeroParameters; }
+ int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
std::string Evaluate(
const std::vector<std::string>& parameters,
@@ -899,13 +899,15 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
return std::string();
}
context->HadContextSensitiveCondition = true;
- if (context->Config.empty()) {
- return parameters.front().empty() ? "1" : "0";
- }
-
- if (cmsysString_strcasecmp(parameters.front().c_str(),
- context->Config.c_str()) == 0) {
- return "1";
+ for (auto& param : parameters) {
+ if (context->Config.empty()) {
+ if (param.empty()) {
+ return "1";
+ }
+ } else if (cmsysString_strcasecmp(param.c_str(),
+ context->Config.c_str()) == 0) {
+ return "1";
+ }
}
if (context->CurrentTarget && context->CurrentTarget->IsImported()) {
@@ -922,10 +924,12 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
"MAP_IMPORTED_CONFIG_", cmSystemTools::UpperCase(context->Config));
if (cmProp mapValue = context->CurrentTarget->GetProperty(mapProp)) {
cmExpandList(cmSystemTools::UpperCase(*mapValue), mappedConfigs);
- return cm::contains(mappedConfigs,
- cmSystemTools::UpperCase(parameters.front()))
- ? "1"
- : "0";
+
+ for (auto& param : parameters) {
+ if (cm::contains(mappedConfigs, cmSystemTools::UpperCase(param))) {
+ return "1";
+ }
+ }
}
}
}
@@ -1708,7 +1712,7 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
std::string error;
std::string lang;
if (!context->LG->GetMakefile()->CompileFeatureKnown(
- context->HeadTarget->Target, p, lang, &error)) {
+ context->HeadTarget->Target->GetName(), p, lang, &error)) {
reportError(context, content->GetOriginalExpression(), error);
return std::string();
}
@@ -1742,9 +1746,9 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
continue;
}
if (!context->LG->GetMakefile()->HaveStandardAvailable(
- target->Target, lit.first, it)) {
+ target, lit.first, context->Config, it)) {
if (evalLL) {
- cmProp l = target->GetProperty(lit.first + "_STANDARD");
+ cmProp l = target->GetLanguageStandard(lit.first, context->Config);
if (!l) {
l = standardDefault;
}
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index f2011ee..992682f 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -947,6 +947,61 @@ bool cmGeneratorTarget::HasExplicitObjectName(cmSourceFile const* file) const
return it != this->ExplicitObjectName.end();
}
+BT<std::string> const* cmGeneratorTarget::GetLanguageStandardProperty(
+ std::string const& lang, std::string const& config) const
+{
+ std::string key = cmStrCat(cmSystemTools::UpperCase(config), '-', lang);
+ auto langStandardIter = this->LanguageStandardMap.find(key);
+ if (langStandardIter != this->LanguageStandardMap.end()) {
+ return &langStandardIter->second;
+ }
+
+ return this->Target->GetLanguageStandardProperty(
+ cmStrCat(lang, "_STANDARD"));
+}
+
+cmProp cmGeneratorTarget::GetLanguageStandard(std::string const& lang,
+ std::string const& config) const
+{
+ BT<std::string> const* languageStandard =
+ this->GetLanguageStandardProperty(lang, config);
+
+ if (languageStandard) {
+ return &(languageStandard->Value);
+ }
+
+ return nullptr;
+}
+
+cmProp cmGeneratorTarget::GetPropertyWithPairedLanguageSupport(
+ std::string const& lang, const char* suffix) const
+{
+ cmProp propertyValue = this->Target->GetProperty(cmStrCat(lang, suffix));
+ if (propertyValue == nullptr) {
+ // Check if we should use the value set by another language.
+ if (lang == "OBJC") {
+ propertyValue = this->GetPropertyWithPairedLanguageSupport("C", suffix);
+ } else if (lang == "OBJCXX" || lang == "CUDA") {
+ propertyValue =
+ this->GetPropertyWithPairedLanguageSupport("CXX", suffix);
+ }
+ }
+ return propertyValue;
+}
+
+cmProp cmGeneratorTarget::GetLanguageExtensions(std::string const& lang) const
+{
+ return this->GetPropertyWithPairedLanguageSupport(lang, "_EXTENSIONS");
+}
+
+bool cmGeneratorTarget::GetLanguageStandardRequired(
+ std::string const& lang) const
+{
+ cmProp p =
+ this->GetPropertyWithPairedLanguageSupport(lang, "_STANDARD_REQUIRED");
+ return p && cmIsOn(*p);
+}
+
void cmGeneratorTarget::GetModuleDefinitionSources(
std::vector<cmSourceFile const*>& data, const std::string& config) const
{
@@ -4408,12 +4463,69 @@ void cmGeneratorTarget::ComputeTargetManifest(const std::string& config) const
bool cmGeneratorTarget::ComputeCompileFeatures(std::string const& config) const
{
+ // Compute the language standard based on the compile features.
std::vector<BT<std::string>> features = this->GetCompileFeatures(config);
for (BT<std::string> const& f : features) {
- if (!this->Makefile->AddRequiredTargetFeature(this->Target, f.Value)) {
+ std::string lang;
+ if (!this->Makefile->CompileFeatureKnown(this->Target->GetName(), f.Value,
+ lang, nullptr)) {
+ return false;
+ }
+
+ std::string key = cmStrCat(cmSystemTools::UpperCase(config), '-', lang);
+ cmProp currentLanguageStandard = this->GetLanguageStandard(lang, config);
+
+ std::string newRequiredStandard;
+ if (!this->Makefile->GetNewRequiredStandard(
+ this->Target->GetName(), f.Value, currentLanguageStandard,
+ newRequiredStandard)) {
return false;
}
+
+ if (!newRequiredStandard.empty()) {
+ this->LanguageStandardMap[key] =
+ BT<std::string>(newRequiredStandard, f.Backtrace);
+ }
}
+
+ return true;
+}
+
+bool cmGeneratorTarget::ComputeCompileFeatures(
+ std::string const& config, std::set<LanguagePair> const& languagePairs) const
+{
+ for (const auto& language : languagePairs) {
+ BT<std::string> const* generatorTargetLanguageStandard =
+ this->GetLanguageStandardProperty(language.first, config);
+ if (!generatorTargetLanguageStandard) {
+ // If the standard isn't explicitly set we copy it over from the
+ // specified paired language.
+ std::string key =
+ cmStrCat(cmSystemTools::UpperCase(config), '-', language.first);
+ BT<std::string> const* standardToCopy =
+ this->GetLanguageStandardProperty(language.second, config);
+ if (standardToCopy != nullptr) {
+ this->LanguageStandardMap[key] = *standardToCopy;
+ generatorTargetLanguageStandard = &this->LanguageStandardMap[key];
+ } else {
+ cmProp defaultStandard = this->Makefile->GetDef(
+ cmStrCat("CMAKE_", language.second, "_STANDARD_DEFAULT"));
+ if (defaultStandard != nullptr) {
+ this->LanguageStandardMap[key] = BT<std::string>(*defaultStandard);
+ generatorTargetLanguageStandard = &this->LanguageStandardMap[key];
+ }
+ }
+
+ // Custom updates for the CUDA standard.
+ if (generatorTargetLanguageStandard != nullptr &&
+ language.first == "CUDA") {
+ if (generatorTargetLanguageStandard->Value == "98") {
+ this->LanguageStandardMap[key].Value = "03";
+ }
+ }
+ }
+ }
+
return true;
}
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 3aedbf5..20f3a07 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -148,6 +148,16 @@ public:
bool HasExplicitObjectName(cmSourceFile const* file) const;
void AddExplicitObjectName(cmSourceFile const* sf);
+ BT<std::string> const* GetLanguageStandardProperty(
+ std::string const& lang, std::string const& config) const;
+
+ cmProp GetLanguageStandard(std::string const& lang,
+ std::string const& config) const;
+
+ cmProp GetLanguageExtensions(std::string const& lang) const;
+
+ bool GetLanguageStandardRequired(std::string const& lang) const;
+
void GetModuleDefinitionSources(std::vector<cmSourceFile const*>&,
const std::string& config) const;
void GetExternalObjects(std::vector<cmSourceFile const*>&,
@@ -515,6 +525,11 @@ public:
bool ComputeCompileFeatures(std::string const& config) const;
+ using LanguagePair = std::pair<std::string, std::string>;
+ bool ComputeCompileFeatures(
+ std::string const& config,
+ std::set<LanguagePair> const& languagePairs) const;
+
/**
* Trace through the source files in this target and add al source files
* that they depend on, used by all generators
@@ -1038,6 +1053,11 @@ private:
bool GetRPATH(const std::string& config, const std::string& prop,
std::string& rpath) const;
+ mutable std::map<std::string, BT<std::string>> LanguageStandardMap;
+
+ cmProp GetPropertyWithPairedLanguageSupport(std::string const& lang,
+ const char* suffix) const;
+
public:
const std::vector<const cmGeneratorTarget*>& GetLinkImplementationClosure(
const std::string& config) const;
diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx
index 811421a..38bffbf 100644
--- a/Source/cmGetFilenameComponentCommand.cxx
+++ b/Source/cmGetFilenameComponentCommand.cxx
@@ -14,6 +14,7 @@ bool cmGetFilenameComponentCommand(std::vector<std::string> const& args,
{
if (args.size() < 3) {
status.SetError("called with incorrect number of arguments");
+ cmSystemTools::SetFatalErrorOccured();
return false;
}
@@ -114,6 +115,7 @@ bool cmGetFilenameComponentCommand(std::vector<std::string> const& args,
} else {
std::string err = "unknown component " + args[2];
status.SetError(err);
+ cmSystemTools::SetFatalErrorOccured();
return false;
}
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 4dc4092..6001999 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -596,6 +596,16 @@ void cmGlobalGenerator::EnableLanguage(
mf->ReadListFile(fpath);
}
}
+
+ if (readCMakeSystem) {
+ // Find the native build tool for this generator.
+ // This has to be done early so that MSBuild can be used to examine the
+ // cross-compilation environment.
+ if (!this->FindMakeProgram(mf)) {
+ return;
+ }
+ }
+
// Load the CMakeDetermineSystem.cmake file and find out
// what platform we are running on
if (!mf->GetDefinition("CMAKE_SYSTEM")) {
@@ -667,11 +677,6 @@ void cmGlobalGenerator::EnableLanguage(
cmSystemTools::SetFatalErrorOccured();
return;
}
-
- // Find the native build tool for this generator.
- if (!this->FindMakeProgram(mf)) {
- return;
- }
}
// Check that the languages are supported by the generator and its
@@ -1442,12 +1447,10 @@ bool cmGlobalGenerator::Compute()
localGen->AddHelperCommands();
}
- // Finalize the set of compile features for each target.
- // FIXME: This turns into calls to cmMakefile::AddRequiredTargetFeature
- // which actually modifies the <lang>_STANDARD target property
- // on the original cmTarget instance. It accumulates features
- // across all configurations. Some refactoring is needed to
- // compute a per-config resulta purely during generation.
+ // Perform up-front computation in order to handle errors (such as unknown
+ // features) at this point. While processing the compile features we also
+ // calculate and cache the language standard required by the compile
+ // features.
for (const auto& localGen : this->LocalGenerators) {
if (!localGen->ComputeTargetCompileFeatures()) {
return false;
@@ -1988,8 +1991,9 @@ int cmGlobalGenerator::Build(
std::string makeCommandStr;
output += "\nRun Build Command(s):";
- for (auto command = makeCommand.begin(); command != makeCommand.end();
- ++command) {
+ retVal = 0;
+ for (auto command = makeCommand.begin();
+ command != makeCommand.end() && retVal == 0; ++command) {
makeCommandStr = command->Printable();
if (command != makeCommand.end()) {
makeCommandStr += " && ";
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index 5dac072..3805546 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -138,9 +138,6 @@ cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator(
"ProductDir",
vc10Express, cmSystemTools::KeyWOW64_32);
this->CudaEnabled = false;
- this->SystemIsWindowsCE = false;
- this->SystemIsWindowsPhone = false;
- this->SystemIsWindowsStore = false;
this->MSBuildCommandInitialized = false;
{
std::string envPlatformToolset;
@@ -511,18 +508,16 @@ bool cmGlobalVisualStudio10Generator::InitializeSystem(cmMakefile* mf)
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
return false;
}
- std::string v = this->GetInstalledNsightTegraVersion();
- if (v.empty()) {
- mf->IssueMessage(MessageType::FATAL_ERROR,
- "CMAKE_SYSTEM_NAME is 'Android' but "
- "'NVIDIA Nsight Tegra Visual Studio Edition' "
- "is not installed.");
- return false;
+ if (mf->GetSafeDefinition("CMAKE_GENERATOR_PLATFORM") == "Tegra-Android") {
+ if (!this->InitializeTegraAndroid(mf)) {
+ return false;
+ }
+ } else {
+ this->SystemIsAndroid = true;
+ if (!this->InitializeAndroid(mf)) {
+ return false;
+ }
}
- this->DefaultPlatformName = "Tegra-Android";
- this->DefaultPlatformToolset = "Default";
- this->NsightTegraVersion = v;
- mf->AddDefinition("CMAKE_VS_NsightTegra_VERSION", v);
}
return true;
@@ -564,6 +559,31 @@ bool cmGlobalVisualStudio10Generator::InitializeWindowsStore(cmMakefile* mf)
return false;
}
+bool cmGlobalVisualStudio10Generator::InitializeTegraAndroid(cmMakefile* mf)
+{
+ std::string v = this->GetInstalledNsightTegraVersion();
+ if (v.empty()) {
+ mf->IssueMessage(MessageType::FATAL_ERROR,
+ "CMAKE_SYSTEM_NAME is 'Android' but "
+ "'NVIDIA Nsight Tegra Visual Studio Edition' "
+ "is not installed.");
+ return false;
+ }
+ this->DefaultPlatformName = "Tegra-Android";
+ this->DefaultPlatformToolset = "Default";
+ this->NsightTegraVersion = v;
+ mf->AddDefinition("CMAKE_VS_NsightTegra_VERSION", v);
+ return true;
+}
+
+bool cmGlobalVisualStudio10Generator::InitializeAndroid(cmMakefile* mf)
+{
+ std::ostringstream e;
+ e << this->GetName() << " does not support Android.";
+ mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ return false;
+}
+
bool cmGlobalVisualStudio10Generator::SelectWindowsPhoneToolset(
std::string& toolset) const
{
@@ -598,6 +618,28 @@ void cmGlobalVisualStudio10Generator::Generate()
{
this->LongestSource = LongestSourcePath();
this->cmGlobalVisualStudio8Generator::Generate();
+ if (!this->AndroidExecutableWarnings.empty() &&
+ !this->CMakeInstance->GetIsInTryCompile()) {
+ std::ostringstream e;
+ /* clang-format off */
+ e <<
+ "You are using Visual Studio tools for Android, which does not support "
+ "standalone executables. However, the following executable targets do "
+ "not have the ANDROID_GUI property set, and thus will not be built as "
+ "expected. They will be built as shared libraries with executable "
+ "filenames:\n"
+ " ";
+ /* clang-format on */
+ bool first = true;
+ for (auto const& name : this->AndroidExecutableWarnings) {
+ if (!first) {
+ e << ", ";
+ }
+ first = false;
+ e << name;
+ }
+ this->CMakeInstance->IssueMessage(MessageType::WARNING, e.str());
+ }
if (this->LongestSource.Length > 0) {
cmLocalGenerator* lg = this->LongestSource.Target->GetLocalGenerator();
std::ostringstream e;
@@ -664,8 +706,14 @@ std::string const& cmGlobalVisualStudio10Generator::GetPlatformToolsetString()
if (!this->GeneratorToolset.empty()) {
return this->GeneratorToolset;
}
- if (!this->DefaultPlatformToolset.empty()) {
- return this->DefaultPlatformToolset;
+ if (this->SystemIsAndroid) {
+ if (!this->DefaultAndroidToolset.empty()) {
+ return this->DefaultAndroidToolset;
+ }
+ } else {
+ if (!this->DefaultPlatformToolset.empty()) {
+ return this->DefaultPlatformToolset;
+ }
}
static std::string const empty;
return empty;
@@ -879,7 +927,10 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf)
epg.Attribute("Label", "Globals");
cmXMLElement(epg, "ProjectGuid")
.Content("{F3FC6D86-508D-3FB1-96D2-995F08B142EC}");
- cmXMLElement(epg, "Keyword").Content("Win32Proj");
+ cmXMLElement(epg, "Keyword")
+ .Content(mf->GetSafeDefinition("CMAKE_SYSTEM_NAME") == "Android"
+ ? "Android"
+ : "Win32Proj");
cmXMLElement(epg, "Platform").Content(this->GetPlatformName());
if (this->GetSystemName() == "WindowsPhone") {
cmXMLElement(epg, "ApplicationType").Content("Windows Phone");
@@ -889,15 +940,21 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf)
cmXMLElement(epg, "ApplicationType").Content("Windows Store");
cmXMLElement(epg, "ApplicationTypeRevision")
.Content(this->GetApplicationTypeRevision());
+ } else if (this->GetSystemName() == "Android") {
+ cmXMLElement(epg, "ApplicationType").Content("Android");
+ cmXMLElement(epg, "ApplicationTypeRevision")
+ .Content(this->GetApplicationTypeRevision());
}
if (!this->WindowsTargetPlatformVersion.empty()) {
cmXMLElement(epg, "WindowsTargetPlatformVersion")
.Content(this->WindowsTargetPlatformVersion);
}
- if (this->GetPlatformName() == "ARM64") {
- cmXMLElement(epg, "WindowsSDKDesktopARM64Support").Content("true");
- } else if (this->GetPlatformName() == "ARM") {
- cmXMLElement(epg, "WindowsSDKDesktopARMSupport").Content("true");
+ if (this->GetSystemName() != "Android") {
+ if (this->GetPlatformName() == "ARM64") {
+ cmXMLElement(epg, "WindowsSDKDesktopARM64Support").Content("true");
+ } else if (this->GetPlatformName() == "ARM") {
+ cmXMLElement(epg, "WindowsSDKDesktopARMSupport").Content("true");
+ }
}
}
cmXMLElement(eprj, "Import")
@@ -1209,6 +1266,10 @@ std::string cmGlobalVisualStudio10Generator::GetInstalledNsightTegraVersion()
std::string cmGlobalVisualStudio10Generator::GetApplicationTypeRevision() const
{
+ if (this->GetSystemName() == "Android") {
+ return this->GetAndroidApplicationTypeRevision();
+ }
+
// Return the first two '.'-separated components of the Windows version.
std::string::size_type end1 = this->SystemVersion.find('.');
std::string::size_type end2 =
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index b8c18b4..0c53537 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -4,6 +4,7 @@
#define cmGlobalVisualStudio10Generator_h
#include <memory>
+#include <set>
#include "cmGlobalVisualStudio8Generator.h"
#include "cmVisualStudio10ToolsetOptions.h"
@@ -43,6 +44,11 @@ public:
void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*,
bool optional) override;
+ void AddAndroidExecutableWarning(const std::string& name)
+ {
+ this->AndroidExecutableWarnings.insert(name);
+ }
+
bool IsCudaEnabled() const { return this->CudaEnabled; }
/** Generating for Nsight Tegra VS plugin? */
@@ -100,6 +106,9 @@ public:
/** Return true if building for WindowsStore */
bool TargetsWindowsStore() const { return this->SystemIsWindowsStore; }
+ /** Return true if building for Android */
+ bool TargetsAndroid() const { return this->SystemIsAndroid; }
+
const char* GetCMakeCFGIntDir() const override { return "$(Configuration)"; }
bool Find64BitTools(cmMakefile* mf);
@@ -128,6 +137,8 @@ public:
/** Return the first two components of CMAKE_SYSTEM_VERSION. */
std::string GetApplicationTypeRevision() const;
+ virtual const char* GetAndroidApplicationTypeRevision() const { return ""; }
+
cmIDEFlagTable const* GetClFlagTable() const;
cmIDEFlagTable const* GetCSharpFlagTable() const;
cmIDEFlagTable const* GetRcFlagTable() const;
@@ -148,6 +159,8 @@ protected:
virtual bool InitializeWindowsCE(cmMakefile* mf);
virtual bool InitializeWindowsPhone(cmMakefile* mf);
virtual bool InitializeWindowsStore(cmMakefile* mf);
+ virtual bool InitializeTegraAndroid(cmMakefile* mf);
+ virtual bool InitializeAndroid(cmMakefile* mf);
virtual bool ProcessGeneratorToolsetField(std::string const& key,
std::string const& value);
@@ -171,6 +184,7 @@ protected:
std::string GeneratorToolsetCudaCustomDir;
std::string DefaultPlatformToolset;
std::string DefaultPlatformToolsetHostArchitecture;
+ std::string DefaultAndroidToolset;
std::string WindowsTargetPlatformVersion;
std::string SystemName;
std::string SystemVersion;
@@ -185,9 +199,10 @@ protected:
std::string DefaultNasmFlagTableName;
std::string DefaultRCFlagTableName;
bool SupportsUnityBuilds = false;
- bool SystemIsWindowsCE;
- bool SystemIsWindowsPhone;
- bool SystemIsWindowsStore;
+ bool SystemIsWindowsCE = false;
+ bool SystemIsWindowsPhone = false;
+ bool SystemIsWindowsStore = false;
+ bool SystemIsAndroid = false;
private:
class Factory;
@@ -211,6 +226,7 @@ private:
std::string MSBuildCommand;
bool MSBuildCommandInitialized;
cmVisualStudio10ToolsetOptions ToolsetOptions;
+ std::set<std::string> AndroidExecutableWarnings;
virtual std::string FindMSBuildCommand();
std::string FindDevEnvCommand() override;
std::string GetVSMakeProgram() override { return this->GetMSBuildCommand(); }
diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx
index f549b6a..451d448 100644
--- a/Source/cmGlobalVisualStudio14Generator.cxx
+++ b/Source/cmGlobalVisualStudio14Generator.cxx
@@ -109,6 +109,7 @@ cmGlobalVisualStudio14Generator::cmGlobalVisualStudio14Generator(
"ProductDir",
vc14Express, cmSystemTools::KeyWOW64_32);
this->DefaultPlatformToolset = "v140";
+ this->DefaultAndroidToolset = "Clang_3_8";
this->DefaultCLFlagTableName = "v140";
this->DefaultCSharpFlagTableName = "v140";
this->DefaultLibFlagTableName = "v14";
@@ -159,6 +160,11 @@ bool cmGlobalVisualStudio14Generator::InitializeWindowsStore(cmMakefile* mf)
return true;
}
+bool cmGlobalVisualStudio14Generator::InitializeAndroid(cmMakefile*)
+{
+ return true;
+}
+
bool cmGlobalVisualStudio14Generator::SelectWindows10SDK(cmMakefile* mf,
bool required)
{
diff --git a/Source/cmGlobalVisualStudio14Generator.h b/Source/cmGlobalVisualStudio14Generator.h
index ccc2917..39353f2 100644
--- a/Source/cmGlobalVisualStudio14Generator.h
+++ b/Source/cmGlobalVisualStudio14Generator.h
@@ -23,12 +23,18 @@ public:
bool MatchesGeneratorName(const std::string& name) const override;
+ const char* GetAndroidApplicationTypeRevision() const override
+ {
+ return "2.0";
+ }
+
protected:
cmGlobalVisualStudio14Generator(cmake* cm, const std::string& name,
std::string const& platformInGeneratorName);
bool InitializeWindows(cmMakefile* mf) override;
bool InitializeWindowsStore(cmMakefile* mf) override;
+ bool InitializeAndroid(cmMakefile* mf) override;
bool SelectWindowsStoreToolset(std::string& toolset) const override;
// These aren't virtual because we need to check if the selected version
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
index 605dc8b..e2e045c 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
@@ -100,6 +100,24 @@ static const char* VSVersionToToolset(
return "";
}
+static const char* VSVersionToAndroidToolset(
+ cmGlobalVisualStudioGenerator::VSVersion v)
+{
+ switch (v) {
+ case cmGlobalVisualStudioGenerator::VS9:
+ case cmGlobalVisualStudioGenerator::VS10:
+ case cmGlobalVisualStudioGenerator::VS11:
+ case cmGlobalVisualStudioGenerator::VS12:
+ return "";
+ case cmGlobalVisualStudioGenerator::VS14:
+ return "Clang_3_8";
+ case cmGlobalVisualStudioGenerator::VS15:
+ case cmGlobalVisualStudioGenerator::VS16:
+ return "Clang_5_0";
+ }
+ return "";
+}
+
static const char vs15generatorName[] = "Visual Studio 15 2017";
// Map generator name without year to name with year.
@@ -284,6 +302,7 @@ cmGlobalVisualStudioVersionedGenerator::cmGlobalVisualStudioVersionedGenerator(
this->Version = version;
this->ExpressEdition = false;
this->DefaultPlatformToolset = VSVersionToToolset(this->Version);
+ this->DefaultAndroidToolset = VSVersionToAndroidToolset(this->Version);
this->DefaultCLFlagTableName = VSVersionToToolset(this->Version);
this->DefaultCSharpFlagTableName = VSVersionToToolset(this->Version);
this->DefaultLinkFlagTableName = VSVersionToToolset(this->Version);
@@ -408,6 +427,25 @@ bool cmGlobalVisualStudioVersionedGenerator::IsStdOutEncodingSupported() const
vsInstanceVersion > vsInstanceVersion16_7_P2);
}
+const char*
+cmGlobalVisualStudioVersionedGenerator::GetAndroidApplicationTypeRevision()
+ const
+{
+ switch (this->Version) {
+ case cmGlobalVisualStudioGenerator::VS9:
+ case cmGlobalVisualStudioGenerator::VS10:
+ case cmGlobalVisualStudioGenerator::VS11:
+ case cmGlobalVisualStudioGenerator::VS12:
+ return "";
+ case cmGlobalVisualStudioGenerator::VS14:
+ return "2.0";
+ case cmGlobalVisualStudioGenerator::VS15:
+ case cmGlobalVisualStudioGenerator::VS16:
+ return "3.0";
+ }
+ return "";
+}
+
std::string cmGlobalVisualStudioVersionedGenerator::GetAuxiliaryToolset() const
{
const char* version = this->GetPlatformToolsetVersion();
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.h b/Source/cmGlobalVisualStudioVersionedGenerator.h
index cbd3ba7..d5b8337 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.h
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.h
@@ -36,6 +36,8 @@ public:
bool IsStdOutEncodingSupported() const override;
+ const char* GetAndroidApplicationTypeRevision() const override;
+
protected:
cmGlobalVisualStudioVersionedGenerator(
VSVersion version, cmake* cm, const std::string& name,
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index a5ce5d1..bb422eb 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -819,6 +819,14 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
default:
break;
}
+
+ // explicitly add the explicit language flag before any other flag
+ // this way backwards compatibility with user flags is maintained
+ if (sf->GetProperty("LANGUAGE")) {
+ this->CurrentLocalGenerator->AppendFeatureOptions(flags, lang,
+ "EXPLICIT_LANGUAGE");
+ }
+
const std::string COMPILE_FLAGS("COMPILE_FLAGS");
if (cmProp cflags = sf->GetProperty(COMPILE_FLAGS)) {
lg->AppendFlags(flags, genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS));
@@ -1144,23 +1152,24 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
}
// organize the sources
- std::vector<cmSourceFile*> classes;
- if (!gtgt->GetConfigCommonSourceFiles(classes)) {
+ std::vector<cmSourceFile*> commonSourceFiles;
+ if (!gtgt->GetConfigCommonSourceFiles(commonSourceFiles)) {
return false;
}
// Add CMakeLists.txt file for user convenience.
- this->AddXCodeProjBuildRule(gtgt, classes);
+ this->AddXCodeProjBuildRule(gtgt, commonSourceFiles);
// Add the Info.plist we are about to generate for an App Bundle.
if (gtgt->GetPropertyAsBool("MACOSX_BUNDLE")) {
std::string plist = this->ComputeInfoPListLocation(gtgt);
cmSourceFile* sf = gtgt->Makefile->GetOrCreateSource(
plist, true, cmSourceFileLocationKind::Known);
- classes.push_back(sf);
+ commonSourceFiles.push_back(sf);
}
- std::sort(classes.begin(), classes.end(), cmSourceFilePathCompare());
+ std::sort(commonSourceFiles.begin(), commonSourceFiles.end(),
+ cmSourceFilePathCompare());
gtgt->ComputeObjectMapping();
@@ -1168,7 +1177,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
std::vector<cmXCodeObject*> headerFiles;
std::vector<cmXCodeObject*> resourceFiles;
std::vector<cmXCodeObject*> sourceFiles;
- for (auto sourceFile : classes) {
+ for (auto sourceFile : commonSourceFiles) {
cmXCodeObject* xsf = this->CreateXCodeSourceFile(
this->CurrentLocalGenerator, sourceFile, gtgt);
cmXCodeObject* fr = xsf->GetObject("fileRef");
@@ -1267,7 +1276,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
using mapOfVectorOfSourceFiles =
std::map<std::string, std::vector<cmSourceFile*>>;
mapOfVectorOfSourceFiles bundleFiles;
- for (auto sourceFile : classes) {
+ for (auto sourceFile : commonSourceFiles) {
cmGeneratorTarget::SourceFileFlags tsFlags =
gtgt->GetTargetSourceFileFlags(sourceFile);
if (tsFlags.Type == cmGeneratorTarget::SourceFileTypeMacContent) {
@@ -1315,7 +1324,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
using mapOfVectorOfSourceFiles =
std::map<std::string, std::vector<cmSourceFile*>>;
mapOfVectorOfSourceFiles bundleFiles;
- for (auto sourceFile : classes) {
+ for (auto sourceFile : commonSourceFiles) {
cmGeneratorTarget::SourceFileFlags tsFlags =
gtgt->GetTargetSourceFileFlags(sourceFile);
if (tsFlags.Type == cmGeneratorTarget::SourceFileTypeDeepResource) {
@@ -1345,22 +1354,20 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
}
}
- // create framework build phase
+ // always create framework build phase
cmXCodeObject* frameworkBuildPhase = nullptr;
- if (!externalObjFiles.empty()) {
- frameworkBuildPhase =
- this->CreateObject(cmXCodeObject::PBXFrameworksBuildPhase);
- frameworkBuildPhase->SetComment("Frameworks");
- frameworkBuildPhase->AddAttribute("buildActionMask",
- this->CreateString("2147483647"));
- buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
- frameworkBuildPhase->AddAttribute("files", buildFiles);
- for (auto& externalObjFile : externalObjFiles) {
- buildFiles->AddObject(externalObjFile);
- }
- frameworkBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
- this->CreateString("0"));
- }
+ frameworkBuildPhase =
+ this->CreateObject(cmXCodeObject::PBXFrameworksBuildPhase);
+ frameworkBuildPhase->SetComment("Frameworks");
+ frameworkBuildPhase->AddAttribute("buildActionMask",
+ this->CreateString("2147483647"));
+ buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ frameworkBuildPhase->AddAttribute("files", buildFiles);
+ for (auto& externalObjFile : externalObjFiles) {
+ buildFiles->AddObject(externalObjFile);
+ }
+ frameworkBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
+ this->CreateString("0"));
// create list of build phases and create the Xcode target
cmXCodeObject* buildPhases = this->CreateObject(cmXCodeObject::OBJECT_LIST);
@@ -2760,6 +2767,156 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
}
}
+ // Separate libraries into ones that can be linked using "Link Binary With
+ // Libraries" build phase and the ones that can't. Only targets that build
+ // Apple bundles (.app, .framework, .bundle) can use this feature and only
+ // targets that represent actual libraries (static or dynamic, local or
+ // imported) not objects and not executables will be used. These are
+ // limitations imposed by CMake use-cases - otherwise a lot of things break.
+ // The rest will be linked using linker flags (OTHER_LDFLAGS setting in Xcode
+ // project).
+ std::map<std::string, std::vector<cmComputeLinkInformation::Item const*>>
+ configItemMap;
+ auto addToLinkerArguments =
+ [&configItemMap](const std::string& configName,
+ cmComputeLinkInformation::Item const* libItemPtr) {
+ auto& linkVector = configItemMap[configName];
+ if (std::find_if(linkVector.begin(), linkVector.end(),
+ [libItemPtr](cmComputeLinkInformation::Item const* p) {
+ return p == libItemPtr;
+ }) == linkVector.end()) {
+ linkVector.push_back(libItemPtr);
+ }
+ };
+ std::vector<cmComputeLinkInformation::Item const*> linkPhaseTargetVector;
+ std::map<std::string, std::vector<std::string>> targetConfigMap;
+ using ConfigItemPair =
+ std::pair<std::string, cmComputeLinkInformation::Item const*>;
+ std::map<std::string, std::vector<ConfigItemPair>> targetItemMap;
+ std::map<std::string, std::vector<std::string>> targetProductNameMap;
+ for (auto const& configName : this->CurrentConfigurationTypes) {
+ cmComputeLinkInformation* cli = gt->GetLinkInformation(configName);
+ if (!cli) {
+ continue;
+ }
+ for (auto const& libItem : cli->GetItems()) {
+ // TODO: Drop this check once we have option to add outside libraries to
+ // Xcode project
+ auto* libTarget = FindXCodeTarget(libItem.Target);
+ if (gt->IsBundleOnApple() &&
+ (gt->GetType() == cmStateEnums::EXECUTABLE ||
+ gt->GetType() == cmStateEnums::SHARED_LIBRARY ||
+ gt->GetType() == cmStateEnums::MODULE_LIBRARY ||
+ gt->GetType() == cmStateEnums::UNKNOWN_LIBRARY) &&
+ (libTarget && libItem.Target &&
+ (libItem.Target->GetType() == cmStateEnums::STATIC_LIBRARY ||
+ libItem.Target->GetType() == cmStateEnums::SHARED_LIBRARY ||
+ libItem.Target->GetType() == cmStateEnums::MODULE_LIBRARY))) {
+ // Add unique configuration name to target-config map for later
+ // checks
+ std::string libName = libItem.Target->GetName();
+ auto& configVector = targetConfigMap[libName];
+ if (std::find(configVector.begin(), configVector.end(), configName) ==
+ configVector.end()) {
+ configVector.push_back(configName);
+ }
+ // Add a pair of config and item to target-item map
+ auto& itemVector = targetItemMap[libName];
+ itemVector.emplace_back(ConfigItemPair(configName, &libItem));
+ // Add product file-name to a lib-product map
+ auto productName = cmSystemTools::GetFilenameName(libItem.Value.Value);
+ auto& productVector = targetProductNameMap[libName];
+ if (std::find(productVector.begin(), productVector.end(),
+ productName) == productVector.end()) {
+ productVector.push_back(productName);
+ }
+ } else {
+ // Add this library item to a regular linker flag list
+ addToLinkerArguments(configName, &libItem);
+ }
+ }
+ }
+
+ // Go through target library map and separate libraries that are linked
+ // in all configurations and produce only single product, from the rest.
+ // Only these will be linked through "Link Binary With Libraries" build
+ // phase.
+ for (auto const& targetLibConfigs : targetConfigMap) {
+ // Add this library to "Link Binary With Libraries" build phase if it's
+ // linked in all configurations and it has only one product name
+ auto& itemVector = targetItemMap[targetLibConfigs.first];
+ auto& productVector = targetProductNameMap[targetLibConfigs.first];
+ if (targetLibConfigs.second == this->CurrentConfigurationTypes &&
+ productVector.size() == 1) {
+ // Add this library to "Link Binary With Libraries" list
+ linkPhaseTargetVector.push_back(itemVector[0].second);
+ } else {
+ for (auto const& libItem : targetItemMap[targetLibConfigs.first]) {
+ // Add this library item to a regular linker flag list
+ addToLinkerArguments(libItem.first, libItem.second);
+ }
+ }
+ }
+
+ // Add libraries to "Link Binary With Libraries" build phase and collect
+ // their search paths. Xcode does not support per-configuration linking
+ // in this build phase so we don't have to do this for each configuration
+ // separately.
+ std::vector<std::string> linkSearchPaths;
+ for (auto const& libItem : linkPhaseTargetVector) {
+ // Add target output directory as a library search path
+ std::string linkDir = cmSystemTools::GetParentDirectory(
+ libItem->Target->GetLocationForBuild());
+ if (std::find(linkSearchPaths.begin(), linkSearchPaths.end(), linkDir) ==
+ linkSearchPaths.end()) {
+ linkSearchPaths.push_back(linkDir);
+ }
+ // Add target dependency
+ auto const& libName = *libItem;
+ if (!libName.Target->IsImported()) {
+ for (auto const& configName : this->CurrentConfigurationTypes) {
+ target->AddDependTarget(configName, libName.Target->GetName());
+ }
+ }
+ // Get the library target
+ auto* libTarget = FindXCodeTarget(libItem->Target);
+ if (!libTarget) {
+ continue;
+ }
+ // Add the target output file as a build reference for other targets
+ // to link against
+ auto* fileRefObject = libTarget->GetObject("productReference");
+ if (!fileRefObject) {
+ continue;
+ }
+ cmXCodeObject* buildFile;
+ auto it = FileRefToBuildFileMap.find(fileRefObject);
+ if (it == FileRefToBuildFileMap.end()) {
+ buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile);
+ buildFile->AddAttribute("fileRef", fileRefObject);
+ FileRefToBuildFileMap[fileRefObject] = buildFile;
+ } else {
+ buildFile = it->second;
+ }
+ // Add this reference to current target
+ auto* buildPhases = target->GetObject("buildPhases");
+ if (!buildPhases) {
+ continue;
+ }
+ auto* frameworkBuildPhase =
+ buildPhases->GetObject(cmXCodeObject::PBXFrameworksBuildPhase);
+ if (!frameworkBuildPhase) {
+ continue;
+ }
+ auto* buildFiles = frameworkBuildPhase->GetObject("files");
+ if (!buildFiles) {
+ continue;
+ }
+ if (!buildFiles->HasObject(buildFile)) {
+ buildFiles->AddObject(buildFile);
+ }
+ }
+
// Loop over configuration types and set per-configuration info.
for (auto const& configName : this->CurrentConfigurationTypes) {
{
@@ -2787,21 +2944,20 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
}
// Compute the link library and directory information.
- cmComputeLinkInformation* pcli = gt->GetLinkInformation(configName);
- if (!pcli) {
+ cmComputeLinkInformation* cli = gt->GetLinkInformation(configName);
+ if (!cli) {
continue;
}
- cmComputeLinkInformation& cli = *pcli;
// Add dependencies directly on library files.
- for (auto const& libDep : cli.GetDepends()) {
+ for (auto const& libDep : cli->GetDepends()) {
target->AddDependLibrary(configName, libDep);
}
// add the library search paths
{
std::string linkDirs;
- for (auto const& libDir : cli.GetDirectories()) {
+ for (auto const& libDir : cli->GetDirectories()) {
if (!libDir.empty() && libDir != "/usr/lib") {
// Now add the same one but append
// $(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) to it:
@@ -2812,15 +2968,22 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
linkDirs += this->XCodeEscapePath(libDir);
}
}
+ // Add previously collected paths where to look for libraries
+ // that were added to "Link Binary With Libraries"
+ for (auto& linkDir : linkSearchPaths) {
+ linkDirs += " ";
+ linkDirs += this->XCodeEscapePath(linkDir);
+ }
this->AppendBuildSettingAttribute(target, "LIBRARY_SEARCH_PATHS",
linkDirs.c_str(), configName);
}
- // now add the link libraries
+ // now add the left-over link libraries
{
std::string linkLibs;
const char* sep = "";
- for (auto const& libName : cli.GetItems()) {
+ for (auto const& libItem : configItemMap[configName]) {
+ auto const& libName = *libItem;
linkLibs += sep;
sep = " ";
if (libName.IsPath) {
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index e380f1c..0fc6558 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -28,7 +28,7 @@ struct cmDocumentationEntry;
/** \class cmGlobalXCodeGenerator
* \brief Write a Unix makefiles.
*
- * cmGlobalXCodeGenerator manages UNIX build process for a tree
+ * cmGlobalXCodeGenerator manages Xcode build process for a tree
*/
class cmGlobalXCodeGenerator : public cmGlobalGenerator
{
@@ -295,6 +295,7 @@ private:
std::map<std::string, cmXCodeObject*> TargetGroup;
std::map<std::string, cmXCodeObject*> FileRefs;
std::map<cmGeneratorTarget const*, cmXCodeObject*> XCodeObjectMap;
+ std::map<cmXCodeObject*, cmXCodeObject*> FileRefToBuildFileMap;
std::vector<std::string> Architectures;
std::string ObjectDirArchDefault;
std::string ObjectDirArch;
diff --git a/Source/cmLinkItemGraphVisitor.cxx b/Source/cmLinkItemGraphVisitor.cxx
index acc23c8..b13def8 100644
--- a/Source/cmLinkItemGraphVisitor.cxx
+++ b/Source/cmLinkItemGraphVisitor.cxx
@@ -24,10 +24,6 @@ void cmLinkItemGraphVisitor::VisitItem(cmLinkItem const& item)
void cmLinkItemGraphVisitor::VisitLinks(cmLinkItem const& item,
cmLinkItem const& rootItem)
{
- if (this->LinkVisited(item, rootItem)) {
- return;
- }
-
if (item.Target == nullptr) {
return;
}
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 3b3f110..95caa30 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -803,39 +803,8 @@ bool cmLocalGenerator::ComputeTargetCompileFeatures()
// Now that C/C++ _STANDARD values have been computed
// set the values to ObjC/ObjCXX _STANDARD variables
if (target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
- auto copyStandardToObjLang = [&](LanguagePair const& lang) -> bool {
- if (!target->GetProperty(cmStrCat(lang.first, "_STANDARD"))) {
- cmProp standard =
- target->GetProperty(cmStrCat(lang.second, "_STANDARD"));
- if (!standard) {
- standard = this->Makefile->GetDef(
- cmStrCat("CMAKE_", lang.second, "_STANDARD_DEFAULT"));
- }
- target->Target->SetProperty(cmStrCat(lang.first, "_STANDARD"),
- standard ? standard->c_str() : nullptr);
- return true;
- }
- return false;
- };
- auto copyPropertyToObjLang = [&](LanguagePair const& lang,
- const char* property) {
- if (!target->GetProperty(cmStrCat(lang.first, property)) &&
- target->GetProperty(cmStrCat(lang.second, property))) {
- cmProp p = target->GetProperty(cmStrCat(lang.second, property));
- target->Target->SetProperty(cmStrCat(lang.first, property),
- p ? p->c_str() : nullptr);
- }
- };
- for (auto const& lang : pairedLanguages) {
- if (copyStandardToObjLang(lang)) {
- copyPropertyToObjLang(lang, "_STANDARD_REQUIRED");
- copyPropertyToObjLang(lang, "_EXTENSIONS");
- }
- }
- if (cmProp standard = target->GetProperty("CUDA_STANDARD")) {
- if (*standard == "98") {
- target->Target->SetProperty("CUDA_STANDARD", "03");
- }
+ for (std::string const& c : configNames) {
+ target->ComputeCompileFeatures(c, inferredEnabledLanguages);
}
}
}
@@ -1026,7 +995,7 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
}
for (auto const& it : target->GetMaxLanguageStandards()) {
- cmProp standard = target->GetProperty(it.first + "_STANDARD");
+ cmProp standard = target->GetLanguageStandard(it.first, config);
if (!standard) {
continue;
}
@@ -1050,7 +1019,7 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
}
std::string compReqFlag;
- this->AddCompilerRequirementFlag(compReqFlag, target, lang);
+ this->AddCompilerRequirementFlag(compReqFlag, target, lang, config);
if (!compReqFlag.empty()) {
flags.emplace_back(std::move(compReqFlag));
}
@@ -2046,7 +2015,7 @@ void cmLocalGenerator::AddLanguageFlagsForLinking(
// when linking in order to use the matching standard library.
// FIXME: If CMake gains an abstraction for standard library
// selection, this will have to be reconciled with it.
- this->AddCompilerRequirementFlag(flags, target, lang);
+ this->AddCompilerRequirementFlag(flags, target, lang, config);
}
this->AddLanguageFlags(flags, target, lang, config);
@@ -2189,7 +2158,8 @@ void cmLocalGenerator::AddSharedFlags(std::string& flags,
}
void cmLocalGenerator::AddCompilerRequirementFlag(
- std::string& flags, cmGeneratorTarget const* target, const std::string& lang)
+ std::string& flags, cmGeneratorTarget const* target, const std::string& lang,
+ const std::string& config)
{
if (lang.empty()) {
return;
@@ -2200,15 +2170,13 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
// This compiler has no notion of language standard levels.
return;
}
- std::string extProp = lang + "_EXTENSIONS";
bool ext = true;
- if (cmProp extPropValue = target->GetProperty(extProp)) {
+ if (cmProp extPropValue = target->GetLanguageExtensions(lang)) {
if (cmIsOff(*extPropValue)) {
ext = false;
}
}
- std::string stdProp = lang + "_STANDARD";
- cmProp standardProp = target->GetProperty(stdProp);
+ cmProp standardProp = target->GetLanguageStandard(lang, config);
if (!standardProp) {
if (ext) {
// No language standard is specified and extensions are not disabled.
@@ -2228,7 +2196,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
std::string const type = ext ? "EXTENSION" : "STANDARD";
- if (target->GetPropertyAsBool(lang + "_STANDARD_REQUIRED")) {
+ if (target->GetLanguageStandardRequired(lang)) {
std::string option_flag =
"CMAKE_" + lang + *standardProp + "_" + type + "_COMPILE_OPTION";
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index f2d9145..f4781d6 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -123,7 +123,8 @@ public:
const std::string& config);
void AddCompilerRequirementFlag(std::string& flags,
cmGeneratorTarget const* target,
- const std::string& lang);
+ const std::string& lang,
+ const std::string& config);
//! Append flags to a string.
virtual void AppendFlags(std::string& flags,
const std::string& newFlags) const;
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 4545a8e..de1461a 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -713,9 +713,10 @@ void cmLocalUnixMakefileGenerator3::WriteSpecialTargetsTop(
// "VERBOSE=1" to be added as a make variable which will change the
// name of this special target. This gives a make-time choice to
// the user.
- this->WriteMakeRule(makefileStream,
- "Suppress display of executed commands.",
- "$(VERBOSE).SILENT", no_depends, no_commands, false);
+ // Write directly to the stream since WriteMakeRule escapes '$'.
+ makefileStream << "#Suppress display of executed commands.\n"
+ "$(VERBOSE).SILENT:\n"
+ "\n";
}
// Work-around for makes that drop rules that have no dependencies
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index c78b751..d34259f 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -39,6 +39,7 @@
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionEvaluationFile.h"
+#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmInstallGenerator.h" // IWYU pragma: keep
#include "cmInstallSubdirectoryGenerator.h"
@@ -1658,7 +1659,8 @@ void cmMakefile::Configure()
this->SetCheckCMP0000(true);
// Implicitly set the version for the user.
- this->SetPolicyVersion("2.4", std::string());
+ cmPolicies::ApplyPolicyVersion(this, 2, 4, 0,
+ cmPolicies::WarnCompat::Off);
}
}
bool hasProject = false;
@@ -4027,6 +4029,8 @@ int cmMakefile::ConfigureFile(const std::string& infile,
if (copyonly) {
if (!cmSystemTools::CopyFileIfDifferent(sinfile, soutfile)) {
+ this->IssueMessage(MessageType::FATAL_ERROR,
+ cmSystemTools::GetLastSystemError());
return 0;
}
} else {
@@ -4077,9 +4081,15 @@ int cmMakefile::ConfigureFile(const std::string& infile,
fin.close();
fout.close();
if (!cmSystemTools::CopyFileIfDifferent(tempOutputFile, soutfile)) {
+ this->IssueMessage(MessageType::FATAL_ERROR,
+ cmSystemTools::GetLastSystemError());
res = 0;
} else {
- cmSystemTools::SetPermissions(soutfile, perm);
+ if (!cmSystemTools::SetPermissions(soutfile, perm)) {
+ this->IssueMessage(MessageType::FATAL_ERROR,
+ cmSystemTools::GetLastSystemError());
+ res = 0;
+ }
}
cmSystemTools::RemoveFile(tempOutputFile);
}
@@ -4554,7 +4564,7 @@ bool cmMakefile::SetPolicy(cmPolicies::PolicyID id,
// Deprecate old policies, especially those that require a lot
// of code to maintain the old behavior.
- if (status == cmPolicies::OLD && id <= cmPolicies::CMP0071 &&
+ if (status == cmPolicies::OLD && id <= cmPolicies::CMP0072 &&
!(this->GetCMakeInstance()->GetIsInTryCompile() &&
(
// Policies set by cmCoreTryCompile::TryCompileCode.
@@ -4596,7 +4606,7 @@ void cmMakefile::PopSnapshot(bool reportError)
// cmStateSnapshot manages nested policy scopes within it.
// Since the scope corresponding to the snapshot is closing,
// reject any still-open nested policy scopes with an error.
- while (!this->StateSnapshot.CanPopPolicyScope()) {
+ while (this->StateSnapshot.CanPopPolicyScope()) {
if (reportError) {
this->IssueMessage(MessageType::FATAL_ERROR,
"cmake_policy PUSH without matching POP");
@@ -4612,7 +4622,8 @@ void cmMakefile::PopSnapshot(bool reportError)
bool cmMakefile::SetPolicyVersion(std::string const& version_min,
std::string const& version_max)
{
- return cmPolicies::ApplyPolicyVersion(this, version_min, version_max);
+ return cmPolicies::ApplyPolicyVersion(this, version_min, version_max,
+ cmPolicies::WarnCompat::On);
}
bool cmMakefile::HasCMP0054AlreadyBeenReported(
@@ -4673,7 +4684,33 @@ bool cmMakefile::AddRequiredTargetFeature(cmTarget* target,
}
std::string lang;
- if (!this->CompileFeatureKnown(target, feature, lang, error)) {
+ if (!this->CheckCompileFeaturesAvailable(target->GetName(), feature, lang,
+ error)) {
+ return false;
+ }
+
+ target->AppendProperty("COMPILE_FEATURES", feature);
+
+ // FIXME: Add a policy to avoid updating the <LANG>_STANDARD target
+ // property due to COMPILE_FEATURES. The language standard selection
+ // should be done purely at generate time based on whatever the project
+ // code put in these properties explicitly. That is mostly true now,
+ // but for compatibility we need to continue updating the property here.
+ if (lang == "C" || lang == "OBJC") {
+ return this->AddRequiredTargetCFeature(target, feature, lang, error);
+ }
+ if (lang == "CUDA") {
+ return this->AddRequiredTargetCudaFeature(target, feature, lang, error);
+ }
+ return this->AddRequiredTargetCxxFeature(target, feature, lang, error);
+}
+
+bool cmMakefile::CheckCompileFeaturesAvailable(const std::string& targetName,
+ const std::string& feature,
+ std::string& lang,
+ std::string* error) const
+{
+ if (!this->CompileFeatureKnown(targetName, feature, lang, error)) {
return false;
}
@@ -4699,18 +4736,10 @@ bool cmMakefile::AddRequiredTargetFeature(cmTarget* target,
return false;
}
- target->AppendProperty("COMPILE_FEATURES", feature);
-
- if (lang == "C" || lang == "OBJC") {
- return this->AddRequiredTargetCFeature(target, feature, lang, error);
- }
- if (lang == "CUDA") {
- return this->AddRequiredTargetCudaFeature(target, feature, lang, error);
- }
- return this->AddRequiredTargetCxxFeature(target, feature, lang, error);
+ return true;
}
-bool cmMakefile::CompileFeatureKnown(cmTarget const* target,
+bool cmMakefile::CompileFeatureKnown(const std::string& targetName,
const std::string& feature,
std::string& lang,
std::string* error) const
@@ -4747,7 +4776,7 @@ bool cmMakefile::CompileFeatureKnown(cmTarget const* target,
e << " unknown feature \"" << feature
<< "\" for "
"target \""
- << target->GetName() << "\".";
+ << targetName << "\".";
if (error) {
*error = e.str();
} else {
@@ -4802,22 +4831,50 @@ const char* cmMakefile::CompileFeaturesAvailable(const std::string& lang,
return featuresKnown;
}
-bool cmMakefile::HaveStandardAvailable(cmTarget const* target,
+bool cmMakefile::GetNewRequiredStandard(const std::string& targetName,
+ const std::string& feature,
+ cmProp currentLangStandardValue,
+ std::string& newRequiredStandard,
+ std::string* error) const
+{
+ std::string lang;
+ if (!this->CheckCompileFeaturesAvailable(targetName, feature, lang, error)) {
+ return false;
+ }
+
+ if (lang == "C" || lang == "OBJC") {
+ return this->GetNewRequiredCStandard(targetName, feature, lang,
+ currentLangStandardValue,
+ newRequiredStandard, error);
+ }
+ if (lang == "CUDA") {
+ return this->GetNewRequiredCudaStandard(targetName, feature, lang,
+ currentLangStandardValue,
+ newRequiredStandard, error);
+ }
+ return this->GetNewRequiredCxxStandard(targetName, feature, lang,
+ currentLangStandardValue,
+ newRequiredStandard, error);
+}
+
+bool cmMakefile::HaveStandardAvailable(cmGeneratorTarget const* target,
std::string const& lang,
+ std::string const& config,
const std::string& feature) const
{
if (lang == "C" || lang == "OBJC") {
- return this->HaveCStandardAvailable(target, feature, lang);
+ return this->HaveCStandardAvailable(target, lang, config, feature);
}
if (lang == "CUDA") {
- return this->HaveCudaStandardAvailable(target, feature, lang);
+ return this->HaveCudaStandardAvailable(target, lang, config, feature);
}
- return this->HaveCxxStandardAvailable(target, feature, lang);
+ return this->HaveCxxStandardAvailable(target, lang, config, feature);
}
-bool cmMakefile::HaveCStandardAvailable(cmTarget const* target,
- const std::string& feature,
- std::string const& lang) const
+bool cmMakefile::HaveCStandardAvailable(cmGeneratorTarget const* target,
+ std::string const& lang,
+ std::string const& config,
+ const std::string& feature) const
{
cmProp defaultCStandard =
this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
@@ -4846,7 +4903,7 @@ bool cmMakefile::HaveCStandardAvailable(cmTarget const* target,
this->CheckNeededCLanguage(feature, lang, needC90, needC99, needC11);
- cmProp existingCStandard = target->GetProperty(cmStrCat(lang, "_STANDARD"));
+ cmProp existingCStandard = target->GetLanguageStandard(lang, config);
if (!existingCStandard) {
existingCStandard = defaultCStandard;
}
@@ -4909,9 +4966,10 @@ bool cmMakefile::IsLaterStandard(std::string const& lang,
cm::cend(CXX_STANDARDS);
}
-bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
- const std::string& feature,
- std::string const& lang) const
+bool cmMakefile::HaveCxxStandardAvailable(cmGeneratorTarget const* target,
+ std::string const& lang,
+ std::string const& config,
+ const std::string& feature) const
{
cmProp defaultCxxStandard =
this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
@@ -4941,8 +4999,7 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
this->CheckNeededCxxLanguage(feature, lang, needCxx98, needCxx11, needCxx14,
needCxx17, needCxx20);
- cmProp existingCxxStandard =
- target->GetProperty(cmStrCat(lang, "_STANDARD"));
+ cmProp existingCxxStandard = target->GetLanguageStandard(lang, config);
if (!existingCxxStandard) {
existingCxxStandard = defaultCxxStandard;
}
@@ -5009,6 +5066,29 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
std::string const& lang,
std::string* error) const
{
+ std::string newRequiredStandard;
+ if (this->GetNewRequiredCxxStandard(
+ target->GetName(), feature, lang,
+ target->GetProperty(cmStrCat(lang, "_STANDARD")), newRequiredStandard,
+ error)) {
+ if (!newRequiredStandard.empty()) {
+ target->SetLanguageStandardProperty(lang, newRequiredStandard, feature);
+ }
+ return true;
+ }
+
+ return false;
+}
+
+bool cmMakefile::GetNewRequiredCxxStandard(const std::string& targetName,
+ const std::string& feature,
+ std::string const& lang,
+ cmProp currentLangStandardValue,
+ std::string& newRequiredStandard,
+ std::string* error) const
+{
+ newRequiredStandard.clear();
+
bool needCxx98 = false;
bool needCxx11 = false;
bool needCxx14 = false;
@@ -5018,8 +5098,7 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
this->CheckNeededCxxLanguage(feature, lang, needCxx98, needCxx11, needCxx14,
needCxx17, needCxx20);
- cmProp existingCxxStandard =
- target->GetProperty(cmStrCat(lang, "_STANDARD"));
+ cmProp existingCxxStandard = currentLangStandardValue;
if (existingCxxStandard == nullptr) {
cmProp defaultCxxStandard =
this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
@@ -5034,7 +5113,7 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
cmStrCmp(*existingCxxStandard));
if (existingCxxLevel == cm::cend(CXX_STANDARDS)) {
const std::string e = cmStrCat(
- "The ", lang, "_STANDARD property on target \"", target->GetName(),
+ "The ", lang, "_STANDARD property on target \"", targetName,
"\" contained an invalid value: \"", *existingCxxStandard, "\".");
if (error) {
*error = e;
@@ -5060,16 +5139,17 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
// Ensure the C++ language level is high enough to support
// the needed C++ features.
if (!existingCxxLevel || existingCxxLevel < needCxxLevel) {
- target->SetProperty(cmStrCat(lang, "_STANDARD"), *needCxxLevel);
+ newRequiredStandard = *needCxxLevel;
}
}
return true;
}
-bool cmMakefile::HaveCudaStandardAvailable(cmTarget const* target,
- const std::string& feature,
- std::string const& lang) const
+bool cmMakefile::HaveCudaStandardAvailable(cmGeneratorTarget const* target,
+ std::string const& lang,
+ std::string const& config,
+ const std::string& feature) const
{
cmProp defaultCudaStandard =
this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
@@ -5100,8 +5180,7 @@ bool cmMakefile::HaveCudaStandardAvailable(cmTarget const* target,
this->CheckNeededCudaLanguage(feature, lang, needCuda03, needCuda11,
needCuda14, needCuda17, needCuda20);
- cmProp existingCudaStandard =
- target->GetProperty(cmStrCat(lang, "_STANDARD"));
+ cmProp existingCudaStandard = target->GetLanguageStandard(lang, config);
if (!existingCudaStandard) {
existingCudaStandard = defaultCudaStandard;
}
@@ -5168,6 +5247,28 @@ bool cmMakefile::AddRequiredTargetCudaFeature(cmTarget* target,
std::string const& lang,
std::string* error) const
{
+ std::string newRequiredStandard;
+ if (this->GetNewRequiredCudaStandard(
+ target->GetName(), feature, lang,
+ target->GetProperty(cmStrCat(lang, "_STANDARD")), newRequiredStandard,
+ error)) {
+ if (!newRequiredStandard.empty()) {
+ target->SetLanguageStandardProperty(lang, newRequiredStandard, feature);
+ }
+ return true;
+ }
+ return false;
+}
+
+bool cmMakefile::GetNewRequiredCudaStandard(const std::string& targetName,
+ const std::string& feature,
+ std::string const& lang,
+ cmProp currentLangStandardValue,
+ std::string& newRequiredStandard,
+ std::string* error) const
+{
+ newRequiredStandard.clear();
+
bool needCuda03 = false;
bool needCuda11 = false;
bool needCuda14 = false;
@@ -5177,8 +5278,7 @@ bool cmMakefile::AddRequiredTargetCudaFeature(cmTarget* target,
this->CheckNeededCudaLanguage(feature, lang, needCuda03, needCuda11,
needCuda14, needCuda17, needCuda20);
- cmProp existingCudaStandard =
- target->GetProperty(cmStrCat(lang, "_STANDARD"));
+ cmProp existingCudaStandard = currentLangStandardValue;
if (existingCudaStandard == nullptr) {
cmProp defaultCudaStandard =
this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
@@ -5193,7 +5293,7 @@ bool cmMakefile::AddRequiredTargetCudaFeature(cmTarget* target,
cmStrCmp(*existingCudaStandard));
if (existingCudaLevel == cm::cend(CUDA_STANDARDS)) {
const std::string e = cmStrCat(
- "The ", lang, "_STANDARD property on target \"", target->GetName(),
+ "The ", lang, "_STANDARD property on target \"", targetName,
"\" contained an invalid value: \"", *existingCudaStandard, "\".");
if (error) {
*error = e;
@@ -5219,7 +5319,7 @@ bool cmMakefile::AddRequiredTargetCudaFeature(cmTarget* target,
// Ensure the CUDA language level is high enough to support
// the needed CUDA features.
if (!existingCudaLevel || existingCudaLevel < needCudaLevel) {
- target->SetProperty("CUDA_STANDARD", *needCudaLevel);
+ newRequiredStandard = *needCudaLevel;
}
}
@@ -5252,13 +5352,36 @@ bool cmMakefile::AddRequiredTargetCFeature(cmTarget* target,
std::string const& lang,
std::string* error) const
{
+ std::string newRequiredStandard;
+ if (this->GetNewRequiredCStandard(
+ target->GetName(), feature, lang,
+ target->GetProperty(cmStrCat(lang, "_STANDARD")), newRequiredStandard,
+ error)) {
+ if (!newRequiredStandard.empty()) {
+ target->SetLanguageStandardProperty(lang, newRequiredStandard, feature);
+ }
+ return true;
+ }
+
+ return false;
+}
+
+bool cmMakefile::GetNewRequiredCStandard(const std::string& targetName,
+ const std::string& feature,
+ std::string const& lang,
+ cmProp currentLangStandardValue,
+ std::string& newRequiredStandard,
+ std::string* error) const
+{
+ newRequiredStandard.clear();
+
bool needC90 = false;
bool needC99 = false;
bool needC11 = false;
this->CheckNeededCLanguage(feature, lang, needC90, needC99, needC11);
- cmProp existingCStandard = target->GetProperty(cmStrCat(lang, "_STANDARD"));
+ cmProp existingCStandard = currentLangStandardValue;
if (existingCStandard == nullptr) {
cmProp defaultCStandard =
this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
@@ -5270,7 +5393,7 @@ bool cmMakefile::AddRequiredTargetCFeature(cmTarget* target,
if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
cmStrCmp(*existingCStandard)) == cm::cend(C_STANDARDS)) {
const std::string e = cmStrCat(
- "The ", lang, "_STANDARD property on target \"", target->GetName(),
+ "The ", lang, "_STANDARD property on target \"", targetName,
"\" contained an invalid value: \"", *existingCStandard, "\".");
if (error) {
*error = e;
@@ -5307,11 +5430,11 @@ bool cmMakefile::AddRequiredTargetCFeature(cmTarget* target,
}
if (setC11) {
- target->SetProperty(cmStrCat(lang, "_STANDARD"), "11");
+ newRequiredStandard = "11";
} else if (setC99) {
- target->SetProperty(cmStrCat(lang, "_STANDARD"), "99");
+ newRequiredStandard = "99";
} else if (setC90) {
- target->SetProperty(cmStrCat(lang, "_STANDARD"), "90");
+ newRequiredStandard = "90";
}
return true;
}
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 45d7109..332554e 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -47,6 +47,7 @@ class cmExpandedCommandArgument;
class cmExportBuildFileGenerator;
class cmFunctionBlocker;
class cmGeneratorExpressionEvaluationFile;
+class cmGeneratorTarget;
class cmGlobalGenerator;
class cmImplicitDependsList;
class cmInstallGenerator;
@@ -928,13 +929,22 @@ public:
bool AddRequiredTargetFeature(cmTarget* target, const std::string& feature,
std::string* error = nullptr) const;
- bool CompileFeatureKnown(cmTarget const* target, const std::string& feature,
- std::string& lang, std::string* error) const;
+ bool CompileFeatureKnown(const std::string& targetName,
+ const std::string& feature, std::string& lang,
+ std::string* error) const;
const char* CompileFeaturesAvailable(const std::string& lang,
std::string* error) const;
- bool HaveStandardAvailable(cmTarget const* target, std::string const& lang,
+ bool GetNewRequiredStandard(const std::string& targetName,
+ const std::string& feature,
+ cmProp currentLangStandardValue,
+ std::string& newRequiredStandard,
+ std::string* error = nullptr) const;
+
+ bool HaveStandardAvailable(cmGeneratorTarget const* target,
+ std::string const& lang,
+ std::string const& config,
const std::string& feature) const;
bool IsLaterStandard(std::string const& lang, std::string const& lhs,
@@ -1174,6 +1184,11 @@ private:
std::string const& lang,
std::string* error = nullptr) const;
+ bool CheckCompileFeaturesAvailable(const std::string& targetName,
+ const std::string& feature,
+ std::string& lang,
+ std::string* error) const;
+
void CheckNeededCLanguage(const std::string& feature,
std::string const& lang, bool& needC90,
bool& needC99, bool& needC11) const;
@@ -1186,15 +1201,37 @@ private:
bool& needCuda11, bool& needCuda14,
bool& needCuda17, bool& needCuda20) const;
- bool HaveCStandardAvailable(cmTarget const* target,
- const std::string& feature,
- std::string const& lang) const;
- bool HaveCxxStandardAvailable(cmTarget const* target,
- const std::string& feature,
- std::string const& lang) const;
- bool HaveCudaStandardAvailable(cmTarget const* target,
+ bool GetNewRequiredCStandard(const std::string& targetName,
+ const std::string& feature,
+ std::string const& lang,
+ cmProp currentLangStandardValue,
+ std::string& newRequiredStandard,
+ std::string* error = nullptr) const;
+ bool GetNewRequiredCxxStandard(const std::string& targetName,
const std::string& feature,
- std::string const& lang) const;
+ std::string const& lang,
+ cmProp currentLangStandardValue,
+ std::string& newRequiredStandard,
+ std::string* error = nullptr) const;
+ bool GetNewRequiredCudaStandard(const std::string& targetName,
+ const std::string& feature,
+ std::string const& lang,
+ cmProp currentLangStandardValue,
+ std::string& newRequiredStandard,
+ std::string* error = nullptr) const;
+
+ bool HaveCStandardAvailable(cmGeneratorTarget const* target,
+ std::string const& lang,
+ std::string const& config,
+ const std::string& feature) const;
+ bool HaveCxxStandardAvailable(cmGeneratorTarget const* target,
+ std::string const& lang,
+ std::string const& config,
+ const std::string& feature) const;
+ bool HaveCudaStandardAvailable(cmGeneratorTarget const* target,
+ std::string const& lang,
+ std::string const& config,
+ const std::string& feature) const;
void CheckForUnusedVariables() const;
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 8396fa3..6887569 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -532,6 +532,13 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
// Build the set of compiler flags.
std::string flags;
+ // explicitly add the explicit language flag before any other flag
+ // this way backwards compatibility with user flags is maintained
+ if (source.GetProperty("LANGUAGE")) {
+ this->LocalGenerator->AppendFeatureOptions(flags, lang,
+ "EXPLICIT_LANGUAGE");
+ }
+
// Add language-specific flags.
std::string langFlags = cmStrCat("$(", lang, "_FLAGS", filterArch, ")");
this->LocalGenerator->AppendFlags(flags, langFlags);
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index d406c99..0c7591a 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -188,7 +188,16 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
}
}
- std::string flags = this->GetFlags(language, config, filterArch);
+ std::string flags;
+ // explicitly add the explicit language flag before any other flag
+ // this way backwards compatibility with user flags is maintained
+ if (source->GetProperty("LANGUAGE")) {
+ this->LocalGenerator->AppendFeatureOptions(flags, language,
+ "EXPLICIT_LANGUAGE");
+ flags += " ";
+ }
+
+ flags += this->GetFlags(language, config, filterArch);
// Add Fortran format flags.
if (language == "Fortran") {
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index dea3f8a..01e8c04 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -7,9 +7,11 @@
#include <sstream>
#include <vector>
+#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmState.h"
+#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -157,7 +159,8 @@ static bool GetPolicyDefault(cmMakefile* mf, std::string const& policy,
bool cmPolicies::ApplyPolicyVersion(cmMakefile* mf,
std::string const& version_min,
- std::string const& version_max)
+ std::string const& version_max,
+ WarnCompat warnCompat)
{
// Parse components of the minimum version.
unsigned int minMajor = 2;
@@ -244,13 +247,34 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile* mf,
polPatch = maxPatch;
}
- return cmPolicies::ApplyPolicyVersion(mf, polMajor, polMinor, polPatch);
+ return cmPolicies::ApplyPolicyVersion(mf, polMajor, polMinor, polPatch,
+ warnCompat);
}
bool cmPolicies::ApplyPolicyVersion(cmMakefile* mf, unsigned int majorVer,
unsigned int minorVer,
- unsigned int patchVer)
+ unsigned int patchVer,
+ WarnCompat warnCompat)
{
+ // Warn about policy versions for which support will be removed.
+ if (warnCompat == WarnCompat::On &&
+ (majorVer < 2 || (majorVer == 2 && minorVer < 8) ||
+ (majorVer == 2 && minorVer == 8 && patchVer < 12)) &&
+ // Avoid warning on calls generated by install(EXPORT)
+ // in CMake versions prior to 3.18.
+ !(majorVer == 2 && minorVer == 6 && patchVer == 0 &&
+ mf->GetStateSnapshot().CanPopPolicyScope() &&
+ cmSystemTools::Strucmp(mf->GetBacktrace().Top().Name.c_str(),
+ "cmake_policy") == 0)) {
+ mf->IssueMessage(
+ MessageType::DEPRECATION_WARNING,
+ "Compatibility with CMake < 2.8.12 will be removed from "
+ "a future version of CMake.\n"
+ "Update the VERSION argument <min> value or use a ...<max> suffix "
+ "to tell CMake that the project does not need compatibility with "
+ "older versions.");
+ }
+
// now loop over all the policies and set them as appropriate
std::vector<cmPolicies::PolicyID> ancientPolicies;
for (PolicyID pid = cmPolicies::CMP0000; pid != cmPolicies::CMPCOUNT;
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index a82f421..bba8b03 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -320,7 +320,10 @@ class cmMakefile;
SELECT(POLICY, CMP0107, "An ALIAS target cannot overwrite another target.", \
3, 18, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0108, "A target cannot link to itself through an alias.", \
- 3, 18, 0, cmPolicies::WARN)
+ 3, 18, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0109, \
+ "find_program() requires permission to execute but not to read.", 3, \
+ 19, 0, cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \
@@ -396,12 +399,20 @@ public:
//! Get the default status for a policy
static cmPolicies::PolicyStatus GetPolicyStatus(cmPolicies::PolicyID id);
+ enum class WarnCompat
+ {
+ Off,
+ On
+ };
+
//! Set a policy level for this listfile
static bool ApplyPolicyVersion(cmMakefile* mf,
std::string const& version_min,
- std::string const& version_max);
+ std::string const& version_max,
+ WarnCompat warnCompat);
static bool ApplyPolicyVersion(cmMakefile* mf, unsigned int majorVer,
- unsigned int minorVer, unsigned int patchVer);
+ unsigned int minorVer, unsigned int patchVer,
+ WarnCompat warnCompat);
//! return a warning string for a given policy
static std::string GetPolicyWarning(cmPolicies::PolicyID id);
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 511a018..e733a3e 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -789,9 +789,9 @@ bool cmQtAutoGenInitializer::InitScanFiles()
// Register files that will be scanned by moc or uic
if (this->MocOrUicEnabled()) {
- if (cm->IsHeaderExtension(extLower)) {
+ if (cm->IsAHeaderExtension(extLower)) {
addMUHeader(makeMUFile(sf, fullPath, true), extLower);
- } else if (cm->IsSourceExtension(extLower)) {
+ } else if (cm->IsACLikeSourceExtension(extLower)) {
addMUSource(makeMUFile(sf, fullPath, true));
}
}
@@ -895,14 +895,14 @@ bool cmQtAutoGenInitializer::InitScanFiles()
std::string const& extLower =
cmSystemTools::LowerCase(sf->GetExtension());
- if (cm->IsHeaderExtension(extLower)) {
+ if (cm->IsAHeaderExtension(extLower)) {
if (!cm::contains(this->AutogenTarget.Headers, sf.get())) {
auto muf = makeMUFile(sf.get(), fullPath, false);
if (muf->SkipMoc || muf->SkipUic) {
addMUHeader(std::move(muf), extLower);
}
}
- } else if (cm->IsSourceExtension(extLower)) {
+ } else if (cm->IsACLikeSourceExtension(extLower)) {
if (!cm::contains(this->AutogenTarget.Sources, sf.get())) {
auto muf = makeMUFile(sf.get(), fullPath, false);
if (muf->SkipMoc || muf->SkipUic) {
diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
index f525439..781ddbc 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -2,7 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmSourceFile.h"
-#include <array>
#include <utility>
#include "cmGlobalGenerator.h"
@@ -130,13 +129,11 @@ bool cmSourceFile::FindFullPath(std::string* error)
// Location path
std::string const& lPath = this->Location.GetFullPath();
// List of extension lists
- std::array<std::vector<std::string> const*, 2> const extsLists = {
- { &makefile->GetCMakeInstance()->GetSourceExtensions(),
- &makefile->GetCMakeInstance()->GetHeaderExtensions() }
- };
+ std::vector<std::string> exts =
+ makefile->GetCMakeInstance()->GetAllExtensions();
// Tries to find the file in a given directory
- auto findInDir = [this, &extsLists, &lPath](std::string const& dir) -> bool {
+ auto findInDir = [this, &exts, &lPath](std::string const& dir) -> bool {
// Compute full path
std::string const fullPath = cmSystemTools::CollapseFullPath(lPath, dir);
// Try full path
@@ -145,14 +142,12 @@ bool cmSourceFile::FindFullPath(std::string* error)
return true;
}
// Try full path with extension
- for (auto& exts : extsLists) {
- for (std::string const& ext : *exts) {
- if (!ext.empty()) {
- std::string extPath = cmStrCat(fullPath, '.', ext);
- if (cmSystemTools::FileExists(extPath)) {
- this->FullPath = extPath;
- return true;
- }
+ for (std::string const& ext : exts) {
+ if (!ext.empty()) {
+ std::string extPath = cmStrCat(fullPath, '.', ext);
+ if (cmSystemTools::FileExists(extPath)) {
+ this->FullPath = extPath;
+ return true;
}
}
}
@@ -175,11 +170,9 @@ bool cmSourceFile::FindFullPath(std::string* error)
// Compose error
std::string err =
cmStrCat("Cannot find source file:\n ", lPath, "\nTried extensions");
- for (auto exts : extsLists) {
- for (std::string const& ext : *exts) {
- err += " .";
- err += ext;
- }
+ for (std::string const& ext : exts) {
+ err += " .";
+ err += ext;
}
if (error != nullptr) {
*error = std::move(err);
diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx
index e852c05..222bafa 100644
--- a/Source/cmSourceFileLocation.cxx
+++ b/Source/cmSourceFileLocation.cxx
@@ -101,7 +101,7 @@ void cmSourceFileLocation::UpdateExtension(const std::string& name)
cmMakefile const* mf = this->Makefile;
auto cm = mf->GetCMakeInstance();
if (!gg->GetLanguageFromExtension(ext.c_str()).empty() ||
- cm->IsSourceExtension(ext) || cm->IsHeaderExtension(ext)) {
+ cm->IsAKnownExtension(ext)) {
// This is a known extension. Use the given filename with extension.
this->Name = cmSystemTools::GetFilenameName(name);
this->AmbiguousExtension = false;
@@ -157,7 +157,7 @@ bool cmSourceFileLocation::MatchesAmbiguousExtension(
auto ext = cm::string_view(this->Name).substr(loc.Name.size() + 1);
cmMakefile const* mf = this->Makefile;
auto cm = mf->GetCMakeInstance();
- return cm->IsSourceExtension(ext) || cm->IsHeaderExtension(ext);
+ return cm->IsAKnownExtension(ext);
}
bool cmSourceFileLocation::Matches(cmSourceFileLocation const& loc)
diff --git a/Source/cmStateSnapshot.cxx b/Source/cmStateSnapshot.cxx
index c223431..15a98af 100644
--- a/Source/cmStateSnapshot.cxx
+++ b/Source/cmStateSnapshot.cxx
@@ -148,7 +148,7 @@ bool cmStateSnapshot::PopPolicy()
bool cmStateSnapshot::CanPopPolicyScope()
{
- return this->Position->Policies == this->Position->PolicyScope;
+ return this->Position->Policies != this->Position->PolicyScope;
}
void cmStateSnapshot::SetPolicy(cmPolicies::PolicyID id,
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 36e1ad5..9f9b6f9 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -7,6 +7,7 @@
#include <cstring>
#include <initializer_list>
#include <iterator>
+#include <map>
#include <set>
#include <sstream>
#include <unordered_set>
@@ -185,6 +186,7 @@ public:
std::vector<cmInstallTargetGenerator*> InstallGenerators;
std::set<std::string> SystemIncludeDirectories;
cmTarget::LinkLibraryVectorType OriginalLinkLibraries;
+ std::map<std::string, BT<std::string>> LanguageStandardProperties;
std::vector<std::string> IncludeDirectoriesEntries;
std::vector<cmListFileBacktrace> IncludeDirectoriesBacktraces;
std::vector<std::string> CompileOptionsEntries;
@@ -598,6 +600,35 @@ cmGlobalGenerator* cmTarget::GetGlobalGenerator() const
return impl->Makefile->GetGlobalGenerator();
}
+BT<std::string> const* cmTarget::GetLanguageStandardProperty(
+ const std::string& propertyName) const
+{
+ auto entry = impl->LanguageStandardProperties.find(propertyName);
+ if (entry != impl->LanguageStandardProperties.end()) {
+ return &entry->second;
+ }
+
+ return nullptr;
+}
+
+void cmTarget::SetLanguageStandardProperty(std::string const& lang,
+ std::string const& value,
+ const std::string& feature)
+{
+ cmListFileBacktrace featureBacktrace;
+ for (size_t i = 0; i < impl->CompileFeaturesEntries.size(); i++) {
+ if (impl->CompileFeaturesEntries[i] == feature) {
+ if (i < impl->CompileFeaturesBacktraces.size()) {
+ featureBacktrace = impl->CompileFeaturesBacktraces[i];
+ }
+ break;
+ }
+ }
+
+ impl->LanguageStandardProperties[cmStrCat(lang, "_STANDARD")] =
+ BT<std::string>(value, featureBacktrace);
+}
+
void cmTarget::AddUtility(std::string const& name, bool cross, cmMakefile* mf)
{
impl->Utilities.insert(BT<std::pair<std::string, bool>>(
@@ -636,6 +667,12 @@ bool cmTarget::IsAppBundleOnApple() const
this->GetPropertyAsBool("MACOSX_BUNDLE"));
}
+bool cmTarget::IsAndroidGuiExecutable() const
+{
+ return (this->GetType() == cmStateEnums::EXECUTABLE && impl->IsAndroid &&
+ this->GetPropertyAsBool("ANDROID_GUI"));
+}
+
std::vector<cmCustomCommand> const& cmTarget::GetPreBuildCommands() const
{
return impl->PreBuildCommands;
@@ -1127,6 +1164,11 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
return;
}
#define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP
+ MAKE_STATIC_PROP(C_STANDARD);
+ MAKE_STATIC_PROP(CXX_STANDARD);
+ MAKE_STATIC_PROP(CUDA_STANDARD);
+ MAKE_STATIC_PROP(OBJC_STANDARD);
+ MAKE_STATIC_PROP(OBJCXX_STANDARD);
MAKE_STATIC_PROP(COMPILE_DEFINITIONS);
MAKE_STATIC_PROP(COMPILE_FEATURES);
MAKE_STATIC_PROP(COMPILE_OPTIONS);
@@ -1310,6 +1352,15 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
cmProp tmp = reusedTarget->GetProperty("COMPILE_PDB_NAME");
this->SetProperty("COMPILE_PDB_NAME", tmp ? tmp->c_str() : nullptr);
this->AddUtility(reusedFrom, false, impl->Makefile);
+ } else if (prop == propC_STANDARD || prop == propCXX_STANDARD ||
+ prop == propCUDA_STANDARD || prop == propOBJC_STANDARD ||
+ prop == propOBJCXX_STANDARD) {
+ if (value) {
+ impl->LanguageStandardProperties[prop] =
+ BT<std::string>(value, impl->Makefile->GetBacktrace());
+ } else {
+ impl->LanguageStandardProperties.erase(prop);
+ }
} else {
impl->Properties.SetProperty(prop, value);
}
@@ -1413,6 +1464,11 @@ void cmTarget::AppendProperty(const std::string& prop,
} else if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME")) {
impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
prop + " property may not be APPENDed.");
+ } else if (prop == "C_STANDARD" || prop == "CXX_STANDARD" ||
+ prop == "CUDA_STANDARD" || prop == "OBJC_STANDARD" ||
+ prop == "OBJCXX_STANDARD") {
+ impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
+ prop + " property may not be appended.");
} else {
impl->Properties.AppendProperty(prop, value, asString);
}
@@ -1626,6 +1682,11 @@ cmProp cmTarget::GetComputedProperty(const std::string& prop,
cmProp cmTarget::GetProperty(const std::string& prop) const
{
#define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP
+ MAKE_STATIC_PROP(C_STANDARD);
+ MAKE_STATIC_PROP(CXX_STANDARD);
+ MAKE_STATIC_PROP(CUDA_STANDARD);
+ MAKE_STATIC_PROP(OBJC_STANDARD);
+ MAKE_STATIC_PROP(OBJCXX_STANDARD);
MAKE_STATIC_PROP(LINK_LIBRARIES);
MAKE_STATIC_PROP(TYPE);
MAKE_STATIC_PROP(INCLUDE_DIRECTORIES);
@@ -1646,6 +1707,11 @@ cmProp cmTarget::GetProperty(const std::string& prop) const
MAKE_STATIC_PROP(TRUE);
#undef MAKE_STATIC_PROP
static std::unordered_set<std::string> const specialProps{
+ propC_STANDARD,
+ propCXX_STANDARD,
+ propCUDA_STANDARD,
+ propOBJC_STANDARD,
+ propOBJCXX_STANDARD,
propLINK_LIBRARIES,
propTYPE,
propINCLUDE_DIRECTORIES,
@@ -1664,6 +1730,15 @@ cmProp cmTarget::GetProperty(const std::string& prop) const
propSOURCES
};
if (specialProps.count(prop)) {
+ if (prop == propC_STANDARD || prop == propCXX_STANDARD ||
+ prop == propCUDA_STANDARD || prop == propOBJC_STANDARD ||
+ prop == propOBJCXX_STANDARD) {
+ auto propertyIter = impl->LanguageStandardProperties.find(prop);
+ if (propertyIter == impl->LanguageStandardProperties.end()) {
+ return nullptr;
+ }
+ return &(propertyIter->second.Value);
+ }
if (prop == propLINK_LIBRARIES) {
if (impl->LinkImplementationPropertyEntries.empty()) {
return nullptr;
@@ -1865,7 +1940,7 @@ const char* cmTarget::GetSuffixVariableInternal(
case cmStateEnums::RuntimeBinaryArtifact:
// Android GUI application packages store the native
// binary as a shared library.
- return (impl->IsAndroid && this->GetPropertyAsBool("ANDROID_GUI")
+ return (this->IsAndroidGuiExecutable()
? "CMAKE_SHARED_LIBRARY_SUFFIX"
: "CMAKE_EXECUTABLE_SUFFIX");
case cmStateEnums::ImportLibraryArtifact:
@@ -1906,7 +1981,7 @@ const char* cmTarget::GetPrefixVariableInternal(
case cmStateEnums::RuntimeBinaryArtifact:
// Android GUI application packages store the native
// binary as a shared library.
- return (impl->IsAndroid && this->GetPropertyAsBool("ANDROID_GUI")
+ return (this->IsAndroidGuiExecutable()
? "CMAKE_SHARED_LIBRARY_PREFIX"
: "");
case cmStateEnums::ImportLibraryArtifact:
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index f0ddb68..b3d6fe0 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -209,6 +209,9 @@ public:
//! Return whether this target is an executable Bundle on Apple.
bool IsAppBundleOnApple() const;
+ //! Return whether this target is a GUI executable on Android.
+ bool IsAndroidGuiExecutable() const;
+
//! Get a backtrace from the creation of the target.
cmListFileBacktrace const& GetBacktrace() const;
@@ -233,6 +236,13 @@ public:
void AddSystemIncludeDirectories(std::set<std::string> const& incs);
std::set<std::string> const& GetSystemIncludeDirectories() const;
+ BT<std::string> const* GetLanguageStandardProperty(
+ const std::string& propertyName) const;
+
+ void SetLanguageStandardProperty(std::string const& lang,
+ std::string const& value,
+ const std::string& feature);
+
cmStringRange GetIncludeDirectoriesEntries() const;
cmBacktraceRange GetIncludeDirectoriesBacktraces() const;
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index a3ccd2b..10a4a0c 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -234,13 +234,14 @@ cmVisualStudio10TargetGenerator::cmVisualStudio10TargetGenerator(
{
this->Makefile->GetConfigurations(this->Configurations);
this->NsightTegra = gg->IsNsightTegra();
+ this->Android = gg->TargetsAndroid();
for (int i = 0; i < 4; ++i) {
this->NsightTegraVersion[i] = 0;
}
sscanf(gg->GetNsightTegraVersion().c_str(), "%u.%u.%u.%u",
&this->NsightTegraVersion[0], &this->NsightTegraVersion[1],
&this->NsightTegraVersion[2], &this->NsightTegraVersion[3]);
- this->MSTools = !this->NsightTegra;
+ this->MSTools = !this->NsightTegra && !this->Android;
this->Managed = false;
this->TargetCompileAsWinRT = false;
this->IsMissingFiles = false;
@@ -333,6 +334,13 @@ void cmVisualStudio10TargetGenerator::Generate()
this->ProjectType = csproj;
this->Managed = true;
}
+
+ if (this->Android &&
+ this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE &&
+ !this->GeneratorTarget->Target->IsAndroidGuiExecutable()) {
+ this->GlobalGenerator->AddAndroidExecutableWarning(this->Name);
+ }
+
// Tell the global generator the name of the project file
this->GeneratorTarget->Target->SetProperty("GENERATOR_FILE_NAME",
this->Name);
@@ -427,7 +435,7 @@ void cmVisualStudio10TargetGenerator::Generate()
e1.Attribute("Label", "Globals");
e1.Element("ProjectGuid", "{" + this->GUID + "}");
- if (this->MSTools &&
+ if ((this->MSTools || this->Android) &&
this->GeneratorTarget->GetType() <= cmStateEnums::GLOBAL_TARGET) {
this->WriteApplicationTypeSettings(e1);
this->VerifyNecessaryFiles();
@@ -469,7 +477,11 @@ void cmVisualStudio10TargetGenerator::Generate()
cmProp vsGlobalKeyword =
this->GeneratorTarget->GetProperty("VS_GLOBAL_KEYWORD");
if (!vsGlobalKeyword) {
- e1.Element("Keyword", "Win32Proj");
+ if (this->GlobalGenerator->TargetsAndroid()) {
+ e1.Element("Keyword", "Android");
+ } else {
+ e1.Element("Keyword", "Win32Proj");
+ }
} else {
e1.Element("Keyword", *vsGlobalKeyword);
}
@@ -1134,9 +1146,11 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues(Elem& e0)
break;
case cmStateEnums::EXECUTABLE:
if (this->NsightTegra &&
- !this->GeneratorTarget->GetPropertyAsBool("ANDROID_GUI")) {
+ !this->GeneratorTarget->Target->IsAndroidGuiExecutable()) {
// Android executables are .so too.
configType = "DynamicLibrary";
+ } else if (this->Android) {
+ configType = "DynamicLibrary";
} else {
configType = "Application";
}
@@ -1166,6 +1180,8 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues(Elem& e0)
}
} else if (this->NsightTegra) {
this->WriteNsightTegraConfigurationValues(e1, c);
+ } else if (this->Android) {
+ this->WriteAndroidConfigurationValues(e1, c);
}
}
}
@@ -1324,6 +1340,24 @@ void cmVisualStudio10TargetGenerator::WriteNsightTegraConfigurationValues(
}
}
+void cmVisualStudio10TargetGenerator::WriteAndroidConfigurationValues(
+ Elem& e1, std::string const&)
+{
+ cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator;
+ if (cmProp projectToolsetOverride =
+ this->GeneratorTarget->GetProperty("VS_PLATFORM_TOOLSET")) {
+ e1.Element("PlatformToolset", *projectToolsetOverride);
+ } else if (const char* toolset = gg->GetPlatformToolset()) {
+ e1.Element("PlatformToolset", toolset);
+ }
+ if (cmProp stlType =
+ this->GeneratorTarget->GetProperty("ANDROID_STL_TYPE")) {
+ if (*stlType != "none") {
+ e1.Element("UseOfStl", *stlType);
+ }
+ }
+}
+
void cmVisualStudio10TargetGenerator::WriteCustomCommands(Elem& e0)
{
this->CSharpCustomCommandNames.clear();
@@ -2909,7 +2943,9 @@ void cmVisualStudio10TargetGenerator::WriteClOptions(
}
}
- if (this->MSTools) {
+ if (this->Android) {
+ e2.Element("ObjectFileName", "$(IntDir)%(filename).o");
+ } else if (this->MSTools) {
cmsys::RegularExpression clangToolset("v[0-9]+_clang_.*");
const char* toolset = this->GlobalGenerator->GetPlatformToolset();
if (toolset && clangToolset.find(toolset)) {
@@ -4015,8 +4051,7 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups(Elem& e0)
// output manifest flags <Manifest></Manifest>
this->WriteManifestOptions(e1, c);
if (this->NsightTegra &&
- this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE &&
- this->GeneratorTarget->GetPropertyAsBool("ANDROID_GUI")) {
+ this->GeneratorTarget->Target->IsAndroidGuiExecutable()) {
this->WriteAntBuildOptions(e1, c);
}
}
@@ -4131,8 +4166,9 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0)
}
// Don't reference targets that don't produce any output.
- if (dt->GetManagedType(this->Configurations[0]) ==
- cmGeneratorTarget::ManagedType::Undefined) {
+ if (this->Configurations.empty() ||
+ dt->GetManagedType(this->Configurations[0]) ==
+ cmGeneratorTarget::ManagedType::Undefined) {
e2.Element("ReferenceOutputAssembly", "false");
e2.Element("CopyToOutputDirectory", "Never");
}
@@ -4348,6 +4384,7 @@ void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings(Elem& e1)
bool isAppContainer = false;
bool const isWindowsPhone = this->GlobalGenerator->TargetsWindowsPhone();
bool const isWindowsStore = this->GlobalGenerator->TargetsWindowsStore();
+ bool const isAndroid = this->GlobalGenerator->TargetsAndroid();
std::string const& rev = this->GlobalGenerator->GetApplicationTypeRevision();
if (isWindowsPhone || isWindowsStore) {
e1.Element("ApplicationType",
@@ -4385,13 +4422,19 @@ void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings(Elem& e1)
this->Name + "_$(Configuration)_$(Platform).xap");
}
}
+ } else if (isAndroid) {
+ e1.Element("ApplicationType", "Android");
+ e1.Element("ApplicationTypeRevision",
+ gg->GetAndroidApplicationTypeRevision());
}
if (isAppContainer) {
e1.Element("AppContainerApplication", "true");
- } else if (this->Platform == "ARM64") {
- e1.Element("WindowsSDKDesktopARM64Support", "true");
- } else if (this->Platform == "ARM") {
- e1.Element("WindowsSDKDesktopARMSupport", "true");
+ } else if (!isAndroid) {
+ if (this->Platform == "ARM64") {
+ e1.Element("WindowsSDKDesktopARM64Support", "true");
+ } else if (this->Platform == "ARM") {
+ e1.Element("WindowsSDKDesktopARMSupport", "true");
+ }
}
std::string const& targetPlatformVersion =
gg->GetWindowsTargetPlatformVersion();
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 7c71de3..c54057a 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -70,6 +70,7 @@ private:
void WriteExtraSource(Elem& e1, cmSourceFile const* sf);
void WriteNsightTegraConfigurationValues(Elem& e1,
std::string const& config);
+ void WriteAndroidConfigurationValues(Elem& e1, std::string const& config);
void WriteSource(Elem& e2, cmSourceFile const* sf);
void WriteExcludeFromBuild(Elem& e2,
std::vector<size_t> const& exclude_configs);
@@ -215,6 +216,7 @@ private:
bool MSTools;
bool Managed;
bool NsightTegra;
+ bool Android;
unsigned int NsightTegraVersion[4];
bool TargetCompileAsWinRT;
std::set<std::string> IPOEnabledConfigurations;
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 162e807..27ecb4d 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -64,10 +64,6 @@
# include "cmVariableWatch.h"
#endif
-#if !defined(CMAKE_BOOTSTRAP)
-# define CMAKE_USE_ECLIPSE
-#endif
-
#if defined(__MINGW32__) && defined(CMAKE_BOOTSTRAP)
# define CMAKE_BOOT_MINGW
#endif
@@ -101,16 +97,13 @@
#if !defined(CMAKE_BOOTSTRAP)
# include "cmGlobalNinjaGenerator.h"
#endif
-#include "cmExtraCodeLiteGenerator.h"
-#if !defined(CMAKE_BOOT_MINGW)
+#if !defined(CMAKE_BOOTSTRAP)
# include "cmExtraCodeBlocksGenerator.h"
-#endif
-#include "cmExtraKateGenerator.h"
-#include "cmExtraSublimeTextGenerator.h"
-
-#ifdef CMAKE_USE_ECLIPSE
+# include "cmExtraCodeLiteGenerator.h"
# include "cmExtraEclipseCDT4Generator.h"
+# include "cmExtraKateGenerator.h"
+# include "cmExtraSublimeTextGenerator.h"
#endif
#if defined(__linux__) || defined(_WIN32)
@@ -201,7 +194,7 @@ cmake::cmake(Role role, cmState::Mode mode)
};
// The "c" extension MUST precede the "C" extension.
- setupExts(this->SourceFileExtensions,
+ setupExts(this->CLikeSourceFileExtensions,
{ "c", "C", "c++", "cc", "cpp", "cxx", "cu", "m", "M", "mm" });
setupExts(this->HeaderFileExtensions,
{ "h", "hh", "h++", "hm", "hpp", "hxx", "in", "txx" });
@@ -1137,13 +1130,9 @@ void cmake::AddDefaultExtraGenerators()
#if !defined(CMAKE_BOOTSTRAP)
this->ExtraGenerators.push_back(cmExtraCodeBlocksGenerator::GetFactory());
this->ExtraGenerators.push_back(cmExtraCodeLiteGenerator::GetFactory());
- this->ExtraGenerators.push_back(cmExtraSublimeTextGenerator::GetFactory());
- this->ExtraGenerators.push_back(cmExtraKateGenerator::GetFactory());
-
-# ifdef CMAKE_USE_ECLIPSE
this->ExtraGenerators.push_back(cmExtraEclipseCDT4Generator::GetFactory());
-# endif
-
+ this->ExtraGenerators.push_back(cmExtraKateGenerator::GetFactory());
+ this->ExtraGenerators.push_back(cmExtraSublimeTextGenerator::GetFactory());
#endif
}
@@ -1970,6 +1959,17 @@ void cmake::AddGlobCacheEntry(bool recurse, bool listDirectories,
backtrace);
}
+std::vector<std::string> cmake::GetAllExtensions() const
+{
+ std::vector<std::string> allExt = this->CLikeSourceFileExtensions.ordered;
+ allExt.insert(allExt.end(), this->HeaderFileExtensions.ordered.begin(),
+ this->HeaderFileExtensions.ordered.end());
+ // cuda extensions are also in SourceFileExtensions so we ignore it here
+ allExt.insert(allExt.end(), this->FortranFileExtensions.ordered.begin(),
+ this->FortranFileExtensions.ordered.end());
+ return allExt;
+}
+
std::string cmake::StripExtension(const std::string& file) const
{
auto dotpos = file.rfind('.');
@@ -1979,7 +1979,7 @@ std::string cmake::StripExtension(const std::string& file) const
#else
auto ext = cm::string_view(file).substr(dotpos + 1);
#endif
- if (this->IsSourceExtension(ext) || this->IsHeaderExtension(ext)) {
+ if (this->IsAKnownExtension(ext)) {
return file.substr(0, dotpos);
}
}
diff --git a/Source/cmake.h b/Source/cmake.h
index 086ec87..c5d608f 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -264,44 +264,33 @@ public:
this->GeneratorToolsetSet = true;
}
- const std::vector<std::string>& GetSourceExtensions() const
+ bool IsAKnownSourceExtension(cm::string_view ext) const
{
- return this->SourceFileExtensions.ordered;
+ return this->CLikeSourceFileExtensions.Test(ext) ||
+ this->CudaFileExtensions.Test(ext) ||
+ this->FortranFileExtensions.Test(ext);
}
- bool IsSourceExtension(cm::string_view ext) const
+ bool IsACLikeSourceExtension(cm::string_view ext) const
{
- return this->SourceFileExtensions.Test(ext);
+ return this->CLikeSourceFileExtensions.Test(ext);
}
- const std::vector<std::string>& GetHeaderExtensions() const
- {
- return this->HeaderFileExtensions.ordered;
- }
-
- bool IsHeaderExtension(cm::string_view ext) const
- {
- return this->HeaderFileExtensions.Test(ext);
- }
-
- const std::vector<std::string>& GetCudaExtensions() const
+ bool IsAKnownExtension(cm::string_view ext) const
{
- return this->CudaFileExtensions.ordered;
+ return this->IsAKnownSourceExtension(ext) || this->IsAHeaderExtension(ext);
}
- bool IsCudaExtension(cm::string_view ext) const
- {
- return this->CudaFileExtensions.Test(ext);
- }
+ std::vector<std::string> GetAllExtensions() const;
- const std::vector<std::string>& GetFortranExtensions() const
+ const std::vector<std::string>& GetHeaderExtensions() const
{
- return this->FortranFileExtensions.ordered;
+ return this->HeaderFileExtensions.ordered;
}
- bool IsFortranExtension(cm::string_view ext) const
+ bool IsAHeaderExtension(cm::string_view ext) const
{
- return this->FortranFileExtensions.Test(ext);
+ return this->HeaderFileExtensions.Test(ext);
}
// Strips the extension (if present and known) from a filename
@@ -628,7 +617,7 @@ private:
std::string CheckStampList;
std::string VSSolutionFile;
std::string EnvironmentGenerator;
- FileExtensions SourceFileExtensions;
+ FileExtensions CLikeSourceFileExtensions;
FileExtensions HeaderFileExtensions;
FileExtensions CudaFileExtensions;
FileExtensions FortranFileExtensions;
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index 75280fb..9fa6705 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -3,11 +3,13 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <algorithm>
#include <cassert>
#include <cctype>
#include <climits>
#include <cstring>
#include <iostream>
+#include <sstream>
#include <string>
#include <vector>
@@ -517,6 +519,121 @@ int do_build(int ac, char const* const* av)
#endif
}
+bool parse_default_directory_permissions(const std::string& permissions,
+ std::string& parsedPermissionsVar)
+{
+ std::vector<std::string> parsedPermissions;
+ enum Doing
+ {
+ DoingNone,
+ DoingOwner,
+ DoingGroup,
+ DoingWorld,
+ DoingOwnerAssignment,
+ DoingGroupAssignment,
+ DoingWorldAssignment,
+ };
+ Doing doing = DoingNone;
+
+ auto uniquePushBack = [&parsedPermissions](const std::string& e) {
+ if (std::find(parsedPermissions.begin(), parsedPermissions.end(), e) ==
+ parsedPermissions.end()) {
+ parsedPermissions.push_back(e);
+ }
+ };
+
+ for (auto const& e : permissions) {
+ switch (doing) {
+ case DoingNone:
+ if (e == 'u') {
+ doing = DoingOwner;
+ } else if (e == 'g') {
+ doing = DoingGroup;
+ } else if (e == 'o') {
+ doing = DoingWorld;
+ } else {
+ return false;
+ }
+ break;
+ case DoingOwner:
+ if (e == '=') {
+ doing = DoingOwnerAssignment;
+ } else {
+ return false;
+ }
+ break;
+ case DoingGroup:
+ if (e == '=') {
+ doing = DoingGroupAssignment;
+ } else {
+ return false;
+ }
+ break;
+ case DoingWorld:
+ if (e == '=') {
+ doing = DoingWorldAssignment;
+ } else {
+ return false;
+ }
+ break;
+ case DoingOwnerAssignment:
+ if (e == 'r') {
+ uniquePushBack("OWNER_READ");
+ } else if (e == 'w') {
+ uniquePushBack("OWNER_WRITE");
+ } else if (e == 'x') {
+ uniquePushBack("OWNER_EXECUTE");
+ } else if (e == ',') {
+ doing = DoingNone;
+ } else {
+ return false;
+ }
+ break;
+ case DoingGroupAssignment:
+ if (e == 'r') {
+ uniquePushBack("GROUP_READ");
+ } else if (e == 'w') {
+ uniquePushBack("GROUP_WRITE");
+ } else if (e == 'x') {
+ uniquePushBack("GROUP_EXECUTE");
+ } else if (e == ',') {
+ doing = DoingNone;
+ } else {
+ return false;
+ }
+ break;
+ case DoingWorldAssignment:
+ if (e == 'r') {
+ uniquePushBack("WORLD_READ");
+ } else if (e == 'w') {
+ uniquePushBack("WORLD_WRITE");
+ } else if (e == 'x') {
+ uniquePushBack("WORLD_EXECUTE");
+ } else if (e == ',') {
+ doing = DoingNone;
+ } else {
+ return false;
+ }
+ break;
+ }
+ }
+ if (doing != DoingOwnerAssignment && doing != DoingGroupAssignment &&
+ doing != DoingWorldAssignment) {
+ return false;
+ }
+
+ std::ostringstream oss;
+ for (auto i = 0u; i < parsedPermissions.size(); i++) {
+ if (i != 0) {
+ oss << ";";
+ }
+ oss << parsedPermissions[i];
+ }
+
+ parsedPermissionsVar = oss.str();
+ return true;
+}
+
int do_install(int ac, char const* const* av)
{
#ifdef CMAKE_BOOTSTRAP
@@ -527,6 +644,7 @@ int do_install(int ac, char const* const* av)
std::string config;
std::string component;
+ std::string defaultDirectoryPermissions;
std::string prefix;
std::string dir;
bool strip = false;
@@ -539,6 +657,7 @@ int do_install(int ac, char const* const* av)
DoingConfig,
DoingComponent,
DoingPrefix,
+ DoingDefaultDirectoryPermissions,
};
Doing doing = DoingDir;
@@ -557,6 +676,8 @@ int do_install(int ac, char const* const* av)
(strcmp(av[i], "-v") == 0)) {
verbose = true;
doing = DoingNone;
+ } else if (strcmp(av[i], "--default-directory-permissions") == 0) {
+ doing = DoingDefaultDirectoryPermissions;
} else {
switch (doing) {
case DoingDir:
@@ -575,6 +696,10 @@ int do_install(int ac, char const* const* av)
prefix = av[i];
doing = DoingNone;
break;
+ case DoingDefaultDirectoryPermissions:
+ defaultDirectoryPermissions = av[i];
+ doing = DoingNone;
+ break;
default:
std::cerr << "Unknown argument " << av[i] << std::endl;
dir.clear();
@@ -591,6 +716,8 @@ int do_install(int ac, char const* const* av)
" <dir> = Project binary directory to install.\n"
" --config <cfg> = For multi-configuration tools, choose <cfg>.\n"
" --component <comp> = Component-based install. Only install <comp>.\n"
+ " --default-directory-permissions <permission> \n"
+ " Default install permission. Use default permission <permission>.\n"
" --prefix <prefix> = The installation prefix CMAKE_INSTALL_PREFIX.\n"
" --strip = Performing install/strip.\n"
" -v --verbose = Enable verbose output.\n"
@@ -631,6 +758,18 @@ int do_install(int ac, char const* const* av)
args.emplace_back("-DCMAKE_INSTALL_CONFIG_NAME=" + config);
}
+ if (!defaultDirectoryPermissions.empty()) {
+ std::string parsedPermissionsVar;
+ if (!parse_default_directory_permissions(defaultDirectoryPermissions,
+ parsedPermissionsVar)) {
+ std::cerr << "--default-directory-permissions is in incorrect format"
+ << std::endl;
+ return 1;
+ }
+ args.emplace_back("-DCMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS=" +
+ parsedPermissionsVar);
+ }
+
args.emplace_back("-P");
args.emplace_back(dir + "/cmake_install.cmake");
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index de76d73..6882fdd 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -582,12 +582,10 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
filesDiffer = cmsys::SystemTools::TextFilesDiffer(args[3], args[4]);
} else {
::CMakeCommandUsage(args[0].c_str());
- return 1;
+ return 2;
}
if (filesDiffer) {
- std::cerr << "Files \"" << args[args.size() - 2] << "\" to \""
- << args[args.size() - 1] << "\" are different.\n";
return 1;
}
return 0;