summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt27
-rw-r--r--Source/CMakeVersion.cmake4
-rw-r--r--Source/CMakeVersion.rc.in34
-rw-r--r--Source/CPack/WiX/cmCMakeToWixPath.cxx39
-rw-r--r--Source/CPack/WiX/cmCMakeToWixPath.h12
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.cxx41
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.h9
-rw-r--r--Source/CPack/WiX/cmWIXFilesSourceWriter.cxx4
-rw-r--r--Source/CPack/cmCPackDragNDropGenerator.cxx20
-rw-r--r--Source/CPack/cmCPackGeneratorFactory.cxx4
-rw-r--r--Source/LexerParser/cmCommandArgumentLexer.cxx21
-rw-r--r--Source/LexerParser/cmCommandArgumentLexer.in.l21
-rw-r--r--Source/Modules/FindLibUUID.cmake85
-rw-r--r--Source/QtDialog/CMakeSetupDialog.cxx36
-rw-r--r--Source/QtDialog/CMakeSetupDialog.h1
-rw-r--r--Source/QtDialog/QCMake.cxx29
-rw-r--r--Source/QtDialog/QCMake.h8
-rw-r--r--Source/cmAddCustomTargetCommand.cxx34
-rw-r--r--Source/cmAddExecutableCommand.cxx53
-rw-r--r--Source/cmAddLibraryCommand.cxx47
-rw-r--r--Source/cmAlgorithms.h77
-rw-r--r--Source/cmCMakeHostSystemInformationCommand.cxx14
-rw-r--r--Source/cmCTest.cxx3
-rw-r--r--Source/cmCommandArgumentParserHelper.cxx39
-rw-r--r--Source/cmCommandArgumentParserHelper.h19
-rw-r--r--Source/cmCurl.cxx38
-rw-r--r--Source/cmCurl.h2
-rw-r--r--Source/cmExternalMakefileProjectGenerator.cxx7
-rw-r--r--Source/cmExternalMakefileProjectGenerator.h3
-rw-r--r--Source/cmExtraSublimeTextGenerator.cxx23
-rw-r--r--Source/cmExtraSublimeTextGenerator.h3
-rw-r--r--Source/cmFileCommand.cxx58
-rw-r--r--Source/cmFilePathChecksum.cxx10
-rw-r--r--Source/cmForEachCommand.cxx5
-rw-r--r--Source/cmGeneratorExpressionNode.cxx4
-rw-r--r--Source/cmGlobalGenerator.cxx247
-rw-r--r--Source/cmGlobalGenerator.h14
-rw-r--r--Source/cmGlobalVisualStudio15Generator.cxx47
-rw-r--r--Source/cmGlobalVisualStudio15Generator.h5
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx42
-rw-r--r--Source/cmGlobalVisualStudioGenerator.h3
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx92
-rw-r--r--Source/cmGlobalXCodeGenerator.h7
-rw-r--r--Source/cmLinkedTree.h6
-rw-r--r--Source/cmLocalGenerator.cxx4
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx100
-rw-r--r--Source/cmLocalVisualStudio7Generator.h4
-rw-r--r--Source/cmLocalVisualStudioGenerator.h2
-rw-r--r--Source/cmMakefile.cxx161
-rw-r--r--Source/cmMakefile.h7
-rw-r--r--Source/cmPolicies.h1
-rw-r--r--Source/cmQtAutoGen.cxx4
-rw-r--r--Source/cmServerDictionary.h2
-rw-r--r--Source/cmServerProtocol.cxx34
-rw-r--r--Source/cmSetCommand.cxx14
-rw-r--r--Source/cmSystemTools.cxx35
-rw-r--r--Source/cmSystemTools.h4
-rw-r--r--Source/cmTargetCompileDefinitionsCommand.cxx11
-rw-r--r--Source/cmTargetCompileDefinitionsCommand.h1
-rw-r--r--Source/cmTargetCompileFeaturesCommand.cxx13
-rw-r--r--Source/cmTargetCompileFeaturesCommand.h1
-rw-r--r--Source/cmTargetCompileOptionsCommand.cxx13
-rw-r--r--Source/cmTargetCompileOptionsCommand.h1
-rw-r--r--Source/cmTargetIncludeDirectoriesCommand.cxx14
-rw-r--r--Source/cmTargetIncludeDirectoriesCommand.h1
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx30
-rw-r--r--Source/cmTargetPropCommandBase.cxx15
-rw-r--r--Source/cmTargetPropCommandBase.h1
-rw-r--r--Source/cmTargetSourcesCommand.cxx9
-rw-r--r--Source/cmTargetSourcesCommand.h1
-rw-r--r--Source/cmTimestamp.cxx6
-rw-r--r--Source/cmTryRunCommand.cxx9
-rw-r--r--Source/cmUnsetCommand.cxx13
-rw-r--r--Source/cmVS141CLFlagTable.h4
-rw-r--r--Source/cmVSSetupHelper.cxx36
-rw-r--r--Source/cmVSSetupHelper.h4
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx40
-rw-r--r--Source/cm_codecvt.cxx14
-rw-r--r--Source/cmake.cxx91
-rw-r--r--Source/cmake.h10
-rw-r--r--Source/cmakemain.cxx43
-rw-r--r--Source/cmcmd.cxx13
-rw-r--r--Source/kwsys/CMakeLists.txt7
-rw-r--r--Source/kwsys/CommandLineArguments.cxx25
-rw-r--r--Source/kwsys/DynamicLoader.cxx17
-rw-r--r--Source/kwsys/ProcessUNIX.c28
-rw-r--r--Source/kwsys/ProcessWin32.c15
-rw-r--r--Source/kwsys/SystemInformation.cxx2
-rw-r--r--Source/kwsys/SystemTools.cxx17
-rw-r--r--Source/kwsys/kwsysPlatformTestsC.c15
-rw-r--r--Source/kwsys/testEncoding.cxx5
-rw-r--r--Source/kwsys/testProcess.c4
-rw-r--r--Source/kwsys/testSystemTools.cxx10
93 files changed, 1567 insertions, 641 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index a4dd918..f15dff8 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -936,8 +936,13 @@ if(UNIX)
endif()
endif()
-if(WIN32)
+if(CYGWIN)
+ find_package(LibUUID)
+endif()
+if(WIN32 OR (CYGWIN AND LibUUID_FOUND))
set(CPACK_SRCS ${CPACK_SRCS}
+ CPack/Wix/cmCMakeToWixPath.cxx
+ CPack/Wix/cmCMakeToWixPath.h
CPack/WiX/cmCPackWIXGenerator.cxx
CPack/WiX/cmCPackWIXGenerator.h
CPack/WiX/cmWIXAccessControlList.cxx
@@ -958,7 +963,7 @@ if(WIN32)
CPack/WiX/cmWIXShortcut.h
CPack/WiX/cmWIXSourceWriter.cxx
CPack/WiX/cmWIXSourceWriter.h
- )
+ )
endif()
if(APPLE)
@@ -991,6 +996,11 @@ if(APPLE)
"See CMakeFiles/CMakeError.log for details of the failure.")
endif()
endif()
+if(CYGWIN AND LibUUID_FOUND)
+ target_link_libraries(CPackLib ${LibUUID_LIBRARIES})
+ include_directories(CPackLib ${LibUUID_INCLUDE_DIRS})
+ set_property(SOURCE CPack/cmCPackGeneratorFactory.cxx PROPERTY COMPILE_DEFINITIONS HAVE_LIBUUID)
+endif()
if(CPACK_ENABLE_FREEBSD_PKG AND FREEBSD_PKG_INCLUDE_DIRS AND FREEBSD_PKG_LIBRARIES)
target_link_libraries(CPackLib ${FREEBSD_PKG_LIBRARIES})
include_directories(${FREEBSD_PKG_INCLUDE_DIRS})
@@ -1047,6 +1057,19 @@ endif()
include (${CMake_BINARY_DIR}/Source/LocalUserOptions.cmake OPTIONAL)
include (${CMake_SOURCE_DIR}/Source/LocalUserOptions.cmake OPTIONAL)
+if(WIN32)
+ # Add Windows executable version information.
+ configure_file("CMakeVersion.rc.in" "CMakeVersion.rc" @ONLY)
+
+ # We use a separate object library for this to work around a limitation of
+ # MinGW's windres tool with spaces in the path to the include directories.
+ add_library(CMakeVersion OBJECT "${CMAKE_CURRENT_BINARY_DIR}/CMakeVersion.rc")
+ set_property(TARGET CMakeVersion PROPERTY INCLUDE_DIRECTORIES "")
+ foreach(_tool ${_tools})
+ target_sources(${_tool} PRIVATE $<TARGET_OBJECTS:CMakeVersion>)
+ endforeach()
+endif()
+
# Install tools
foreach(_tool ${_tools})
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 3a14f8e..0ecbd07 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 10)
-set(CMake_VERSION_PATCH 0)
-set(CMake_VERSION_RC 3)
+set(CMake_VERSION_PATCH 20171101)
+#set(CMake_VERSION_RC 1)
diff --git a/Source/CMakeVersion.rc.in b/Source/CMakeVersion.rc.in
new file mode 100644
index 0000000..f4ca3d5
--- /dev/null
+++ b/Source/CMakeVersion.rc.in
@@ -0,0 +1,34 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#define VER_FILEVERSION @CMake_VERSION_MAJOR@,@CMake_VERSION_MINOR@,@CMake_VERSION_PATCH@
+#define VER_FILEVERSION_STR "@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@.@CMake_VERSION_PATCH@\0"
+
+#define VER_PRODUCTVERSION @CMake_VERSION_MAJOR@,@CMake_VERSION_MINOR@,@CMake_VERSION_PATCH@
+#define VER_PRODUCTVERSION_STR "@CMake_VERSION@\0"
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION VER_FILEVERSION
+PRODUCTVERSION VER_PRODUCTVERSION
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904E4"
+ BEGIN
+ VALUE "FileVersion", VER_FILEVERSION_STR
+ VALUE "ProductVersion", VER_PRODUCTVERSION_STR
+ END
+ END
+
+ BLOCK "VarFileInfo"
+ BEGIN
+ /* The following line should only be modified for localized versions. */
+ /* It consists of any number of WORD,WORD pairs, with each pair */
+ /* describing a language,codepage combination supported by the file. */
+ /* */
+ /* For example, a file might have values "0x409,1252" indicating that it */
+ /* supports English language (0x409) in the Windows ANSI codepage (1252). */
+
+ VALUE "Translation", 0x409, 1252
+ END
+END
diff --git a/Source/CPack/WiX/cmCMakeToWixPath.cxx b/Source/CPack/WiX/cmCMakeToWixPath.cxx
new file mode 100644
index 0000000..0b0e42a
--- /dev/null
+++ b/Source/CPack/WiX/cmCMakeToWixPath.cxx
@@ -0,0 +1,39 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmCMakeToWixPath.h"
+
+#include "cmSystemTools.h"
+
+#include <string>
+#include <vector>
+
+#ifdef __CYGWIN__
+#include <sys/cygwin.h>
+std::string CMakeToWixPath(const std::string& cygpath)
+{
+ std::vector<char> winpath_chars;
+ ssize_t winpath_size;
+
+ // Get the required buffer size.
+ winpath_size =
+ cygwin_conv_path(CCP_POSIX_TO_WIN_A, cygpath.c_str(), nullptr, 0);
+ if (winpath_size <= 0) {
+ return cygpath;
+ }
+
+ winpath_chars.assign(static_cast<size_t>(winpath_size) + 1, '\0');
+
+ winpath_size = cygwin_conv_path(CCP_POSIX_TO_WIN_A, cygpath.c_str(),
+ winpath_chars.data(), winpath_size);
+ if (winpath_size < 0) {
+ return cygpath;
+ }
+
+ return cmSystemTools::TrimWhitespace(winpath_chars.data());
+}
+#else
+std::string CMakeToWixPath(const std::string& path)
+{
+ return path;
+}
+#endif
diff --git a/Source/CPack/WiX/cmCMakeToWixPath.h b/Source/CPack/WiX/cmCMakeToWixPath.h
new file mode 100644
index 0000000..8bb9e04
--- /dev/null
+++ b/Source/CPack/WiX/cmCMakeToWixPath.h
@@ -0,0 +1,12 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmCMakeToWixPath_h
+#define cmCMakeToWixPath_h
+
+#include "cmConfigure.h" //IWYU pragma: keep
+
+#include <string>
+
+std::string CMakeToWixPath(const std::string& cygpath);
+
+#endif // cmCMakeToWixPath_h
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index ba07d08..a0bc0ea 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -22,7 +22,13 @@
#include "cmsys/FStream.hxx"
#include "cmsys/SystemTools.hxx"
-#include <rpc.h> // for GUID generation
+#ifdef _WIN32
+#include <rpc.h> // for GUID generation (windows only)
+#else
+#include <uuid/uuid.h> // for GUID generation (libuuid)
+#endif
+
+#include "cmCMakeToWixPath.h"
cmCPackWIXGenerator::cmCPackWIXGenerator()
: Patch(0)
@@ -110,7 +116,7 @@ bool cmCPackWIXGenerator::RunLightCommand(std::string const& objectFiles)
std::ostringstream command;
command << QuotePath(executable);
command << " -nologo";
- command << " -out " << QuotePath(packageFileNames.at(0));
+ command << " -out " << QuotePath(CMakeToWixPath(packageFileNames.at(0)));
for (std::string const& ext : this->LightExtensions) {
command << " -ext " << QuotePath(ext);
@@ -270,11 +276,12 @@ bool cmCPackWIXGenerator::PackageFilesImpl()
std::string objectFilename =
this->CPackTopLevel + "/" + uniqueBaseName + ".wixobj";
- if (!RunCandleCommand(sourceFilename, objectFilename)) {
+ if (!RunCandleCommand(CMakeToWixPath(sourceFilename),
+ CMakeToWixPath(objectFilename))) {
return false;
}
- objectFiles << " " << QuotePath(objectFilename);
+ objectFiles << " " << QuotePath(CMakeToWixPath(objectFilename));
}
AppendUserSuppliedExtraObjects(objectFiles);
@@ -320,10 +327,10 @@ void cmCPackWIXGenerator::CreateWiXVariablesIncludeFile()
CopyDefinition(includeFile, "CPACK_PACKAGE_VENDOR");
CopyDefinition(includeFile, "CPACK_PACKAGE_NAME");
CopyDefinition(includeFile, "CPACK_PACKAGE_VERSION");
- CopyDefinition(includeFile, "CPACK_WIX_LICENSE_RTF");
- CopyDefinition(includeFile, "CPACK_WIX_PRODUCT_ICON");
- CopyDefinition(includeFile, "CPACK_WIX_UI_BANNER");
- CopyDefinition(includeFile, "CPACK_WIX_UI_DIALOG");
+ CopyDefinition(includeFile, "CPACK_WIX_LICENSE_RTF", DefinitionType::PATH);
+ CopyDefinition(includeFile, "CPACK_WIX_PRODUCT_ICON", DefinitionType::PATH);
+ CopyDefinition(includeFile, "CPACK_WIX_UI_BANNER", DefinitionType::PATH);
+ CopyDefinition(includeFile, "CPACK_WIX_UI_DIALOG", DefinitionType::PATH);
SetOptionIfNotSet("CPACK_WIX_PROGRAM_MENU_FOLDER",
GetOption("CPACK_PACKAGE_NAME"));
CopyDefinition(includeFile, "CPACK_WIX_PROGRAM_MENU_FOLDER");
@@ -390,11 +397,16 @@ void cmCPackWIXGenerator::CreateWiXProductFragmentIncludeFile()
}
void cmCPackWIXGenerator::CopyDefinition(cmWIXSourceWriter& source,
- std::string const& name)
+ std::string const& name,
+ DefinitionType type)
{
const char* value = GetOption(name.c_str());
if (value) {
- AddDefinition(source, name, value);
+ if (type == DefinitionType::PATH) {
+ AddDefinition(source, name, CMakeToWixPath(value));
+ } else {
+ AddDefinition(source, name, value);
+ }
}
}
@@ -966,6 +978,7 @@ std::string cmCPackWIXGenerator::GetArchitecture() const
std::string cmCPackWIXGenerator::GenerateGUID()
{
+#ifdef _WIN32
UUID guid;
UuidCreate(&guid);
@@ -975,6 +988,14 @@ std::string cmCPackWIXGenerator::GenerateGUID()
std::string result =
cmsys::Encoding::ToNarrow(reinterpret_cast<wchar_t*>(tmp));
RpcStringFreeW(&tmp);
+#else
+ uuid_t guid;
+ char guid_ch[37] = { 0 };
+
+ uuid_generate(guid);
+ uuid_unparse(guid, guid_ch);
+ std::string result = guid_ch;
+#endif
return cmSystemTools::UpperCase(result);
}
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.h b/Source/CPack/WiX/cmCPackWIXGenerator.h
index b2633a7..128a04d 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.h
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.h
@@ -48,6 +48,12 @@ private:
typedef std::map<std::string, size_t> ambiguity_map_t;
typedef std::set<std::string> extension_set_t;
+ enum class DefinitionType
+ {
+ STRING,
+ PATH
+ };
+
bool InitializeWiXConfiguration();
bool PackageFilesImpl();
@@ -58,7 +64,8 @@ private:
void CreateWiXProductFragmentIncludeFile();
- void CopyDefinition(cmWIXSourceWriter& source, std::string const& name);
+ void CopyDefinition(cmWIXSourceWriter& source, std::string const& name,
+ DefinitionType type = DefinitionType::STRING);
void AddDefinition(cmWIXSourceWriter& source, std::string const& name,
std::string const& value);
diff --git a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
index b4cd1a3..dd3caf9 100644
--- a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
@@ -11,6 +11,8 @@
#include "cm_sys_stat.h"
+#include "cmCMakeToWixPath.h"
+
cmWIXFilesSourceWriter::cmWIXFilesSourceWriter(cmCPackLog* logger,
std::string const& filename,
GuidType componentGuidType)
@@ -139,7 +141,7 @@ std::string cmWIXFilesSourceWriter::EmitComponentFile(
patch.ApplyFragment(componentId, *this);
BeginElement("File");
AddAttribute("Id", fileId);
- AddAttribute("Source", filePath);
+ AddAttribute("Source", CMakeToWixPath(filePath));
AddAttribute("KeyPath", "yes");
mode_t fileMode = 0;
diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx
index 1e1543f..bb35623 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.cxx
+++ b/Source/CPack/cmCPackDragNDropGenerator.cxx
@@ -411,6 +411,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
std::string temp_image = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
temp_image += "/temp.dmg";
+ std::string create_error;
std::ostringstream temp_image_command;
temp_image_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
temp_image_command << " create";
@@ -421,9 +422,11 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
temp_image_command << " -format " << temp_image_format;
temp_image_command << " \"" << temp_image << "\"";
- if (!this->RunCommand(temp_image_command)) {
+ if (!this->RunCommand(temp_image_command, &create_error)) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Error generating temporary disk image." << std::endl);
+ "Error generating temporary disk image." << std::endl
+ << create_error
+ << std::endl);
return 0;
}
@@ -464,15 +467,17 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
// Optionally set the custom icon flag for the image ...
if (!had_error && !cpack_package_icon.empty()) {
+ std::string error;
std::ostringstream setfile_command;
setfile_command << this->GetOption("CPACK_COMMAND_SETFILE");
setfile_command << " -a C";
setfile_command << " \"" << temp_mount << "\"";
- if (!this->RunCommand(setfile_command)) {
+ if (!this->RunCommand(setfile_command, &error)) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Error assigning custom icon to temporary disk image."
- << std::endl);
+ << std::endl
+ << error << std::endl);
had_error = true;
}
@@ -717,9 +722,12 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
final_image_command << " zlib-level=9";
final_image_command << " -o \"" << output_file << "\"";
- if (!this->RunCommand(final_image_command)) {
+ std::string convert_error;
+
+ if (!this->RunCommand(final_image_command, &convert_error)) {
cmCPackLogger(cmCPackLog::LOG_ERROR, "Error compressing disk image."
- << std::endl);
+ << std::endl
+ << convert_error << std::endl);
return 0;
}
diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx
index 4b81bbc..47e7527 100644
--- a/Source/CPack/cmCPackGeneratorFactory.cxx
+++ b/Source/CPack/cmCPackGeneratorFactory.cxx
@@ -40,7 +40,7 @@
#include "cmCPackRPMGenerator.h"
#endif
-#ifdef _WIN32
+#if defined(_WIN32) || (defined(__CYGWIN__) && defined(HAVE_LIBUUID))
#include "WiX/cmCPackWIXGenerator.h"
#endif
@@ -87,7 +87,7 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
this->RegisterGenerator("7Z", "7-Zip file format",
cmCPack7zGenerator::CreateGenerator);
}
-#ifdef _WIN32
+#if defined(_WIN32) || (defined(__CYGWIN__) && defined(HAVE_LIBUUID))
if (cmCPackWIXGenerator::CanGenerate()) {
this->RegisterGenerator("WIX", "MSI file format via WiX tools",
cmCPackWIXGenerator::CreateGenerator);
diff --git a/Source/LexerParser/cmCommandArgumentLexer.cxx b/Source/LexerParser/cmCommandArgumentLexer.cxx
index bf6bc2f..6b4fc85 100644
--- a/Source/LexerParser/cmCommandArgumentLexer.cxx
+++ b/Source/LexerParser/cmCommandArgumentLexer.cxx
@@ -674,6 +674,13 @@ Modify cmCommandArgumentLexer.cxx:
/* Include the set of tokens from the parser. */
#include "cmCommandArgumentParserTokens.h"
+static const char *DCURLYVariable = "${";
+static const char *RCURLYVariable = "}";
+static const char *ATVariable = "@";
+static const char *DOLLARVariable = "$";
+static const char *LCURLYVariable = "{";
+static const char *BSLASHVariable = "\\";
+
/*--------------------------------------------------------------------------*/
#define INITIAL 0
@@ -1011,7 +1018,7 @@ YY_RULE_SETUP
{
//std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl;
//yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
- yylvalp->str = yyextra->DCURLYVariable;
+ yylvalp->str = DCURLYVariable;
return cal_DCURLY;
}
YY_BREAK
@@ -1020,7 +1027,7 @@ YY_RULE_SETUP
{
//std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl;
//yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
- yylvalp->str = yyextra->RCURLYVariable;
+ yylvalp->str = RCURLYVariable;
return cal_RCURLY;
}
YY_BREAK
@@ -1029,7 +1036,7 @@ YY_RULE_SETUP
{
//std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl;
//yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
- yylvalp->str = yyextra->ATVariable;
+ yylvalp->str = ATVariable;
return cal_AT;
}
YY_BREAK
@@ -1064,7 +1071,7 @@ case 10:
YY_RULE_SETUP
{
//yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
- yylvalp->str = yyextra->DOLLARVariable;
+ yylvalp->str = DOLLARVariable;
return cal_DOLLAR;
}
YY_BREAK
@@ -1072,7 +1079,7 @@ case 11:
YY_RULE_SETUP
{
//yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
- yylvalp->str = yyextra->LCURLYVariable;
+ yylvalp->str = LCURLYVariable;
return cal_LCURLY;
}
YY_BREAK
@@ -1080,7 +1087,7 @@ case 12:
YY_RULE_SETUP
{
//yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
- yylvalp->str = yyextra->BSLASHVariable;
+ yylvalp->str = BSLASHVariable;
return cal_BSLASH;
}
YY_BREAK
@@ -1088,7 +1095,7 @@ case 13:
YY_RULE_SETUP
{
//yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
- yylvalp->str = yyextra->BSLASHVariable;
+ yylvalp->str = BSLASHVariable;
return cal_SYMBOL;
}
YY_BREAK
diff --git a/Source/LexerParser/cmCommandArgumentLexer.in.l b/Source/LexerParser/cmCommandArgumentLexer.in.l
index acf18f3..5927b9e 100644
--- a/Source/LexerParser/cmCommandArgumentLexer.in.l
+++ b/Source/LexerParser/cmCommandArgumentLexer.in.l
@@ -28,6 +28,13 @@ Modify cmCommandArgumentLexer.cxx:
/* Include the set of tokens from the parser. */
#include "cmCommandArgumentParserTokens.h"
+static const char *DCURLYVariable = "${";
+static const char *RCURLYVariable = "}";
+static const char *ATVariable = "@";
+static const char *DOLLARVariable = "$";
+static const char *LCURLYVariable = "{";
+static const char *BSLASHVariable = "\\";
+
/*--------------------------------------------------------------------------*/
%}
@@ -63,21 +70,21 @@ Modify cmCommandArgumentLexer.cxx:
"${" {
//std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl;
//yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
- yylvalp->str = yyextra->DCURLYVariable;
+ yylvalp->str = DCURLYVariable;
return cal_DCURLY;
}
"}" {
//std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl;
//yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
- yylvalp->str = yyextra->RCURLYVariable;
+ yylvalp->str = RCURLYVariable;
return cal_RCURLY;
}
"@" {
//std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl;
//yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
- yylvalp->str = yyextra->ATVariable;
+ yylvalp->str = ATVariable;
return cal_AT;
}
@@ -103,25 +110,25 @@ Modify cmCommandArgumentLexer.cxx:
"$" {
//yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
- yylvalp->str = yyextra->DOLLARVariable;
+ yylvalp->str = DOLLARVariable;
return cal_DOLLAR;
}
"{" {
//yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
- yylvalp->str = yyextra->LCURLYVariable;
+ yylvalp->str = LCURLYVariable;
return cal_LCURLY;
}
<ESCAPES>"\\" {
//yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
- yylvalp->str = yyextra->BSLASHVariable;
+ yylvalp->str = BSLASHVariable;
return cal_BSLASH;
}
<NOESCAPES>"\\" {
//yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
- yylvalp->str = yyextra->BSLASHVariable;
+ yylvalp->str = BSLASHVariable;
return cal_SYMBOL;
}
diff --git a/Source/Modules/FindLibUUID.cmake b/Source/Modules/FindLibUUID.cmake
new file mode 100644
index 0000000..17f11c1
--- /dev/null
+++ b/Source/Modules/FindLibUUID.cmake
@@ -0,0 +1,85 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+FindLibUUID
+------------
+
+Find LibUUID include directory and library.
+
+Imported Targets
+^^^^^^^^^^^^^^^^
+
+An :ref:`imported target <Imported targets>` named
+``LibUUID::LibUUID`` is provided if LibUUID has been found.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module defines the following variables:
+
+``LibUUID_FOUND``
+ True if LibUUID was found, false otherwise.
+``LibUUID_INCLUDE_DIRS``
+ Include directories needed to include LibUUID headers.
+``LibUUID_LIBRARIES``
+ Libraries needed to link to LibUUID.
+
+Cache Variables
+^^^^^^^^^^^^^^^
+
+This module uses the following cache variables:
+
+``LibUUID_LIBRARY``
+ The location of the LibUUID library file.
+``LibUUID_INCLUDE_DIR``
+ The location of the LibUUID include directory containing ``uuid/uuid.h``.
+
+The cache variables should not be used by project code.
+They may be set by end users to point at LibUUID components.
+#]=======================================================================]
+
+#-----------------------------------------------------------------------------
+if(CYGWIN)
+ # Note: on current version of Cygwin, linking to libuuid.dll.a doesn't
+ # import the right symbols sometimes. Fix this by linking directly
+ # to the DLL that provides the symbols, instead.
+ set(old_suffixes ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .dll)
+ find_library(LibUUID_LIBRARY
+ NAMES cyguuid-1.dll
+ )
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ${old_suffixes})
+else()
+ find_library(LibUUID_LIBRARY
+ NAMES uuid
+ )
+endif()
+mark_as_advanced(LibUUID_LIBRARY)
+
+find_path(LibUUID_INCLUDE_DIR
+ NAMES uuid/uuid.h
+ )
+mark_as_advanced(LibUUID_INCLUDE_DIR)
+
+#-----------------------------------------------------------------------------
+include(${CMAKE_CURRENT_LIST_DIR}/../../Modules/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibUUID
+ FOUND_VAR LibUUID_FOUND
+ REQUIRED_VARS LibUUID_LIBRARY LibUUID_INCLUDE_DIR
+ )
+set(LIBUUID_FOUND ${LibUUID_FOUND})
+
+#-----------------------------------------------------------------------------
+# Provide documented result variables and targets.
+if(LibUUID_FOUND)
+ set(LibUUID_INCLUDE_DIRS ${LibUUID_INCLUDE_DIR})
+ set(LibUUID_LIBRARIES ${LibUUID_LIBRARY})
+ if(NOT TARGET LibUUID::LibUUID)
+ add_library(LibUUID::LibUUID UNKNOWN IMPORTED)
+ set_target_properties(LibUUID::LibUUID PROPERTIES
+ IMPORTED_LOCATION "${LibUUID_LIBRARY}"
+ INTERFACE_INCLUDE_DIRECTORIES "${LibUUID_INCLUDE_DIRS}"
+ )
+ endif()
+endif()
diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx
index bbb2395..5be9ec3 100644
--- a/Source/QtDialog/CMakeSetupDialog.cxx
+++ b/Source/QtDialog/CMakeSetupDialog.cxx
@@ -188,6 +188,9 @@ CMakeSetupDialog::CMakeSetupDialog()
connect(this->Output, SIGNAL(customContextMenuRequested(const QPoint&)),
this, SLOT(doOutputContextMenu(const QPoint&)));
+ // disable open project button
+ this->OpenProjectButton->setDisabled(true);
+
// start the cmake worker thread
this->CMakeThread = new QCMakeThread(this);
QObject::connect(this->CMakeThread, SIGNAL(cmakeInitialized()), this,
@@ -249,6 +252,10 @@ void CMakeSetupDialog::initialize()
SIGNAL(outputMessage(QString)), this,
SLOT(message(QString)));
+ QObject::connect(this->CMakeThread->cmakeInstance(),
+ SIGNAL(openPossible(bool)), this->OpenProjectButton,
+ SLOT(setEnabled(bool)));
+
QObject::connect(this->groupedCheck, SIGNAL(toggled(bool)), this,
SLOT(setGroupedView(bool)));
QObject::connect(this->advancedCheck, SIGNAL(toggled(bool)), this,
@@ -492,24 +499,10 @@ void CMakeSetupDialog::doGenerate()
this->ConfigureNeeded = true;
}
-QString CMakeSetupDialog::getProjectFilename()
-{
- QStringList nameFilter;
- nameFilter << "*.sln"
- << "*.xcodeproj";
- QDir directory(this->BinaryDirectory->currentText());
- QStringList nlnFile = directory.entryList(nameFilter);
-
- if (nlnFile.count() == 1) {
- return this->BinaryDirectory->currentText() + "/" + nlnFile.at(0);
- }
-
- return QString();
-}
-
void CMakeSetupDialog::doOpenProject()
{
- QDesktopServices::openUrl(QUrl::fromLocalFile(this->getProjectFilename()));
+ QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(), "open",
+ Qt::QueuedConnection);
}
void CMakeSetupDialog::closeEvent(QCloseEvent* e)
@@ -630,11 +623,6 @@ void CMakeSetupDialog::updateBinaryDirectory(const QString& dir)
this->BinaryDirectory->setEditText(dir);
this->BinaryDirectory->blockSignals(false);
}
- if (!this->getProjectFilename().isEmpty()) {
- this->OpenProjectButton->setEnabled(true);
- } else {
- this->OpenProjectButton->setEnabled(false);
- }
}
void CMakeSetupDialog::doBinaryBrowse()
@@ -1039,9 +1027,6 @@ void CMakeSetupDialog::enterState(CMakeSetupDialog::State s)
this->GenerateButton->setEnabled(true);
this->GenerateAction->setEnabled(true);
this->ConfigureButton->setEnabled(true);
- if (!this->getProjectFilename().isEmpty()) {
- this->OpenProjectButton->setEnabled(true);
- }
this->ConfigureButton->setText(tr("&Configure"));
this->GenerateButton->setText(tr("&Generate"));
} else if (s == ReadyGenerate) {
@@ -1049,9 +1034,6 @@ void CMakeSetupDialog::enterState(CMakeSetupDialog::State s)
this->GenerateButton->setEnabled(true);
this->GenerateAction->setEnabled(true);
this->ConfigureButton->setEnabled(true);
- if (!this->getProjectFilename().isEmpty()) {
- this->OpenProjectButton->setEnabled(true);
- }
this->ConfigureButton->setText(tr("&Configure"));
this->GenerateButton->setText(tr("&Generate"));
}
diff --git a/Source/QtDialog/CMakeSetupDialog.h b/Source/QtDialog/CMakeSetupDialog.h
index 0da28d8..7b767e5 100644
--- a/Source/QtDialog/CMakeSetupDialog.h
+++ b/Source/QtDialog/CMakeSetupDialog.h
@@ -31,7 +31,6 @@ protected slots:
void initialize();
void doConfigure();
void doGenerate();
- QString getProjectFilename();
void doOpenProject();
void doInstallForCommandLine();
void doHelp();
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx
index d473d9b..7e94a27 100644
--- a/Source/QtDialog/QCMake.cxx
+++ b/Source/QtDialog/QCMake.cxx
@@ -115,6 +115,8 @@ void QCMake::setBinaryDirectory(const QString& _dir)
if (toolset) {
this->setToolset(QString::fromLocal8Bit(toolset));
}
+
+ checkOpenPossible();
}
}
@@ -183,6 +185,26 @@ void QCMake::generate()
#endif
emit this->generateDone(err);
+ checkOpenPossible();
+}
+
+void QCMake::open()
+{
+#ifdef Q_OS_WIN
+ UINT lastErrorMode = SetErrorMode(0);
+#endif
+
+ InterruptFlag = 0;
+ cmSystemTools::ResetErrorOccuredFlag();
+
+ auto successful = this->CMakeInstance->Open(
+ this->BinaryDirectory.toLocal8Bit().data(), false);
+
+#ifdef Q_OS_WIN
+ SetErrorMode(lastErrorMode);
+#endif
+
+ emit this->openDone(successful);
}
void QCMake::setProperties(const QCMakePropertyList& newProps)
@@ -450,3 +472,10 @@ void QCMake::setWarnUnusedMode(bool value)
{
this->WarnUnusedMode = value;
}
+
+void QCMake::checkOpenPossible()
+{
+ auto data = this->BinaryDirectory.toLocal8Bit().data();
+ auto possible = this->CMakeInstance->Open(data, true);
+ emit openPossible(possible);
+}
diff --git a/Source/QtDialog/QCMake.h b/Source/QtDialog/QCMake.h
index 3b8cea7..6fae7e3 100644
--- a/Source/QtDialog/QCMake.h
+++ b/Source/QtDialog/QCMake.h
@@ -80,6 +80,8 @@ public slots:
void configure();
/// generate the files
void generate();
+ /// open the project
+ void open();
/// set the property values
void setProperties(const QCMakePropertyList&);
/// interrupt the configure or generate process (if connecting, make a direct
@@ -111,6 +113,8 @@ public slots:
void setWarnUninitializedMode(bool value);
/// set whether to run cmake with warnings about unused variables
void setWarnUnusedMode(bool value);
+ /// check if project IDE open is possible and emit openPossible signal
+ void checkOpenPossible();
public:
/// get the list of cache properties
@@ -151,6 +155,10 @@ signals:
void debugOutputChanged(bool);
/// signal when the toolset changes
void toolsetChanged(const QString& toolset);
+ /// signal when open is done
+ void openDone(bool successful);
+ /// signal when open is done
+ void openPossible(bool possible);
protected:
cmake* CMakeInstance;
diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx
index a8d5b2e..f4b4f66 100644
--- a/Source/cmAddCustomTargetCommand.cxx
+++ b/Source/cmAddCustomTargetCommand.cxx
@@ -8,7 +8,7 @@
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
-#include "cmPolicies.h"
+#include "cmStateTypes.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmake.h"
@@ -160,35 +160,9 @@ bool cmAddCustomTargetCommand::InitialPass(
if (nameOk) {
nameOk = targetName.find(':') == std::string::npos;
}
- if (!nameOk) {
- cmake::MessageType messageType = cmake::AUTHOR_WARNING;
- std::ostringstream e;
- bool issueMessage = false;
- switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0037)) {
- case cmPolicies::WARN:
- e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0037) << "\n";
- issueMessage = true;
- case cmPolicies::OLD:
- break;
- case cmPolicies::NEW:
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- issueMessage = true;
- messageType = cmake::FATAL_ERROR;
- }
- if (issueMessage) {
- /* clang-format off */
- e << "The target name \"" << targetName <<
- "\" is reserved or not valid for certain "
- "CMake features, such as generator expressions, and may result "
- "in undefined behavior.";
- /* clang-format on */
- this->Makefile->IssueMessage(messageType, e.str());
-
- if (messageType == cmake::FATAL_ERROR) {
- return false;
- }
- }
+ if (!nameOk &&
+ !this->Makefile->CheckCMP0037(targetName, cmStateEnums::UTILITY)) {
+ return false;
}
// Store the last command line finished.
diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx
index 1d0376f..b9e200a 100644
--- a/Source/cmAddExecutableCommand.cxx
+++ b/Source/cmAddExecutableCommand.cxx
@@ -7,10 +7,8 @@
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
-#include "cmPolicies.h"
#include "cmStateTypes.h"
#include "cmTarget.h"
-#include "cmake.h"
class cmExecutionStatus;
@@ -18,7 +16,7 @@ class cmExecutionStatus;
bool cmAddExecutableCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
- if (args.size() < 2) {
+ if (args.empty()) {
this->SetError("called with incorrect number of arguments");
return false;
}
@@ -63,35 +61,9 @@ bool cmAddExecutableCommand::InitialPass(std::vector<std::string> const& args,
if (nameOk && !importTarget && !isAlias) {
nameOk = exename.find(':') == std::string::npos;
}
- if (!nameOk) {
- cmake::MessageType messageType = cmake::AUTHOR_WARNING;
- std::ostringstream e;
- bool issueMessage = false;
- switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0037)) {
- case cmPolicies::WARN:
- e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0037) << "\n";
- issueMessage = true;
- case cmPolicies::OLD:
- break;
- case cmPolicies::NEW:
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- issueMessage = true;
- messageType = cmake::FATAL_ERROR;
- }
- if (issueMessage) {
- /* clang-format off */
- e << "The target name \"" << exename <<
- "\" is reserved or not valid for certain "
- "CMake features, such as generator expressions, and may result "
- "in undefined behavior.";
- /* clang-format on */
- this->Makefile->IssueMessage(messageType, e.str());
-
- if (messageType == cmake::FATAL_ERROR) {
- return false;
- }
- }
+ if (!nameOk &&
+ !this->Makefile->CheckCMP0037(exename, cmStateEnums::EXECUTABLE)) {
+ return false;
}
// Special modifiers are not allowed with IMPORTED signature.
@@ -140,8 +112,7 @@ bool cmAddExecutableCommand::InitialPass(std::vector<std::string> const& args,
if (!aliasedTarget) {
std::ostringstream e;
e << "cannot create ALIAS target \"" << exename << "\" because target \""
- << aliasedName << "\" does not already "
- "exist.";
+ << aliasedName << "\" does not already exist.";
this->SetError(e.str());
return false;
}
@@ -149,15 +120,15 @@ bool cmAddExecutableCommand::InitialPass(std::vector<std::string> const& args,
if (type != cmStateEnums::EXECUTABLE) {
std::ostringstream e;
e << "cannot create ALIAS target \"" << exename << "\" because target \""
- << aliasedName << "\" is not an "
- "executable.";
+ << aliasedName << "\" is not an executable.";
this->SetError(e.str());
return false;
}
- if (aliasedTarget->IsImported()) {
+ if (aliasedTarget->IsImported() &&
+ !aliasedTarget->IsImportedGloballyVisible()) {
std::ostringstream e;
e << "cannot create ALIAS target \"" << exename << "\" because target \""
- << aliasedName << "\" is IMPORTED.";
+ << aliasedName << "\" is imported but not globally visible.";
this->SetError(e.str());
return false;
}
@@ -191,12 +162,6 @@ bool cmAddExecutableCommand::InitialPass(std::vector<std::string> const& args,
}
}
- if (s == args.end()) {
- this->SetError(
- "called with incorrect number of arguments, no sources provided");
- return false;
- }
-
std::vector<std::string> srclists(s, args.end());
cmTarget* tgt =
this->Makefile->AddExecutable(exename.c_str(), srclists, excludeFromAll);
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index ebf1763..0fcffdd 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -7,7 +7,6 @@
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
-#include "cmPolicies.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmSystemTools.h"
@@ -175,35 +174,8 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
if (nameOk && !importTarget && !isAlias) {
nameOk = libName.find(':') == std::string::npos;
}
- if (!nameOk) {
- cmake::MessageType messageType = cmake::AUTHOR_WARNING;
- std::ostringstream e;
- bool issueMessage = false;
- switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0037)) {
- case cmPolicies::WARN:
- if (type != cmStateEnums::INTERFACE_LIBRARY) {
- e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0037) << "\n";
- issueMessage = true;
- }
- case cmPolicies::OLD:
- break;
- case cmPolicies::NEW:
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- issueMessage = true;
- messageType = cmake::FATAL_ERROR;
- }
- if (issueMessage) {
- e << "The target name \"" << libName
- << "\" is reserved or not valid for certain "
- "CMake features, such as generator expressions, and may result "
- "in undefined behavior.";
- this->Makefile->IssueMessage(messageType, e.str());
-
- if (messageType == cmake::FATAL_ERROR) {
- return false;
- }
- }
+ if (!nameOk && !this->Makefile->CheckCMP0037(libName, type)) {
+ return false;
}
if (isAlias) {
@@ -256,13 +228,6 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
this->SetError(e.str());
return false;
}
- if (aliasedTarget->IsImported()) {
- std::ostringstream e;
- e << "cannot create ALIAS target \"" << libName << "\" because target \""
- << aliasedName << "\" is IMPORTED.";
- this->SetError(e.str());
- return false;
- }
this->Makefile->AddAlias(libName, aliasedName);
return true;
}
@@ -362,14 +327,6 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
return true;
}
- if (s == args.end()) {
- std::string msg = "You have called ADD_LIBRARY for library ";
- msg += args[0];
- msg += " without any source files. This typically indicates a problem ";
- msg += "with your CMakeLists.txt file";
- cmSystemTools::Message(msg.c_str(), "Warning");
- }
-
srclists.insert(srclists.end(), s, args.end());
this->Makefile->AddLibrary(libName, type, srclists, excludeFromAll);
diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h
index 69d0ed6..3380b78 100644
--- a/Source/cmAlgorithms.h
+++ b/Source/cmAlgorithms.h
@@ -43,22 +43,6 @@ inline bool cmHasLiteralSuffixImpl(const char* str1, const char* str2,
}
template <typename T, size_t N>
-const T* cmArrayBegin(const T (&a)[N])
-{
- return a;
-}
-template <typename T, size_t N>
-const T* cmArrayEnd(const T (&a)[N])
-{
- return a + N;
-}
-template <typename T, size_t N>
-size_t cmArraySize(const T (&)[N])
-{
- return N;
-}
-
-template <typename T, size_t N>
bool cmHasLiteralPrefix(const T& str1, const char (&str2)[N])
{
return cmHasLiteralPrefixImpl(str1, str2, N - 1);
@@ -418,6 +402,67 @@ std::unique_ptr<T> make_unique(Args&&... args)
#endif
+#if __cplusplus >= 201703L || defined(_MSVC_LANG) && _MSVC_LANG >= 201703L
+
+using std::size;
+
+#else
+
+// std::size backport from C++17.
+template <class C>
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+constexpr
+#endif
+ auto
+ size(C const& c) -> decltype(c.size())
+{
+ return c.size();
+}
+
+template <typename T, size_t N>
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+constexpr
+#endif
+ std::size_t
+ size(const T (&)[N]) throw()
+{
+ return N;
+}
+
+#endif
+
+#if __cplusplus >= 201402L || defined(_MSVC_LANG) && _MSVC_LANG >= 201402L
+
+using std::cbegin;
+using std::cend;
+
+#else
+
+// std::c{begin,end} backport from C++14
+template <class C>
+#if defined(_MSC_VER) && _MSC_VER < 1900
+auto cbegin(C const& c)
+#else
+constexpr auto cbegin(C const& c) noexcept(noexcept(std::begin(c)))
+#endif
+ -> decltype(std::begin(c))
+{
+ return std::begin(c);
+}
+
+template <class C>
+#if defined(_MSC_VER) && _MSC_VER < 1900
+auto cend(C const& c)
+#else
+constexpr auto cend(C const& c) noexcept(noexcept(std::end(c)))
+#endif
+ -> decltype(std::end(c))
+{
+ return std::end(c);
+}
+
+#endif
+
} // namespace cm
#endif
diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx
index 5106f52..662dd74 100644
--- a/Source/cmCMakeHostSystemInformationCommand.cxx
+++ b/Source/cmCMakeHostSystemInformationCommand.cxx
@@ -8,6 +8,9 @@
#include "cmsys/SystemInformation.hxx"
#if defined(_WIN32)
+#include "cmAlgorithms.h"
+#include "cmGlobalGenerator.h"
+#include "cmGlobalVisualStudio15Generator.h"
#include "cmSystemTools.h"
#include "cmVSSetupHelper.h"
#define HAVE_VS_SETUP_HELPER
@@ -127,6 +130,17 @@ bool cmCMakeHostSystemInformationCommand::GetValue(
value = this->ValueToString(info.GetOSPlatform());
#ifdef HAVE_VS_SETUP_HELPER
} else if (key == "VS_15_DIR") {
+ // If generating for the VS 15 IDE, use the same instance.
+ cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
+ if (cmHasLiteralPrefix(gg->GetName(), "Visual Studio 15 ")) {
+ cmGlobalVisualStudio15Generator* vs15gen =
+ static_cast<cmGlobalVisualStudio15Generator*>(gg);
+ if (vs15gen->GetVSInstance(value)) {
+ return true;
+ }
+ }
+
+ // Otherwise, find a VS 15 instance ourselves.
cmVSSetupAPIHelper vsSetupAPIHelper;
if (vsSetupAPIHelper.GetVSInstanceInfo(value)) {
cmSystemTools::ConvertToUnixSlashes(value);
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 4ea1493..37ff901 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -12,6 +12,7 @@
#include "cmsys/String.hxx"
#include "cmsys/SystemInformation.hxx"
#include <algorithm>
+#include <cstdint>
#include <ctype.h>
#include <iostream>
#include <map>
@@ -1421,7 +1422,7 @@ int cmCTest::GenerateCTestNotesOutput(cmXMLWriter& xml,
std::string note_time = this->CurrentTime();
xml.StartElement("Note");
xml.Attribute("Name", file);
- xml.Element("Time", cmSystemTools::GetTime());
+ xml.Element("Time", static_cast<uint64_t>(cmSystemTools::GetTime()));
xml.Element("DateTime", note_time);
xml.StartElement("Text");
cmsys::ifstream ifs(file.c_str());
diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx
index 6ae58d6..bf314bd 100644
--- a/Source/cmCommandArgumentParserHelper.cxx
+++ b/Source/cmCommandArgumentParserHelper.cxx
@@ -21,13 +21,6 @@ cmCommandArgumentParserHelper::cmCommandArgumentParserHelper()
this->FileLine = -1;
this->FileName = nullptr;
this->RemoveEmpty = true;
- this->EmptyVariable[0] = 0;
- strcpy(this->DCURLYVariable, "${");
- strcpy(this->RCURLYVariable, "}");
- strcpy(this->ATVariable, "@");
- strcpy(this->DOLLARVariable, "$");
- strcpy(this->LCURLYVariable, "{");
- strcpy(this->BSLASHVariable, "\\");
this->NoEscapeMode = false;
this->ReplaceAtSyntax = false;
@@ -44,10 +37,10 @@ void cmCommandArgumentParserHelper::SetLineFile(long line, const char* file)
this->FileName = file;
}
-char* cmCommandArgumentParserHelper::AddString(const std::string& str)
+const char* cmCommandArgumentParserHelper::AddString(const std::string& str)
{
if (str.empty()) {
- return this->EmptyVariable;
+ return "";
}
char* stVal = new char[str.size() + 1];
strcpy(stVal, str.c_str());
@@ -55,14 +48,14 @@ char* cmCommandArgumentParserHelper::AddString(const std::string& str)
return stVal;
}
-char* cmCommandArgumentParserHelper::ExpandSpecialVariable(const char* key,
- const char* var)
+const char* cmCommandArgumentParserHelper::ExpandSpecialVariable(
+ const char* key, const char* var)
{
if (!key) {
return this->ExpandVariable(var);
}
if (!var) {
- return this->EmptyVariable;
+ return "";
}
if (strcmp(key, "ENV") == 0) {
std::string str;
@@ -72,7 +65,7 @@ char* cmCommandArgumentParserHelper::ExpandSpecialVariable(const char* key,
}
return this->AddString(str);
}
- return this->EmptyVariable;
+ return "";
}
if (strcmp(key, "CACHE") == 0) {
if (const char* c =
@@ -82,7 +75,7 @@ char* cmCommandArgumentParserHelper::ExpandSpecialVariable(const char* key,
}
return this->AddString(c);
}
- return this->EmptyVariable;
+ return "";
}
std::ostringstream e;
e << "Syntax $" << key << "{} is not supported. "
@@ -91,7 +84,7 @@ char* cmCommandArgumentParserHelper::ExpandSpecialVariable(const char* key,
return nullptr;
}
-char* cmCommandArgumentParserHelper::ExpandVariable(const char* var)
+const char* cmCommandArgumentParserHelper::ExpandVariable(const char* var)
{
if (!var) {
return nullptr;
@@ -125,11 +118,11 @@ char* cmCommandArgumentParserHelper::ExpandVariable(const char* var)
return this->AddString(value ? value : "");
}
-char* cmCommandArgumentParserHelper::ExpandVariableForAt(const char* var)
+const char* cmCommandArgumentParserHelper::ExpandVariableForAt(const char* var)
{
if (this->ReplaceAtSyntax) {
// try to expand the variable
- char* ret = this->ExpandVariable(var);
+ const char* ret = this->ExpandVariable(var);
// if the return was 0 and we want to replace empty strings
// then return an empty string
if (!ret && this->RemoveEmpty) {
@@ -150,7 +143,8 @@ char* cmCommandArgumentParserHelper::ExpandVariableForAt(const char* var)
return this->AddString(ref);
}
-char* cmCommandArgumentParserHelper::CombineUnions(char* in1, char* in2)
+const char* cmCommandArgumentParserHelper::CombineUnions(const char* in1,
+ const char* in2)
{
if (!in1) {
return in2;
@@ -176,10 +170,11 @@ void cmCommandArgumentParserHelper::AllocateParserType(
if (len == 0) {
return;
}
- pt->str = new char[len + 1];
- strncpy(pt->str, str, len);
- pt->str[len] = 0;
- this->Variables.push_back(pt->str);
+ char* out = new char[len + 1];
+ strncpy(out, str, len);
+ out[len] = 0;
+ pt->str = out;
+ this->Variables.push_back(out);
}
bool cmCommandArgumentParserHelper::HandleEscapeSymbol(
diff --git a/Source/cmCommandArgumentParserHelper.h b/Source/cmCommandArgumentParserHelper.h
index cb2a390..098c000 100644
--- a/Source/cmCommandArgumentParserHelper.h
+++ b/Source/cmCommandArgumentParserHelper.h
@@ -17,7 +17,7 @@ class cmCommandArgumentParserHelper
public:
struct ParserType
{
- char* str;
+ const char* str;
};
cmCommandArgumentParserHelper();
@@ -35,11 +35,11 @@ public:
void Error(const char* str);
// For yacc
- char* CombineUnions(char* in1, char* in2);
+ const char* CombineUnions(const char* in1, const char* in2);
- char* ExpandSpecialVariable(const char* key, const char* var);
- char* ExpandVariable(const char* var);
- char* ExpandVariableForAt(const char* var);
+ const char* ExpandSpecialVariable(const char* key, const char* var);
+ const char* ExpandVariable(const char* var);
+ const char* ExpandVariableForAt(const char* var);
void SetResult(const char* value);
void SetMakefile(const cmMakefile* mf);
@@ -53,13 +53,6 @@ public:
void SetRemoveEmpty(bool b) { this->RemoveEmpty = b; }
const char* GetError() { return this->ErrorString.c_str(); }
- char EmptyVariable[1];
- char DCURLYVariable[3];
- char RCURLYVariable[3];
- char ATVariable[3];
- char DOLLARVariable[3];
- char LCURLYVariable[3];
- char BSLASHVariable[3];
private:
std::string::size_type InputBufferPos;
@@ -69,7 +62,7 @@ private:
void Print(const char* place, const char* str);
void SafePrintMissing(const char* str, int line, int cnt);
- char* AddString(const std::string& str);
+ const char* AddString(const std::string& str);
void CleanupParser();
void SetError(std::string const& msg);
diff --git a/Source/cmCurl.cxx b/Source/cmCurl.cxx
index 341b8c0..8ef8bff 100644
--- a/Source/cmCurl.cxx
+++ b/Source/cmCurl.cxx
@@ -56,3 +56,41 @@ std::string cmCurlSetCAInfo(::CURL* curl, const char* cafile)
#endif
return e;
}
+
+std::string cmCurlSetNETRCOption(::CURL* curl, const std::string& netrc_level,
+ const std::string& netrc_file)
+{
+ std::string e;
+ CURL_NETRC_OPTION curl_netrc_level = CURL_NETRC_LAST;
+ ::CURLcode res;
+
+ if (!netrc_level.empty()) {
+ if (netrc_level == "OPTIONAL") {
+ curl_netrc_level = CURL_NETRC_OPTIONAL;
+ } else if (netrc_level == "REQUIRED") {
+ curl_netrc_level = CURL_NETRC_REQUIRED;
+ } else if (netrc_level == "IGNORED") {
+ curl_netrc_level = CURL_NETRC_IGNORED;
+ } else {
+ e = "NETRC accepts OPTIONAL, IGNORED or REQUIRED but got: ";
+ e += netrc_level;
+ return e;
+ }
+ }
+
+ if (curl_netrc_level != CURL_NETRC_LAST &&
+ curl_netrc_level != CURL_NETRC_IGNORED) {
+ res = ::curl_easy_setopt(curl, CURLOPT_NETRC, curl_netrc_level);
+ check_curl_result(res, "Unable to set netrc level: ");
+ if (!e.empty()) {
+ return e;
+ }
+
+ // check to see if a .netrc file has been specified
+ if (!netrc_file.empty()) {
+ res = ::curl_easy_setopt(curl, CURLOPT_NETRC_FILE, netrc_file.c_str());
+ check_curl_result(res, "Unable to set .netrc file path : ");
+ }
+ }
+ return e;
+}
diff --git a/Source/cmCurl.h b/Source/cmCurl.h
index 0688bb2..fe7eb80 100644
--- a/Source/cmCurl.h
+++ b/Source/cmCurl.h
@@ -9,5 +9,7 @@
#include <string>
std::string cmCurlSetCAInfo(::CURL* curl, const char* cafile = nullptr);
+std::string cmCurlSetNETRCOption(::CURL* curl, const std::string& netrc_level,
+ const std::string& netrc_file);
#endif
diff --git a/Source/cmExternalMakefileProjectGenerator.cxx b/Source/cmExternalMakefileProjectGenerator.cxx
index 825ec65..fecd821 100644
--- a/Source/cmExternalMakefileProjectGenerator.cxx
+++ b/Source/cmExternalMakefileProjectGenerator.cxx
@@ -24,6 +24,13 @@ std::string cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
return fullName;
}
+bool cmExternalMakefileProjectGenerator::Open(
+ const std::string& /*bindir*/, const std::string& /*projectName*/,
+ bool /*dryRun*/)
+{
+ return false;
+}
+
cmExternalMakefileProjectGeneratorFactory::
cmExternalMakefileProjectGeneratorFactory(const std::string& n,
const std::string& doc)
diff --git a/Source/cmExternalMakefileProjectGenerator.h b/Source/cmExternalMakefileProjectGenerator.h
index a1734ee..7f332a8 100644
--- a/Source/cmExternalMakefileProjectGenerator.h
+++ b/Source/cmExternalMakefileProjectGenerator.h
@@ -55,6 +55,9 @@ public:
void SetName(const std::string& n) { Name = n; }
std::string GetName() const { return Name; }
+ virtual bool Open(const std::string& bindir, const std::string& projectName,
+ bool dryRun);
+
protected:
///! Contains the names of the global generators support by this generator.
std::vector<std::string> SupportedGlobalGenerators;
diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx
index 73a9c85..3d72ae3 100644
--- a/Source/cmExtraSublimeTextGenerator.cxx
+++ b/Source/cmExtraSublimeTextGenerator.cxx
@@ -400,3 +400,26 @@ std::string cmExtraSublimeTextGenerator::ComputeDefines(
return definesString;
}
+
+bool cmExtraSublimeTextGenerator::Open(const std::string& bindir,
+ const std::string& projectName,
+ bool dryRun)
+{
+ const char* sublExecutable =
+ this->GlobalGenerator->GetCMakeInstance()->GetCacheDefinition(
+ "CMAKE_SUBLIMETEXT_EXECUTABLE");
+ if (!sublExecutable) {
+ return false;
+ }
+ if (cmSystemTools::IsNOTFOUND(sublExecutable)) {
+ return false;
+ }
+
+ std::string filename = bindir + "/" + projectName + ".sublime-project";
+ if (dryRun) {
+ return cmSystemTools::FileExists(filename, true);
+ }
+
+ return cmSystemTools::RunSingleCommand(
+ { sublExecutable, "--project", filename });
+}
diff --git a/Source/cmExtraSublimeTextGenerator.h b/Source/cmExtraSublimeTextGenerator.h
index 7fb304e..57ba1cf 100644
--- a/Source/cmExtraSublimeTextGenerator.h
+++ b/Source/cmExtraSublimeTextGenerator.h
@@ -65,6 +65,9 @@ private:
std::string ComputeDefines(cmSourceFile* source, cmLocalGenerator* lg,
cmGeneratorTarget* gtgt);
+ bool Open(const std::string& bindir, const std::string& projectName,
+ bool dryRun) override;
+
bool ExcludeBuildFolder;
std::string EnvSettings;
};
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index fdd5f0c..191a666 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -2626,6 +2626,9 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
std::string statusVar;
bool tls_verify = this->Makefile->IsOn("CMAKE_TLS_VERIFY");
const char* cainfo = this->Makefile->GetDefinition("CMAKE_TLS_CAINFO");
+ std::string netrc_level = this->Makefile->GetSafeDefinition("CMAKE_NETRC");
+ std::string netrc_file =
+ this->Makefile->GetSafeDefinition("CMAKE_NETRC_FILE");
std::string expectedHash;
std::string hashMatchMSG;
std::unique_ptr<cmCryptoHash> hash;
@@ -2681,6 +2684,22 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
this->SetError("TLS_CAFILE missing file value.");
return false;
}
+ } else if (*i == "NETRC_FILE") {
+ ++i;
+ if (i != args.end()) {
+ netrc_file = *i;
+ } else {
+ this->SetError("DOWNLOAD missing file value for NETRC_FILE.");
+ return false;
+ }
+ } else if (*i == "NETRC") {
+ ++i;
+ if (i != args.end()) {
+ netrc_level = *i;
+ } else {
+ this->SetError("DOWNLOAD missing level value for NETRC.");
+ return false;
+ }
} else if (*i == "EXPECTED_MD5") {
++i;
if (i == args.end()) {
@@ -2822,6 +2841,16 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
return false;
}
+ // check to see if netrc parameters have been specified
+ // local command args takes precedence over CMAKE_NETRC*
+ netrc_level = cmSystemTools::UpperCase(netrc_level);
+ std::string const& netrc_option_err =
+ cmCurlSetNETRCOption(curl, netrc_level, netrc_file);
+ if (!netrc_option_err.empty()) {
+ this->SetError(netrc_option_err);
+ return false;
+ }
+
cmFileCommandVectorOfChar chunkDebug;
res = ::curl_easy_setopt(curl, CURLOPT_WRITEDATA, &fout);
@@ -2964,6 +2993,9 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
std::string statusVar;
bool showProgress = false;
std::string userpwd;
+ std::string netrc_level = this->Makefile->GetSafeDefinition("CMAKE_NETRC");
+ std::string netrc_file =
+ this->Makefile->GetSafeDefinition("CMAKE_NETRC_FILE");
std::vector<std::string> curl_headers;
@@ -3000,6 +3032,22 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
statusVar = *i;
} else if (*i == "SHOW_PROGRESS") {
showProgress = true;
+ } else if (*i == "NETRC_FILE") {
+ ++i;
+ if (i != args.end()) {
+ netrc_file = *i;
+ } else {
+ this->SetError("UPLOAD missing file value for NETRC_FILE.");
+ return false;
+ }
+ } else if (*i == "NETRC") {
+ ++i;
+ if (i != args.end()) {
+ netrc_level = *i;
+ } else {
+ this->SetError("UPLOAD missing level value for NETRC.");
+ return false;
+ }
} else if (*i == "USERPWD") {
++i;
if (i == args.end()) {
@@ -3132,6 +3180,16 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
check_curl_result(res, "UPLOAD cannot set user password: ");
}
+ // check to see if netrc parameters have been specified
+ // local command args takes precedence over CMAKE_NETRC*
+ netrc_level = cmSystemTools::UpperCase(netrc_level);
+ std::string const& netrc_option_err =
+ cmCurlSetNETRCOption(curl, netrc_level, netrc_file);
+ if (!netrc_option_err.empty()) {
+ this->SetError(netrc_option_err);
+ return false;
+ }
+
struct curl_slist* headers = nullptr;
for (std::string const& h : curl_headers) {
headers = ::curl_slist_append(headers, h.c_str());
diff --git a/Source/cmFilePathChecksum.cxx b/Source/cmFilePathChecksum.cxx
index f9afeef..f84360e 100644
--- a/Source/cmFilePathChecksum.cxx
+++ b/Source/cmFilePathChecksum.cxx
@@ -34,10 +34,10 @@ void cmFilePathChecksum::setupParentDirs(std::string const& currentSrcDir,
std::string const& projectSrcDir,
std::string const& projectBinDir)
{
- this->parentDirs[0].first = cmsys::SystemTools::GetRealPath(currentSrcDir);
- this->parentDirs[1].first = cmsys::SystemTools::GetRealPath(currentBinDir);
- this->parentDirs[2].first = cmsys::SystemTools::GetRealPath(projectSrcDir);
- this->parentDirs[3].first = cmsys::SystemTools::GetRealPath(projectBinDir);
+ this->parentDirs[0].first = cmSystemTools::GetRealPath(currentSrcDir);
+ this->parentDirs[1].first = cmSystemTools::GetRealPath(currentBinDir);
+ this->parentDirs[2].first = cmSystemTools::GetRealPath(projectSrcDir);
+ this->parentDirs[3].first = cmSystemTools::GetRealPath(projectBinDir);
this->parentDirs[0].second = "CurrentSource";
this->parentDirs[1].second = "CurrentBinary";
@@ -50,7 +50,7 @@ std::string cmFilePathChecksum::get(std::string const& filePath) const
std::string relPath;
std::string relSeed;
{
- std::string const fileReal = cmsys::SystemTools::GetRealPath(filePath);
+ std::string const fileReal = cmSystemTools::GetRealPath(filePath);
std::string parentDir;
// Find closest project parent directory
for (auto const& pDir : this->parentDirs) {
diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx
index 542a860..df288bd 100644
--- a/Source/cmForEachCommand.cxx
+++ b/Source/cmForEachCommand.cxx
@@ -7,6 +7,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include "cmAlgorithms.h"
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
@@ -121,7 +122,7 @@ bool cmForEachCommand::InitialPass(std::vector<std::string> const& args,
}
// create a function blocker
- cmForEachFunctionBlocker* f = new cmForEachFunctionBlocker(this->Makefile);
+ auto f = cm::make_unique<cmForEachFunctionBlocker>(this->Makefile);
if (args.size() > 1) {
if (args[1] == "RANGE") {
int start = 0;
@@ -175,7 +176,7 @@ bool cmForEachCommand::InitialPass(std::vector<std::string> const& args,
} else {
f->Args = args;
}
- this->Makefile->AddFunctionBlocker(f);
+ this->Makefile->AddFunctionBlocker(f.release());
return true;
}
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index fea20ba..7fe0cbe 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -1035,7 +1035,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
// No error. We just skip cyclic references.
return std::string();
case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
- for (size_t i = 1; i < cmArraySize(targetPropertyTransitiveWhitelist);
+ for (size_t i = 1; i < cm::size(targetPropertyTransitiveWhitelist);
++i) {
if (targetPropertyTransitiveWhitelist[i] == propertyName) {
// No error. We're not going to find anything new here.
@@ -1443,7 +1443,7 @@ static const struct TargetPolicyNode : public cmGeneratorExpressionNode
context->HadContextSensitiveCondition = true;
context->HadHeadSensitiveCondition = true;
- for (size_t i = 1; i < cmArraySize(targetPolicyWhitelist); ++i) {
+ for (size_t i = 1; i < cm::size(targetPolicyWhitelist); ++i) {
const char* policy = targetPolicyWhitelist[i];
if (parameters.front() == policy) {
cmLocalGenerator* lg = context->HeadTarget->GetLocalGenerator();
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 05efff3..11ea46f 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -111,6 +111,26 @@ cmGlobalGenerator::~cmGlobalGenerator()
delete this->ExtraGenerator;
}
+bool cmGlobalGenerator::SetGeneratorInstance(std::string const& i,
+ cmMakefile* mf)
+{
+ if (i.empty()) {
+ return true;
+ }
+
+ std::ostringstream e;
+ /* clang-format off */
+ e <<
+ "Generator\n"
+ " " << this->GetName() << "\n"
+ "does not support instance specification, but instance\n"
+ " " << i << "\n"
+ "was specified.";
+ /* clang-format on */
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+}
+
bool cmGlobalGenerator::SetGeneratorPlatform(std::string const& p,
cmMakefile* mf)
{
@@ -261,6 +281,43 @@ void cmGlobalGenerator::ForceLinkerLanguages()
{
}
+bool cmGlobalGenerator::CheckTargetsForMissingSources() const
+{
+ bool failed = false;
+ for (cmLocalGenerator* localGen : this->LocalGenerators) {
+ const std::vector<cmGeneratorTarget*>& targets =
+ localGen->GetGeneratorTargets();
+
+ for (cmGeneratorTarget* target : targets) {
+ if (target->GetType() == cmStateEnums::TargetType::GLOBAL_TARGET ||
+ target->GetType() == cmStateEnums::TargetType::INTERFACE_LIBRARY ||
+ target->GetType() == cmStateEnums::TargetType::UTILITY) {
+ continue;
+ }
+
+ std::vector<std::string> configs;
+ target->Makefile->GetConfigurations(configs);
+ std::vector<cmSourceFile*> srcs;
+ if (configs.empty()) {
+ target->GetSourceFiles(srcs, "");
+ } else {
+ for (std::vector<std::string>::const_iterator ci = configs.begin();
+ ci != configs.end() && srcs.empty(); ++ci) {
+ target->GetSourceFiles(srcs, *ci);
+ }
+ }
+ if (srcs.empty()) {
+ std::ostringstream e;
+ e << "No SOURCES given to target: " << target->GetName();
+ this->GetCMakeInstance()->IssueMessage(cmake::FATAL_ERROR, e.str(),
+ target->GetBacktrace());
+ failed = true;
+ }
+ }
+ }
+ return failed;
+}
+
bool cmGlobalGenerator::IsExportedTargetsFile(
const std::string& filename) const
{
@@ -491,6 +548,13 @@ void cmGlobalGenerator::EnableLanguage(
}
if (readCMakeSystem) {
+ // Tell the generator about the instance, if any.
+ std::string instance = mf->GetSafeDefinition("CMAKE_GENERATOR_INSTANCE");
+ if (!this->SetGeneratorInstance(instance, mf)) {
+ cmSystemTools::SetFatalErrorOccured();
+ return;
+ }
+
// Find the native build tool for this generator.
if (!this->FindMakeProgram(mf)) {
return;
@@ -1292,6 +1356,11 @@ bool cmGlobalGenerator::Compute()
localGen->TraceDependencies();
}
+ // Make sure that all (non-imported) targets have source files added!
+ if (this->CheckTargetsForMissingSources()) {
+ return false;
+ }
+
this->ForceLinkerLanguages();
// Compute the manifest of main targets generated.
@@ -1824,6 +1893,16 @@ int cmGlobalGenerator::Build(const std::string& /*unused*/,
return retVal;
}
+bool cmGlobalGenerator::Open(const std::string& bindir,
+ const std::string& projectName, bool dryRun)
+{
+ if (this->ExtraGenerator) {
+ return this->ExtraGenerator->Open(bindir, projectName, dryRun);
+ }
+
+ return false;
+}
+
std::string cmGlobalGenerator::GenerateCMakeBuildCommand(
const std::string& target, const std::string& config,
const std::string& native, bool ignoreErrors)
@@ -2141,6 +2220,45 @@ inline std::string removeQuotes(const std::string& s)
return s;
}
+bool cmGlobalGenerator::CheckCMP0037(std::string const& targetName,
+ std::string const& reason) const
+{
+ cmTarget* tgt = this->FindTarget(targetName);
+ if (!tgt) {
+ return true;
+ }
+ cmake::MessageType messageType = cmake::AUTHOR_WARNING;
+ std::ostringstream e;
+ bool issueMessage = false;
+ switch (tgt->GetPolicyStatusCMP0037()) {
+ case cmPolicies::WARN:
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0037) << "\n";
+ issueMessage = true;
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::NEW:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ issueMessage = true;
+ messageType = cmake::FATAL_ERROR;
+ break;
+ }
+ if (issueMessage) {
+ e << "The target name \"" << targetName << "\" is reserved " << reason
+ << ".";
+ if (messageType == cmake::AUTHOR_WARNING) {
+ e << " It may result in undefined behavior.";
+ }
+ this->GetCMakeInstance()->IssueMessage(messageType, e.str(),
+ tgt->GetBacktrace());
+ if (messageType == cmake::FATAL_ERROR) {
+ return false;
+ }
+ }
+ return true;
+}
+
void cmGlobalGenerator::CreateDefaultGlobalTargets(
std::vector<GlobalTargetInfo>& targets)
{
@@ -2156,6 +2274,20 @@ void cmGlobalGenerator::AddGlobalTarget_Package(
std::vector<GlobalTargetInfo>& targets)
{
cmMakefile* mf = this->Makefiles[0];
+ std::string configFile = mf->GetCurrentBinaryDirectory();
+ configFile += "/CPackConfig.cmake";
+ if (!cmSystemTools::FileExists(configFile.c_str())) {
+ return;
+ }
+
+ const char* reservedTargets[] = { "package", "PACKAGE" };
+ for (const char* const* tn = cm::cbegin(reservedTargets);
+ tn != cm::cend(reservedTargets); ++tn) {
+ if (!this->CheckCMP0037(*tn, "when CPack packaging is enabled")) {
+ return;
+ }
+ }
+
const char* cmakeCfgIntDir = this->GetCMakeCFGIntDir();
GlobalTargetInfo gti;
gti.Name = this->GetPackageTargetName();
@@ -2169,8 +2301,6 @@ void cmGlobalGenerator::AddGlobalTarget_Package(
singleLine.push_back(cmakeCfgIntDir);
}
singleLine.push_back("--config");
- std::string configFile = mf->GetCurrentBinaryDirectory();
- configFile += "/CPackConfig.cmake";
std::string relConfigFile = "./CPackConfig.cmake";
singleLine.push_back(relConfigFile);
gti.CommandLines.push_back(singleLine);
@@ -2183,61 +2313,81 @@ void cmGlobalGenerator::AddGlobalTarget_Package(
gti.Depends.push_back(this->GetAllTargetName());
}
}
- if (cmSystemTools::FileExists(configFile.c_str())) {
- targets.push_back(gti);
- }
+ targets.push_back(gti);
}
void cmGlobalGenerator::AddGlobalTarget_PackageSource(
std::vector<GlobalTargetInfo>& targets)
{
- cmMakefile* mf = this->Makefiles[0];
const char* packageSourceTargetName = this->GetPackageSourceTargetName();
- if (packageSourceTargetName) {
- GlobalTargetInfo gti;
- gti.Name = packageSourceTargetName;
- gti.Message = "Run CPack packaging tool for source...";
- gti.WorkingDir = mf->GetCurrentBinaryDirectory();
- gti.UsesTerminal = true;
- cmCustomCommandLine singleLine;
- singleLine.push_back(cmSystemTools::GetCPackCommand());
- singleLine.push_back("--config");
- std::string configFile = mf->GetCurrentBinaryDirectory();
- configFile += "/CPackSourceConfig.cmake";
- std::string relConfigFile = "./CPackSourceConfig.cmake";
- singleLine.push_back(relConfigFile);
- if (cmSystemTools::FileExists(configFile.c_str())) {
- singleLine.push_back(configFile);
- gti.CommandLines.push_back(singleLine);
- targets.push_back(gti);
+ if (!packageSourceTargetName) {
+ return;
+ }
+
+ cmMakefile* mf = this->Makefiles[0];
+ std::string configFile = mf->GetCurrentBinaryDirectory();
+ configFile += "/CPackSourceConfig.cmake";
+ if (!cmSystemTools::FileExists(configFile.c_str())) {
+ return;
+ }
+
+ const char* reservedTargets[] = { "package_source" };
+ for (const char* const* tn = cm::cbegin(reservedTargets);
+ tn != cm::cend(reservedTargets); ++tn) {
+ if (!this->CheckCMP0037(*tn, "when CPack source packaging is enabled")) {
+ return;
}
}
+
+ GlobalTargetInfo gti;
+ gti.Name = packageSourceTargetName;
+ gti.Message = "Run CPack packaging tool for source...";
+ gti.WorkingDir = mf->GetCurrentBinaryDirectory();
+ gti.UsesTerminal = true;
+ cmCustomCommandLine singleLine;
+ singleLine.push_back(cmSystemTools::GetCPackCommand());
+ singleLine.push_back("--config");
+ std::string relConfigFile = "./CPackSourceConfig.cmake";
+ singleLine.push_back(relConfigFile);
+ singleLine.push_back(configFile);
+ gti.CommandLines.push_back(singleLine);
+ targets.push_back(gti);
}
void cmGlobalGenerator::AddGlobalTarget_Test(
std::vector<GlobalTargetInfo>& targets)
{
cmMakefile* mf = this->Makefiles[0];
- const char* cmakeCfgIntDir = this->GetCMakeCFGIntDir();
- if (mf->IsOn("CMAKE_TESTING_ENABLED")) {
- GlobalTargetInfo gti;
- gti.Name = this->GetTestTargetName();
- gti.Message = "Running tests...";
- gti.UsesTerminal = true;
- cmCustomCommandLine singleLine;
- singleLine.push_back(cmSystemTools::GetCTestCommand());
- singleLine.push_back("--force-new-ctest-process");
- if (cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.') {
- singleLine.push_back("-C");
- singleLine.push_back(cmakeCfgIntDir);
- } else // TODO: This is a hack. Should be something to do with the
- // generator
- {
- singleLine.push_back("$(ARGS)");
+ if (!mf->IsOn("CMAKE_TESTING_ENABLED")) {
+ return;
+ }
+
+ const char* reservedTargets[] = { "test", "RUN_TESTS" };
+ for (const char* const* tn = cm::cbegin(reservedTargets);
+ tn != cm::cend(reservedTargets); ++tn) {
+ if (!this->CheckCMP0037(*tn, "when CTest testing is enabled")) {
+ return;
}
- gti.CommandLines.push_back(singleLine);
- targets.push_back(gti);
}
+
+ const char* cmakeCfgIntDir = this->GetCMakeCFGIntDir();
+ GlobalTargetInfo gti;
+ gti.Name = this->GetTestTargetName();
+ gti.Message = "Running tests...";
+ gti.UsesTerminal = true;
+ cmCustomCommandLine singleLine;
+ singleLine.push_back(cmSystemTools::GetCTestCommand());
+ singleLine.push_back("--force-new-ctest-process");
+ if (cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.') {
+ singleLine.push_back("-C");
+ singleLine.push_back(cmakeCfgIntDir);
+ } else // TODO: This is a hack. Should be something to do with the
+ // generator
+ {
+ singleLine.push_back("$(ARGS)");
+ }
+ gti.CommandLines.push_back(singleLine);
+ targets.push_back(gti);
}
void cmGlobalGenerator::AddGlobalTarget_EditCache(
@@ -2503,14 +2653,13 @@ bool cmGlobalGenerator::IsReservedTarget(std::string const& name)
// by one or more of the cmake generators.
// Adding additional targets to this list will require a policy!
- const char* reservedTargets[] = {
- "all", "ALL_BUILD", "help", "install", "INSTALL",
- "preinstall", "clean", "edit_cache", "rebuild_cache", "test",
- "RUN_TESTS", "package", "PACKAGE", "package_source", "ZERO_CHECK"
- };
-
- return std::find(cmArrayBegin(reservedTargets), cmArrayEnd(reservedTargets),
- name) != cmArrayEnd(reservedTargets);
+ const char* reservedTargets[] = { "all", "ALL_BUILD", "help",
+ "install", "INSTALL", "preinstall",
+ "clean", "edit_cache", "rebuild_cache",
+ "ZERO_CHECK" };
+
+ return std::find(cm::cbegin(reservedTargets), cm::cend(reservedTargets),
+ name) != cm::cend(reservedTargets);
}
void cmGlobalGenerator::SetExternalMakefileProjectGenerator(
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 18ca682..8fcb533 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -70,6 +70,9 @@ public:
/** Tell the generator about the target system. */
virtual bool SetSystemName(std::string const&, cmMakefile*) { return true; }
+ /** Set the generator-specific instance. Returns true if supported. */
+ virtual bool SetGeneratorInstance(std::string const& i, cmMakefile* mf);
+
/** Set the generator-specific platform name. Returns true if platform
is supported and false otherwise. */
virtual bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf);
@@ -162,6 +165,12 @@ public:
std::vector<std::string> const& nativeOptions =
std::vector<std::string>());
+ /**
+ * Open a generated IDE project given the following information.
+ */
+ virtual bool Open(const std::string& bindir, const std::string& projectName,
+ bool dryRun);
+
virtual void GenerateBuildCommand(
std::vector<std::string>& makeCommand, const std::string& makeProgram,
const std::string& projectName, const std::string& projectDir,
@@ -533,6 +542,8 @@ private:
virtual void ForceLinkerLanguages();
+ bool CheckTargetsForMissingSources() const;
+
void CreateLocalGenerators();
void CheckCompilerIdCompatibility(cmMakefile* mf,
@@ -557,6 +568,9 @@ private:
void ClearGeneratorMembers();
+ bool CheckCMP0037(std::string const& targetName,
+ std::string const& reason) const;
+
void IndexMakefile(cmMakefile* mf);
virtual const char* GetBuildIgnoreErrorsFlag() const { return nullptr; }
diff --git a/Source/cmGlobalVisualStudio15Generator.cxx b/Source/cmGlobalVisualStudio15Generator.cxx
index d2bf7cc..014d93d 100644
--- a/Source/cmGlobalVisualStudio15Generator.cxx
+++ b/Source/cmGlobalVisualStudio15Generator.cxx
@@ -111,6 +111,53 @@ void cmGlobalVisualStudio15Generator::WriteSLNHeader(std::ostream& fout)
}
}
+bool cmGlobalVisualStudio15Generator::SetGeneratorInstance(
+ std::string const& i, cmMakefile* mf)
+{
+ if (!i.empty()) {
+ if (!this->vsSetupAPIHelper.SetVSInstance(i)) {
+ std::ostringstream e;
+ /* clang-format off */
+ e <<
+ "Generator\n"
+ " " << this->GetName() << "\n"
+ "could not find specified instance of Visual Studio:\n"
+ " " << i;
+ /* clang-format on */
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ }
+
+ std::string vsInstance;
+ if (!this->vsSetupAPIHelper.GetVSInstanceInfo(vsInstance)) {
+ std::ostringstream e;
+ /* clang-format off */
+ e <<
+ "Generator\n"
+ " " << this->GetName() << "\n"
+ "could not find any instance of Visual Studio.\n";
+ /* clang-format on */
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+
+ // Save the selected instance persistently.
+ std::string genInstance = mf->GetSafeDefinition("CMAKE_GENERATOR_INSTANCE");
+ if (vsInstance != genInstance) {
+ this->CMakeInstance->AddCacheEntry(
+ "CMAKE_GENERATOR_INSTANCE", vsInstance.c_str(),
+ "Generator instance identifier.", cmStateEnums::INTERNAL);
+ }
+
+ return true;
+}
+
+bool cmGlobalVisualStudio15Generator::GetVSInstance(std::string& dir) const
+{
+ return vsSetupAPIHelper.GetVSInstanceInfo(dir);
+}
+
bool cmGlobalVisualStudio15Generator::InitializeWindows(cmMakefile* mf)
{
// If the Win 8.1 SDK is installed then we can select a SDK matching
diff --git a/Source/cmGlobalVisualStudio15Generator.h b/Source/cmGlobalVisualStudio15Generator.h
index e934882..852a4e7 100644
--- a/Source/cmGlobalVisualStudio15Generator.h
+++ b/Source/cmGlobalVisualStudio15Generator.h
@@ -27,6 +27,11 @@ public:
virtual void WriteSLNHeader(std::ostream& fout);
virtual const char* GetToolsVersion() { return "15.0"; }
+
+ bool SetGeneratorInstance(std::string const& i, cmMakefile* mf) override;
+
+ bool GetVSInstance(std::string& dir) const;
+
protected:
bool InitializeWindows(cmMakefile* mf) override;
virtual bool SelectWindowsStoreToolset(std::string& toolset) const;
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index 0651536..99600df 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -4,7 +4,10 @@
#include "cmGlobalVisualStudioGenerator.h"
#include "cmsys/Encoding.hxx"
+#include <future>
#include <iostream>
+#include <objbase.h>
+#include <shellapi.h>
#include <windows.h>
#include "cmAlgorithms.h"
@@ -103,15 +106,6 @@ void cmGlobalVisualStudioGenerator::AddExtraIDETargets()
// Configure CMake Visual Studio macros, for this user on this version
// of Visual Studio.
this->ConfigureCMakeVisualStudioMacros();
-
- // Add CMakeLists.txt with custom command to rerun CMake.
- for (std::vector<cmLocalGenerator*>::const_iterator lgi =
- this->LocalGenerators.begin();
- lgi != this->LocalGenerators.end(); ++lgi) {
- cmLocalVisualStudioGenerator* lg =
- static_cast<cmLocalVisualStudioGenerator*>(*lgi);
- lg->AddCMakeListsRules();
- }
}
void cmGlobalVisualStudioGenerator::ComputeTargetObjectDirectory(
@@ -928,3 +922,33 @@ void cmGlobalVisualStudioGenerator::AddSymbolExportCommand(
commandLines, "Auto build dll exports", ".");
commands.push_back(command);
}
+
+static bool OpenSolution(std::string sln)
+{
+ HRESULT comInitialized =
+ CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
+ if (FAILED(comInitialized)) {
+ return false;
+ }
+
+ HINSTANCE hi =
+ ShellExecuteA(NULL, "open", sln.c_str(), NULL, NULL, SW_SHOWNORMAL);
+
+ CoUninitialize();
+
+ return reinterpret_cast<intptr_t>(hi) > 32;
+}
+
+bool cmGlobalVisualStudioGenerator::Open(const std::string& bindir,
+ const std::string& projectName,
+ bool dryRun)
+{
+ std::string buildDir = cmSystemTools::ConvertToOutputPath(bindir.c_str());
+ std::string sln = buildDir + "\\" + projectName + ".sln";
+
+ if (dryRun) {
+ return cmSystemTools::FileExists(sln, true);
+ }
+
+ return std::async(std::launch::async, OpenSolution, sln).get();
+}
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index 62bfd3b..55a6813 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -131,6 +131,9 @@ public:
std::vector<cmCustomCommand>& commands,
std::string const& configName);
+ bool Open(const std::string& bindir, const std::string& projectName,
+ bool dryRun) override;
+
protected:
virtual void AddExtraIDETargets();
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index c79ee47..a85a700 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -35,6 +35,11 @@
struct cmLinkImplementation;
+#if defined(CMAKE_BUILD_WITH_CMAKE) && defined(__APPLE__)
+#define HAVE_APPLICATION_SERVICES
+#include <ApplicationServices/ApplicationServices.h>
+#endif
+
#if defined(CMAKE_BUILD_WITH_CMAKE)
#include "cmXMLParser.h"
@@ -287,6 +292,35 @@ void cmGlobalXCodeGenerator::EnableLanguage(
this->ComputeArchitectures(mf);
}
+bool cmGlobalXCodeGenerator::Open(const std::string& bindir,
+ const std::string& projectName, bool dryRun)
+{
+ bool ret = false;
+
+#ifdef HAVE_APPLICATION_SERVICES
+ std::string url = bindir + "/" + projectName + ".xcodeproj";
+
+ if (dryRun) {
+ return cmSystemTools::FileExists(url, false);
+ }
+
+ CFStringRef cfStr = CFStringCreateWithCString(
+ kCFAllocatorDefault, url.c_str(), kCFStringEncodingUTF8);
+ if (cfStr) {
+ CFURLRef cfUrl = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfStr,
+ kCFURLPOSIXPathStyle, true);
+ if (cfUrl) {
+ OSStatus err = LSOpenCFURLRef(cfUrl, nullptr);
+ ret = err == noErr;
+ CFRelease(cfUrl);
+ }
+ CFRelease(cfStr);
+ }
+#endif
+
+ return ret;
+}
+
void cmGlobalXCodeGenerator::GenerateBuildCommand(
std::vector<std::string>& makeCommand, const std::string& makeProgram,
const std::string& projectName, const std::string& /*projectDir*/,
@@ -354,6 +388,17 @@ void cmGlobalXCodeGenerator::Generate()
std::map<std::string, std::vector<cmLocalGenerator*>>::iterator it;
for (it = this->ProjectMap.begin(); it != this->ProjectMap.end(); ++it) {
cmLocalGenerator* root = it->second[0];
+
+ bool generateTopLevelProjectOnly =
+ root->GetMakefile()->IsOn("CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY");
+
+ if (generateTopLevelProjectOnly) {
+ cmStateSnapshot snp = root->GetStateSnapshot();
+ if (snp.GetBuildsystemDirectoryParent().IsValid()) {
+ continue;
+ }
+ }
+
this->SetGenerationRoot(root);
// now create the project
this->OutputXCodeProject(root, it->second);
@@ -404,12 +449,6 @@ void cmGlobalXCodeGenerator::AddExtraTargets(
cmGeneratorTarget* allBuildGt = new cmGeneratorTarget(allbuild, root);
root->AddGeneratorTarget(allBuildGt);
- // Refer to the main build configuration file for easy editing.
- std::string listfile = root->GetCurrentSourceDirectory();
- listfile += "/";
- listfile += "CMakeLists.txt";
- allBuildGt->AddSource(listfile);
-
// Add XCODE depend helper
std::string dir = root->GetCurrentBinaryDirectory();
cmCustomCommandLine makeHelper;
@@ -479,12 +518,6 @@ void cmGlobalXCodeGenerator::AddExtraTargets(
!target->GetPropertyAsBool("EXCLUDE_FROM_ALL")) {
allbuild->AddUtility(target->GetName());
}
-
- // Refer to the build configuration file for easy editing.
- listfile = gen->GetCurrentSourceDirectory();
- listfile += "/";
- listfile += "CMakeLists.txt";
- target->AddSource(listfile);
}
}
}
@@ -962,6 +995,13 @@ bool cmGlobalXCodeGenerator::CreateXCodeTargets(
if (!gtgt->GetConfigCommonSourceFiles(classes)) {
return false;
}
+
+ // Add CMakeLists.txt file for user convenience.
+ std::string listfile =
+ gtgt->GetLocalGenerator()->GetCurrentSourceDirectory();
+ listfile += "/CMakeLists.txt";
+ classes.push_back(gtgt->Makefile->GetOrCreateSource(listfile));
+
std::sort(classes.begin(), classes.end(), cmSourceFilePathCompare());
gtgt->ComputeObjectMapping();
@@ -2259,12 +2299,19 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateUtilityTarget(
this->XCodeObjectMap[gtgt] = target;
// Add source files without build rules for editing convenience.
- if (gtgt->GetType() == cmStateEnums::UTILITY) {
+ if (gtgt->GetType() == cmStateEnums::UTILITY &&
+ gtgt->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
std::vector<cmSourceFile*> sources;
if (!gtgt->GetConfigCommonSourceFiles(sources)) {
return nullptr;
}
+ // Add CMakeLists.txt file for user convenience.
+ std::string listfile =
+ gtgt->GetLocalGenerator()->GetCurrentSourceDirectory();
+ listfile += "/CMakeLists.txt";
+ sources.push_back(gtgt->Makefile->GetOrCreateSource(listfile));
+
for (std::vector<cmSourceFile*>::const_iterator i = sources.begin();
i != sources.end(); ++i) {
if (!(*i)->GetPropertyAsBool("GENERATED")) {
@@ -2670,7 +2717,7 @@ bool cmGlobalXCodeGenerator::CreateGroups(
generator->GetGeneratorTargets();
for (auto gtgt : tgts) {
// Same skipping logic here as in CreateXCodeTargets so that we do not
- // end up with (empty anyhow) ALL_BUILD and XCODE_DEPEND_HELPER source
+ // end up with (empty anyhow) ZERO_CHECK, install, or test source
// groups:
//
if (gtgt->GetType() == cmStateEnums::GLOBAL_TARGET) {
@@ -2679,6 +2726,9 @@ bool cmGlobalXCodeGenerator::CreateGroups(
if (gtgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
+ if (gtgt->GetName() == CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
+ continue;
+ }
// add the soon to be generated Info.plist file as a source for a
// MACOSX_BUNDLE file
@@ -2706,6 +2756,20 @@ bool cmGlobalXCodeGenerator::CreateGroups(
std::string key = GetGroupMapKeyFromPath(gtgt, source);
this->GroupMap[key] = pbxgroup;
}
+
+ // Add CMakeLists.txt file for user convenience.
+ {
+ std::string listfile =
+ gtgt->GetLocalGenerator()->GetCurrentSourceDirectory();
+ listfile += "/CMakeLists.txt";
+ cmSourceFile* sf = gtgt->Makefile->GetOrCreateSource(listfile);
+ std::string const& source = sf->GetFullPath();
+ cmSourceGroup* sourceGroup =
+ mf->FindSourceGroup(source.c_str(), sourceGroups);
+ cmXCodeObject* pbxgroup = this->CreateOrGetPBXGroup(gtgt, sourceGroup);
+ std::string key = GetGroupMapKeyFromPath(gtgt, source);
+ this->GroupMap[key] = pbxgroup;
+ }
}
}
return true;
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index e9ca91c..b758e97 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -55,6 +55,13 @@ public:
*/
void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*,
bool optional) override;
+
+ /**
+ * Open a generated IDE project given the following information.
+ */
+ bool Open(const std::string& bindir, const std::string& projectName,
+ bool dryRun) override;
+
/**
* Try running cmake and building a file. This is used for dynalically
* loaded commands, not as part of the usual build process.
diff --git a/Source/cmLinkedTree.h b/Source/cmLinkedTree.h
index 8865e23..975f052 100644
--- a/Source/cmLinkedTree.h
+++ b/Source/cmLinkedTree.h
@@ -137,7 +137,7 @@ public:
iterator Push(iterator it) { return Push_impl(it, T()); }
- iterator Push(iterator it, T t) { return Push_impl(it, t); }
+ iterator Push(iterator it, T t) { return Push_impl(it, std::move(t)); }
bool IsLast(iterator it) { return it.Position == this->Data.size(); }
@@ -177,12 +177,12 @@ private:
T* GetPointer(PositionType pos) { return &this->Data[pos]; }
- iterator Push_impl(iterator it, T t)
+ iterator Push_impl(iterator it, T&& t)
{
assert(this->UpPositions.size() == this->Data.size());
assert(it.Position <= this->UpPositions.size());
this->UpPositions.push_back(it.Position);
- this->Data.push_back(t);
+ this->Data.push_back(std::move(t));
return iterator(this, this->UpPositions.size());
}
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 1a088ea..12c0cfd 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -135,8 +135,8 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile)
this->VariableMappings[compilerOptionSysroot] =
this->Makefile->GetSafeDefinition(compilerOptionSysroot);
- for (const char* const* replaceIter = cmArrayBegin(ruleReplaceVars);
- replaceIter != cmArrayEnd(ruleReplaceVars); ++replaceIter) {
+ for (const char* const* replaceIter = cm::cbegin(ruleReplaceVars);
+ replaceIter != cm::cend(ruleReplaceVars); ++replaceIter) {
std::string actualReplace = *replaceIter;
if (actualReplace.find("${LANG}") != std::string::npos) {
cmSystemTools::ReplaceString(actualReplace, "${LANG}", lang);
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index d8030b7..beb80f2 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -36,6 +36,13 @@ private:
cmLocalVisualStudio7Generator* LocalGenerator;
};
+class cmLocalVisualStudio7Generator::AllConfigSources
+{
+public:
+ std::vector<cmGeneratorTarget::AllConfigSource> Sources;
+ std::map<cmSourceFile const*, size_t> Index;
+};
+
extern cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[];
static void cmConvertToWindowsSlash(std::string& s)
@@ -83,29 +90,6 @@ void cmLocalVisualStudio7Generator::Generate()
this->WriteStampFiles();
}
-void cmLocalVisualStudio7Generator::AddCMakeListsRules()
-{
- // Create the regeneration custom rule.
- if (!this->Makefile->IsOn("CMAKE_SUPPRESS_REGENERATION")) {
- // Create a rule to regenerate the build system when the target
- // specification source changes.
- if (cmSourceFile* sf = this->CreateVCProjBuildRule()) {
- // Add the rule to targets that need it.
- const std::vector<cmGeneratorTarget*>& tgts =
- this->GetGeneratorTargets();
- for (std::vector<cmGeneratorTarget*>::const_iterator l = tgts.begin();
- l != tgts.end(); ++l) {
- if ((*l)->GetType() == cmStateEnums::GLOBAL_TARGET) {
- continue;
- }
- if ((*l)->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
- (*l)->AddSource(sf->GetFullPath());
- }
- }
- }
- }
-}
-
void cmLocalVisualStudio7Generator::FixGlobalTargets()
{
// Visual Studio .NET 2003 Service Pack 1 will not run post-build
@@ -239,19 +223,29 @@ void cmLocalVisualStudio7Generator::CreateSingleVCProj(
cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
{
+ if (this->Makefile->IsOn("CMAKE_SUPPRESS_REGENERATION")) {
+ return nullptr;
+ }
+
+ std::string makefileIn = this->GetCurrentSourceDirectory();
+ makefileIn += "/";
+ makefileIn += "CMakeLists.txt";
+ makefileIn = cmSystemTools::CollapseFullPath(makefileIn);
+ if (cmSourceFile* file = this->Makefile->GetSource(makefileIn)) {
+ if (file->GetCustomCommand()) {
+ return file;
+ }
+ }
+ if (!cmSystemTools::FileExists(makefileIn)) {
+ return nullptr;
+ }
+
std::string stampName = this->GetCurrentBinaryDirectory();
stampName += "/";
stampName += cmake::GetCMakeFilesDirectoryPostSlash();
stampName += "generate.stamp";
cmCustomCommandLine commandLine;
commandLine.push_back(cmSystemTools::GetCMakeCommand());
- std::string makefileIn = this->GetCurrentSourceDirectory();
- makefileIn += "/";
- makefileIn += "CMakeLists.txt";
- makefileIn = cmSystemTools::CollapseFullPath(makefileIn.c_str());
- if (!cmSystemTools::FileExists(makefileIn.c_str())) {
- return 0;
- }
std::string comment = "Building Custom Rule ";
comment += makefileIn;
std::string args;
@@ -275,10 +269,13 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
fullpathStampName.c_str(), listFiles, makefileIn.c_str(), commandLines,
comment.c_str(), no_working_directory, true, false);
if (cmSourceFile* file = this->Makefile->GetSource(makefileIn.c_str())) {
+ // Finalize the source file path now since we're adding this after
+ // the generator validated all project-named sources.
+ file->GetFullPath();
return file;
} else {
cmSystemTools::Error("Error adding rule for ", makefileIn.c_str());
- return 0;
+ return nullptr;
}
}
@@ -1368,13 +1365,26 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
// We may be modifying the source groups temporarily, so make a copy.
std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
- std::vector<cmGeneratorTarget::AllConfigSource> const& sources =
- target->GetAllConfigSources();
- std::map<cmSourceFile const*, size_t> sourcesIndex;
+ AllConfigSources sources;
+ sources.Sources = target->GetAllConfigSources();
+
+ // Add CMakeLists.txt file with rule to re-run CMake for user convenience.
+ if (target->GetType() != cmStateEnums::GLOBAL_TARGET &&
+ target->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
+ if (cmSourceFile const* sf = this->CreateVCProjBuildRule()) {
+ cmGeneratorTarget::AllConfigSource acs;
+ acs.Source = sf;
+ acs.Kind = cmGeneratorTarget::SourceKindCustomCommand;
+ for (size_t ci = 0; ci < configs.size(); ++ci) {
+ acs.Configs.push_back(ci);
+ }
+ sources.Sources.emplace_back(std::move(acs));
+ }
+ }
- for (size_t si = 0; si < sources.size(); ++si) {
- cmSourceFile const* sf = sources[si].Source;
- sourcesIndex[sf] = si;
+ for (size_t si = 0; si < sources.Sources.size(); ++si) {
+ cmSourceFile const* sf = sources.Sources[si].Source;
+ sources.Index[sf] = si;
if (!sf->GetObjectLibrary().empty()) {
if (this->FortranProject) {
// Intel Fortran does not support per-config source locations
@@ -1400,7 +1410,7 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
// Loop through every source group.
for (unsigned int i = 0; i < sourceGroups.size(); ++i) {
cmSourceGroup sg = sourceGroups[i];
- this->WriteGroup(&sg, target, fout, libName, configs, sourcesIndex);
+ this->WriteGroup(&sg, target, fout, libName, configs, sources);
}
fout << "\t</Files>\n";
@@ -1567,7 +1577,7 @@ std::string cmLocalVisualStudio7Generator::ComputeLongestObjectDirectory(
bool cmLocalVisualStudio7Generator::WriteGroup(
const cmSourceGroup* sg, cmGeneratorTarget* target, std::ostream& fout,
const std::string& libName, std::vector<std::string> const& configs,
- std::map<cmSourceFile const*, size_t> const& sourcesIndex)
+ AllConfigSources const& sources)
{
cmGlobalVisualStudio7Generator* gg =
static_cast<cmGlobalVisualStudio7Generator*>(this->GlobalGenerator);
@@ -1579,7 +1589,7 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
std::ostringstream tmpOut;
for (unsigned int i = 0; i < children.size(); ++i) {
if (this->WriteGroup(&children[i], target, tmpOut, libName, configs,
- sourcesIndex)) {
+ sources)) {
hasChildrenWithSources = true;
}
}
@@ -1595,9 +1605,6 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
this->WriteVCProjBeginGroup(fout, name.c_str(), "");
}
- std::vector<cmGeneratorTarget::AllConfigSource> const& sources =
- target->GetAllConfigSources();
-
// Loop through each source in the source group.
for (std::vector<const cmSourceFile*>::const_iterator sf =
sourceFiles.begin();
@@ -1608,10 +1615,11 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
target->GetType() == cmStateEnums::GLOBAL_TARGET) {
// Look up the source kind and configs.
std::map<cmSourceFile const*, size_t>::const_iterator map_it =
- sourcesIndex.find(*sf);
+ sources.Index.find(*sf);
// The map entry must exist because we populated it earlier.
- assert(map_it != sourcesIndex.end());
- cmGeneratorTarget::AllConfigSource const& acs = sources[map_it->second];
+ assert(map_it != sources.Index.end());
+ cmGeneratorTarget::AllConfigSource const& acs =
+ sources.Sources[map_it->second];
FCInfo fcinfo(this, target, acs, configs);
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
index 7a77574..48f2e1a 100644
--- a/Source/cmLocalVisualStudio7Generator.h
+++ b/Source/cmLocalVisualStudio7Generator.h
@@ -65,7 +65,6 @@ public:
virtual void ReadAndStoreExternalGUID(const std::string& name,
const char* path);
- virtual void AddCMakeListsRules();
protected:
void CreateSingleVCProj(const std::string& lname, cmGeneratorTarget* tgt);
@@ -117,10 +116,11 @@ private:
FCInfo& fcinfo);
void WriteTargetVersionAttribute(std::ostream& fout, cmGeneratorTarget* gt);
+ class AllConfigSources;
bool WriteGroup(const cmSourceGroup* sg, cmGeneratorTarget* target,
std::ostream& fout, const std::string& libName,
std::vector<std::string> const& configs,
- std::map<cmSourceFile const*, size_t> const& sourcesIndex);
+ AllConfigSources const& sources);
friend class cmLocalVisualStudio7GeneratorFCInfo;
friend class cmLocalVisualStudio7GeneratorInternals;
diff --git a/Source/cmLocalVisualStudioGenerator.h b/Source/cmLocalVisualStudioGenerator.h
index cba24fe..ace2f89 100644
--- a/Source/cmLocalVisualStudioGenerator.h
+++ b/Source/cmLocalVisualStudioGenerator.h
@@ -44,8 +44,6 @@ public:
virtual std::string ComputeLongestObjectDirectory(
cmGeneratorTarget const*) const = 0;
- virtual void AddCMakeListsRules() = 0;
-
virtual void ComputeObjectFilenames(
std::map<cmSourceFile const*, std::string>& mapping,
cmGeneratorTarget const* = 0);
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 5643c97..43c529c 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -7,6 +7,7 @@
#include <algorithm>
#include <assert.h>
#include <ctype.h>
+#include <iterator>
#include <memory> // IWYU pragma: keep
#include <sstream>
#include <stdlib.h>
@@ -122,6 +123,42 @@ void cmMakefile::IssueMessage(cmake::MessageType t,
this->GetCMakeInstance()->IssueMessage(t, text, this->GetBacktrace());
}
+bool cmMakefile::CheckCMP0037(std::string const& targetName,
+ cmStateEnums::TargetType targetType) const
+{
+ cmake::MessageType messageType = cmake::AUTHOR_WARNING;
+ std::ostringstream e;
+ bool issueMessage = false;
+ switch (this->GetPolicyStatus(cmPolicies::CMP0037)) {
+ case cmPolicies::WARN:
+ if (targetType != cmStateEnums::INTERFACE_LIBRARY) {
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0037) << "\n";
+ issueMessage = true;
+ }
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::NEW:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ issueMessage = true;
+ messageType = cmake::FATAL_ERROR;
+ break;
+ }
+ if (issueMessage) {
+ e << "The target name \"" << targetName
+ << "\" is reserved or not valid for certain "
+ "CMake features, such as generator expressions, and may result "
+ "in undefined behavior.";
+ this->IssueMessage(messageType, e.str());
+
+ if (messageType == cmake::FATAL_ERROR) {
+ return false;
+ }
+ }
+ return true;
+}
+
cmStringRange cmMakefile::GetIncludeDirectoriesEntries() const
{
return this->StateSnapshot.GetDirectory().GetIncludeDirectoriesEntries();
@@ -3186,6 +3223,7 @@ int cmMakefile::TryCompile(const std::string& srcdir,
// do a configure
cm.SetHomeDirectory(srcdir);
cm.SetHomeOutputDirectory(bindir);
+ cm.SetGeneratorInstance(this->GetSafeDefinition("CMAKE_GENERATOR_INSTANCE"));
cm.SetGeneratorPlatform(this->GetSafeDefinition("CMAKE_GENERATOR_PLATFORM"));
cm.SetGeneratorToolset(this->GetSafeDefinition("CMAKE_GENERATOR_TOOLSET"));
cm.LoadCache();
@@ -4133,15 +4171,15 @@ bool cmMakefile::CompileFeatureKnown(cmTarget const* target,
assert(cmGeneratorExpression::Find(feature) == std::string::npos);
bool isCFeature =
- std::find_if(cmArrayBegin(C_FEATURES) + 1, cmArrayEnd(C_FEATURES),
- cmStrCmp(feature)) != cmArrayEnd(C_FEATURES);
+ std::find_if(cm::cbegin(C_FEATURES) + 1, cm::cend(C_FEATURES),
+ cmStrCmp(feature)) != cm::cend(C_FEATURES);
if (isCFeature) {
lang = "C";
return true;
}
bool isCxxFeature =
- std::find_if(cmArrayBegin(CXX_FEATURES) + 1, cmArrayEnd(CXX_FEATURES),
- cmStrCmp(feature)) != cmArrayEnd(CXX_FEATURES);
+ std::find_if(cm::cbegin(CXX_FEATURES) + 1, cm::cend(CXX_FEATURES),
+ cmStrCmp(feature)) != cm::cend(CXX_FEATURES);
if (isCxxFeature) {
lang = "CXX";
return true;
@@ -4230,8 +4268,8 @@ bool cmMakefile::HaveCStandardAvailable(cmTarget const* target,
// Return true so the caller does not try to lookup the default standard.
return true;
}
- if (std::find_if(cmArrayBegin(C_STANDARDS), cmArrayEnd(C_STANDARDS),
- cmStrCmp(defaultCStandard)) == cmArrayEnd(C_STANDARDS)) {
+ if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
+ cmStrCmp(defaultCStandard)) == cm::cend(C_STANDARDS)) {
std::ostringstream e;
e << "The CMAKE_C_STANDARD_DEFAULT variable contains an "
"invalid value: \""
@@ -4251,8 +4289,8 @@ bool cmMakefile::HaveCStandardAvailable(cmTarget const* target,
existingCStandard = defaultCStandard;
}
- if (std::find_if(cmArrayBegin(C_STANDARDS), cmArrayEnd(C_STANDARDS),
- cmStrCmp(existingCStandard)) == cmArrayEnd(C_STANDARDS)) {
+ if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
+ cmStrCmp(existingCStandard)) == cm::cend(C_STANDARDS)) {
std::ostringstream e;
e << "The C_STANDARD property on target \"" << target->GetName()
<< "\" contained an invalid value: \"" << existingCStandard << "\".";
@@ -4261,23 +4299,23 @@ bool cmMakefile::HaveCStandardAvailable(cmTarget const* target,
}
const char* const* existingCIt = existingCStandard
- ? std::find_if(cmArrayBegin(C_STANDARDS), cmArrayEnd(C_STANDARDS),
+ ? std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
cmStrCmp(existingCStandard))
- : cmArrayEnd(C_STANDARDS);
+ : cm::cend(C_STANDARDS);
if (needC11 && existingCStandard &&
- existingCIt < std::find_if(cmArrayBegin(C_STANDARDS),
- cmArrayEnd(C_STANDARDS), cmStrCmp("11"))) {
+ existingCIt < std::find_if(cm::cbegin(C_STANDARDS),
+ cm::cend(C_STANDARDS), cmStrCmp("11"))) {
return false;
}
if (needC99 && existingCStandard &&
- existingCIt < std::find_if(cmArrayBegin(C_STANDARDS),
- cmArrayEnd(C_STANDARDS), cmStrCmp("99"))) {
+ existingCIt < std::find_if(cm::cbegin(C_STANDARDS),
+ cm::cend(C_STANDARDS), cmStrCmp("99"))) {
return false;
}
if (needC90 && existingCStandard &&
- existingCIt < std::find_if(cmArrayBegin(C_STANDARDS),
- cmArrayEnd(C_STANDARDS), cmStrCmp("90"))) {
+ existingCIt < std::find_if(cm::cbegin(C_STANDARDS),
+ cm::cend(C_STANDARDS), cmStrCmp("90"))) {
return false;
}
return true;
@@ -4289,16 +4327,16 @@ bool cmMakefile::IsLaterStandard(std::string const& lang,
{
if (lang == "C") {
const char* const* rhsIt = std::find_if(
- cmArrayBegin(C_STANDARDS), cmArrayEnd(C_STANDARDS), cmStrCmp(rhs));
+ cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS), cmStrCmp(rhs));
- return std::find_if(rhsIt, cmArrayEnd(C_STANDARDS), cmStrCmp(lhs)) !=
- cmArrayEnd(C_STANDARDS);
+ return std::find_if(rhsIt, cm::cend(C_STANDARDS), cmStrCmp(lhs)) !=
+ cm::cend(C_STANDARDS);
}
const char* const* rhsIt = std::find_if(
- cmArrayBegin(CXX_STANDARDS), cmArrayEnd(CXX_STANDARDS), cmStrCmp(rhs));
+ cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS), cmStrCmp(rhs));
- return std::find_if(rhsIt, cmArrayEnd(CXX_STANDARDS), cmStrCmp(lhs)) !=
- cmArrayEnd(CXX_STANDARDS);
+ return std::find_if(rhsIt, cm::cend(CXX_STANDARDS), cmStrCmp(lhs)) !=
+ cm::cend(CXX_STANDARDS);
}
bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
@@ -4314,9 +4352,8 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
// Return true so the caller does not try to lookup the default standard.
return true;
}
- if (std::find_if(cmArrayBegin(CXX_STANDARDS), cmArrayEnd(CXX_STANDARDS),
- cmStrCmp(defaultCxxStandard)) ==
- cmArrayEnd(CXX_STANDARDS)) {
+ if (std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
+ cmStrCmp(defaultCxxStandard)) == cm::cend(CXX_STANDARDS)) {
std::ostringstream e;
e << "The CMAKE_CXX_STANDARD_DEFAULT variable contains an "
"invalid value: \""
@@ -4337,9 +4374,8 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
existingCxxStandard = defaultCxxStandard;
}
- if (std::find_if(cmArrayBegin(CXX_STANDARDS), cmArrayEnd(CXX_STANDARDS),
- cmStrCmp(existingCxxStandard)) ==
- cmArrayEnd(CXX_STANDARDS)) {
+ if (std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
+ cmStrCmp(existingCxxStandard)) == cm::cend(CXX_STANDARDS)) {
std::ostringstream e;
e << "The CXX_STANDARD property on target \"" << target->GetName()
<< "\" contained an invalid value: \"" << existingCxxStandard << "\".";
@@ -4348,32 +4384,28 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
}
const char* const* existingCxxIt = existingCxxStandard
- ? std::find_if(cmArrayBegin(CXX_STANDARDS), cmArrayEnd(CXX_STANDARDS),
+ ? std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
cmStrCmp(existingCxxStandard))
- : cmArrayEnd(CXX_STANDARDS);
+ : cm::cend(CXX_STANDARDS);
if (needCxx17 &&
- existingCxxIt < std::find_if(cmArrayBegin(CXX_STANDARDS),
- cmArrayEnd(CXX_STANDARDS),
- cmStrCmp("17"))) {
+ existingCxxIt < std::find_if(cm::cbegin(CXX_STANDARDS),
+ cm::cend(CXX_STANDARDS), cmStrCmp("17"))) {
return false;
}
if (needCxx14 &&
- existingCxxIt < std::find_if(cmArrayBegin(CXX_STANDARDS),
- cmArrayEnd(CXX_STANDARDS),
- cmStrCmp("14"))) {
+ existingCxxIt < std::find_if(cm::cbegin(CXX_STANDARDS),
+ cm::cend(CXX_STANDARDS), cmStrCmp("14"))) {
return false;
}
if (needCxx11 &&
- existingCxxIt < std::find_if(cmArrayBegin(CXX_STANDARDS),
- cmArrayEnd(CXX_STANDARDS),
- cmStrCmp("11"))) {
+ existingCxxIt < std::find_if(cm::cbegin(CXX_STANDARDS),
+ cm::cend(CXX_STANDARDS), cmStrCmp("11"))) {
return false;
}
if (needCxx98 &&
- existingCxxIt < std::find_if(cmArrayBegin(CXX_STANDARDS),
- cmArrayEnd(CXX_STANDARDS),
- cmStrCmp("98"))) {
+ existingCxxIt < std::find_if(cm::cbegin(CXX_STANDARDS),
+ cm::cend(CXX_STANDARDS), cmStrCmp("98"))) {
return false;
}
return true;
@@ -4423,9 +4455,9 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
const char* existingCxxStandard = target->GetProperty("CXX_STANDARD");
if (existingCxxStandard) {
- if (std::find_if(cmArrayBegin(CXX_STANDARDS), cmArrayEnd(CXX_STANDARDS),
+ if (std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
cmStrCmp(existingCxxStandard)) ==
- cmArrayEnd(CXX_STANDARDS)) {
+ cm::cend(CXX_STANDARDS)) {
std::ostringstream e;
e << "The CXX_STANDARD property on target \"" << target->GetName()
<< "\" contained an invalid value: \"" << existingCxxStandard << "\".";
@@ -4439,9 +4471,9 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
}
}
const char* const* existingCxxIt = existingCxxStandard
- ? std::find_if(cmArrayBegin(CXX_STANDARDS), cmArrayEnd(CXX_STANDARDS),
+ ? std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
cmStrCmp(existingCxxStandard))
- : cmArrayEnd(CXX_STANDARDS);
+ : cm::cend(CXX_STANDARDS);
bool setCxx98 = needCxx98 && !existingCxxStandard;
bool setCxx11 = needCxx11 && !existingCxxStandard;
@@ -4449,23 +4481,22 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
bool setCxx17 = needCxx17 && !existingCxxStandard;
if (needCxx17 && existingCxxStandard &&
- existingCxxIt < std::find_if(cmArrayBegin(CXX_STANDARDS),
- cmArrayEnd(CXX_STANDARDS),
- cmStrCmp("17"))) {
+ existingCxxIt < std::find_if(cm::cbegin(CXX_STANDARDS),
+ cm::cend(CXX_STANDARDS), cmStrCmp("17"))) {
setCxx17 = true;
} else if (needCxx14 && existingCxxStandard &&
- existingCxxIt < std::find_if(cmArrayBegin(CXX_STANDARDS),
- cmArrayEnd(CXX_STANDARDS),
+ existingCxxIt < std::find_if(cm::cbegin(CXX_STANDARDS),
+ cm::cend(CXX_STANDARDS),
cmStrCmp("14"))) {
setCxx14 = true;
} else if (needCxx11 && existingCxxStandard &&
- existingCxxIt < std::find_if(cmArrayBegin(CXX_STANDARDS),
- cmArrayEnd(CXX_STANDARDS),
+ existingCxxIt < std::find_if(cm::cbegin(CXX_STANDARDS),
+ cm::cend(CXX_STANDARDS),
cmStrCmp("11"))) {
setCxx11 = true;
} else if (needCxx98 && existingCxxStandard &&
- existingCxxIt < std::find_if(cmArrayBegin(CXX_STANDARDS),
- cmArrayEnd(CXX_STANDARDS),
+ existingCxxIt < std::find_if(cm::cbegin(CXX_STANDARDS),
+ cm::cend(CXX_STANDARDS),
cmStrCmp("98"))) {
setCxx98 = true;
}
@@ -4522,8 +4553,8 @@ bool cmMakefile::AddRequiredTargetCFeature(cmTarget* target,
const char* existingCStandard = target->GetProperty("C_STANDARD");
if (existingCStandard) {
- if (std::find_if(cmArrayBegin(C_STANDARDS), cmArrayEnd(C_STANDARDS),
- cmStrCmp(existingCStandard)) == cmArrayEnd(C_STANDARDS)) {
+ if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
+ cmStrCmp(existingCStandard)) == cm::cend(C_STANDARDS)) {
std::ostringstream e;
e << "The C_STANDARD property on target \"" << target->GetName()
<< "\" contained an invalid value: \"" << existingCStandard << "\".";
@@ -4537,26 +4568,26 @@ bool cmMakefile::AddRequiredTargetCFeature(cmTarget* target,
}
}
const char* const* existingCIt = existingCStandard
- ? std::find_if(cmArrayBegin(C_STANDARDS), cmArrayEnd(C_STANDARDS),
+ ? std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
cmStrCmp(existingCStandard))
- : cmArrayEnd(C_STANDARDS);
+ : cm::cend(C_STANDARDS);
bool setC90 = needC90 && !existingCStandard;
bool setC99 = needC99 && !existingCStandard;
bool setC11 = needC11 && !existingCStandard;
if (needC11 && existingCStandard &&
- existingCIt < std::find_if(cmArrayBegin(C_STANDARDS),
- cmArrayEnd(C_STANDARDS), cmStrCmp("11"))) {
+ existingCIt < std::find_if(cm::cbegin(C_STANDARDS),
+ cm::cend(C_STANDARDS), cmStrCmp("11"))) {
setC11 = true;
} else if (needC99 && existingCStandard &&
- existingCIt < std::find_if(cmArrayBegin(C_STANDARDS),
- cmArrayEnd(C_STANDARDS),
+ existingCIt < std::find_if(cm::cbegin(C_STANDARDS),
+ cm::cend(C_STANDARDS),
cmStrCmp("99"))) {
setC99 = true;
} else if (needC90 && existingCStandard &&
- existingCIt < std::find_if(cmArrayBegin(C_STANDARDS),
- cmArrayEnd(C_STANDARDS),
+ existingCIt < std::find_if(cm::cbegin(C_STANDARDS),
+ cm::cend(C_STANDARDS),
cmStrCmp("90"))) {
setC90 = true;
}
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 0273f5b..5e7a361 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -665,6 +665,10 @@ public:
{
return this->InstallGenerators;
}
+ const std::vector<cmInstallGenerator*>& GetInstallGenerators() const
+ {
+ return this->InstallGenerators;
+ }
void AddTestGenerator(cmTestGenerator* g)
{
@@ -737,6 +741,9 @@ public:
/** Set whether or not to report a CMP0000 violation. */
void SetCheckCMP0000(bool b) { this->CheckCMP0000 = b; }
+ bool CheckCMP0037(std::string const& targetName,
+ cmStateEnums::TargetType targetType) const;
+
cmStringRange GetIncludeDirectoriesEntries() const;
cmBacktraceRange GetIncludeDirectoriesBacktraces() const;
cmStringRange GetCompileOptionsEntries() const;
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 6c33e2b..f614dca 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -225,6 +225,7 @@ class cmMakefile;
F(CMP0021) \
F(CMP0022) \
F(CMP0027) \
+ F(CMP0037) \
F(CMP0038) \
F(CMP0041) \
F(CMP0042) \
diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx
index 5e89978..9dc77ac 100644
--- a/Source/cmQtAutoGen.cxx
+++ b/Source/cmQtAutoGen.cxx
@@ -9,6 +9,7 @@
#include "cmsys/RegularExpression.hxx"
#include <algorithm>
+#include <iterator>
#include <sstream>
#include <stddef.h>
@@ -301,8 +302,7 @@ std::string cmQtAutoGen::Quoted(std::string const& text)
"\r", "\\r", "\t", "\\t", "\v", "\\v" };
std::string res = text;
- for (const char* const* it = cmArrayBegin(rep); it != cmArrayEnd(rep);
- it += 2) {
+ for (const char* const* it = cm::cbegin(rep); it != cm::cend(rep); it += 2) {
cmSystemTools::ReplaceString(res, *it, *(it + 1));
}
res = '"' + res;
diff --git a/Source/cmServerDictionary.h b/Source/cmServerDictionary.h
index 405ff6b..03f1cc1 100644
--- a/Source/cmServerDictionary.h
+++ b/Source/cmServerDictionary.h
@@ -88,6 +88,8 @@ static const std::string kWARN_UNUSED_CLI_KEY = "warnUnusedCli";
static const std::string kWARN_UNUSED_KEY = "warnUnused";
static const std::string kWATCHED_DIRECTORIES_KEY = "watchedDirectories";
static const std::string kWATCHED_FILES_KEY = "watchedFiles";
+static const std::string kHAS_INSTALL_RULE = "hasInstallRule";
+static const std::string kINSTALL_PATHS = "installPaths";
static const std::string kTARGET_CROSS_REFERENCES_KEY = "crossReferences";
static const std::string kLINE_NUMBER_KEY = "line";
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
index e835b7a..fc06fed 100644
--- a/Source/cmServerProtocol.cxx
+++ b/Source/cmServerProtocol.cxx
@@ -8,6 +8,8 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmInstallGenerator.h"
+#include "cmInstallTargetGenerator.h"
#include "cmLinkLineComputer.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
@@ -30,6 +32,7 @@
#include <functional>
#include <limits>
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <unordered_map>
@@ -252,7 +255,7 @@ bool cmServerProtocol::DoActivate(const cmServerRequest& /*request*/,
std::pair<int, int> cmServerProtocol1::ProtocolVersion() const
{
- return std::make_pair(1, 1);
+ return std::make_pair(1, 2);
}
static void setErrorMessage(std::string* errorMessage, const std::string& text)
@@ -797,6 +800,34 @@ static Json::Value DumpTarget(cmGeneratorTarget* target,
result[kFULL_NAME_KEY] = target->GetFullName(config);
+ if (target->Target->GetHaveInstallRule()) {
+ result[kHAS_INSTALL_RULE] = true;
+
+ Json::Value installPaths = Json::arrayValue;
+ auto targetGenerators = target->Makefile->GetInstallGenerators();
+ for (auto installGenerator : targetGenerators) {
+ auto installTargetGenerator =
+ dynamic_cast<cmInstallTargetGenerator*>(installGenerator);
+ if (installTargetGenerator != nullptr &&
+ installTargetGenerator->GetTarget()->Target == target->Target) {
+ auto dest = installTargetGenerator->GetDestination(config);
+
+ std::string installPath;
+ if (!dest.empty() && cmSystemTools::FileIsFullPath(dest.c_str())) {
+ installPath = dest;
+ } else {
+ std::string installPrefix =
+ target->Makefile->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
+ installPath = installPrefix + '/' + dest;
+ }
+
+ installPaths.append(installPath);
+ }
+ }
+
+ result[kINSTALL_PATHS] = installPaths;
+ }
+
Json::Value crossRefs = Json::objectValue;
crossRefs[kBACKTRACE_KEY] = DumpBacktrace(target->Target->GetBacktrace());
@@ -933,6 +964,7 @@ static Json::Value DumpProjectList(const cmake* cm, std::string const& config)
// Project structure information:
const cmMakefile* mf = lg->GetMakefile();
+ pObj[kHAS_INSTALL_RULE] = mf->GetInstallGenerators().empty() == false;
pObj[kSOURCE_DIRECTORY_KEY] = mf->GetCurrentSourceDirectory();
pObj[kBUILD_DIRECTORY_KEY] = mf->GetCurrentBinaryDirectory();
pObj[kTARGETS_KEY] = DumpTargetsList(projectIt.second, config);
diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx
index b32cda3..985aac8 100644
--- a/Source/cmSetCommand.cxx
+++ b/Source/cmSetCommand.cxx
@@ -2,8 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmSetCommand.h"
-#include <string.h>
-
#include "cmAlgorithms.h"
#include "cmMakefile.h"
#include "cmState.h"
@@ -22,19 +20,15 @@ bool cmSetCommand::InitialPass(std::vector<std::string> const& args,
}
// watch for ENV signatures
- const char* variable = args[0].c_str(); // VAR is always first
- if (cmHasLiteralPrefix(variable, "ENV{") && strlen(variable) > 5) {
+ auto const& variable = args[0]; // VAR is always first
+ if (cmHasLiteralPrefix(variable, "ENV{") && variable.size() > 5) {
// what is the variable name
- char* varName = new char[strlen(variable)];
- strncpy(varName, variable + 4, strlen(variable) - 5);
- varName[strlen(variable) - 5] = '\0';
- std::string putEnvArg = varName;
- putEnvArg += "=";
+ auto const& varName = variable.substr(4, variable.size() - 5);
+ std::string putEnvArg = varName + "=";
// what is the current value if any
std::string currValue;
const bool currValueSet = cmSystemTools::GetEnv(varName, currValue);
- delete[] varName;
// will it be set to something, then set it
if (args.size() > 1 && !args[1].empty()) {
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 63c1452..5d1f5f7 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -50,6 +50,8 @@
#include <windows.h>
// include wincrypt.h after windows.h
#include <wincrypt.h>
+
+#include "cm_uv.h"
#else
#include <sys/time.h>
#include <unistd.h>
@@ -943,6 +945,39 @@ cmSystemTools::WindowsFileRetry cmSystemTools::GetWindowsFileRetry()
}
return retry;
}
+
+std::string cmSystemTools::GetRealPath(const std::string& path,
+ std::string* errorMessage)
+{
+ // uv_fs_realpath uses Windows Vista API so fallback to kwsys if not found
+ std::string resolved_path;
+ uv_fs_t req;
+ int err = uv_fs_realpath(NULL, &req, path.c_str(), NULL);
+ if (!err) {
+ resolved_path = std::string((char*)req.ptr);
+ cmSystemTools::ConvertToUnixSlashes(resolved_path);
+ // Normalize to upper-case drive letter as GetActualCaseForPath does.
+ if (resolved_path.size() > 1 && resolved_path[1] == ':') {
+ resolved_path[0] = toupper(resolved_path[0]);
+ }
+ } else if (err == UV_ENOSYS) {
+ resolved_path = cmsys::SystemTools::GetRealPath(path, errorMessage);
+ } else if (errorMessage) {
+ LPSTR message = NULL;
+ DWORD size = FormatMessageA(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&message, 0,
+ NULL);
+ *errorMessage = std::string(message, size);
+ LocalFree(message);
+
+ resolved_path = "";
+ } else {
+ resolved_path = path;
+ }
+ return resolved_path;
+}
#endif
bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index e7082e6..2646df9 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -497,6 +497,10 @@ public:
unsigned int Delay;
};
static WindowsFileRetry GetWindowsFileRetry();
+
+ /** Get the real path for a given path, removing all symlinks. */
+ static std::string GetRealPath(const std::string& path,
+ std::string* errorMessage = 0);
#endif
private:
static bool s_ForceUnixPaths;
diff --git a/Source/cmTargetCompileDefinitionsCommand.cxx b/Source/cmTargetCompileDefinitionsCommand.cxx
index d159d41..bd4121d 100644
--- a/Source/cmTargetCompileDefinitionsCommand.cxx
+++ b/Source/cmTargetCompileDefinitionsCommand.cxx
@@ -17,15 +17,6 @@ bool cmTargetCompileDefinitionsCommand::InitialPass(
return this->HandleArguments(args, "COMPILE_DEFINITIONS");
}
-void cmTargetCompileDefinitionsCommand::HandleImportedTarget(
- const std::string& tgt)
-{
- std::ostringstream e;
- e << "Cannot specify compile definitions for imported target \"" << tgt
- << "\".";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
-}
-
void cmTargetCompileDefinitionsCommand::HandleMissingTarget(
const std::string& name)
{
@@ -56,5 +47,5 @@ bool cmTargetCompileDefinitionsCommand::HandleDirectContent(
cmTarget* tgt, const std::vector<std::string>& content, bool, bool)
{
tgt->AppendProperty("COMPILE_DEFINITIONS", this->Join(content).c_str());
- return true;
+ return true; // Successfully handled.
}
diff --git a/Source/cmTargetCompileDefinitionsCommand.h b/Source/cmTargetCompileDefinitionsCommand.h
index f910452..d41483a 100644
--- a/Source/cmTargetCompileDefinitionsCommand.h
+++ b/Source/cmTargetCompileDefinitionsCommand.h
@@ -30,7 +30,6 @@ public:
cmExecutionStatus& status) override;
private:
- void HandleImportedTarget(const std::string& tgt) override;
void HandleMissingTarget(const std::string& name) override;
bool HandleDirectContent(cmTarget* tgt,
diff --git a/Source/cmTargetCompileFeaturesCommand.cxx b/Source/cmTargetCompileFeaturesCommand.cxx
index 722bbe5..f58e404 100644
--- a/Source/cmTargetCompileFeaturesCommand.cxx
+++ b/Source/cmTargetCompileFeaturesCommand.cxx
@@ -17,15 +17,6 @@ bool cmTargetCompileFeaturesCommand::InitialPass(
return this->HandleArguments(args, "COMPILE_FEATURES", NO_FLAGS);
}
-void cmTargetCompileFeaturesCommand::HandleImportedTarget(
- const std::string& tgt)
-{
- std::ostringstream e;
- e << "Cannot specify compile features for imported target \"" << tgt
- << "\".";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
-}
-
void cmTargetCompileFeaturesCommand::HandleMissingTarget(
const std::string& name)
{
@@ -49,8 +40,8 @@ bool cmTargetCompileFeaturesCommand::HandleDirectContent(
std::string error;
if (!this->Makefile->AddRequiredTargetFeature(tgt, it, &error)) {
this->SetError(error);
- return false;
+ return false; // Not (successfully) handled.
}
}
- return true;
+ return true; // Successfully handled.
}
diff --git a/Source/cmTargetCompileFeaturesCommand.h b/Source/cmTargetCompileFeaturesCommand.h
index 444d260..45240a5 100644
--- a/Source/cmTargetCompileFeaturesCommand.h
+++ b/Source/cmTargetCompileFeaturesCommand.h
@@ -22,7 +22,6 @@ class cmTargetCompileFeaturesCommand : public cmTargetPropCommandBase
cmExecutionStatus& status) override;
private:
- void HandleImportedTarget(const std::string& tgt) override;
void HandleMissingTarget(const std::string& name) override;
bool HandleDirectContent(cmTarget* tgt,
diff --git a/Source/cmTargetCompileOptionsCommand.cxx b/Source/cmTargetCompileOptionsCommand.cxx
index 1b4056d..4df3630 100644
--- a/Source/cmTargetCompileOptionsCommand.cxx
+++ b/Source/cmTargetCompileOptionsCommand.cxx
@@ -18,21 +18,12 @@ bool cmTargetCompileOptionsCommand::InitialPass(
return this->HandleArguments(args, "COMPILE_OPTIONS", PROCESS_BEFORE);
}
-void cmTargetCompileOptionsCommand::HandleImportedTarget(
- const std::string& tgt)
-{
- std::ostringstream e;
- e << "Cannot specify compile options for imported target \"" << tgt << "\".";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
-}
-
void cmTargetCompileOptionsCommand::HandleMissingTarget(
const std::string& name)
{
std::ostringstream e;
e << "Cannot specify compile options for target \"" << name
- << "\" "
- "which is not built by this project.";
+ << "\" which is not built by this project.";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
}
@@ -47,5 +38,5 @@ bool cmTargetCompileOptionsCommand::HandleDirectContent(
{
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
tgt->InsertCompileOption(this->Join(content), lfbt);
- return true;
+ return true; // Successfully handled.
}
diff --git a/Source/cmTargetCompileOptionsCommand.h b/Source/cmTargetCompileOptionsCommand.h
index 3fab238..6fb151a 100644
--- a/Source/cmTargetCompileOptionsCommand.h
+++ b/Source/cmTargetCompileOptionsCommand.h
@@ -30,7 +30,6 @@ public:
cmExecutionStatus& status) override;
private:
- void HandleImportedTarget(const std::string& tgt) override;
void HandleMissingTarget(const std::string& name) override;
bool HandleDirectContent(cmTarget* tgt,
diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx
index 4646c7e..dcec830 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.cxx
+++ b/Source/cmTargetIncludeDirectoriesCommand.cxx
@@ -21,22 +21,12 @@ bool cmTargetIncludeDirectoriesCommand::InitialPass(
ArgumentFlags(PROCESS_BEFORE | PROCESS_SYSTEM));
}
-void cmTargetIncludeDirectoriesCommand::HandleImportedTarget(
- const std::string& tgt)
-{
- std::ostringstream e;
- e << "Cannot specify include directories for imported target \"" << tgt
- << "\".";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
-}
-
void cmTargetIncludeDirectoriesCommand::HandleMissingTarget(
const std::string& name)
{
std::ostringstream e;
e << "Cannot specify include directories for target \"" << name
- << "\" "
- "which is not built by this project.";
+ << "\" which is not built by this project.";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
}
@@ -79,7 +69,7 @@ bool cmTargetIncludeDirectoriesCommand::HandleDirectContent(
}
tgt->AddSystemIncludeDirectories(sdirs);
}
- return true;
+ return true; // Successfully handled.
}
void cmTargetIncludeDirectoriesCommand::HandleInterfaceContent(
diff --git a/Source/cmTargetIncludeDirectoriesCommand.h b/Source/cmTargetIncludeDirectoriesCommand.h
index 27a2f43..57bf8fc 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.h
+++ b/Source/cmTargetIncludeDirectoriesCommand.h
@@ -30,7 +30,6 @@ public:
cmExecutionStatus& status) override;
private:
- void HandleImportedTarget(const std::string& tgt) override;
void HandleMissingTarget(const std::string& name) override;
bool HandleDirectContent(cmTarget* tgt,
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index dda0464..37bcb70 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -40,6 +40,16 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
this->Makefile->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(
args[0]);
if (!this->Target) {
+ const std::vector<cmTarget*>& importedTargets =
+ this->Makefile->GetOwnedImportedTargets();
+ for (cmTarget* importedTarget : importedTargets) {
+ if (importedTarget->GetName() == args[0]) {
+ this->Target = importedTarget;
+ break;
+ }
+ }
+ }
+ if (!this->Target) {
cmake::MessageType t = cmake::FATAL_ERROR; // fail by default
std::ostringstream e;
e << "Cannot specify link libraries for target \"" << args[0] << "\" "
@@ -228,7 +238,7 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
} else {
// Lookup old-style cache entry if type is unspecified. So if you
// do a target_link_libraries(foo optimized bar) it will stay optimized
- // and not use the lookup. As there maybe the case where someone has
+ // and not use the lookup. As there may be the case where someone has
// specifed that a library is both debug and optimized. (this check is
// only there for backwards compatibility when mixing projects built
// with old versions of CMake and new)
@@ -299,6 +309,14 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
"target_link_libraries");
return false;
}
+ if (this->Target->IsImported() &&
+ this->CurrentProcessingState != ProcessingKeywordLinkInterface) {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "IMPORTED library can only be used with the INTERFACE keyword of "
+ "target_link_libraries");
+ return false;
+ }
cmTarget::TLLSignature sig =
(this->CurrentProcessingState == ProcessingPlainPrivateInterface ||
@@ -355,6 +373,16 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
cmTarget* t =
this->Makefile->FindLocalNonAliasTarget(this->Target->GetName());
if (!t) {
+ const std::vector<cmTarget*>& importedTargets =
+ this->Makefile->GetOwnedImportedTargets();
+ for (cmTarget* importedTarget : importedTargets) {
+ if (importedTarget->GetName() == this->Target->GetName()) {
+ t = importedTarget;
+ break;
+ }
+ }
+ }
+ if (!t) {
std::ostringstream e;
e << "Attempt to add link library \"" << lib << "\" to target \""
<< this->Target->GetName()
diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx
index 45fe430..9a8fd96 100644
--- a/Source/cmTargetPropCommandBase.cxx
+++ b/Source/cmTargetPropCommandBase.cxx
@@ -17,11 +17,11 @@ bool cmTargetPropCommandBase::HandleArguments(
return false;
}
- // Lookup the target for which libraries are specified.
if (this->Makefile->IsAlias(args[0])) {
this->SetError("can not be used on an ALIAS target.");
return false;
}
+ // Lookup the target for which property-values are specified.
this->Target =
this->Makefile->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(
args[0]);
@@ -84,16 +84,13 @@ bool cmTargetPropCommandBase::ProcessContentArgs(
this->SetError("called with invalid arguments");
return false;
}
-
- if (this->Target->IsImported()) {
- this->HandleImportedTarget(args[0]);
- return false;
- }
-
if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY &&
scope != "INTERFACE") {
- this->SetError("may only be set INTERFACE properties on INTERFACE "
- "targets");
+ this->SetError("may only set INTERFACE properties on INTERFACE targets");
+ return false;
+ }
+ if (this->Target->IsImported() && scope != "INTERFACE") {
+ this->SetError("may only set INTERFACE properties on IMPORTED targets");
return false;
}
diff --git a/Source/cmTargetPropCommandBase.h b/Source/cmTargetPropCommandBase.h
index 46a2f6b..3c736fc 100644
--- a/Source/cmTargetPropCommandBase.h
+++ b/Source/cmTargetPropCommandBase.h
@@ -35,7 +35,6 @@ protected:
bool prepend, bool system);
private:
- virtual void HandleImportedTarget(const std::string& tgt) = 0;
virtual void HandleMissingTarget(const std::string& name) = 0;
virtual bool HandleDirectContent(cmTarget* tgt,
diff --git a/Source/cmTargetSourcesCommand.cxx b/Source/cmTargetSourcesCommand.cxx
index 058659a..3dd3748 100644
--- a/Source/cmTargetSourcesCommand.cxx
+++ b/Source/cmTargetSourcesCommand.cxx
@@ -17,13 +17,6 @@ bool cmTargetSourcesCommand::InitialPass(std::vector<std::string> const& args,
return this->HandleArguments(args, "SOURCES");
}
-void cmTargetSourcesCommand::HandleImportedTarget(const std::string& tgt)
-{
- std::ostringstream e;
- e << "Cannot specify sources for imported target \"" << tgt << "\".";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
-}
-
void cmTargetSourcesCommand::HandleMissingTarget(const std::string& name)
{
std::ostringstream e;
@@ -43,5 +36,5 @@ bool cmTargetSourcesCommand::HandleDirectContent(
cmTarget* tgt, const std::vector<std::string>& content, bool, bool)
{
tgt->AppendProperty("SOURCES", this->Join(content).c_str());
- return true;
+ return true; // Successfully handled.
}
diff --git a/Source/cmTargetSourcesCommand.h b/Source/cmTargetSourcesCommand.h
index 0639e98..ea8776a 100644
--- a/Source/cmTargetSourcesCommand.h
+++ b/Source/cmTargetSourcesCommand.h
@@ -30,7 +30,6 @@ public:
cmExecutionStatus& status) override;
private:
- void HandleImportedTarget(const std::string& tgt) override;
void HandleMissingTarget(const std::string& name) override;
bool HandleDirectContent(cmTarget* tgt,
diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx
index 9fb79d9..e747adb 100644
--- a/Source/cmTimestamp.cxx
+++ b/Source/cmTimestamp.cxx
@@ -33,11 +33,13 @@ std::string cmTimestamp::FileModificationTime(const char* path,
const std::string& formatString,
bool utcFlag)
{
- if (!cmsys::SystemTools::FileExists(path)) {
+ std::string real_path = cmSystemTools::GetRealPath(path);
+
+ if (!cmsys::SystemTools::FileExists(real_path)) {
return std::string();
}
- time_t mtime = cmsys::SystemTools::ModifiedTime(path);
+ time_t mtime = cmsys::SystemTools::ModifiedTime(real_path);
return CreateTimestampFromTimeT(mtime, formatString, utcFlag);
}
diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx
index dcaa493..932b976 100644
--- a/Source/cmTryRunCommand.cxx
+++ b/Source/cmTryRunCommand.cxx
@@ -4,7 +4,6 @@
#include "cmsys/FStream.hxx"
#include <stdio.h>
-#include <string.h>
#include "cmMakefile.h"
#include "cmState.h"
@@ -191,13 +190,15 @@ void cmTryRunCommand::RunExecutable(const std::string& runArgs,
finalCommand.c_str(), out, out, &retVal, nullptr,
cmSystemTools::OUTPUT_NONE, timeout);
// set the run var
- char retChar[1000];
+ char retChar[16];
+ const char* retStr;
if (worked) {
sprintf(retChar, "%i", retVal);
+ retStr = retChar;
} else {
- strcpy(retChar, "FAILED_TO_RUN");
+ retStr = "FAILED_TO_RUN";
}
- this->Makefile->AddCacheDefinition(this->RunResultVariable, retChar,
+ this->Makefile->AddCacheDefinition(this->RunResultVariable, retStr,
"Result of TRY_RUN",
cmStateEnums::INTERNAL);
}
diff --git a/Source/cmUnsetCommand.cxx b/Source/cmUnsetCommand.cxx
index 18bbdd7..cfaa1fd2 100644
--- a/Source/cmUnsetCommand.cxx
+++ b/Source/cmUnsetCommand.cxx
@@ -2,8 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmUnsetCommand.h"
-#include <string.h>
-
#include "cmAlgorithms.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
@@ -19,19 +17,16 @@ bool cmUnsetCommand::InitialPass(std::vector<std::string> const& args,
return false;
}
- const char* variable = args[0].c_str();
+ auto const& variable = args[0];
// unset(ENV{VAR})
- if (cmHasLiteralPrefix(variable, "ENV{") && strlen(variable) > 5) {
+ if (cmHasLiteralPrefix(variable, "ENV{") && variable.size() > 5) {
// what is the variable name
- char* envVarName = new char[strlen(variable)];
- strncpy(envVarName, variable + 4, strlen(variable) - 5);
- envVarName[strlen(variable) - 5] = '\0';
+ auto const& envVarName = variable.substr(4, variable.size() - 5);
#ifdef CMAKE_BUILD_WITH_CMAKE
- cmSystemTools::UnsetEnv(envVarName);
+ cmSystemTools::UnsetEnv(envVarName.c_str());
#endif
- delete[] envVarName;
return true;
}
// unset(VAR)
diff --git a/Source/cmVS141CLFlagTable.h b/Source/cmVS141CLFlagTable.h
index c780d46..7d3e356 100644
--- a/Source/cmVS141CLFlagTable.h
+++ b/Source/cmVS141CLFlagTable.h
@@ -1,6 +1,10 @@
static cmVS7FlagTable cmVS141CLFlagTable[] = {
// Enum Properties
+ { "DiagnosticsFormat", "diagnostics:classic", "Classic", "Classic", 0 },
+ { "DiagnosticsFormat", "diagnostics:column", "Column", "Column", 0 },
+ { "DiagnosticsFormat", "diagnostics:caret", "Caret", "Caret", 0 },
+
{ "DebugInformationFormat", "", "None", "None", 0 },
{ "DebugInformationFormat", "Z7", "C7 compatible", "OldStyle", 0 },
{ "DebugInformationFormat", "Zi", "Program Database", "ProgramDatabase", 0 },
diff --git a/Source/cmVSSetupHelper.cxx b/Source/cmVSSetupHelper.cxx
index ea13649..c2f8deb 100644
--- a/Source/cmVSSetupHelper.cxx
+++ b/Source/cmVSSetupHelper.cxx
@@ -80,6 +80,14 @@ cmVSSetupAPIHelper::~cmVSSetupAPIHelper()
CoUninitialize();
}
+bool cmVSSetupAPIHelper::SetVSInstance(std::string const& vsInstallLocation)
+{
+ this->SpecifiedVSInstallLocation = vsInstallLocation;
+ cmSystemTools::ConvertToUnixSlashes(this->SpecifiedVSInstallLocation);
+ chosenInstanceInfo = VSInstanceInfo();
+ return this->EnumerateAndChooseVSInstance();
+}
+
bool cmVSSetupAPIHelper::IsVS2017Installed()
{
return this->EnumerateAndChooseVSInstance();
@@ -265,13 +273,6 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance()
if (cmSystemTools::GetEnv("VS150COMNTOOLS", envVSCommonToolsDir)) {
cmSystemTools::ConvertToUnixSlashes(envVSCommonToolsDir);
}
- // FIXME: If the environment variable value changes between runs
- // of CMake within a given build tree the results are not defined.
- // Instead we should save a CMAKE_GENERATOR_INSTANCE value in the cache
- // (similar to CMAKE_GENERATOR_TOOLSET) to hold it persistently.
- // Unfortunately doing so will require refactoring elsewhere in
- // order to make sure the value is available in time to create
- // the generator.
std::vector<VSInstanceInfo> vecVSInstances;
SmartCOMPtr<IEnumSetupInstances> enumInstances = NULL;
@@ -296,16 +297,29 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance()
instance = instance2 = NULL;
if (isInstalled) {
- if (!envVSCommonToolsDir.empty()) {
+ if (!this->SpecifiedVSInstallLocation.empty()) {
+ // We are looking for a specific instance.
std::string currentVSLocation = instanceInfo.GetInstallLocation();
- currentVSLocation += "/Common7/Tools";
if (cmSystemTools::ComparePath(currentVSLocation,
- envVSCommonToolsDir)) {
+ this->SpecifiedVSInstallLocation)) {
chosenInstanceInfo = instanceInfo;
return true;
}
+ } else {
+ // We are not looking for a specific instance.
+ // If we've been given a hint then use it.
+ if (!envVSCommonToolsDir.empty()) {
+ std::string currentVSLocation = instanceInfo.GetInstallLocation();
+ currentVSLocation += "/Common7/Tools";
+ if (cmSystemTools::ComparePath(currentVSLocation,
+ envVSCommonToolsDir)) {
+ chosenInstanceInfo = instanceInfo;
+ return true;
+ }
+ }
+ // Otherwise, add this to the list of candidates.
+ vecVSInstances.push_back(instanceInfo);
}
- vecVSInstances.push_back(instanceInfo);
}
}
diff --git a/Source/cmVSSetupHelper.h b/Source/cmVSSetupHelper.h
index 74a7ec0..c07cfaf 100644
--- a/Source/cmVSSetupHelper.h
+++ b/Source/cmVSSetupHelper.h
@@ -126,6 +126,8 @@ public:
cmVSSetupAPIHelper();
~cmVSSetupAPIHelper();
+ bool SetVSInstance(std::string const& vsInstallLocation);
+
bool IsVS2017Installed();
bool GetVSInstanceInfo(std::string& vsInstallLocation);
bool IsWin10SDKInstalled();
@@ -150,6 +152,8 @@ private:
HRESULT comInitialized;
// current best instance of VS selected
VSInstanceInfo chosenInstanceInfo;
+
+ std::string SpecifiedVSInstallLocation;
};
#endif
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index c61902a..1aadf67 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -15,6 +15,7 @@
#include "cmVisualStudioGeneratorOptions.h"
#include "windows.h"
+#include <iterator>
#include <memory> // IWYU pragma: keep
static std::string cmVS10EscapeXML(std::string arg)
@@ -1174,6 +1175,15 @@ void cmVisualStudio10TargetGenerator::WriteCustomCommands()
si != customCommands.end(); ++si) {
this->WriteCustomCommand(*si);
}
+
+ // Add CMakeLists.txt file with rule to re-run CMake for user convenience.
+ if (this->GeneratorTarget->GetType() != cmStateEnums::GLOBAL_TARGET &&
+ this->GeneratorTarget->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
+ if (cmSourceFile const* sf =
+ this->LocalGenerator->CreateVCProjBuildRule()) {
+ this->WriteCustomCommand(sf);
+ }
+ }
}
void cmVisualStudio10TargetGenerator::WriteCustomCommand(
@@ -1592,6 +1602,8 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf)
std::string shaderEntryPoint;
std::string shaderModel;
std::string shaderAdditionalFlags;
+ std::string shaderDisableOptimizations;
+ std::string shaderEnableDebug;
std::string outputHeaderFile;
std::string variableName;
std::string settingsGenerator;
@@ -1658,6 +1670,16 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf)
shaderAdditionalFlags = saf;
toolHasSettings = true;
}
+ // Figure out if debug information should be generated
+ if (const char* sed = sf->GetProperty("VS_SHADER_ENABLE_DEBUG")) {
+ shaderEnableDebug = cmSystemTools::IsOn(sed) ? "true" : "false";
+ toolHasSettings = true;
+ }
+ // Figure out if optimizations should be disabled
+ if (const char* sdo = sf->GetProperty("VS_SHADER_DISABLE_OPTIMIZATIONS")) {
+ shaderDisableOptimizations = cmSystemTools::IsOn(sdo) ? "true" : "false";
+ toolHasSettings = true;
+ }
} else if (ext == "jpg" || ext == "png") {
tool = "Image";
} else if (ext == "resw") {
@@ -1800,6 +1822,16 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf)
this->WriteString("</VariableName>\n", 0);
}
}
+ if (!shaderEnableDebug.empty()) {
+ this->WriteString("<EnableDebuggingInformation>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(shaderEnableDebug)
+ << "</EnableDebuggingInformation>\n";
+ }
+ if (!shaderDisableOptimizations.empty()) {
+ this->WriteString("<DisableOptimizations>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(shaderDisableOptimizations)
+ << "</DisableOptimizations>\n";
+ }
if (!shaderAdditionalFlags.empty()) {
this->WriteString("<AdditionalOptions>", 3);
(*this->BuildFileStream) << cmVS10EscapeXML(shaderAdditionalFlags)
@@ -2359,14 +2391,14 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
// Choose a language whose flags to use for ClCompile.
static const char* clLangs[] = { "CXX", "C", "Fortran", "CSharp" };
std::string langForClCompile;
- if (std::find(cmArrayBegin(clLangs), cmArrayEnd(clLangs), linkLanguage) !=
- cmArrayEnd(clLangs)) {
+ if (std::find(cm::cbegin(clLangs), cm::cend(clLangs), linkLanguage) !=
+ cm::cend(clLangs)) {
langForClCompile = linkLanguage;
} else {
std::set<std::string> languages;
this->GeneratorTarget->GetLanguages(languages, configName);
- for (const char* const* l = cmArrayBegin(clLangs);
- l != cmArrayEnd(clLangs); ++l) {
+ for (const char* const* l = cm::cbegin(clLangs); l != cm::cend(clLangs);
+ ++l) {
if (languages.find(*l) != languages.end()) {
langForClCompile = *l;
break;
diff --git a/Source/cm_codecvt.cxx b/Source/cm_codecvt.cxx
index cf55741..6705851 100644
--- a/Source/cm_codecvt.cxx
+++ b/Source/cm_codecvt.cxx
@@ -38,12 +38,14 @@ codecvt::codecvt(Encoding e)
}
}
-codecvt::~codecvt(){};
+codecvt::~codecvt()
+{
+}
bool codecvt::do_always_noconv() const throw()
{
return m_noconv;
-};
+}
std::codecvt_base::result codecvt::do_out(mbstate_t& state, const char* from,
const char* from_end,
@@ -122,7 +124,7 @@ std::codecvt_base::result codecvt::do_out(mbstate_t& state, const char* from,
static_cast<void>(to_next);
return std::codecvt_base::noconv;
#endif
-};
+}
std::codecvt_base::result codecvt::do_unshift(mbstate_t& state, char* to,
char* to_end,
@@ -143,7 +145,7 @@ std::codecvt_base::result codecvt::do_unshift(mbstate_t& state, char* to,
static_cast<void>(to_end);
return std::codecvt_base::ok;
#endif
-};
+}
#if defined(_WIN32)
std::codecvt_base::result codecvt::Decode(mbstate_t& state, int size,
@@ -235,9 +237,9 @@ void codecvt::BufferPartial(mbstate_t& state, int size,
int codecvt::do_max_length() const throw()
{
return 4;
-};
+}
int codecvt::do_encoding() const throw()
{
return 0;
-};
+}
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index fd7151f..fde77a7 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -110,6 +110,7 @@
#include "cmsys/RegularExpression.hxx"
#include <algorithm>
#include <iostream>
+#include <iterator>
#include <memory> // IWYU pragma: keep
#include <sstream>
#include <stdio.h>
@@ -1326,6 +1327,25 @@ int cmake::ActualConfigure()
cmStateEnums::INTERNAL);
}
+ if (const char* instance =
+ this->State->GetInitializedCacheValue("CMAKE_GENERATOR_INSTANCE")) {
+ if (!this->GeneratorInstance.empty() &&
+ this->GeneratorInstance != instance) {
+ std::string message = "Error: generator instance: ";
+ message += this->GeneratorInstance;
+ message += "\nDoes not match the instance used previously: ";
+ message += instance;
+ message += "\nEither remove the CMakeCache.txt file and CMakeFiles "
+ "directory or choose a different binary directory.";
+ cmSystemTools::Error(message.c_str());
+ return -2;
+ }
+ } else {
+ this->AddCacheEntry(
+ "CMAKE_GENERATOR_INSTANCE", this->GeneratorInstance.c_str(),
+ "Generator instance identifier.", cmStateEnums::INTERNAL);
+ }
+
if (const char* platformName =
this->State->GetInitializedCacheValue("CMAKE_GENERATOR_PLATFORM")) {
if (!this->GeneratorPlatform.empty() &&
@@ -1453,12 +1473,12 @@ void cmake::CreateDefaultGlobalGenerator()
if (vsSetupAPIHelper.IsVS2017Installed()) {
found = "Visual Studio 15 2017";
} else {
- for (VSVersionedGenerator const* g = cmArrayBegin(vsGenerators);
- found.empty() && g != cmArrayEnd(vsGenerators); ++g) {
- for (const char* const* v = cmArrayBegin(vsVariants);
- found.empty() && v != cmArrayEnd(vsVariants); ++v) {
- for (const char* const* e = cmArrayBegin(vsEntries);
- found.empty() && e != cmArrayEnd(vsEntries); ++e) {
+ for (VSVersionedGenerator const* g = cm::cbegin(vsGenerators);
+ found.empty() && g != cm::cend(vsGenerators); ++g) {
+ for (const char* const* v = cm::cbegin(vsVariants);
+ found.empty() && v != cm::cend(vsVariants); ++v) {
+ for (const char* const* e = cm::cbegin(vsEntries);
+ found.empty() && e != cm::cend(vsEntries); ++e) {
std::string const reg = vsregBase + *v + g->MSVersion + *e;
std::string dir;
if (cmSystemTools::ReadRegistryValue(reg, dir,
@@ -1716,8 +1736,8 @@ bool cmake::LoadCache(const std::string& path, bool internal,
bool result = this->State->LoadCache(path, internal, excludes, includes);
static const char* entries[] = { "CMAKE_CACHE_MAJOR_VERSION",
"CMAKE_CACHE_MINOR_VERSION" };
- for (const char* const* nameIt = cmArrayBegin(entries);
- nameIt != cmArrayEnd(entries); ++nameIt) {
+ for (const char* const* nameIt = cm::cbegin(entries);
+ nameIt != cm::cend(entries); ++nameIt) {
this->UnwatchUnusedCli(*nameIt);
}
return result;
@@ -1730,8 +1750,8 @@ bool cmake::SaveCache(const std::string& path)
"CMAKE_CACHE_MINOR_VERSION",
"CMAKE_CACHE_PATCH_VERSION",
"CMAKE_CACHEFILE_DIR" };
- for (const char* const* nameIt = cmArrayBegin(entries);
- nameIt != cmArrayEnd(entries); ++nameIt) {
+ for (const char* const* nameIt = cm::cbegin(entries);
+ nameIt != cm::cend(entries); ++nameIt) {
this->UnwatchUnusedCli(*nameIt);
}
return result;
@@ -2360,6 +2380,14 @@ int cmake::Build(const std::string& dir, const std::string& target,
<< "\"\n";
return 1;
}
+ const char* cachedGeneratorInstance =
+ this->State->GetCacheEntryValue("CMAKE_GENERATOR_INSTANCE");
+ if (cachedGeneratorInstance) {
+ cmMakefile mf(gen.get(), this->GetCurrentSnapshot());
+ if (!gen->SetGeneratorInstance(cachedGeneratorInstance, &mf)) {
+ return 1;
+ }
+ }
std::string output;
std::string projName;
const char* cachedProjectName =
@@ -2425,6 +2453,49 @@ int cmake::Build(const std::string& dir, const std::string& target,
nativeOptions);
}
+bool cmake::Open(const std::string& dir, bool dryRun)
+{
+ this->SetHomeDirectory("");
+ this->SetHomeOutputDirectory("");
+ if (!cmSystemTools::FileIsDirectory(dir)) {
+ std::cerr << "Error: " << dir << " is not a directory\n";
+ return false;
+ }
+
+ std::string cachePath = FindCacheFile(dir);
+ if (!this->LoadCache(cachePath)) {
+ std::cerr << "Error: could not load cache\n";
+ return false;
+ }
+ const char* genName = this->State->GetCacheEntryValue("CMAKE_GENERATOR");
+ if (!genName) {
+ std::cerr << "Error: could not find CMAKE_GENERATOR in Cache\n";
+ return false;
+ }
+ const char* extraGenName =
+ this->State->GetInitializedCacheValue("CMAKE_EXTRA_GENERATOR");
+ std::string fullName =
+ cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
+ genName, extraGenName ? extraGenName : "");
+
+ std::unique_ptr<cmGlobalGenerator> gen(
+ this->CreateGlobalGenerator(fullName));
+ if (!gen.get()) {
+ std::cerr << "Error: could create CMAKE_GENERATOR \"" << fullName
+ << "\"\n";
+ return false;
+ }
+
+ const char* cachedProjectName =
+ this->State->GetCacheEntryValue("CMAKE_PROJECT_NAME");
+ if (!cachedProjectName) {
+ std::cerr << "Error: could not find CMAKE_PROJECT_NAME in Cache\n";
+ return false;
+ }
+
+ return gen->Open(dir, cachedProjectName, dryRun);
+}
+
void cmake::WatchUnusedCli(const std::string& var)
{
#ifdef CMAKE_BUILD_WITH_CMAKE
diff --git a/Source/cmake.h b/Source/cmake.h
index b31b6f5..5c5a90d 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -203,6 +203,12 @@ public:
///! Get the names of the current registered generators
void GetRegisteredGenerators(std::vector<GeneratorInfo>& generators) const;
+ ///! Set the name of the selected generator-specific instance.
+ void SetGeneratorInstance(std::string const& instance)
+ {
+ this->GeneratorInstance = instance;
+ }
+
///! Set the name of the selected generator-specific platform.
void SetGeneratorPlatform(std::string const& ts)
{
@@ -401,6 +407,9 @@ public:
const std::string& config,
const std::vector<std::string>& nativeOptions, bool clean);
+ ///! run the --open option
+ bool Open(const std::string& dir, bool dryRun);
+
void UnwatchUnusedCli(const std::string& var);
void WatchUnusedCli(const std::string& var);
@@ -428,6 +437,7 @@ protected:
cmGlobalGenerator* GlobalGenerator;
std::map<std::string, DiagLevel> DiagLevels;
+ std::string GeneratorInstance;
std::string GeneratorPlatform;
std::string GeneratorToolset;
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index a1dfc3e..59b908a 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -66,6 +66,7 @@ static const char* cmDocumentationOptions[][2] = {
{ "-E", "CMake command mode." },
{ "-L[A][H]", "List non-advanced cached variables." },
{ "--build <dir>", "Build a CMake-generated project binary tree." },
+ { "--open <dir>", "Open generated project in the associated application." },
{ "-N", "View mode only." },
{ "-P <file>", "Process script mode." },
{ "--find-package", "Run in pkg-config like mode." },
@@ -100,6 +101,7 @@ static int do_command(int ac, char const* const* av)
int do_cmake(int ac, char const* const* av);
static int do_build(int ac, char const* const* av);
+static int do_open(int ac, char const* const* av);
static cmMakefile* cmakemainGetMakefile(void* clientdata)
{
@@ -186,6 +188,9 @@ int main(int ac, char const* const* av)
if (strcmp(av[1], "--build") == 0) {
return do_build(ac, av);
}
+ if (strcmp(av[1], "--open") == 0) {
+ return do_open(ac, av);
+ }
if (strcmp(av[1], "-E") == 0) {
return do_command(ac, av);
}
@@ -423,3 +428,41 @@ static int do_build(int ac, char const* const* av)
return cm.Build(dir, target, config, nativeOptions, clean);
#endif
}
+
+static int do_open(int ac, char const* const* av)
+{
+#ifndef CMAKE_BUILD_WITH_CMAKE
+ std::cerr << "This cmake does not support --open\n";
+ return -1;
+#else
+ std::string dir;
+
+ enum Doing
+ {
+ DoingNone,
+ DoingDir,
+ };
+ Doing doing = DoingDir;
+ for (int i = 2; i < ac; ++i) {
+ switch (doing) {
+ case DoingDir:
+ dir = cmSystemTools::CollapseFullPath(av[i]);
+ doing = DoingNone;
+ break;
+ default:
+ std::cerr << "Unknown argument " << av[i] << std::endl;
+ dir.clear();
+ break;
+ }
+ }
+ if (dir.empty()) {
+ std::cerr << "Usage: cmake --open <dir>\n";
+ return 1;
+ }
+
+ cmake cm(cmake::RoleInternal);
+ cmSystemTools::SetMessageCallback(cmakemainMessageCallback, &cm);
+ cm.SetProgressCallback(cmakemainProgressCallback, &cm);
+ return cm.Open(dir, false) ? 0 : 1;
+#endif
+}
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index b4772a9..ef75b01 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -34,6 +34,7 @@
#include "cmsys/Terminal.h"
#include <algorithm>
#include <iostream>
+#include <iterator>
#include <memory> // IWYU pragma: keep
#include <sstream>
#include <stdio.h>
@@ -371,8 +372,8 @@ int cmcmd::HandleCoCompileCommands(std::vector<std::string>& args)
doing_options = false;
} else if (doing_options) {
bool optionFound = false;
- for (CoCompiler const* cc = cmArrayBegin(CoCompilers);
- cc != cmArrayEnd(CoCompilers); ++cc) {
+ for (CoCompiler const* cc = cm::cbegin(CoCompilers);
+ cc != cm::cend(CoCompilers); ++cc) {
size_t optionLen = strlen(cc->Option);
if (arg.compare(0, optionLen, cc->Option) == 0) {
optionFound = true;
@@ -402,8 +403,8 @@ int cmcmd::HandleCoCompileCommands(std::vector<std::string>& args)
if (jobs.empty()) {
std::cerr << "__run_co_compile missing command to run. "
"Looking for one or more of the following:\n";
- for (CoCompiler const* cc = cmArrayBegin(CoCompilers);
- cc != cmArrayEnd(CoCompilers); ++cc) {
+ for (CoCompiler const* cc = cm::cbegin(CoCompilers);
+ cc != cm::cend(CoCompilers); ++cc) {
std::cerr << cc->Option << "\n";
}
return 1;
@@ -1024,8 +1025,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
} else if (cmHasLiteralPrefix(arg, "--format=")) {
format = arg.substr(9);
bool isKnown =
- std::find(cmArrayBegin(knownFormats), cmArrayEnd(knownFormats),
- format) != cmArrayEnd(knownFormats);
+ std::find(cm::cbegin(knownFormats), cm::cend(knownFormats),
+ format) != cm::cend(knownFormats);
if (!isKnown) {
cmSystemTools::Error("Unknown -E tar --format= argument: ",
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index 21568bb..f36f9b6 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -445,8 +445,13 @@ KWSYS_PLATFORM_C_TEST(KWSYS_C_HAS_PTRDIFF_T
"Checking whether C compiler has ptrdiff_t in stddef.h" DIRECT)
KWSYS_PLATFORM_C_TEST(KWSYS_C_HAS_SSIZE_T
"Checking whether C compiler has ssize_t in unistd.h" DIRECT)
+IF(KWSYS_USE_Process)
+ KWSYS_PLATFORM_C_TEST(KWSYS_C_HAS_CLOCK_GETTIME_MONOTONIC
+ "Checking whether C compiler has clock_gettime" DIRECT)
+ENDIF()
+
SET_SOURCE_FILES_PROPERTIES(ProcessUNIX.c System.c PROPERTIES
- COMPILE_FLAGS "-DKWSYS_C_HAS_PTRDIFF_T=${KWSYS_C_HAS_PTRDIFF_T} -DKWSYS_C_HAS_SSIZE_T=${KWSYS_C_HAS_SSIZE_T}"
+ COMPILE_FLAGS "-DKWSYS_C_HAS_PTRDIFF_T=${KWSYS_C_HAS_PTRDIFF_T} -DKWSYS_C_HAS_SSIZE_T=${KWSYS_C_HAS_SSIZE_T} -DKWSYS_C_HAS_CLOCK_GETTIME_MONOTONIC=${KWSYS_C_HAS_CLOCK_GETTIME_MONOTONIC}"
)
IF(DEFINED KWSYS_PROCESS_USE_SELECT)
diff --git a/Source/kwsys/CommandLineArguments.cxx b/Source/kwsys/CommandLineArguments.cxx
index 5613bd7..5792da9 100644
--- a/Source/kwsys/CommandLineArguments.cxx
+++ b/Source/kwsys/CommandLineArguments.cxx
@@ -529,10 +529,7 @@ void CommandLineArguments::GenerateHelp()
}
}
- // Create format for that string
- char format[80];
- sprintf(format, " %%-%us ", static_cast<unsigned int>(maxlen));
-
+ CommandLineArguments::Internal::String::size_type maxstrlen = maxlen;
maxlen += 4; // For the space before and after the option
// Print help for each option
@@ -540,27 +537,24 @@ void CommandLineArguments::GenerateHelp()
CommandLineArguments::Internal::SetOfStrings::iterator sit;
for (sit = mpit->second.begin(); sit != mpit->second.end(); sit++) {
str << std::endl;
- char argument[100];
- sprintf(argument, "%s", sit->c_str());
+ std::string argument = *sit;
switch (this->Internals->Callbacks[*sit].ArgumentType) {
case CommandLineArguments::NO_ARGUMENT:
break;
case CommandLineArguments::CONCAT_ARGUMENT:
- strcat(argument, "opt");
+ argument += "opt";
break;
case CommandLineArguments::SPACE_ARGUMENT:
- strcat(argument, " opt");
+ argument += " opt";
break;
case CommandLineArguments::EQUAL_ARGUMENT:
- strcat(argument, "=opt");
+ argument += "=opt";
break;
case CommandLineArguments::MULTI_ARGUMENT:
- strcat(argument, " opt opt ...");
+ argument += " opt opt ...";
break;
}
- char buffer[80];
- sprintf(buffer, format, argument);
- str << buffer;
+ str << " " << argument.substr(0, maxstrlen) << " ";
}
const char* ptr = this->Internals->Callbacks[mpit->first].Help;
size_t len = strlen(ptr);
@@ -649,10 +643,7 @@ void CommandLineArguments::PopulateVariable(double* variable,
void CommandLineArguments::PopulateVariable(char** variable,
const std::string& value)
{
- if (*variable) {
- delete[] * variable;
- *variable = 0;
- }
+ delete[] * variable;
*variable = new char[value.size() + 1];
strcpy(*variable, value.c_str());
}
diff --git a/Source/kwsys/DynamicLoader.cxx b/Source/kwsys/DynamicLoader.cxx
index 1b4596a..664f183 100644
--- a/Source/kwsys/DynamicLoader.cxx
+++ b/Source/kwsys/DynamicLoader.cxx
@@ -163,17 +163,13 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
{
void* result = 0;
// Need to prepend symbols with '_' on Apple-gcc compilers
- size_t len = sym.size();
- char* rsym = new char[len + 1 + 1];
- strcpy(rsym, "_");
- strcat(rsym + 1, sym.c_str());
+ std::string rsym = '_' + sym;
- NSSymbol symbol = NSLookupSymbolInModule(lib, rsym);
+ NSSymbol symbol = NSLookupSymbolInModule(lib, rsym.c_str());
if (symbol) {
result = NSAddressOfSymbol(symbol);
}
- delete[] rsym;
// Hack to cast pointer-to-data to pointer-to-function.
return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result);
}
@@ -237,17 +233,12 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
void* result;
#if defined(__BORLANDC__) || defined(__WATCOMC__)
// Need to prepend symbols with '_'
- size_t len = sym.size();
- char* rsym = new char[len + 1 + 1];
- strcpy(rsym, "_");
- strcat(rsym, sym.c_str());
+ std::string ssym = '_' + sym;
+ const char* rsym = ssym.c_str();
#else
const char* rsym = sym.c_str();
#endif
result = (void*)GetProcAddress(lib, rsym);
-#if defined(__BORLANDC__) || defined(__WATCOMC__)
- delete[] rsym;
-#endif
// Hack to cast pointer-to-data to pointer-to-function.
#ifdef __WATCOMC__
return *(DynamicLoader::SymbolPointer*)(&result);
diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c
index 3b32ca7..e62ef34 100644
--- a/Source/kwsys/ProcessUNIX.c
+++ b/Source/kwsys/ProcessUNIX.c
@@ -359,9 +359,7 @@ void kwsysProcess_Delete(kwsysProcess* cp)
kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDIN, 0);
kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDOUT, 0);
kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDERR, 0);
- if (cp->CommandExitCodes) {
- free(cp->CommandExitCodes);
- }
+ free(cp->CommandExitCodes);
free(cp->ProcessResults);
free(cp);
}
@@ -498,11 +496,10 @@ int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp, const char* dir)
cp->WorkingDirectory = 0;
}
if (dir) {
- cp->WorkingDirectory = (char*)malloc(strlen(dir) + 1);
+ cp->WorkingDirectory = strdup(dir);
if (!cp->WorkingDirectory) {
return 0;
}
- strcpy(cp->WorkingDirectory, dir);
}
return 1;
}
@@ -531,11 +528,10 @@ int kwsysProcess_SetPipeFile(kwsysProcess* cp, int prPipe, const char* file)
*pfile = 0;
}
if (file) {
- *pfile = (char*)malloc(strlen(file) + 1);
+ *pfile = strdup(file);
if (!*pfile) {
return 0;
}
- strcpy(*pfile, file);
}
/* If we are redirecting the pipe, do not share it or use a native
@@ -1514,9 +1510,7 @@ static int kwsysProcessInitialize(kwsysProcess* cp)
oldForkPIDs = cp->ForkPIDs;
cp->ForkPIDs = (volatile pid_t*)malloc(sizeof(volatile pid_t) *
(size_t)(cp->NumberOfCommands));
- if (oldForkPIDs) {
- kwsysProcessVolatileFree(oldForkPIDs);
- }
+ kwsysProcessVolatileFree(oldForkPIDs);
if (!cp->ForkPIDs) {
return 0;
}
@@ -1524,9 +1518,7 @@ static int kwsysProcessInitialize(kwsysProcess* cp)
cp->ForkPIDs[i] = 0; /* can't use memset due to volatile */
}
- if (cp->CommandExitCodes) {
- free(cp->CommandExitCodes);
- }
+ free(cp->CommandExitCodes);
cp->CommandExitCodes =
(int*)malloc(sizeof(int) * (size_t)(cp->NumberOfCommands));
if (!cp->CommandExitCodes) {
@@ -1938,6 +1930,7 @@ static int kwsysProcessSetupOutputPipeFile(int* p, const char* name)
/* Set close-on-exec flag on the pipe's end. */
if (fcntl(fout, F_SETFD, FD_CLOEXEC) < 0) {
+ close(fout);
return 0;
}
@@ -2033,7 +2026,15 @@ static kwsysProcessTime kwsysProcessTimeGetCurrent(void)
{
kwsysProcessTime current;
kwsysProcessTimeNative current_native;
+#if KWSYS_C_HAS_CLOCK_GETTIME_MONOTONIC
+ struct timespec current_timespec;
+ clock_gettime(CLOCK_MONOTONIC, &current_timespec);
+
+ current_native.tv_sec = current_timespec.tv_sec;
+ current_native.tv_usec = current_timespec.tv_nsec / 1000;
+#else
gettimeofday(&current_native, 0);
+#endif
current.tv_sec = (long)current_native.tv_sec;
current.tv_usec = (long)current_native.tv_usec;
return current;
@@ -2290,6 +2291,7 @@ static void kwsysProcessChildErrorExit(int errorPipe)
char buffer[KWSYSPE_PIPE_BUFFER_SIZE];
kwsysProcess_ssize_t result;
strncpy(buffer, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
+ buffer[KWSYSPE_PIPE_BUFFER_SIZE - 1] = '\0';
/* Report the error to the parent through the special pipe. */
result = write(errorPipe, buffer, strlen(buffer));
diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c
index 5183e3d..945fa28 100644
--- a/Source/kwsys/ProcessWin32.c
+++ b/Source/kwsys/ProcessWin32.c
@@ -523,9 +523,7 @@ void kwsysProcess_Delete(kwsysProcess* cp)
kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDIN, 0);
kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDOUT, 0);
kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDERR, 0);
- if (cp->CommandExitCodes) {
- free(cp->CommandExitCodes);
- }
+ free(cp->CommandExitCodes);
free(cp->ProcessResults);
free(cp);
}
@@ -713,11 +711,10 @@ int kwsysProcess_SetPipeFile(kwsysProcess* cp, int pipe, const char* file)
*pfile = 0;
}
if (file) {
- *pfile = (char*)malloc(strlen(file) + 1);
+ *pfile = strdup(file);
if (!*pfile) {
return 0;
}
- strcpy(*pfile, file);
}
/* If we are redirecting the pipe, do not share it or use a native
@@ -1607,9 +1604,7 @@ int kwsysProcessInitialize(kwsysProcess* cp)
}
ZeroMemory(cp->ProcessInformation,
sizeof(PROCESS_INFORMATION) * cp->NumberOfCommands);
- if (cp->CommandExitCodes) {
- free(cp->CommandExitCodes);
- }
+ free(cp->CommandExitCodes);
cp->CommandExitCodes = (DWORD*)malloc(sizeof(DWORD) * cp->NumberOfCommands);
if (!cp->CommandExitCodes) {
return 0;
@@ -2362,9 +2357,7 @@ static int kwsysProcess_List__New_NT4(kwsysProcess_List* self)
static void kwsysProcess_List__Delete_NT4(kwsysProcess_List* self)
{
/* Free the process information buffer. */
- if (self->Buffer) {
- free(self->Buffer);
- }
+ free(self->Buffer);
}
static int kwsysProcess_List__Update_NT4(kwsysProcess_List* self)
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index 86fdccd..366fe30 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -1346,7 +1346,7 @@ std::string SymbolProperties::GetBinary() const
std::string binary;
char buf[1024] = { '\0' };
ssize_t ll = 0;
- if ((ll = readlink("/proc/self/exe", buf, 1024)) > 0) {
+ if ((ll = readlink("/proc/self/exe", buf, 1024)) > 0 && ll < 1024) {
buf[ll] = '\0';
binary = buf;
} else {
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index ecfa331..a24a326 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -20,6 +20,7 @@
#include KWSYS_HEADER(SystemTools.hxx)
#include KWSYS_HEADER(Directory.hxx)
#include KWSYS_HEADER(FStream.hxx)
+#include KWSYS_HEADER(Encoding.h)
#include KWSYS_HEADER(Encoding.hxx)
#include <fstream>
@@ -227,13 +228,17 @@ inline const char* Getcwd(char* buf, unsigned int len)
{
std::vector<wchar_t> w_buf(len);
if (_wgetcwd(&w_buf[0], len)) {
- // make sure the drive letter is capital
- if (wcslen(&w_buf[0]) > 1 && w_buf[1] == L':') {
- w_buf[0] = towupper(w_buf[0]);
+ size_t nlen = kwsysEncoding_wcstombs(buf, &w_buf[0], len);
+ if (nlen == static_cast<size_t>(-1)) {
+ return 0;
+ }
+ if (nlen < len) {
+ // make sure the drive letter is capital
+ if (nlen > 1 && buf[1] == ':') {
+ buf[0] = toupper(buf[0]);
+ }
+ return buf;
}
- std::string tmp = KWSYS_NAMESPACE::Encoding::ToNarrow(&w_buf[0]);
- strcpy(buf, tmp.c_str());
- return buf;
}
return 0;
}
diff --git a/Source/kwsys/kwsysPlatformTestsC.c b/Source/kwsys/kwsysPlatformTestsC.c
index 64a361b..5432633 100644
--- a/Source/kwsys/kwsysPlatformTestsC.c
+++ b/Source/kwsys/kwsysPlatformTestsC.c
@@ -55,6 +55,21 @@ int KWSYS_PLATFORM_TEST_C_MAIN()
}
#endif
+#ifdef TEST_KWSYS_C_HAS_CLOCK_GETTIME_MONOTONIC
+#if defined(__APPLE__)
+#include <AvailabilityMacros.h>
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 101200
+#error "clock_gettime not available on macOS < 10.12"
+#endif
+#endif
+#include <time.h>
+int KWSYS_PLATFORM_TEST_C_MAIN()
+{
+ struct timespec ts;
+ return clock_gettime(CLOCK_MONOTONIC, &ts);
+}
+#endif
+
#ifdef TEST_KWSYS_C_TYPE_MACROS
char* info_macros =
#if defined(__SIZEOF_SHORT__)
diff --git a/Source/kwsys/testEncoding.cxx b/Source/kwsys/testEncoding.cxx
index 2c5ef46..2742fe4 100644
--- a/Source/kwsys/testEncoding.cxx
+++ b/Source/kwsys/testEncoding.cxx
@@ -75,6 +75,10 @@ static int testRobustEncoding()
// test that the conversion functions handle invalid
// unicode correctly/gracefully
+ // we manipulate the format flags of stdout, remember
+ // the original state here to restore before return
+ std::ios::fmtflags const& flags = std::cout.flags();
+
int ret = 0;
char cstr[] = { (char)-1, 0 };
// this conversion could fail
@@ -120,6 +124,7 @@ static int testRobustEncoding()
ret++;
}
+ std::cout.flags(flags);
return ret;
}
diff --git a/Source/kwsys/testProcess.c b/Source/kwsys/testProcess.c
index 092dd03..cd817d9 100644
--- a/Source/kwsys/testProcess.c
+++ b/Source/kwsys/testProcess.c
@@ -687,9 +687,7 @@ int main(int argc, const char* argv[])
fflush(stdout);
fflush(stderr);
#if defined(_WIN32)
- if (argv0) {
- free(argv0);
- }
+ free(argv0);
#endif
return r;
} else if (argc > 2 && strcmp(argv[1], "0") == 0) {
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index 768eb4d..3b694c9 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -254,22 +254,22 @@ static bool CheckFileOperations()
}
// should work, was created as new file before
if (!kwsys::SystemTools::FileExists(testNewFile)) {
- std::cerr << "Problem with FileExists for: " << testNewDir << std::endl;
+ std::cerr << "Problem with FileExists for: " << testNewFile << std::endl;
res = false;
}
if (!kwsys::SystemTools::FileExists(testNewFile.c_str())) {
- std::cerr << "Problem with FileExists as C string for: " << testNewDir
+ std::cerr << "Problem with FileExists as C string for: " << testNewFile
<< std::endl;
res = false;
}
if (!kwsys::SystemTools::FileExists(testNewFile, true)) {
- std::cerr << "Problem with FileExists as file for: " << testNewDir
+ std::cerr << "Problem with FileExists as file for: " << testNewFile
<< std::endl;
res = false;
}
if (!kwsys::SystemTools::FileExists(testNewFile.c_str(), true)) {
std::cerr << "Problem with FileExists as C string and file for: "
- << testNewDir << std::endl;
+ << testNewFile << std::endl;
res = false;
}
@@ -285,7 +285,7 @@ static bool CheckFileOperations()
}
// should work, was created as new file before
if (!kwsys::SystemTools::PathExists(testNewFile)) {
- std::cerr << "Problem with PathExists for: " << testNewDir << std::endl;
+ std::cerr << "Problem with PathExists for: " << testNewFile << std::endl;
res = false;
}