summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/cmCPackGenerator.cxx3
-rw-r--r--Source/CPack/cpack.cxx3
-rw-r--r--Source/CTest/cmCTestBuildAndTestHandler.cxx3
-rw-r--r--Source/CTest/cmCTestLaunch.cxx3
-rw-r--r--Source/CTest/cmCTestScriptHandler.cxx2
-rw-r--r--Source/CTest/cmCTestSubmitCommand.cxx53
-rw-r--r--Source/CTest/cmCTestSubmitCommand.h2
-rw-r--r--Source/CTest/cmCTestSubmitHandler.cxx114
-rw-r--r--Source/CTest/cmCTestSubmitHandler.h2
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx2
-rw-r--r--Source/CursesDialog/ccmake.cxx3
-rw-r--r--Source/CursesDialog/cmCursesMainForm.cxx2
-rw-r--r--Source/QtDialog/CMakeSetup.cxx2
-rw-r--r--Source/QtDialog/QCMake.cxx2
-rw-r--r--Source/cmCTest.cxx28
-rw-r--r--Source/cmCTest.h2
-rw-r--r--Source/cmCoreTryCompile.cxx16
-rw-r--r--Source/cmFileCommand.cxx119
-rw-r--r--Source/cmFileCommand.h1
-rw-r--r--Source/cmFindPackageCommand.cxx10
-rw-r--r--Source/cmFindPackageCommand.h1
-rw-r--r--Source/cmGhsMultiGpj.cxx31
-rw-r--r--Source/cmGhsMultiGpj.h6
-rw-r--r--Source/cmGhsMultiTargetGenerator.cxx798
-rw-r--r--Source/cmGhsMultiTargetGenerator.h100
-rw-r--r--Source/cmGlobalGenerator.cxx3
-rw-r--r--Source/cmGlobalGhsMultiGenerator.cxx505
-rw-r--r--Source/cmGlobalGhsMultiGenerator.h99
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx2
-rw-r--r--Source/cmGraphVizWriter.cxx3
-rw-r--r--Source/cmLocalGhsMultiGenerator.cxx81
-rw-r--r--Source/cmLocalGhsMultiGenerator.h11
-rw-r--r--Source/cmMakefile.cxx2
-rw-r--r--Source/cmQtAutoGenerator.cxx3
-rw-r--r--Source/cmServerProtocol.cxx3
-rw-r--r--Source/cmState.cxx47
-rw-r--r--Source/cmState.h20
-rw-r--r--Source/cmSystemTools.cxx30
-rw-r--r--Source/cmSystemTools.h9
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx105
-rw-r--r--Source/cmake.cxx6
-rw-r--r--Source/cmake.h4
-rw-r--r--Source/cmakemain.cxx22
-rw-r--r--Source/cmcmd.cxx6
45 files changed, 1216 insertions, 1055 deletions
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 1a300f2..62f5f70 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 13)
-set(CMake_VERSION_PATCH 20190116)
+set(CMake_VERSION_PATCH 20190121)
#set(CMake_VERSION_RC 1)
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index acd6650..b205105 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -18,6 +18,7 @@
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
+#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmVersion.h"
#include "cmWorkingDirectory.h"
@@ -690,7 +691,7 @@ int cmCPackGenerator::InstallCMakeProject(
"- Install component: " << component << std::endl);
}
- cmake cm(cmake::RoleScript);
+ cmake cm(cmake::RoleScript, cmState::CPack);
cm.SetHomeDirectory("");
cm.SetHomeOutputDirectory("");
cm.GetCurrentSnapshot().SetDefaultDefinitions();
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index 4e49727..db9a0e7 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -24,6 +24,7 @@
#include "cmDocumentationFormatter.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
+#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmSystemTools.h"
#include "cmake.h"
@@ -208,7 +209,7 @@ int main(int argc, char const* const* argv)
cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
"Read CPack config file: " << cpackConfigFile << std::endl);
- cmake cminst(cmake::RoleScript);
+ cmake cminst(cmake::RoleScript, cmState::CPack);
cminst.SetHomeDirectory("");
cminst.SetHomeOutputDirectory("");
cminst.SetProgressCallback(cpackProgressCallback, nullptr);
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx
index 668a387..d49fba2 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.cxx
+++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx
@@ -6,6 +6,7 @@
#include "cmCTestTestHandler.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
+#include "cmState.h"
#include "cmSystemTools.h"
#include "cmWorkingDirectory.h"
#include "cmake.h"
@@ -163,7 +164,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
return 1;
}
- cmake cm(cmake::RoleProject);
+ cmake cm(cmake::RoleProject, cmState::CTest);
cm.SetHomeDirectory("");
cm.SetHomeOutputDirectory("");
std::string cmakeOutString;
diff --git a/Source/CTest/cmCTestLaunch.cxx b/Source/CTest/cmCTestLaunch.cxx
index 6cd1c09..4facea2 100644
--- a/Source/CTest/cmCTestLaunch.cxx
+++ b/Source/CTest/cmCTestLaunch.cxx
@@ -15,6 +15,7 @@
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmProcessOutput.h"
+#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmSystemTools.h"
#include "cmXMLWriter.h"
@@ -610,7 +611,7 @@ int cmCTestLaunch::Main(int argc, const char* const argv[])
void cmCTestLaunch::LoadConfig()
{
- cmake cm(cmake::RoleScript);
+ cmake cm(cmake::RoleScript, cmState::CTest);
cm.SetHomeDirectory("");
cm.SetHomeOutputDirectory("");
cm.GetCurrentSnapshot().SetDefaultDefinitions();
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index 30192c2..aa37ff9 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -280,7 +280,7 @@ void cmCTestScriptHandler::CreateCMake()
delete this->GlobalGenerator;
delete this->Makefile;
}
- this->CMake = new cmake(cmake::RoleScript);
+ this->CMake = new cmake(cmake::RoleScript, cmState::CTest);
this->CMake->SetHomeDirectory("");
this->CMake->SetHomeOutputDirectory("");
this->CMake->GetCurrentSnapshot().SetDefaultDefinitions();
diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx
index 76a1830..00c0610 100644
--- a/Source/CTest/cmCTestSubmitCommand.cxx
+++ b/Source/CTest/cmCTestSubmitCommand.cxx
@@ -15,36 +15,28 @@ class cmExecutionStatus;
cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
{
- const char* ctestDropMethod =
- this->Makefile->GetDefinition("CTEST_DROP_METHOD");
- const char* ctestDropSite = this->Makefile->GetDefinition("CTEST_DROP_SITE");
- const char* ctestDropLocation =
- this->Makefile->GetDefinition("CTEST_DROP_LOCATION");
- if (!ctestDropMethod) {
- ctestDropMethod = "http";
- }
+ const char* submitURL = !this->SubmitURL.empty()
+ ? this->SubmitURL.c_str()
+ : this->Makefile->GetDefinition("CTEST_SUBMIT_URL");
- if (!ctestDropSite) {
- // error: CDash requires CTEST_DROP_SITE definition
- // in CTestConfig.cmake
- }
- if (!ctestDropLocation) {
- // error: CDash requires CTEST_DROP_LOCATION definition
- // in CTestConfig.cmake
+ if (submitURL) {
+ this->CTest->SetCTestConfiguration("SubmitURL", submitURL, this->Quiet);
+ } else {
+ this->CTest->SetCTestConfigurationFromCMakeVariable(
+ this->Makefile, "DropMethod", "CTEST_DROP_METHOD", this->Quiet);
+ this->CTest->SetCTestConfigurationFromCMakeVariable(
+ this->Makefile, "DropSiteUser", "CTEST_DROP_SITE_USER", this->Quiet);
+ this->CTest->SetCTestConfigurationFromCMakeVariable(
+ this->Makefile, "DropSitePassword", "CTEST_DROP_SITE_PASSWORD",
+ this->Quiet);
+ this->CTest->SetCTestConfigurationFromCMakeVariable(
+ this->Makefile, "DropSite", "CTEST_DROP_SITE", this->Quiet);
+ this->CTest->SetCTestConfigurationFromCMakeVariable(
+ this->Makefile, "DropLocation", "CTEST_DROP_LOCATION", this->Quiet);
}
- this->CTest->SetCTestConfiguration("DropMethod", ctestDropMethod,
- this->Quiet);
- this->CTest->SetCTestConfiguration("DropSite", ctestDropSite, this->Quiet);
- this->CTest->SetCTestConfiguration("DropLocation", ctestDropLocation,
- this->Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(
this->Makefile, "CurlOptions", "CTEST_CURL_OPTIONS", this->Quiet);
- this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "DropSiteUser", "CTEST_DROP_SITE_USER", this->Quiet);
- this->CTest->SetCTestConfigurationFromCMakeVariable(
- this->Makefile, "DropSitePassword", "CTEST_DROP_SITE_PASSWORD",
- this->Quiet);
const char* notesFilesVariable =
this->Makefile->GetDefinition("CTEST_NOTES_FILES");
@@ -184,6 +176,11 @@ bool cmCTestSubmitCommand::CheckArgumentKeyword(std::string const& arg)
return true;
}
+ if (arg == "SUBMIT_URL") {
+ this->ArgumentDoing = ArgumentDoingSubmitURL;
+ return true;
+ }
+
if (arg == "INTERNAL_TEST_CHECKSUM") {
this->InternalTest = true;
return true;
@@ -249,6 +246,12 @@ bool cmCTestSubmitCommand::CheckArgumentValue(std::string const& arg)
return true;
}
+ if (this->ArgumentDoing == ArgumentDoingSubmitURL) {
+ this->ArgumentDoing = ArgumentDoingNone;
+ this->SubmitURL = arg;
+ return true;
+ }
+
// Look for other arguments.
return this->Superclass::CheckArgumentValue(arg);
}
diff --git a/Source/CTest/cmCTestSubmitCommand.h b/Source/CTest/cmCTestSubmitCommand.h
index c4b84ce..0caccd6 100644
--- a/Source/CTest/cmCTestSubmitCommand.h
+++ b/Source/CTest/cmCTestSubmitCommand.h
@@ -71,6 +71,7 @@ protected:
ArgumentDoingCDashUpload,
ArgumentDoingCDashUploadType,
ArgumentDoingHttpHeader,
+ ArgumentDoingSubmitURL,
ArgumentDoingLast2
};
@@ -85,6 +86,7 @@ protected:
std::string CDashUploadFile;
std::string CDashUploadType;
std::vector<std::string> HttpHeaders;
+ std::string SubmitURL;
};
#endif
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index 3042480..600194a 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -162,7 +162,6 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(
/* In windows, this will init the winsock stuff */
::curl_global_init(CURL_GLOBAL_ALL);
- std::string dropMethod(this->CTest->GetCTestConfiguration("DropMethod"));
std::string curlopt(this->CTest->GetCTestConfiguration("CurlOptions"));
std::vector<std::string> args;
cmSystemTools::ExpandListArgument(curlopt, args);
@@ -495,27 +494,6 @@ void cmCTestSubmitHandler::ParseResponse(
}
}
-void cmCTestSubmitHandler::ConstructCDashURL(std::string& dropMethod,
- std::string& url)
-{
- dropMethod = this->CTest->GetCTestConfiguration("DropMethod");
- url = dropMethod;
- url += "://";
- if (!this->CTest->GetCTestConfiguration("DropSiteUser").empty()) {
- url += this->CTest->GetCTestConfiguration("DropSiteUser");
- cmCTestOptionalLog(
- this->CTest, HANDLER_OUTPUT,
- this->CTest->GetCTestConfiguration("DropSiteUser").c_str(), this->Quiet);
- if (!this->CTest->GetCTestConfiguration("DropSitePassword").empty()) {
- url += ":" + this->CTest->GetCTestConfiguration("DropSitePassword");
- cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, ":******", this->Quiet);
- }
- url += "@";
- }
- url += this->CTest->GetCTestConfiguration("DropSite") +
- this->CTest->GetCTestConfiguration("DropLocation");
-}
-
int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
std::string const& typeString)
{
@@ -536,16 +514,15 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
curl.SetCurlOptions(args);
curl.SetTimeOutSeconds(SUBMIT_TIMEOUT_IN_SECONDS_DEFAULT);
curl.SetHttpHeaders(this->HttpHeaders);
- std::string dropMethod;
- std::string url;
- this->ConstructCDashURL(dropMethod, url);
+ std::string url = this->CTest->GetSubmitURL();
std::string fields;
std::string::size_type pos = url.find('?');
if (pos != std::string::npos) {
fields = url.substr(pos + 1);
url = url.substr(0, pos);
}
- if (!(dropMethod == "http" || dropMethod == "https")) {
+ if (!cmHasLiteralPrefix(url, "http://") &&
+ !cmHasLiteralPrefix(url, "https://")) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Only http and https are supported for CDASH_UPLOAD\n");
return -1;
@@ -872,10 +849,7 @@ int cmCTestSubmitHandler::ProcessHandler()
cnt++;
}
}
- cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
- "Submit files (using "
- << this->CTest->GetCTestConfiguration("DropMethod")
- << ")" << std::endl,
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "Submit files\n",
this->Quiet);
const char* specificTrack = this->CTest->GetSpecificTrack();
if (specificTrack) {
@@ -885,72 +859,32 @@ int cmCTestSubmitHandler::ProcessHandler()
}
this->SetLogFile(&ofs);
- std::string dropMethod(this->CTest->GetCTestConfiguration("DropMethod"));
-
- if (dropMethod.empty()) {
- dropMethod = "http";
+ std::string url = this->CTest->GetSubmitURL();
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ " SubmitURL: " << url << '\n', this->Quiet);
+ if (!this->SubmitUsingHTTP(buildDirectory + "/Testing/" +
+ this->CTest->GetCurrentTag(),
+ files, prefix, url)) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ " Problems when submitting via HTTP\n");
+ ofs << " Problems when submitting via HTTP\n";
+ return -1;
}
-
- if (dropMethod == "http" || dropMethod == "https") {
- std::string url = dropMethod;
- url += "://";
- ofs << "Using drop method: " << dropMethod << std::endl;
- cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
- " Using HTTP submit method" << std::endl
- << " Drop site:" << url,
- this->Quiet);
- if (!this->CTest->GetCTestConfiguration("DropSiteUser").empty()) {
- url += this->CTest->GetCTestConfiguration("DropSiteUser");
- cmCTestOptionalLog(
- this->CTest, HANDLER_OUTPUT,
- this->CTest->GetCTestConfiguration("DropSiteUser").c_str(),
- this->Quiet);
- if (!this->CTest->GetCTestConfiguration("DropSitePassword").empty()) {
- url += ":" + this->CTest->GetCTestConfiguration("DropSitePassword");
- cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, ":******",
- this->Quiet);
- }
- url += "@";
- cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "@", this->Quiet);
- }
- url += this->CTest->GetCTestConfiguration("DropSite") +
- this->CTest->GetCTestConfiguration("DropLocation");
+ if (this->HasErrors) {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ " Errors occurred during submission.\n");
+ ofs << " Errors occurred during submission.\n";
+ } else {
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
- this->CTest->GetCTestConfiguration("DropSite")
- << this->CTest->GetCTestConfiguration("DropLocation")
+ " Submission successful"
+ << (this->HasWarnings ? ", with warnings." : "")
<< std::endl,
this->Quiet);
- if (!this->SubmitUsingHTTP(buildDirectory + "/Testing/" +
- this->CTest->GetCurrentTag(),
- files, prefix, url)) {
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- " Problems when submitting via HTTP" << std::endl);
- ofs << " Problems when submitting via HTTP" << std::endl;
- return -1;
- }
- if (this->HasErrors) {
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
- " Errors occurred during "
- "submission."
- << std::endl);
- ofs << " Errors occurred during submission. " << std::endl;
- } else {
- cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
- " Submission successful"
- << (this->HasWarnings ? ", with warnings." : "")
- << std::endl,
- this->Quiet);
- ofs << " Submission successful"
- << (this->HasWarnings ? ", with warnings." : "") << std::endl;
- }
-
- return 0;
+ ofs << " Submission successful"
+ << (this->HasWarnings ? ", with warnings." : "") << std::endl;
}
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- " Unknown submission method: \"" << dropMethod << "\""
- << std::endl);
- return -1;
+ return 0;
}
std::string cmCTestSubmitHandler::GetSubmitResultsPrefix()
diff --git a/Source/CTest/cmCTestSubmitHandler.h b/Source/CTest/cmCTestSubmitHandler.h
index 393e826..58f4f97 100644
--- a/Source/CTest/cmCTestSubmitHandler.h
+++ b/Source/CTest/cmCTestSubmitHandler.h
@@ -48,8 +48,6 @@ public:
this->HttpHeaders = v;
}
- void ConstructCDashURL(std::string& dropMethod, std::string& url);
-
private:
void SetLogFile(std::ostream* ost) { this->LogFile = ost; }
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 9fd2299..acbe465 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -1676,7 +1676,7 @@ void cmCTestTestHandler::GetListOfTests()
}
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Constructing a list of tests" << std::endl, this->Quiet);
- cmake cm(cmake::RoleScript);
+ cmake cm(cmake::RoleScript, cmState::CTest);
cm.SetHomeDirectory("");
cm.SetHomeOutputDirectory("");
cm.GetCurrentSnapshot().SetDefaultDefinitions();
diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx
index a3e0717..6dc692e 100644
--- a/Source/CursesDialog/ccmake.cxx
+++ b/Source/CursesDialog/ccmake.cxx
@@ -6,6 +6,7 @@
#include "cmCursesStandardIncludes.h"
#include "cmDocumentation.h"
#include "cmDocumentationEntry.h"
+#include "cmState.h"
#include "cmSystemTools.h"
#include "cmake.h"
@@ -83,7 +84,7 @@ int main(int argc, char const* const* argv)
cmDocumentation doc;
doc.addCMakeStandardDocSections();
if (doc.CheckOptions(argc, argv)) {
- cmake hcm(cmake::RoleInternal);
+ cmake hcm(cmake::RoleInternal, cmState::Unknown);
hcm.SetHomeDirectory("");
hcm.SetHomeOutputDirectory("");
hcm.AddCMakePaths();
diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx
index 931797a..a75d913 100644
--- a/Source/CursesDialog/cmCursesMainForm.cxx
+++ b/Source/CursesDialog/cmCursesMainForm.cxx
@@ -41,7 +41,7 @@ cmCursesMainForm::cmCursesMainForm(std::vector<std::string> const& args,
"Welcome to ccmake, curses based user interface for CMake.");
this->HelpMessage.push_back("");
this->HelpMessage.push_back(s_ConstHelpMessage);
- this->CMakeInstance = new cmake(cmake::RoleProject);
+ this->CMakeInstance = new cmake(cmake::RoleProject, cmState::Project);
this->CMakeInstance->SetCMakeEditCommand(
cmSystemTools::GetCMakeCursesCommand());
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx
index 98cf8b0..b4307bb 100644
--- a/Source/QtDialog/CMakeSetup.cxx
+++ b/Source/QtDialog/CMakeSetup.cxx
@@ -64,7 +64,7 @@ int main(int argc, char** argv)
doc.addCMakeStandardDocSections();
if (argc2 > 1 && doc.CheckOptions(argc2, argv2)) {
// Construct and print requested documentation.
- cmake hcm(cmake::RoleInternal);
+ cmake hcm(cmake::RoleInternal, cmState::Unknown);
hcm.SetHomeDirectory("");
hcm.SetHomeOutputDirectory("");
hcm.AddCMakePaths();
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx
index 0133b88..9a6784e 100644
--- a/Source/QtDialog/QCMake.cxx
+++ b/Source/QtDialog/QCMake.cxx
@@ -27,7 +27,7 @@ QCMake::QCMake(QObject* p)
cmSystemTools::SetStdoutCallback(QCMake::stdoutCallback, this);
cmSystemTools::SetStderrCallback(QCMake::stderrCallback, this);
- this->CMakeInstance = new cmake(cmake::RoleProject);
+ this->CMakeInstance = new cmake(cmake::RoleProject, cmState::Project);
this->CMakeInstance->SetCMakeEditCommand(
cmSystemTools::GetCMakeGUICommand());
this->CMakeInstance->SetProgressCallback(QCMake::progressCallback, this);
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index ccd74c0..4959288 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -429,7 +429,7 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
}
}
- cmake cm(cmake::RoleScript);
+ cmake cm(cmake::RoleScript, cmState::CTest);
cm.SetHomeDirectory("");
cm.SetHomeOutputDirectory("");
cm.GetCurrentSnapshot().SetDefaultDefinitions();
@@ -2629,6 +2629,32 @@ void cmCTest::SetCTestConfiguration(const char* name, const char* value,
this->CTestConfiguration[name] = value;
}
+std::string cmCTest::GetSubmitURL()
+{
+ std::string url = this->GetCTestConfiguration("SubmitURL");
+ if (url.empty()) {
+ std::string method = this->GetCTestConfiguration("DropMethod");
+ std::string user = this->GetCTestConfiguration("DropSiteUser");
+ std::string password = this->GetCTestConfiguration("DropSitePassword");
+ std::string site = this->GetCTestConfiguration("DropSite");
+ std::string location = this->GetCTestConfiguration("DropLocation");
+
+ url = method.empty() ? "http" : method;
+ url += "://";
+ if (!user.empty()) {
+ url += user;
+ if (!password.empty()) {
+ url += ':';
+ url += password;
+ }
+ url += '@';
+ }
+ url += site;
+ url += location;
+ }
+ return url;
+}
+
std::string cmCTest::GetCurrentTag()
{
return this->CurrentTag;
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index 2b40ca3..a82f400 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -176,6 +176,8 @@ public:
bool suppress = false);
void EmptyCTestConfiguration();
+ std::string GetSubmitURL();
+
/**
* constructor and destructor
*/
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index a483fd1..137b25f 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -57,6 +57,12 @@ static std::string const kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES =
"CMAKE_TRY_COMPILE_PLATFORM_VARIABLES";
static std::string const kCMAKE_WARN_DEPRECATED = "CMAKE_WARN_DEPRECATED";
+/* GHS Multi platform variables */
+static std::set<std::string> ghs_platform_vars{
+ "GHS_TARGET_PLATFORM", "GHS_PRIMARY_TARGET", "GHS_TOOLSET_ROOT",
+ "GHS_OS_ROOT", "GHS_OS_DIR", "GHS_BSP_NAME"
+};
+
static void writeProperty(FILE* fout, std::string const& targetName,
std::string const& prop, std::string const& value)
{
@@ -869,6 +875,16 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
projectName = "CMAKE_TRY_COMPILE";
}
+ if (this->Makefile->GetState()->UseGhsMultiIDE()) {
+ // Forward the GHS variables to the inner project cache.
+ for (std::string const& var : ghs_platform_vars) {
+ if (const char* val = this->Makefile->GetDefinition(var)) {
+ std::string flag = "-D" + var + "=" + val;
+ cmakeFlags.push_back(std::move(flag));
+ }
+ }
+ }
+
bool erroroc = cmSystemTools::GetErrorOccuredFlag();
cmSystemTools::ResetErrorOccuredFlag();
std::string output;
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index db2fde8..999af54 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -185,6 +185,9 @@ bool cmFileCommand::InitialPass(std::vector<std::string> const& args,
if (subCommand == "READ_SYMLINK") {
return this->HandleReadSymlinkCommand(args);
}
+ if (subCommand == "CREATE_LINK") {
+ return this->HandleCreateLinkCommand(args);
+ }
std::string e = "does not recognize sub-command " + subCommand;
this->SetError(e);
@@ -3670,3 +3673,119 @@ bool cmFileCommand::HandleReadSymlinkCommand(
return true;
}
+
+bool cmFileCommand::HandleCreateLinkCommand(
+ std::vector<std::string> const& args)
+{
+ if (args.size() < 3) {
+ this->SetError("CREATE_LINK must be called with at least two additional "
+ "arguments");
+ return false;
+ }
+
+ cmCommandArgumentsHelper argHelper;
+ cmCommandArgumentGroup group;
+
+ cmCAString linkArg(&argHelper, "CREATE_LINK");
+ cmCAString fileArg(&argHelper, nullptr);
+ cmCAString newFileArg(&argHelper, nullptr);
+
+ cmCAString resultArg(&argHelper, "RESULT", &group);
+ cmCAEnabler copyOnErrorArg(&argHelper, "COPY_ON_ERROR", &group);
+ cmCAEnabler symbolicArg(&argHelper, "SYMBOLIC", &group);
+
+ linkArg.Follows(nullptr);
+ fileArg.Follows(&linkArg);
+ newFileArg.Follows(&fileArg);
+ group.Follows(&newFileArg);
+
+ std::vector<std::string> unconsumedArgs;
+ argHelper.Parse(&args, &unconsumedArgs);
+
+ if (!unconsumedArgs.empty()) {
+ this->SetError("unknown argument: \"" + unconsumedArgs.front() + '\"');
+ return false;
+ }
+
+ std::string fileName = fileArg.GetString();
+ std::string newFileName = newFileArg.GetString();
+
+ // Output variable for storing the result.
+ const std::string& resultVar = resultArg.GetString();
+
+ // The system error message generated in the operation.
+ std::string result;
+
+ // Check if the paths are distinct.
+ if (fileName == newFileName) {
+ result = "CREATE_LINK cannot use same file and newfile";
+ if (!resultVar.empty()) {
+ this->Makefile->AddDefinition(resultVar, result.c_str());
+ return true;
+ }
+ this->SetError(result);
+ return false;
+ }
+
+ // Hard link requires original file to exist.
+ if (!symbolicArg.IsEnabled() && !cmSystemTools::FileExists(fileName)) {
+ result = "Cannot hard link \'" + fileName + "\' as it does not exist.";
+ if (!resultVar.empty()) {
+ this->Makefile->AddDefinition(resultVar, result.c_str());
+ return true;
+ }
+ this->SetError(result);
+ return false;
+ }
+
+ // Check if the new file already exists and remove it.
+ if ((cmSystemTools::FileExists(newFileName) ||
+ cmSystemTools::FileIsSymlink(newFileName)) &&
+ !cmSystemTools::RemoveFile(newFileName)) {
+ std::ostringstream e;
+ e << "Failed to create link '" << newFileName
+ << "' because existing path cannot be removed: "
+ << cmSystemTools::GetLastSystemError() << "\n";
+
+ if (!resultVar.empty()) {
+ this->Makefile->AddDefinition(resultVar, e.str().c_str());
+ return true;
+ }
+ this->SetError(e.str());
+ return false;
+ }
+
+ // Whether the operation completed successfully.
+ bool completed = false;
+
+ // Check if the command requires a symbolic link.
+ if (symbolicArg.IsEnabled()) {
+ completed = cmSystemTools::CreateSymlink(fileName, newFileName, &result);
+ } else {
+ completed = cmSystemTools::CreateLink(fileName, newFileName, &result);
+ }
+
+ // Check if copy-on-error is enabled in the arguments.
+ if (!completed && copyOnErrorArg.IsEnabled()) {
+ completed =
+ cmSystemTools::cmCopyFile(fileName.c_str(), newFileName.c_str());
+ if (!completed) {
+ result = "Copy failed: " + cmSystemTools::GetLastSystemError();
+ }
+ }
+
+ // Check if the operation was successful.
+ if (completed) {
+ result = "0";
+ } else if (resultVar.empty()) {
+ // The operation failed and the result is not reported in a variable.
+ this->SetError(result);
+ return false;
+ }
+
+ if (!resultVar.empty()) {
+ this->Makefile->AddDefinition(resultVar, result.c_str());
+ }
+
+ return true;
+}
diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h
index fe05c98..12c5115 100644
--- a/Source/cmFileCommand.h
+++ b/Source/cmFileCommand.h
@@ -61,6 +61,7 @@ protected:
bool HandleLockCommand(std::vector<std::string> const& args);
bool HandleSizeCommand(std::vector<std::string> const& args);
bool HandleReadSymlinkCommand(std::vector<std::string> const& args);
+ bool HandleCreateLinkCommand(std::vector<std::string> const& args);
private:
void AddEvaluationFile(const std::string& inputName,
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 8dc7ca2..2567b7a 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -95,6 +95,7 @@ cmFindPackageCommand::cmFindPackageCommand()
this->UseLib32Paths = false;
this->UseLib64Paths = false;
this->UseLibx32Paths = false;
+ this->UseRealPath = false;
this->PolicyScope = true;
this->VersionMajor = 0;
this->VersionMinor = 0;
@@ -195,6 +196,11 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args,
this->NoSystemRegistry = true;
}
+ // Check whether we should resolve symlinks when finding packages
+ if (this->Makefile->IsOn("CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS")) {
+ this->UseRealPath = true;
+ }
+
// Check if Sorting should be enabled
if (const char* so =
this->Makefile->GetDefinition("CMAKE_FIND_PACKAGE_SORT_ORDER")) {
@@ -1502,6 +1508,10 @@ bool cmFindPackageCommand::FindConfigFile(std::string const& dir,
fprintf(stderr, "Checking file [%s]\n", file.c_str());
}
if (cmSystemTools::FileExists(file, true) && this->CheckVersion(file)) {
+ // Allow resolving symlinks when the config file is found through a link
+ if (this->UseRealPath) {
+ file = cmSystemTools::GetRealPath(file);
+ }
return true;
}
}
diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h
index 05bad49..83d8431 100644
--- a/Source/cmFindPackageCommand.h
+++ b/Source/cmFindPackageCommand.h
@@ -178,6 +178,7 @@ private:
bool UseLib32Paths;
bool UseLib64Paths;
bool UseLibx32Paths;
+ bool UseRealPath;
bool PolicyScope;
std::string LibraryArchitecture;
std::vector<std::string> Names;
diff --git a/Source/cmGhsMultiGpj.cxx b/Source/cmGhsMultiGpj.cxx
index f58cfc1..c1f0742 100644
--- a/Source/cmGhsMultiGpj.cxx
+++ b/Source/cmGhsMultiGpj.cxx
@@ -4,31 +4,34 @@
#include "cmGeneratedFileStream.h"
-void GhsMultiGpj::WriteGpjTag(Types const gpjType,
- cmGeneratedFileStream* const filestream)
+static const char* GHS_TAG[] = { "[INTEGRITY Application]",
+ "[Library]",
+ "[Project]",
+ "[Program]",
+ "[Reference]",
+ "[Subproject]" };
+
+const char* GhsMultiGpj::GetGpjTag(Types const gpjType)
{
char const* tag;
switch (gpjType) {
case INTERGRITY_APPLICATION:
- tag = "INTEGRITY Application";
- break;
case LIBRARY:
- tag = "Library";
- break;
case PROJECT:
- tag = "Project";
- break;
case PROGRAM:
- tag = "Program";
- break;
case REFERENCE:
- tag = "Reference";
- break;
case SUBPROJECT:
- tag = "Subproject";
+ tag = GHS_TAG[gpjType];
break;
default:
tag = "";
}
- *filestream << "[" << tag << "]" << std::endl;
+ return tag;
+}
+
+void GhsMultiGpj::WriteGpjTag(Types const gpjType, std::ostream& fout)
+{
+ char const* tag;
+ tag = GhsMultiGpj::GetGpjTag(gpjType);
+ fout << tag << std::endl;
}
diff --git a/Source/cmGhsMultiGpj.h b/Source/cmGhsMultiGpj.h
index b1eead1..6d59225 100644
--- a/Source/cmGhsMultiGpj.h
+++ b/Source/cmGhsMultiGpj.h
@@ -4,6 +4,7 @@
#define cmGhsMultiGpj_h
#include "cmConfigure.h" // IWYU pragma: keep
+#include <iosfwd>
class cmGeneratedFileStream;
@@ -20,8 +21,9 @@ public:
SUBPROJECT
};
- static void WriteGpjTag(Types const gpjType,
- cmGeneratedFileStream* filestream);
+ static void WriteGpjTag(Types const gpjType, std::ostream& fout);
+
+ static const char* GetGpjTag(Types const gpjType);
};
#endif // ! cmGhsMultiGpjType_h
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index 1a25633..19605e4 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGhsMultiTargetGenerator.h"
+#include "cmComputeLinkInformation.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGhsMultiGenerator.h"
@@ -9,177 +10,128 @@
#include "cmLocalGhsMultiGenerator.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
+#include "cmSourceGroup.h"
#include "cmTarget.h"
-#include <assert.h>
-
-std::string const cmGhsMultiTargetGenerator::DDOption("-dynamic");
cmGhsMultiTargetGenerator::cmGhsMultiTargetGenerator(cmGeneratorTarget* target)
: GeneratorTarget(target)
, LocalGenerator(
static_cast<cmLocalGhsMultiGenerator*>(target->GetLocalGenerator()))
, Makefile(target->Target->GetMakefile())
- , TargetGroup(DetermineIfTargetGroup(target))
- , DynamicDownload(false)
-{
- this->RelBuildFilePath = this->GetRelBuildFilePath(target);
-
- this->RelOutputFileName = this->RelBuildFilePath + target->GetName() + ".a";
-
- this->RelBuildFileName = this->RelBuildFilePath;
- this->RelBuildFileName += this->GetBuildFileName(target);
-
- std::string absPathToRoot = this->GetAbsPathToRoot(target);
- absPathToRoot = this->AddSlashIfNeededToPath(absPathToRoot);
- this->AbsBuildFilePath = absPathToRoot + this->RelBuildFilePath;
- this->AbsBuildFileName = absPathToRoot + this->RelBuildFileName;
- this->AbsOutputFileName = absPathToRoot + this->RelOutputFileName;
-}
-
-cmGhsMultiTargetGenerator::~cmGhsMultiTargetGenerator()
+ , Name(target->GetName())
{
- cmDeleteAll(this->FolderBuildStreams);
-}
-
-std::string cmGhsMultiTargetGenerator::GetRelBuildFilePath(
- const cmGeneratorTarget* target)
-{
- std::string output = target->GetEffectiveFolderName();
- cmSystemTools::ConvertToUnixSlashes(output);
- if (!output.empty()) {
- output += "/";
+ // Store the configuration name that is being used
+ if (const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE")) {
+ // Use the build type given by the user.
+ this->ConfigName = config;
+ } else {
+ // No configuration type given.
+ this->ConfigName.clear();
}
- output += target->GetName() + "/";
- return output;
-}
-
-std::string cmGhsMultiTargetGenerator::GetAbsPathToRoot(
- const cmGeneratorTarget* target)
-{
- return target->GetLocalGenerator()->GetBinaryDirectory();
}
-std::string cmGhsMultiTargetGenerator::GetAbsBuildFilePath(
- const cmGeneratorTarget* target)
-{
- std::string output;
- output = cmGhsMultiTargetGenerator::GetAbsPathToRoot(target);
- output = cmGhsMultiTargetGenerator::AddSlashIfNeededToPath(output);
- output += cmGhsMultiTargetGenerator::GetRelBuildFilePath(target);
- return output;
-}
-
-std::string cmGhsMultiTargetGenerator::GetRelBuildFileName(
- const cmGeneratorTarget* target)
-{
- std::string output;
- output = cmGhsMultiTargetGenerator::GetRelBuildFilePath(target);
- output = cmGhsMultiTargetGenerator::AddSlashIfNeededToPath(output);
- output += cmGhsMultiTargetGenerator::GetBuildFileName(target);
- return output;
-}
-
-std::string cmGhsMultiTargetGenerator::GetBuildFileName(
- const cmGeneratorTarget* target)
-{
- std::string output;
- output = target->GetName();
- output += cmGlobalGhsMultiGenerator::FILE_EXTENSION;
- return output;
-}
-
-std::string cmGhsMultiTargetGenerator::AddSlashIfNeededToPath(
- std::string const& input)
+cmGhsMultiTargetGenerator::~cmGhsMultiTargetGenerator()
{
- std::string output(input);
- if (!cmHasLiteralSuffix(output, "/")) {
- output += "/";
- }
- return output;
}
void cmGhsMultiTargetGenerator::Generate()
{
- std::vector<cmSourceFile*> objectSources = this->GetSources();
- if (!objectSources.empty() && this->IncludeThisTarget()) {
- if (!cmSystemTools::FileExists(this->AbsBuildFilePath.c_str())) {
- cmSystemTools::MakeDirectory(this->AbsBuildFilePath.c_str());
+ // Determine type of target for this project
+ switch (this->GeneratorTarget->GetType()) {
+ case cmStateEnums::EXECUTABLE: {
+ // Get the name of the executable to generate.
+ std::string targetName;
+ std::string targetNameImport;
+ std::string targetNamePDB;
+ this->GeneratorTarget->GetExecutableNames(
+ targetName, this->TargetNameReal, targetNameImport, targetNamePDB,
+ this->ConfigName);
+ if (cmGhsMultiTargetGenerator::DetermineIfIntegrityApp()) {
+ this->TagType = GhsMultiGpj::INTERGRITY_APPLICATION;
+ } else {
+ this->TagType = GhsMultiGpj::PROGRAM;
+ }
+ break;
+ }
+ case cmStateEnums::STATIC_LIBRARY: {
+ std::string targetName;
+ std::string targetNameSO;
+ std::string targetNameImport;
+ std::string targetNamePDB;
+ this->GeneratorTarget->GetLibraryNames(
+ targetName, targetNameSO, this->TargetNameReal, targetNameImport,
+ targetNamePDB, this->ConfigName);
+ this->TagType = GhsMultiGpj::LIBRARY;
+ break;
+ }
+ case cmStateEnums::SHARED_LIBRARY: {
+ std::string msg = "add_library(<name> SHARED ...) not supported: ";
+ msg += this->Name;
+ cmSystemTools::Message(msg.c_str());
+ return;
}
- cmGlobalGhsMultiGenerator::Open(std::string(""), this->AbsBuildFileName,
- &this->FolderBuildStreams);
- cmGlobalGhsMultiGenerator::OpenBuildFileStream(
- this->GetFolderBuildStreams());
- std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
- if (0 == config.length()) {
- config = "RELEASE";
+ case cmStateEnums::OBJECT_LIBRARY: {
+ std::string targetName;
+ std::string targetNameSO;
+ std::string targetNameImport;
+ std::string targetNamePDB;
+ this->GeneratorTarget->GetLibraryNames(
+ targetName, targetNameSO, this->TargetNameReal, targetNameImport,
+ targetNamePDB, this->ConfigName);
+ this->TagType = GhsMultiGpj::SUBPROJECT;
+ break;
}
- const std::string language(
- this->GeneratorTarget->GetLinkerLanguage(config));
- config = cmSystemTools::UpperCase(config);
- this->DynamicDownload = this->DetermineIfDynamicDownload(config, language);
- if (this->DynamicDownload) {
- *this->GetFolderBuildStreams()
- << "#component integrity_dynamic_download" << std::endl;
+ case cmStateEnums::MODULE_LIBRARY: {
+ std::string msg = "add_library(<name> MODULE ...) not supported: ";
+ msg += this->Name;
+ cmSystemTools::Message(msg.c_str());
+ return;
}
- GhsMultiGpj::WriteGpjTag(this->GetGpjTag(), this->GetFolderBuildStreams());
- cmGlobalGhsMultiGenerator::WriteDisclaimer(this->GetFolderBuildStreams());
-
- bool const notKernel = this->IsNotKernel(config, language);
- this->WriteTypeSpecifics(config, notKernel);
- this->SetCompilerFlags(config, language, notKernel);
- this->WriteCompilerFlags(config, language);
- this->WriteCompilerDefinitions(config, language);
- this->WriteIncludes(config, language);
- if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) {
- this->WriteTargetLinkLibraries(config, language);
+ case cmStateEnums::UTILITY: {
+ std::string msg = "add_custom_target(<name> ...) not supported: ";
+ msg += this->Name;
+ cmSystemTools::Message(msg.c_str());
+ return;
}
- this->WriteCustomCommands();
+ default:
+ return;
+ }
- std::map<const cmSourceFile*, std::string> objectNames =
- cmGhsMultiTargetGenerator::GetObjectNames(
- &objectSources, this->LocalGenerator, this->GeneratorTarget);
+ // Tell the global generator the name of the project file
+ this->GeneratorTarget->Target->SetProperty("GENERATOR_FILE_NAME",
+ this->Name.c_str());
+ this->GeneratorTarget->Target->SetProperty(
+ "GENERATOR_FILE_NAME_EXT", GhsMultiGpj::GetGpjTag(this->TagType));
- this->WriteSources(objectSources, objectNames);
- }
+ this->GenerateTarget();
}
-bool cmGhsMultiTargetGenerator::IncludeThisTarget()
+void cmGhsMultiTargetGenerator::GenerateTarget()
{
- bool output = true;
- char const* excludeFromAll =
- this->GeneratorTarget->GetProperty("EXCLUDE_FROM_ALL");
- if (NULL != excludeFromAll && '1' == excludeFromAll[0] &&
- '\0' == excludeFromAll[1]) {
- output = false;
- }
- return output;
-}
+ // Open the filestream in copy-if-different mode.
+ std::string fname = this->LocalGenerator->GetCurrentBinaryDirectory();
+ fname += "/";
+ fname += this->Name;
+ fname += cmGlobalGhsMultiGenerator::FILE_EXTENSION;
+ cmGeneratedFileStream fout(fname.c_str());
+ fout.SetCopyIfDifferent(true);
-std::vector<cmSourceFile*> cmGhsMultiTargetGenerator::GetSources() const
-{
- std::vector<cmSourceFile*> output;
- std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
- this->GeneratorTarget->GetSourceFiles(output, config);
- return output;
-}
+ this->GetGlobalGenerator()->WriteFileHeader(fout);
+ GhsMultiGpj::WriteGpjTag(this->TagType, fout);
-GhsMultiGpj::Types cmGhsMultiTargetGenerator::GetGpjTag() const
-{
- return cmGhsMultiTargetGenerator::GetGpjTag(this->GeneratorTarget);
-}
+ const std::string language(
+ this->GeneratorTarget->GetLinkerLanguage(this->ConfigName));
-GhsMultiGpj::Types cmGhsMultiTargetGenerator::GetGpjTag(
- const cmGeneratorTarget* target)
-{
- GhsMultiGpj::Types output;
- if (cmGhsMultiTargetGenerator::DetermineIfTargetGroup(target)) {
- output = GhsMultiGpj::INTERGRITY_APPLICATION;
- } else if (target->GetType() == cmStateEnums::STATIC_LIBRARY) {
- output = GhsMultiGpj::LIBRARY;
- } else {
- output = GhsMultiGpj::PROGRAM;
- }
- return output;
+ this->WriteTargetSpecifics(fout, this->ConfigName);
+ this->SetCompilerFlags(this->ConfigName, language);
+ this->WriteCompilerFlags(fout, this->ConfigName, language);
+ this->WriteCompilerDefinitions(fout, this->ConfigName, language);
+ this->WriteIncludes(fout, this->ConfigName, language);
+ this->WriteTargetLinkLine(fout, this->ConfigName);
+ this->WriteCustomCommands(fout);
+ this->WriteSources(fout);
+ this->WriteReferences(fout);
+ fout.Close();
}
cmGlobalGhsMultiGenerator* cmGhsMultiTargetGenerator::GetGlobalGenerator()
@@ -189,41 +141,27 @@ cmGlobalGhsMultiGenerator* cmGhsMultiTargetGenerator::GetGlobalGenerator()
this->LocalGenerator->GetGlobalGenerator());
}
-void cmGhsMultiTargetGenerator::WriteTypeSpecifics(const std::string& config,
- bool const notKernel)
+void cmGhsMultiTargetGenerator::WriteTargetSpecifics(std::ostream& fout,
+ const std::string& config)
{
- std::string outputDir(this->GetOutputDirectory(config));
- std::string outputFilename(this->GetOutputFilename(config));
-
- if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY) {
- std::string const& static_library_suffix =
- this->Makefile->GetSafeDefinition("CMAKE_STATIC_LIBRARY_SUFFIX");
- *this->GetFolderBuildStreams()
- << " -o \"" << outputDir << outputFilename << static_library_suffix
- << "\"" << std::endl;
- } else if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) {
- if (notKernel && !this->IsTargetGroup()) {
- *this->GetFolderBuildStreams() << " -relprog" << std::endl;
- }
- if (this->IsTargetGroup()) {
- *this->GetFolderBuildStreams()
- << " -o \"" << outputDir << outputFilename << ".elf\"" << std::endl;
- *this->GetFolderBuildStreams()
- << " :extraOutputFile=\"" << outputDir << outputFilename
- << ".elf.ael\"" << std::endl;
- } else {
- std::string const executable_suffix =
- this->Makefile->GetSafeDefinition("CMAKE_EXECUTABLE_SUFFIX");
- *this->GetFolderBuildStreams()
- << " -o \"" << outputDir << outputFilename << executable_suffix
- << "\"" << std::endl;
- }
+ std::string outpath;
+ std::string rootpath = this->LocalGenerator->GetCurrentBinaryDirectory();
+
+ if (this->TagType != GhsMultiGpj::SUBPROJECT) {
+ // set target binary file destination
+ outpath = this->GeneratorTarget->GetDirectory(config);
+ outpath = this->LocalGenerator->ConvertToRelativePath(rootpath, outpath);
+ fout << " :binDirRelative=\"" << outpath << "\"" << std::endl;
+ fout << " -o \"" << this->TargetNameReal << "\"" << std::endl;
}
+
+ // set target object file destination
+ outpath = this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
+ fout << " :outputDirRelative=\"" << outpath << "\"" << std::endl;
}
void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const& config,
- const std::string& language,
- bool const notKernel)
+ const std::string& language)
{
std::map<std::string, std::string>::iterator i =
this->FlagsByLanguage.find(language);
@@ -231,14 +169,9 @@ void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const& config,
std::string flags;
const char* lang = language.c_str();
- if (notKernel) {
- this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget,
- lang, config);
- } else {
- this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget,
- lang + std::string("_GHS_KERNEL"),
- config);
- }
+ this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget, lang,
+ config);
+
this->LocalGenerator->AddCMP0018Flags(flags, this->GeneratorTarget, lang,
config);
this->LocalGenerator->AddVisibilityPresetFlags(
@@ -281,21 +214,25 @@ std::string cmGhsMultiTargetGenerator::GetDefines(const std::string& language,
return i->second;
}
-void cmGhsMultiTargetGenerator::WriteCompilerFlags(std::string const&,
+void cmGhsMultiTargetGenerator::WriteCompilerFlags(std::ostream& fout,
+ std::string const&,
const std::string& language)
{
std::map<std::string, std::string>::iterator flagsByLangI =
this->FlagsByLanguage.find(language);
if (flagsByLangI != this->FlagsByLanguage.end()) {
if (!flagsByLangI->second.empty()) {
- *this->GetFolderBuildStreams()
- << " " << flagsByLangI->second << std::endl;
+ std::vector<std::string> ghsCompFlags =
+ cmSystemTools::ParseArguments(flagsByLangI->second.c_str());
+ for (auto& f : ghsCompFlags) {
+ fout << " " << f << std::endl;
+ }
}
}
}
void cmGhsMultiTargetGenerator::WriteCompilerDefinitions(
- const std::string& config, const std::string& language)
+ std::ostream& fout, const std::string& config, const std::string& language)
{
std::vector<std::string> compileDefinitions;
this->GeneratorTarget->GetCompileDefinitions(compileDefinitions, config,
@@ -303,11 +240,12 @@ void cmGhsMultiTargetGenerator::WriteCompilerDefinitions(
for (std::vector<std::string>::const_iterator cdI =
compileDefinitions.begin();
cdI != compileDefinitions.end(); ++cdI) {
- *this->GetFolderBuildStreams() << " -D" << (*cdI) << std::endl;
+ fout << " -D" << (*cdI) << std::endl;
}
}
-void cmGhsMultiTargetGenerator::WriteIncludes(const std::string& config,
+void cmGhsMultiTargetGenerator::WriteIncludes(std::ostream& fout,
+ const std::string& config,
const std::string& language)
{
std::vector<std::string> includes;
@@ -316,80 +254,73 @@ void cmGhsMultiTargetGenerator::WriteIncludes(const std::string& config,
for (std::vector<std::string>::const_iterator includes_i = includes.begin();
includes_i != includes.end(); ++includes_i) {
- *this->GetFolderBuildStreams()
- << " -I\"" << *includes_i << "\"" << std::endl;
+ fout << " -I\"" << *includes_i << "\"" << std::endl;
}
}
-void cmGhsMultiTargetGenerator::WriteTargetLinkLibraries(
- std::string const& config, std::string const& language)
+void cmGhsMultiTargetGenerator::WriteTargetLinkLine(std::ostream& fout,
+ std::string const& config)
{
- // library directories
- cmTargetDependSet tds =
- this->GetGlobalGenerator()->GetTargetDirectDepends(this->GeneratorTarget);
- for (cmTargetDependSet::iterator tdsI = tds.begin(); tdsI != tds.end();
- ++tdsI) {
- const cmGeneratorTarget* tg = *tdsI;
- *this->GetFolderBuildStreams()
- << " -L\"" << GetAbsBuildFilePath(tg) << "\"" << std::endl;
+ if (this->TagType == GhsMultiGpj::INTERGRITY_APPLICATION) {
+ return;
}
- // library targets
- cmTarget::LinkLibraryVectorType llv =
- this->GeneratorTarget->Target->GetOriginalLinkLibraries();
- for (cmTarget::LinkLibraryVectorType::const_iterator llvI = llv.begin();
- llvI != llv.end(); ++llvI) {
- std::string libName = llvI->first;
- // if it is a user defined target get the full path to the lib
- cmTarget* tg(GetGlobalGenerator()->FindTarget(libName));
- if (NULL != tg) {
- libName = tg->GetName() + ".a";
- }
- *this->GetFolderBuildStreams()
- << " -l\"" << libName << "\"" << std::endl;
+
+ std::string linkLibraries;
+ std::string flags;
+ std::string linkFlags;
+ std::string frameworkPath;
+ std::string linkPath;
+
+ std::unique_ptr<cmLinkLineComputer> linkLineComputer(
+ this->GetGlobalGenerator()->CreateLinkLineComputer(
+ this->LocalGenerator,
+ this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+
+ this->LocalGenerator->GetTargetFlags(
+ linkLineComputer.get(), config, linkLibraries, flags, linkFlags,
+ frameworkPath, linkPath, this->GeneratorTarget);
+
+ // write out link options
+ std::vector<std::string> lopts =
+ cmSystemTools::ParseArguments(linkFlags.c_str());
+ for (auto& l : lopts) {
+ fout << " " << l << std::endl;
}
- if (!this->TargetGroup) {
- std::string linkLibraries;
- std::string flags;
- std::string linkFlags;
- std::string frameworkPath;
- std::string linkPath;
- std::string createRule =
- this->GeneratorTarget->GetCreateRuleVariable(language, config);
- bool useWatcomQuote =
- this->Makefile->IsOn(createRule + "_USE_WATCOM_QUOTE");
- std::unique_ptr<cmLinkLineComputer> linkLineComputer(
- this->GetGlobalGenerator()->CreateLinkLineComputer(
- this->LocalGenerator,
- this->LocalGenerator->GetStateSnapshot().GetDirectory()));
- linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
-
- this->LocalGenerator->GetTargetFlags(
- linkLineComputer.get(), config, linkLibraries, flags, linkFlags,
- frameworkPath, linkPath, this->GeneratorTarget);
- linkFlags = cmSystemTools::TrimWhitespace(linkFlags);
-
- if (!linkPath.empty()) {
- linkPath = " " + linkPath.substr(0U, linkPath.size() - 1U);
- *this->GetFolderBuildStreams() << linkPath;
- }
+ // write out link search paths
+ // must be quoted for paths that contain spaces
+ std::vector<std::string> lpath =
+ cmSystemTools::ParseArguments(linkPath.c_str());
+ for (auto& l : lpath) {
+ fout << " -L\"" << l << "\"" << std::endl;
+ }
+
+ // write out link libs
+ // must be quoted for filepaths that contains spaces
+ std::string cbd = this->LocalGenerator->GetCurrentBinaryDirectory();
- if (!linkFlags.empty()) {
- *this->GetFolderBuildStreams() << " " << linkFlags << std::endl;
+ std::vector<std::string> llibs =
+ cmSystemTools::ParseArguments(linkLibraries.c_str());
+ for (auto& l : llibs) {
+ if (l.compare(0, 2, "-l") == 0) {
+ fout << " \"" << l << "\"" << std::endl;
+ } else {
+ std::string rl = cmSystemTools::CollapseCombinedPath(cbd, l);
+ fout << " -l\"" << rl << "\"" << std::endl;
}
}
}
-void cmGhsMultiTargetGenerator::WriteCustomCommands()
+void cmGhsMultiTargetGenerator::WriteCustomCommands(std::ostream& fout)
{
- WriteCustomCommandsHelper(this->GeneratorTarget->GetPreBuildCommands(),
+ WriteCustomCommandsHelper(fout, this->GeneratorTarget->GetPreBuildCommands(),
cmTarget::PRE_BUILD);
- WriteCustomCommandsHelper(this->GeneratorTarget->GetPostBuildCommands(),
- cmTarget::POST_BUILD);
+ WriteCustomCommandsHelper(
+ fout, this->GeneratorTarget->GetPostBuildCommands(), cmTarget::POST_BUILD);
}
void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper(
- std::vector<cmCustomCommand> const& commandsSet,
+ std::ostream& fout, std::vector<cmCustomCommand> const& commandsSet,
cmTarget::CustomCommandType const commandType)
{
for (std::vector<cmCustomCommand>::const_iterator commandsSetI =
@@ -400,10 +331,10 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper(
commandI != commands.end(); ++commandI) {
switch (commandType) {
case cmTarget::PRE_BUILD:
- *this->GetFolderBuildStreams() << " :preexecShellSafe=";
+ fout << " :preexecShellSafe=";
break;
case cmTarget::POST_BUILD:
- *this->GetFolderBuildStreams() << " :postexecShellSafe=";
+ fout << " :postexecShellSafe=";
break;
default:
assert("Only pre and post are supported");
@@ -414,242 +345,237 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper(
std::string subCommandE =
this->LocalGenerator->EscapeForShell(*commandLineI, true);
if (!command.empty()) {
- *this->GetFolderBuildStreams()
- << (command.begin() == commandLineI ? "'" : " ");
+ fout << (command.begin() == commandLineI ? "'" : " ");
// Need to double escape backslashes
cmSystemTools::ReplaceString(subCommandE, "\\", "\\\\");
}
- *this->GetFolderBuildStreams() << subCommandE;
+ fout << subCommandE;
}
if (!command.empty()) {
- *this->GetFolderBuildStreams() << "'" << std::endl;
+ fout << "'" << std::endl;
}
}
}
}
-std::map<const cmSourceFile*, std::string>
-cmGhsMultiTargetGenerator::GetObjectNames(
- std::vector<cmSourceFile*>* const objectSources,
- cmLocalGhsMultiGenerator* const localGhsMultiGenerator,
- cmGeneratorTarget* const generatorTarget)
+void cmGhsMultiTargetGenerator::WriteSourceProperty(std::ostream& fout,
+ const cmSourceFile* sf,
+ std::string propName,
+ std::string propFlag)
{
- std::map<std::string, std::vector<cmSourceFile*>> filenameToSource;
- std::map<cmSourceFile*, std::string> sourceToFilename;
- for (std::vector<cmSourceFile*>::const_iterator sf = objectSources->begin();
- sf != objectSources->end(); ++sf) {
- const std::string filename =
- cmSystemTools::GetFilenameName((*sf)->GetFullPath());
- const std::string lower_filename = cmSystemTools::LowerCase(filename);
- filenameToSource[lower_filename].push_back(*sf);
- sourceToFilename[*sf] = lower_filename;
- }
-
- std::vector<cmSourceFile*> duplicateSources;
- for (std::map<std::string, std::vector<cmSourceFile*>>::const_iterator
- msvSourceI = filenameToSource.begin();
- msvSourceI != filenameToSource.end(); ++msvSourceI) {
- if (msvSourceI->second.size() > 1) {
- duplicateSources.insert(duplicateSources.end(),
- msvSourceI->second.begin(),
- msvSourceI->second.end());
+ const char* prop = sf->GetProperty(propName);
+ if (prop) {
+ std::vector<std::string> list;
+ cmSystemTools::ExpandListArgument(prop, list);
+ for (auto& p : list) {
+ fout << " " << propFlag << p << std::endl;
}
}
-
- std::map<const cmSourceFile*, std::string> objectNamesCorrected;
-
- for (std::vector<cmSourceFile*>::const_iterator sf =
- duplicateSources.begin();
- sf != duplicateSources.end(); ++sf) {
- std::string const longestObjectDirectory(
- cmGhsMultiTargetGenerator::ComputeLongestObjectDirectory(
- localGhsMultiGenerator, generatorTarget, *sf));
- std::string objFilenameName =
- localGhsMultiGenerator->GetObjectFileNameWithoutTarget(
- **sf, longestObjectDirectory);
- cmsys::SystemTools::ReplaceString(objFilenameName, "/", "_");
- objectNamesCorrected[*sf] = objFilenameName;
- }
-
- return objectNamesCorrected;
}
-void cmGhsMultiTargetGenerator::WriteSources(
- std::vector<cmSourceFile*> const& objectSources,
- std::map<const cmSourceFile*, std::string> const& objectNames)
+void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
{
- for (const cmSourceFile* sf : objectSources) {
- std::vector<cmSourceGroup> sourceGroups(this->Makefile->GetSourceGroups());
- std::string const& sourceFullPath = sf->GetFullPath();
- cmSourceGroup* sourceGroup =
- this->Makefile->FindSourceGroup(sourceFullPath, sourceGroups);
- std::string sgPath = sourceGroup->GetFullName();
- cmSystemTools::ConvertToUnixSlashes(sgPath);
- cmGlobalGhsMultiGenerator::AddFilesUpToPath(
- this->GetFolderBuildStreams(), &this->FolderBuildStreams,
- this->LocalGenerator->GetBinaryDirectory().c_str(), sgPath,
- GhsMultiGpj::SUBPROJECT, this->RelBuildFilePath);
-
- std::string fullSourcePath(sf->GetFullPath());
- if (sf->GetExtension() == "int" || sf->GetExtension() == "bsp") {
- *this->FolderBuildStreams[sgPath] << fullSourcePath << std::endl;
- } else {
- // WORKAROUND: GHS MULTI needs the path to use backslashes without quotes
- // to open files in search as of version 6.1.6
- cmsys::SystemTools::ReplaceString(fullSourcePath, "/", "\\");
- *this->FolderBuildStreams[sgPath] << fullSourcePath << std::endl;
- }
+ /* vector of all sources for this target */
+ std::vector<cmSourceFile*> sources;
+ this->GeneratorTarget->GetSourceFiles(sources, this->ConfigName);
- if ("ld" != sf->GetExtension() && "int" != sf->GetExtension() &&
- "bsp" != sf->GetExtension()) {
- this->WriteObjectLangOverride(this->FolderBuildStreams[sgPath], sf);
- if (objectNames.end() != objectNames.find(sf)) {
- *this->FolderBuildStreams[sgPath]
- << " -o \"" << objectNames.find(sf)->second << "\"" << std::endl;
- }
+ /* vector of all groups defined for this target
+ * -- but the vector is not expanded with sub groups or in any useful order
+ */
+ std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
- this->WriteObjectDir(this->FolderBuildStreams[sgPath],
- this->AbsBuildFilePath + sgPath);
- }
+ /* for each source file assign it to its group */
+ std::map<std::string, std::vector<cmSourceFile*>> groupFiles;
+ std::set<std::string> groupNames;
+ for (auto& sf : sources) {
+ cmSourceGroup* sourceGroup =
+ this->Makefile->FindSourceGroup(sf->GetFullPath(), sourceGroups);
+ std::string gn = sourceGroup->GetFullName();
+ groupFiles[gn].push_back(sf);
+ groupNames.insert(gn);
}
-}
-void cmGhsMultiTargetGenerator::WriteObjectLangOverride(
- cmGeneratedFileStream* fileStream, const cmSourceFile* sourceFile)
-{
- const char* rawLangProp = sourceFile->GetProperty("LANGUAGE");
- if (NULL != rawLangProp) {
- std::string sourceLangProp(rawLangProp);
- std::string extension(sourceFile->GetExtension());
- if ("CXX" == sourceLangProp && ("c" == extension || "C" == extension)) {
- *fileStream << " -dotciscxx" << std::endl;
+ /* list of known groups and the order they are displayed in a project file */
+ const std::vector<std::string> standardGroups = {
+ "Header Files", "Source Files", "CMake Rules",
+ "Object Files", "Object Libraries", "Resources"
+ };
+
+ /* list of groups in the order they are displayed in a project file*/
+ std::vector<std::string> groupFilesList(groupFiles.size());
+
+ /* put the groups in the order they should be listed
+ * - standard groups first, and then everything else
+ * in the order used by std::map.
+ */
+ int i = 0;
+ for (const std::string& gn : standardGroups) {
+ auto n = groupNames.find(gn);
+ if (n != groupNames.end()) {
+ groupFilesList[i] = *n;
+ i += 1;
+ groupNames.erase(gn);
}
}
-}
-void cmGhsMultiTargetGenerator::WriteObjectDir(
- cmGeneratedFileStream* fileStream, std::string const& dir)
-{
- std::string workingDir(dir);
- cmSystemTools::ConvertToUnixSlashes(workingDir);
- if (!workingDir.empty()) {
- workingDir += "/";
+ { /* catch-all group - is last item */
+ std::string gn = "";
+ auto n = groupNames.find(gn);
+ if (n != groupNames.end()) {
+ groupFilesList.back() = *n;
+ groupNames.erase(gn);
+ }
}
- workingDir += "Objs";
- *fileStream << " -object_dir=\"" << workingDir << "\"" << std::endl;
-}
-std::string cmGhsMultiTargetGenerator::GetOutputDirectory(
- const std::string& config) const
-{
- std::string outputDir(AbsBuildFilePath);
-
- const char* runtimeOutputProp =
- this->GeneratorTarget->GetProperty("RUNTIME_OUTPUT_DIRECTORY");
- if (NULL != runtimeOutputProp) {
- outputDir = runtimeOutputProp;
+ for (auto& n : groupNames) {
+ groupFilesList[i] = n;
+ i += 1;
}
- std::string configCapped(cmSystemTools::UpperCase(config));
- const char* runtimeOutputSProp = this->GeneratorTarget->GetProperty(
- "RUNTIME_OUTPUT_DIRECTORY_" + configCapped);
- if (NULL != runtimeOutputSProp) {
- outputDir = runtimeOutputSProp;
+ /* sort the files within each group */
+ for (auto& n : groupFilesList) {
+ std::sort(groupFiles[n].begin(), groupFiles[n].end(),
+ [](cmSourceFile* l, cmSourceFile* r) {
+ return l->GetFullPath() < r->GetFullPath();
+ });
}
- cmSystemTools::ConvertToUnixSlashes(outputDir);
- if (!outputDir.empty()) {
- outputDir += "/";
- }
+ /* list of open project files */
+ std::vector<cmGeneratedFileStream*> gfiles;
+
+ /* write files into the proper project file
+ * -- groups go into main project file
+ * unless FOLDER property or variable is set.
+ */
+ for (auto& sg : groupFilesList) {
+ std::ostream* fout;
+ bool useProjectFile =
+ cmSystemTools::IsOn(
+ this->GeneratorTarget->GetProperty("GHS_NO_SOURCE_GROUP_FILE")) ||
+ cmSystemTools::IsOn(
+ this->Makefile->GetDefinition("GHS_NO_SOURCE_GROUP_FILE"));
+ if (useProjectFile || sg.empty()) {
+ fout = &fout_proj;
+ } else {
+ // Open the filestream in copy-if-different mode.
+ std::string gname = sg;
+ cmsys::SystemTools::ReplaceString(gname, "\\", "_");
+ std::string lpath =
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
+ lpath += "/";
+ lpath += gname;
+ lpath += cmGlobalGhsMultiGenerator::FILE_EXTENSION;
+ std::string fpath = this->LocalGenerator->GetCurrentBinaryDirectory();
+ fpath += "/";
+ fpath += lpath;
+ cmGeneratedFileStream* f = new cmGeneratedFileStream(fpath.c_str());
+ f->SetCopyIfDifferent(true);
+ gfiles.push_back(f);
+ fout = f;
+ this->GetGlobalGenerator()->WriteFileHeader(*f);
+ GhsMultiGpj::WriteGpjTag(GhsMultiGpj::SUBPROJECT, *f);
+ fout_proj << lpath << " ";
+ GhsMultiGpj::WriteGpjTag(GhsMultiGpj::SUBPROJECT, fout_proj);
+ }
- return outputDir;
-}
+ if (useProjectFile) {
+ if (sg.empty()) {
+ *fout << "{comment} Others" << std::endl;
+ } else {
+ *fout << "{comment} " << sg << std::endl;
+ }
+ }
-std::string cmGhsMultiTargetGenerator::GetOutputFilename(
- const std::string& config) const
-{
- std::string outputFilename(this->GeneratorTarget->GetName());
+ /* output rule for each source file */
+ for (const cmSourceFile* si : groupFiles[sg]) {
- const char* outputNameProp =
- this->GeneratorTarget->GetProperty("OUTPUT_NAME");
- if (NULL != outputNameProp) {
- outputFilename = outputNameProp;
- }
+ // Convert filename to native system
+ // WORKAROUND: GHS MULTI 6.1.4 and 6.1.6 are known to need backslash on
+ // windows when opening some files from the search window.
+ std::string fname(si->GetFullPath());
+ cmSystemTools::ConvertToOutputSlashes(fname);
+ *fout << fname << std::endl;
+
+ if ("ld" != si->GetExtension() && "int" != si->GetExtension() &&
+ "bsp" != si->GetExtension()) {
+ this->WriteObjectLangOverride(*fout, si);
+ }
+
+ this->WriteSourceProperty(*fout, si, "INCLUDE_DIRECTORIES", "-I");
+ this->WriteSourceProperty(*fout, si, "COMPILE_DEFINITIONS", "-D");
+ this->WriteSourceProperty(*fout, si, "COMPILE_OPTIONS", "");
- std::string configCapped(cmSystemTools::UpperCase(config));
- const char* outputNameSProp =
- this->GeneratorTarget->GetProperty(configCapped + "_OUTPUT_NAME");
- if (NULL != outputNameSProp) {
- outputFilename = outputNameSProp;
+ /* to avoid clutter in the gui only print out the objectName if it has
+ * been renamed */
+ std::string objectName = this->GeneratorTarget->GetObjectName(si);
+ if (!objectName.empty() &&
+ this->GeneratorTarget->HasExplicitObjectName(si)) {
+ *fout << " -o " << objectName << std::endl;
+ }
+ }
}
- return outputFilename;
+ for (cmGeneratedFileStream* f : gfiles) {
+ f->Close();
+ }
}
-std::string cmGhsMultiTargetGenerator::ComputeLongestObjectDirectory(
- cmLocalGhsMultiGenerator const* localGhsMultiGenerator,
- cmGeneratorTarget* const generatorTarget, cmSourceFile* const sourceFile)
+void cmGhsMultiTargetGenerator::WriteObjectLangOverride(
+ std::ostream& fout, const cmSourceFile* sourceFile)
{
- std::string dir_max;
- dir_max +=
- localGhsMultiGenerator->GetMakefile()->GetCurrentBinaryDirectory();
- dir_max += "/";
- dir_max += generatorTarget->Target->GetName();
- dir_max += "/";
- std::vector<cmSourceGroup> sourceGroups(
- localGhsMultiGenerator->GetMakefile()->GetSourceGroups());
- std::string const& sourceFullPath = sourceFile->GetFullPath();
- cmSourceGroup* sourceGroup =
- localGhsMultiGenerator->GetMakefile()->FindSourceGroup(sourceFullPath,
- sourceGroups);
- std::string const& sgPath = sourceGroup->GetFullName();
- dir_max += sgPath;
- dir_max += "/Objs/libs/";
- dir_max += generatorTarget->Target->GetName();
- dir_max += "/";
- return dir_max;
+ const char* rawLangProp = sourceFile->GetProperty("LANGUAGE");
+ if (NULL != rawLangProp) {
+ std::string sourceLangProp(rawLangProp);
+ std::string extension(sourceFile->GetExtension());
+ if ("CXX" == sourceLangProp && ("c" == extension || "C" == extension)) {
+ fout << " -dotciscxx" << std::endl;
+ }
+ }
}
-bool cmGhsMultiTargetGenerator::IsNotKernel(std::string const& config,
- const std::string& language)
+void cmGhsMultiTargetGenerator::WriteReferences(std::ostream& fout)
{
- bool output;
- std::vector<std::string> options;
- this->GeneratorTarget->GetCompileOptions(options, config, language);
- output =
- options.end() == std::find(options.begin(), options.end(), "-kernel");
- return output;
-}
+ // This only applies to INTEGRITY Applications
+ if (this->TagType != GhsMultiGpj::INTERGRITY_APPLICATION) {
+ return;
+ }
-bool cmGhsMultiTargetGenerator::DetermineIfTargetGroup(
- const cmGeneratorTarget* target)
-{
- bool output = false;
- std::vector<cmSourceFile*> sources;
- std::string config =
- target->Target->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
- target->GetSourceFiles(sources, config);
- for (std::vector<cmSourceFile*>::const_iterator sources_i = sources.begin();
- sources.end() != sources_i; ++sources_i) {
- if ("int" == (*sources_i)->GetExtension()) {
- output = true;
- }
+ // Get the targets that this one depends upon
+ cmTargetDependSet unordered =
+ this->GetGlobalGenerator()->GetTargetDirectDepends(this->GeneratorTarget);
+ cmGlobalGhsMultiGenerator::OrderedTargetDependSet ordered(unordered,
+ this->Name);
+ for (auto& t : ordered) {
+ std::string tname = t->GetName();
+ std::string tpath = t->LocalGenerator->GetCurrentBinaryDirectory();
+ std::string rootpath = this->LocalGenerator->GetCurrentBinaryDirectory();
+ std::string outpath =
+ this->LocalGenerator->ConvertToRelativePath(rootpath, tpath) + "/" +
+ tname + "REF" + cmGlobalGhsMultiGenerator::FILE_EXTENSION;
+
+ fout << outpath;
+ fout << " ";
+ GhsMultiGpj::WriteGpjTag(GhsMultiGpj::REFERENCE, fout);
+
+ // Tell the global generator that a refernce project needs to be created
+ t->Target->SetProperty("GHS_REFERENCE_PROJECT", "ON");
}
- return output;
}
-bool cmGhsMultiTargetGenerator::DetermineIfDynamicDownload(
- std::string const& config, const std::string& language)
+bool cmGhsMultiTargetGenerator::DetermineIfIntegrityApp(void)
{
- std::vector<std::string> options;
- bool output = false;
- this->GeneratorTarget->GetCompileOptions(options, config, language);
- for (std::vector<std::string>::const_iterator options_i = options.begin();
- options_i != options.end(); ++options_i) {
- std::string option = *options_i;
- if (this->DDOption == option) {
- output = true;
+ const char* p = this->GeneratorTarget->GetProperty("ghs_integrity_app");
+ if (p) {
+ return cmSystemTools::IsOn(
+ this->GeneratorTarget->GetProperty("ghs_integrity_app"));
+ } else {
+ std::vector<cmSourceFile*> sources;
+ this->GeneratorTarget->GetSourceFiles(sources, this->ConfigName);
+ for (auto& sf : sources) {
+ if ("int" == sf->GetExtension()) {
+ return true;
+ }
}
+ return false;
}
- return output;
}
diff --git a/Source/cmGhsMultiTargetGenerator.h b/Source/cmGhsMultiTargetGenerator.h
index e936b08..a241cc6 100644
--- a/Source/cmGhsMultiTargetGenerator.h
+++ b/Source/cmGhsMultiTargetGenerator.h
@@ -24,97 +24,49 @@ public:
virtual void Generate();
- bool IncludeThisTarget();
- std::vector<cmSourceFile*> GetSources() const;
- GhsMultiGpj::Types GetGpjTag() const;
- static GhsMultiGpj::Types GetGpjTag(const cmGeneratorTarget* target);
- const char* GetAbsBuildFilePath() const
- {
- return this->AbsBuildFilePath.c_str();
- }
- const char* GetRelBuildFileName() const
- {
- return this->RelBuildFileName.c_str();
- }
- const char* GetAbsBuildFileName() const
- {
- return this->AbsBuildFileName.c_str();
- }
- const char* GetAbsOutputFileName() const
- {
- return this->AbsOutputFileName.c_str();
- }
-
- static std::string GetRelBuildFilePath(const cmGeneratorTarget* target);
- static std::string GetAbsPathToRoot(const cmGeneratorTarget* target);
- static std::string GetAbsBuildFilePath(const cmGeneratorTarget* target);
- static std::string GetRelBuildFileName(const cmGeneratorTarget* target);
- static std::string GetBuildFileName(const cmGeneratorTarget* target);
- static std::string AddSlashIfNeededToPath(std::string const& input);
-
private:
cmGlobalGhsMultiGenerator* GetGlobalGenerator() const;
- cmGeneratedFileStream* GetFolderBuildStreams()
- {
- return this->FolderBuildStreams[""];
- };
- bool IsTargetGroup() const { return this->TargetGroup; }
-
- void WriteTypeSpecifics(const std::string& config, bool notKernel);
- void WriteCompilerFlags(const std::string& config,
+
+ void GenerateTarget();
+
+ void WriteTargetSpecifics(std::ostream& fout, const std::string& config);
+
+ void WriteCompilerFlags(std::ostream& fout, const std::string& config,
const std::string& language);
- void WriteCompilerDefinitions(const std::string& config,
+ void WriteCompilerDefinitions(std::ostream& fout, const std::string& config,
const std::string& language);
- void SetCompilerFlags(std::string const& config, const std::string& language,
- bool const notKernel);
+ void SetCompilerFlags(std::string const& config,
+ const std::string& language);
+
std::string GetDefines(const std::string& langugae,
std::string const& config);
- void WriteIncludes(const std::string& config, const std::string& language);
- void WriteTargetLinkLibraries(std::string const& config,
- std::string const& language);
- void WriteCustomCommands();
+ void WriteIncludes(std::ostream& fout, const std::string& config,
+ const std::string& language);
+ void WriteTargetLinkLine(std::ostream& fout, std::string const& config);
+ void WriteCustomCommands(std::ostream& fout);
void WriteCustomCommandsHelper(
- std::vector<cmCustomCommand> const& commandsSet,
+ std::ostream& fout, std::vector<cmCustomCommand> const& commandsSet,
cmTarget::CustomCommandType commandType);
- void WriteSources(
- std::vector<cmSourceFile*> const& objectSources,
- std::map<const cmSourceFile*, std::string> const& objectNames);
- static std::map<const cmSourceFile*, std::string> GetObjectNames(
- std::vector<cmSourceFile*>* objectSources,
- cmLocalGhsMultiGenerator* localGhsMultiGenerator,
- cmGeneratorTarget* generatorTarget);
- static void WriteObjectLangOverride(cmGeneratedFileStream* fileStream,
+ void WriteSources(std::ostream& fout_proj);
+ void WriteSourceProperty(std::ostream& fout, const cmSourceFile* sf,
+ std::string propName, std::string propFlag);
+ void WriteReferences(std::ostream& fout);
+ static void WriteObjectLangOverride(std::ostream& fout,
const cmSourceFile* sourceFile);
- static void WriteObjectDir(cmGeneratedFileStream* fileStream,
- std::string const& dir);
- std::string GetOutputDirectory(const std::string& config) const;
- std::string GetOutputFilename(const std::string& config) const;
- static std::string ComputeLongestObjectDirectory(
- cmLocalGhsMultiGenerator const* localGhsMultiGenerator,
- cmGeneratorTarget* generatorTarget, cmSourceFile* const sourceFile);
-
- bool IsNotKernel(std::string const& config, const std::string& language);
- static bool DetermineIfTargetGroup(const cmGeneratorTarget* target);
- bool DetermineIfDynamicDownload(std::string const& config,
- const std::string& language);
+ bool DetermineIfIntegrityApp(void);
cmGeneratorTarget* GeneratorTarget;
cmLocalGhsMultiGenerator* LocalGenerator;
cmMakefile* Makefile;
- std::string AbsBuildFilePath;
- std::string RelBuildFilePath;
- std::string AbsBuildFileName;
- std::string RelBuildFileName;
- std::string RelOutputFileName;
- std::string AbsOutputFileName;
- std::map<std::string, cmGeneratedFileStream*> FolderBuildStreams;
- bool TargetGroup;
- bool DynamicDownload;
- static std::string const DDOption;
std::map<std::string, std::string> FlagsByLanguage;
std::map<std::string, std::string> DefinesByLanguage;
+
+ std::string TargetNameReal;
+ GhsMultiGpj::Types TagType;
+ std::string const Name;
+ std::string ConfigName; /* CMAKE_BUILD_TYPE */
};
#endif // ! cmGhsMultiTargetGenerator_h
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 85c2345..a5c90bf 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -302,7 +302,8 @@ bool cmGlobalGenerator::CheckTargetsForMissingSources() const
for (cmGeneratorTarget* target : targets) {
if (target->GetType() == cmStateEnums::TargetType::GLOBAL_TARGET ||
target->GetType() == cmStateEnums::TargetType::INTERFACE_LIBRARY ||
- target->GetType() == cmStateEnums::TargetType::UTILITY) {
+ target->GetType() == cmStateEnums::TargetType::UTILITY ||
+ cmSystemTools::IsOn(target->GetProperty("ghs_integrity_app"))) {
continue;
}
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index 831c4a9..557efec 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -11,6 +11,7 @@
#include "cmGhsMultiTargetGenerator.h"
#include "cmLocalGhsMultiGenerator.h"
#include "cmMakefile.h"
+#include "cmState.h"
#include "cmVersion.h"
#include "cmake.h"
@@ -20,13 +21,12 @@ const char* cmGlobalGhsMultiGenerator::DEFAULT_TOOLSET_ROOT = "C:/ghs";
cmGlobalGhsMultiGenerator::cmGlobalGhsMultiGenerator(cmake* cm)
: cmGlobalGenerator(cm)
- , OSDirRelative(false)
{
+ cm->GetState()->SetGhsMultiIDE(true);
}
cmGlobalGhsMultiGenerator::~cmGlobalGhsMultiGenerator()
{
- cmDeleteAll(TargetFolderBuildStreams);
}
cmLocalGenerator* cmGlobalGhsMultiGenerator::CreateLocalGenerator(
@@ -42,46 +42,59 @@ void cmGlobalGhsMultiGenerator::GetDocumentation(cmDocumentationEntry& entry)
"Generates Green Hills MULTI files (experimental, work-in-progress).";
}
+void cmGlobalGhsMultiGenerator::ComputeTargetObjectDirectory(
+ cmGeneratorTarget* gt) const
+{
+ // Compute full path to object file directory for this target.
+ std::string dir;
+ dir += gt->LocalGenerator->GetCurrentBinaryDirectory();
+ dir += "/";
+ dir += gt->LocalGenerator->GetTargetDirectory(gt);
+ dir += "/";
+ gt->ObjectDirectory = dir;
+}
+
bool cmGlobalGhsMultiGenerator::SetGeneratorToolset(std::string const& ts,
cmMakefile* mf)
{
- std::string tsp; /* toolset path */
- std::string tsn = ts; /* toolset name */
+ std::string tsp; /* toolset path */
- GetToolset(mf, tsp, tsn);
+ this->GetToolset(mf, tsp, ts);
/* no toolset was found */
- if (tsn.empty()) {
+ if (tsp.empty()) {
return false;
} else if (ts.empty()) {
std::string message;
message =
"Green Hills MULTI: -T <toolset> not specified; defaulting to \"";
- message += tsn;
+ message += tsp;
message += "\"";
cmSystemTools::Message(message.c_str());
- /* store the toolset for later use
+ /* store the full toolset for later use
* -- already done if -T<toolset> was specified
*/
- mf->AddCacheDefinition("CMAKE_GENERATOR_TOOLSET", tsn.c_str(),
- "Name of generator toolset.",
+ mf->AddCacheDefinition("CMAKE_GENERATOR_TOOLSET", tsp.c_str(),
+ "Location of generator toolset.",
cmStateEnums::INTERNAL);
}
/* set the build tool to use */
+ std::string gbuild(tsp + ((tsp.back() == '/') ? "" : "/") +
+ DEFAULT_BUILD_PROGRAM);
const char* prevTool = mf->GetDefinition("CMAKE_MAKE_PROGRAM");
- std::string gbuild(tsp + "/" + tsn + "/" + DEFAULT_BUILD_PROGRAM);
/* check if the toolset changed from last generate */
if (prevTool != NULL && (gbuild != prevTool)) {
- std::string message = "generator toolset: ";
+ std::string message = "toolset build tool: ";
message += gbuild;
- message += "\nDoes not match the toolset used previously: ";
+ message += "\nDoes not match the previously used build tool: ";
message += prevTool;
message += "\nEither remove the CMakeCache.txt file and CMakeFiles "
"directory or choose a different binary directory.";
cmSystemTools::Error(message.c_str());
+ return false;
} else {
/* store the toolset that is being used for this build */
mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", gbuild.c_str(),
@@ -89,25 +102,7 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorToolset(std::string const& ts,
true);
}
- mf->AddDefinition("CMAKE_SYSTEM_VERSION", tsn.c_str());
-
- // FIXME: compiler detection not implemented
- // gbuild uses the primaryTarget setting in the top-level project
- // file to determine which compiler to use. Because compiler
- // detection is not implemented these variables must be
- // set to skip past these tests. However cmake will verify that
- // the executable pointed to by CMAKE_<LANG>_COMPILER exists.
- // To pass this additional check gbuild is used as a place holder for the
- // actual compiler.
- mf->AddDefinition("CMAKE_C_COMPILER", gbuild.c_str());
- mf->AddDefinition("CMAKE_C_COMPILER_ID_RUN", "TRUE");
- mf->AddDefinition("CMAKE_C_COMPILER_ID", "GHS");
- mf->AddDefinition("CMAKE_C_COMPILER_FORCED", "TRUE");
-
- mf->AddDefinition("CMAKE_CXX_COMPILER", gbuild.c_str());
- mf->AddDefinition("CMAKE_CXX_COMPILER_ID_RUN", "TRUE");
- mf->AddDefinition("CMAKE_CXX_COMPILER_ID", "GHS");
- mf->AddDefinition("CMAKE_CXX_COMPILER_FORCED", "TRUE");
+ mf->AddDefinition("CMAKE_SYSTEM_VERSION", tsp.c_str());
return true;
}
@@ -130,6 +125,8 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorPlatform(std::string const& p,
const char* tgtPlatform = mf->GetDefinition("GHS_TARGET_PLATFORM");
if (tgtPlatform == nullptr) {
+ cmSystemTools::Message("Green Hills MULTI: GHS_TARGET_PLATFORM not "
+ "specified; defaulting to \"integrity\"");
tgtPlatform = "integrity";
}
@@ -160,11 +157,11 @@ bool cmGlobalGhsMultiGenerator::FindMakeProgram(cmMakefile* /*mf*/)
}
void cmGlobalGhsMultiGenerator::GetToolset(cmMakefile* mf, std::string& tsd,
- std::string& ts)
+ const std::string& ts)
{
const char* ghsRoot = mf->GetDefinition("GHS_TOOLSET_ROOT");
- if (!ghsRoot) {
+ if (!ghsRoot || ghsRoot[0] == '\0') {
ghsRoot = DEFAULT_TOOLSET_ROOT;
}
tsd = ghsRoot;
@@ -173,129 +170,208 @@ void cmGlobalGhsMultiGenerator::GetToolset(cmMakefile* mf, std::string& tsd,
std::vector<std::string> output;
// Use latest? version
+ if (tsd.back() != '/') {
+ tsd += "/";
+ }
cmSystemTools::Glob(tsd, "comp_[^;]+", output);
if (output.empty()) {
- cmSystemTools::Error("GHS toolset not found in ", tsd.c_str());
- ts = "";
+ std::string msg =
+ "No GHS toolsets found in GHS_TOOLSET_ROOT \"" + tsd + "\".";
+ cmSystemTools::Error(msg.c_str());
+ tsd = "";
} else {
- ts = output.back();
+ tsd += output.back();
}
} else {
- std::string tryPath = tsd + std::string("/") + ts;
+ std::string tryPath;
+ /* CollapseCombinedPath will check if ts is an absolute path */
+ tryPath = cmSystemTools::CollapseCombinedPath(tsd, ts);
if (!cmSystemTools::FileExists(tryPath)) {
- cmSystemTools::Error("GHS toolset \"", ts.c_str(), "\" not found in ",
- tsd.c_str());
- ts = "";
+ std::string msg = "GHS toolset \"" + tryPath + "\" not found.";
+ cmSystemTools::Error(msg.c_str());
+ tsd = "";
+ } else {
+ tsd = tryPath;
}
}
}
-void cmGlobalGhsMultiGenerator::OpenBuildFileStream(
- std::string const& filepath, cmGeneratedFileStream** filestream)
+void cmGlobalGhsMultiGenerator::WriteFileHeader(std::ostream& fout)
{
- // Get a stream where to generate things.
- if (NULL == *filestream) {
- *filestream = new cmGeneratedFileStream(filepath.c_str());
- if (NULL != *filestream) {
- OpenBuildFileStream(*filestream);
- }
- }
+ fout << "#!gbuild" << std::endl;
+ fout << "#" << std::endl
+ << "# CMAKE generated file: DO NOT EDIT!" << std::endl
+ << "# Generated by \"" << this->GetActualName() << "\""
+ << " Generator, CMake Version " << cmVersion::GetMajorVersion() << "."
+ << cmVersion::GetMinorVersion() << std::endl
+ << "#" << std::endl
+ << std::endl;
}
-void cmGlobalGhsMultiGenerator::OpenBuildFileStream(
- cmGeneratedFileStream* filestream)
+void cmGlobalGhsMultiGenerator::WriteTopLevelProject(
+ std::ostream& fout, cmLocalGenerator* root,
+ std::vector<cmLocalGenerator*>& generators)
{
- *filestream << "#!gbuild" << std::endl;
-}
+ WriteFileHeader(fout);
-void cmGlobalGhsMultiGenerator::OpenBuildFileStream()
-{
- // Compute GHS MULTI's build file path.
- std::string buildFilePath =
- this->GetCMakeInstance()->GetHomeOutputDirectory();
- buildFilePath += "/";
- buildFilePath += "default";
- buildFilePath += FILE_EXTENSION;
-
- this->Open(std::string(""), buildFilePath, &this->TargetFolderBuildStreams);
- OpenBuildFileStream(GetBuildFileStream());
-
- char const* osDir =
- this->GetCMakeInstance()->GetCacheDefinition("GHS_OS_DIR");
- if (NULL == osDir) {
- osDir = "";
- cmSystemTools::Error("GHS_OS_DIR cache variable must be set");
- } else {
- this->GetCMakeInstance()->MarkCliAsUsed("GHS_OS_DIR");
- }
- std::string fOSDir(this->trimQuotes(osDir));
- std::replace(fOSDir.begin(), fOSDir.end(), '\\', '/');
- if (!fOSDir.empty() && ('c' == fOSDir[0] || 'C' == fOSDir[0])) {
- this->OSDirRelative = false;
- } else {
- this->OSDirRelative = true;
+ this->WriteMacros(fout);
+ this->WriteHighLevelDirectives(fout);
+ GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fout);
+
+ fout << "# Top Level Project File" << std::endl;
+
+ // Specify BSP option if supplied by user
+ // -- not all platforms require this entry in the project file
+ // integrity platforms require this field; use default if needed
+ std::string platform;
+ if (const char* p =
+ this->GetCMakeInstance()->GetCacheDefinition("GHS_TARGET_PLATFORM")) {
+ platform = p;
}
std::string bspName;
- char const* bspCache =
- this->GetCMakeInstance()->GetCacheDefinition("GHS_BSP_NAME");
- if (bspCache) {
+ if (char const* bspCache =
+ this->GetCMakeInstance()->GetCacheDefinition("GHS_BSP_NAME")) {
bspName = bspCache;
this->GetCMakeInstance()->MarkCliAsUsed("GHS_BSP_NAME");
+ } else {
+ bspName = "IGNORE";
}
- if (bspName.empty() || bspName.compare("IGNORE") == 0) {
+
+ if (platform.find("integrity") != std::string::npos &&
+ cmSystemTools::IsOff(bspName.c_str())) {
const char* a =
this->GetCMakeInstance()->GetCacheDefinition("CMAKE_GENERATOR_PLATFORM");
bspName = "sim";
bspName += (a ? a : "");
}
- this->WriteMacros();
- this->WriteHighLevelDirectives();
+ if (!cmSystemTools::IsOff(bspName.c_str())) {
+ fout << " -bsp " << bspName << std::endl;
+ }
+
+ // Specify OS DIR if supplied by user
+ // -- not all platforms require this entry in the project file
+ std::string osDir;
+ std::string osDirOption;
+ if (char const* osDirCache =
+ this->GetCMakeInstance()->GetCacheDefinition("GHS_OS_DIR")) {
+ osDir = osDirCache;
+ }
+
+ if (char const* osDirOptionCache =
+ this->GetCMakeInstance()->GetCacheDefinition("GHS_OS_DIR_OPTION")) {
+ osDirOption = osDirOptionCache;
+ }
- GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, this->GetBuildFileStream());
- this->WriteDisclaimer(this->GetBuildFileStream());
- *this->GetBuildFileStream() << "# Top Level Project File" << std::endl;
- *this->GetBuildFileStream() << " -bsp " << bspName << std::endl;
+ if (!cmSystemTools::IsOff(osDir.c_str()) ||
+ platform.find("integrity") != std::string::npos) {
+ std::replace(osDir.begin(), osDir.end(), '\\', '/');
+ fout << " " << osDirOption << "\"" << osDir << "\"" << std::endl;
+ }
- this->WriteCompilerOptions(fOSDir);
+ WriteSubProjects(fout, root, generators);
}
-void cmGlobalGhsMultiGenerator::CloseBuildFileStream(
- cmGeneratedFileStream** filestream)
+void cmGlobalGhsMultiGenerator::WriteSubProjects(
+ std::ostream& fout, cmLocalGenerator* root,
+ std::vector<cmLocalGenerator*>& generators)
{
- if (filestream) {
- delete *filestream;
- *filestream = NULL;
- } else {
- cmSystemTools::Error("Build file stream was not open.");
+ // Collect all targets under this root generator and the transitive
+ // closure of their dependencies.
+ TargetDependSet projectTargets;
+ TargetDependSet originalTargets;
+ this->GetTargetSets(projectTargets, originalTargets, root, generators);
+ OrderedTargetDependSet orderedProjectTargets(projectTargets, "");
+
+ // write out all the sub-projects
+ std::string rootBinaryDir = root->GetCurrentBinaryDirectory();
+ for (cmGeneratorTarget const* target : orderedProjectTargets) {
+ if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+ continue;
+ }
+
+ const char* projName = target->GetProperty("GENERATOR_FILE_NAME");
+ const char* projType = target->GetProperty("GENERATOR_FILE_NAME_EXT");
+ if (projName && projType) {
+ cmLocalGenerator* lg = target->GetLocalGenerator();
+ std::string dir = lg->GetCurrentBinaryDirectory();
+ dir = root->ConvertToRelativePath(rootBinaryDir, dir.c_str());
+ if (dir == ".") {
+ dir.clear();
+ } else {
+ if (dir.back() != '/') {
+ dir += "/";
+ }
+ }
+
+ if (cmSystemTools::IsOn(target->GetProperty("EXCLUDE_FROM_ALL"))) {
+ fout << "{comment} ";
+ }
+ std::string projFile = dir + projName + FILE_EXTENSION;
+ fout << projFile;
+ fout << " " << projType << std::endl;
+
+ if (cmSystemTools::IsOn(target->GetProperty("GHS_REFERENCE_PROJECT"))) {
+ // create reference project
+ std::string fname = dir;
+ fname += target->GetName();
+ fname += "REF";
+ fname += FILE_EXTENSION;
+
+ cmGeneratedFileStream fref(fname.c_str());
+ fref.SetCopyIfDifferent(true);
+
+ this->WriteFileHeader(fref);
+ GhsMultiGpj::WriteGpjTag(GhsMultiGpj::REFERENCE, fref);
+ fref << " :reference=" << projFile << std::endl;
+
+ fref.Close();
+ }
+ }
}
}
void cmGlobalGhsMultiGenerator::Generate()
{
+ // first do the superclass method
this->cmGlobalGenerator::Generate();
- if (!this->LocalGenerators.empty()) {
- this->OpenBuildFileStream();
+ // output top-level projects
+ for (auto& it : this->ProjectMap) {
+ this->OutputTopLevelProject(it.second[0], it.second);
+ }
+}
- // Build all the folder build files
- for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i) {
- cmLocalGhsMultiGenerator* lg =
- static_cast<cmLocalGhsMultiGenerator*>(this->LocalGenerators[i]);
- const std::vector<cmGeneratorTarget*>& tgts = lg->GetGeneratorTargets();
- this->UpdateBuildFiles(tgts);
- }
+void cmGlobalGhsMultiGenerator::OutputTopLevelProject(
+ cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators)
+{
+ if (generators.empty()) {
+ return;
}
- cmDeleteAll(TargetFolderBuildStreams);
- this->TargetFolderBuildStreams.clear();
+ /* Name top-level projects as filename.top.gpj to avoid name clashes
+ * with target projects. This avoid the issue where the project has
+ * the same name as the executable target.
+ */
+ std::string fname = root->GetCurrentBinaryDirectory();
+ fname += "/";
+ fname += root->GetProjectName();
+ fname += ".top";
+ fname += FILE_EXTENSION;
+
+ cmGeneratedFileStream fout(fname.c_str());
+ fout.SetCopyIfDifferent(true);
+
+ this->WriteTopLevelProject(fout, root, generators);
+
+ fout.Close();
}
void cmGlobalGhsMultiGenerator::GenerateBuildCommand(
std::vector<std::string>& makeCommand, const std::string& makeProgram,
- const std::string& /*projectName*/, const std::string& /*projectDir*/,
+ const std::string& projectName, const std::string& projectDir,
const std::string& targetName, const std::string& /*config*/, bool /*fast*/,
int jobs, bool /*verbose*/, std::vector<std::string> const& makeOptions)
{
@@ -313,16 +389,34 @@ void cmGlobalGhsMultiGenerator::GenerateBuildCommand(
makeCommand.insert(makeCommand.end(), makeOptions.begin(),
makeOptions.end());
+
+ /* determine which top-project file to use */
+ std::string proj = projectName + ".top" + FILE_EXTENSION;
+ std::vector<std::string> files;
+ cmSystemTools::Glob(projectDir, ".*\\.top\\.gpj", files);
+ if (!files.empty()) {
+ auto p = std::find(files.begin(), files.end(), proj);
+ if (p == files.end()) {
+ proj = files.at(0);
+ }
+ }
+
+ makeCommand.push_back("-top");
+ makeCommand.push_back(proj);
if (!targetName.empty()) {
if (targetName == "clean") {
makeCommand.push_back("-clean");
} else {
- makeCommand.push_back(targetName);
+ if (targetName.compare(targetName.size() - 4, 4, ".gpj") == 0) {
+ makeCommand.push_back(targetName);
+ } else {
+ makeCommand.push_back(targetName + ".gpj");
+ }
}
}
}
-void cmGlobalGhsMultiGenerator::WriteMacros()
+void cmGlobalGhsMultiGenerator::WriteMacros(std::ostream& fout)
{
char const* ghsGpjMacros =
this->GetCMakeInstance()->GetCacheDefinition("GHS_GPJ_MACROS");
@@ -332,12 +426,12 @@ void cmGlobalGhsMultiGenerator::WriteMacros()
for (std::vector<std::string>::const_iterator expandedListI =
expandedList.begin();
expandedListI != expandedList.end(); ++expandedListI) {
- *this->GetBuildFileStream() << "macro " << *expandedListI << std::endl;
+ fout << "macro " << *expandedListI << std::endl;
}
}
}
-void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives()
+void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives(std::ostream& fout)
{
/* set primary target */
std::string tgt;
@@ -357,183 +451,46 @@ void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives()
tgt += ".tgt";
}
- *this->GetBuildFileStream() << "primaryTarget=" << tgt << std::endl;
+ fout << "primaryTarget=" << tgt << std::endl;
char const* const customization =
this->GetCMakeInstance()->GetCacheDefinition("GHS_CUSTOMIZATION");
if (NULL != customization && strlen(customization) > 0) {
- *this->GetBuildFileStream()
- << "customization=" << trimQuotes(customization) << std::endl;
+ fout << "customization=" << trimQuotes(customization) << std::endl;
this->GetCMakeInstance()->MarkCliAsUsed("GHS_CUSTOMIZATION");
}
}
-void cmGlobalGhsMultiGenerator::WriteCompilerOptions(std::string const& fOSDir)
-{
- *this->GetBuildFileStream()
- << " -os_dir=\"" << fOSDir << "\"" << std::endl;
-}
-
-void cmGlobalGhsMultiGenerator::WriteDisclaimer(std::ostream* os)
-{
- (*os) << "#" << std::endl
- << "# CMAKE generated file: DO NOT EDIT!" << std::endl
- << "# Generated by \"" << GetActualName() << "\""
- << " Generator, CMake Version " << cmVersion::GetMajorVersion() << "."
- << cmVersion::GetMinorVersion() << std::endl
- << "#" << std::endl;
-}
-
-void cmGlobalGhsMultiGenerator::AddFilesUpToPath(
- cmGeneratedFileStream* mainBuildFile,
- std::map<std::string, cmGeneratedFileStream*>* targetFolderBuildStreams,
- char const* homeOutputDirectory, std::string const& path,
- GhsMultiGpj::Types projType, std::string const& relPath)
+std::string cmGlobalGhsMultiGenerator::trimQuotes(std::string const& str)
{
- std::string workingPath(path);
- cmSystemTools::ConvertToUnixSlashes(workingPath);
- std::vector<std::string> splitPath = cmSystemTools::SplitString(workingPath);
- std::string workingRelPath(relPath);
- cmSystemTools::ConvertToUnixSlashes(workingRelPath);
- if (!workingRelPath.empty()) {
- workingRelPath += "/";
- }
- std::string pathUpTo;
- for (std::vector<std::string>::const_iterator splitPathI = splitPath.begin();
- splitPath.end() != splitPathI; ++splitPathI) {
- pathUpTo += *splitPathI;
- if (targetFolderBuildStreams->end() ==
- targetFolderBuildStreams->find(pathUpTo)) {
- AddFilesUpToPathNewBuildFile(
- mainBuildFile, targetFolderBuildStreams, homeOutputDirectory, pathUpTo,
- splitPath.begin() == splitPathI, workingRelPath, projType);
+ std::string result;
+ result.reserve(str.size());
+ for (const char* ch = str.c_str(); *ch != '\0'; ++ch) {
+ if (*ch != '"') {
+ result += *ch;
}
- AddFilesUpToPathAppendNextFile(targetFolderBuildStreams, pathUpTo,
- splitPathI, splitPath.end(), projType);
- pathUpTo += "/";
- }
-}
-
-void cmGlobalGhsMultiGenerator::Open(
- std::string const& mapKeyName, std::string const& fileName,
- std::map<std::string, cmGeneratedFileStream*>* fileMap)
-{
- if (fileMap->end() == fileMap->find(fileName)) {
- cmGeneratedFileStream* temp(new cmGeneratedFileStream);
- temp->open(fileName.c_str());
- (*fileMap)[mapKeyName] = temp;
- }
-}
-
-void cmGlobalGhsMultiGenerator::AddFilesUpToPathNewBuildFile(
- cmGeneratedFileStream* mainBuildFile,
- std::map<std::string, cmGeneratedFileStream*>* targetFolderBuildStreams,
- char const* homeOutputDirectory, std::string const& pathUpTo,
- bool const isFirst, std::string const& relPath,
- GhsMultiGpj::Types const projType)
-{
- // create folders up to file path
- std::string absPath = std::string(homeOutputDirectory) + "/" + relPath;
- std::string newPath = absPath + pathUpTo;
- if (!cmSystemTools::FileExists(newPath.c_str())) {
- cmSystemTools::MakeDirectory(newPath.c_str());
- }
-
- // Write out to filename for first time
- std::string relFilename(GetFileNameFromPath(pathUpTo));
- std::string absFilename = absPath + relFilename;
- Open(pathUpTo, absFilename, targetFolderBuildStreams);
- OpenBuildFileStream((*targetFolderBuildStreams)[pathUpTo]);
- GhsMultiGpj::WriteGpjTag(projType, (*targetFolderBuildStreams)[pathUpTo]);
- WriteDisclaimer((*targetFolderBuildStreams)[pathUpTo]);
-
- // Add to main build file
- if (isFirst) {
- *mainBuildFile << relFilename << " ";
- GhsMultiGpj::WriteGpjTag(projType, mainBuildFile);
- }
-}
-
-void cmGlobalGhsMultiGenerator::AddFilesUpToPathAppendNextFile(
- std::map<std::string, cmGeneratedFileStream*>* targetFolderBuildStreams,
- std::string const& pathUpTo,
- std::vector<std::string>::const_iterator splitPathI,
- std::vector<std::string>::const_iterator end,
- GhsMultiGpj::Types const projType)
-{
- std::vector<std::string>::const_iterator splitPathNextI = splitPathI + 1;
- if (end != splitPathNextI &&
- targetFolderBuildStreams->end() ==
- targetFolderBuildStreams->find(pathUpTo + "/" + *splitPathNextI)) {
- std::string nextFilename(*splitPathNextI);
- nextFilename = GetFileNameFromPath(nextFilename);
- *(*targetFolderBuildStreams)[pathUpTo] << nextFilename << " ";
- GhsMultiGpj::WriteGpjTag(projType, (*targetFolderBuildStreams)[pathUpTo]);
}
+ return result;
}
-std::string cmGlobalGhsMultiGenerator::GetFileNameFromPath(
- std::string const& path)
+bool cmGlobalGhsMultiGenerator::TargetCompare::operator()(
+ cmGeneratorTarget const* l, cmGeneratorTarget const* r) const
{
- std::string output(path);
- if (!path.empty()) {
- cmSystemTools::ConvertToUnixSlashes(output);
- std::vector<std::string> splitPath = cmSystemTools::SplitString(output);
- output += "/" + splitPath.back() + FILE_EXTENSION;
+ // Make sure a given named target is ordered first,
+ // e.g. to set ALL_BUILD as the default active project.
+ // When the empty string is named this is a no-op.
+ if (r->GetName() == this->First) {
+ return false;
}
- return output;
-}
-
-void cmGlobalGhsMultiGenerator::UpdateBuildFiles(
- const std::vector<cmGeneratorTarget*>& tgts)
-{
- for (std::vector<cmGeneratorTarget*>::const_iterator tgtsI = tgts.begin();
- tgtsI != tgts.end(); ++tgtsI) {
- const cmGeneratorTarget* tgt = *tgtsI;
- if (IsTgtForBuild(tgt)) {
- std::string folderName = tgt->GetEffectiveFolderName();
- if (this->TargetFolderBuildStreams.end() ==
- this->TargetFolderBuildStreams.find(folderName)) {
- this->AddFilesUpToPath(
- GetBuildFileStream(), &this->TargetFolderBuildStreams,
- this->GetCMakeInstance()->GetHomeOutputDirectory().c_str(),
- folderName, GhsMultiGpj::PROJECT);
- }
- std::vector<std::string> splitPath = cmSystemTools::SplitString(
- cmGhsMultiTargetGenerator::GetRelBuildFileName(tgt));
- std::string foldNameRelBuildFile(*(splitPath.end() - 2) + "/" +
- splitPath.back());
- *this->TargetFolderBuildStreams[folderName] << foldNameRelBuildFile
- << " ";
- GhsMultiGpj::WriteGpjTag(cmGhsMultiTargetGenerator::GetGpjTag(tgt),
- this->TargetFolderBuildStreams[folderName]);
- }
+ if (l->GetName() == this->First) {
+ return true;
}
+ return l->GetName() < r->GetName();
}
-bool cmGlobalGhsMultiGenerator::IsTgtForBuild(const cmGeneratorTarget* tgt)
+cmGlobalGhsMultiGenerator::OrderedTargetDependSet::OrderedTargetDependSet(
+ TargetDependSet const& targets, std::string const& first)
+ : derived(TargetCompare(first))
{
- const std::string config =
- tgt->Target->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
- std::vector<cmSourceFile*> tgtSources;
- tgt->GetSourceFiles(tgtSources, config);
- bool tgtInBuild = true;
- char const* excludeFromAll = tgt->GetProperty("EXCLUDE_FROM_ALL");
- if (NULL != excludeFromAll && '1' == excludeFromAll[0] &&
- '\0' == excludeFromAll[1]) {
- tgtInBuild = false;
- }
- return !tgtSources.empty() && tgtInBuild;
-}
-
-std::string cmGlobalGhsMultiGenerator::trimQuotes(std::string const& str)
-{
- std::string result;
- result.reserve(str.size());
- for (const char* ch = str.c_str(); *ch != '\0'; ++ch) {
- if (*ch != '"') {
- result += *ch;
- }
- }
- return result;
+ this->insert(targets.begin(), targets.end());
}
diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h
index a5aff73..9332567 100644
--- a/Source/cmGlobalGhsMultiGenerator.h
+++ b/Source/cmGlobalGhsMultiGenerator.h
@@ -13,7 +13,7 @@ class cmGeneratedFileStream;
class cmGlobalGhsMultiGenerator : public cmGlobalGenerator
{
public:
- /// The default name of GHS MULTI's build file. Typically: monolith.gpj.
+ // The default filename extension of GHS MULTI's build files.
static const char* FILE_EXTENSION;
cmGlobalGhsMultiGenerator(cmake* cm);
@@ -63,29 +63,28 @@ public:
*/
bool FindMakeProgram(cmMakefile* mf) override;
- cmGeneratedFileStream* GetBuildFileStream()
- {
- return this->TargetFolderBuildStreams[""];
- }
+ void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const override;
- static void OpenBuildFileStream(std::string const& filepath,
- cmGeneratedFileStream** filestream);
- static void OpenBuildFileStream(cmGeneratedFileStream* filestream);
- static void CloseBuildFileStream(cmGeneratedFileStream** filestream);
- /// Write the common disclaimer text at the top of each build file.
- static void WriteDisclaimer(std::ostream* os);
- std::vector<std::string> GetLibDirs() { return this->LibDirs; }
-
- static void AddFilesUpToPath(
- cmGeneratedFileStream* mainBuildFile,
- std::map<std::string, cmGeneratedFileStream*>* targetFolderBuildStreams,
- char const* homeOutputDirectory, std::string const& path,
- GhsMultiGpj::Types projType, std::string const& relPath = "");
- static void Open(std::string const& mapKeyName, std::string const& fileName,
- std::map<std::string, cmGeneratedFileStream*>* fileMap);
-
- static std::string trimQuotes(std::string const& str);
- inline bool IsOSDirRelative() { return this->OSDirRelative; }
+ // Write the common disclaimer text at the top of each build file.
+ void WriteFileHeader(std::ostream& fout);
+
+ // Target dependency sorting
+ class TargetSet : public std::set<cmGeneratorTarget const*>
+ {
+ };
+ class TargetCompare
+ {
+ std::string First;
+
+ public:
+ TargetCompare(std::string const& first)
+ : First(first)
+ {
+ }
+ bool operator()(cmGeneratorTarget const* l,
+ cmGeneratorTarget const* r) const;
+ };
+ class OrderedTargetDependSet;
protected:
void Generate() override;
@@ -100,35 +99,35 @@ protected:
std::vector<std::string>()) override;
private:
- void GetToolset(cmMakefile* mf, std::string& tsd, std::string& ts);
- void OpenBuildFileStream();
-
- void WriteMacros();
- void WriteHighLevelDirectives();
- void WriteCompilerOptions(std::string const& fOSDir);
-
- static void AddFilesUpToPathNewBuildFile(
- cmGeneratedFileStream* mainBuildFile,
- std::map<std::string, cmGeneratedFileStream*>* targetFolderBuildStreams,
- char const* homeOutputDirectory, std::string const& pathUpTo, bool isFirst,
- std::string const& relPath, GhsMultiGpj::Types projType);
- static void AddFilesUpToPathAppendNextFile(
- std::map<std::string, cmGeneratedFileStream*>* targetFolderBuildStreams,
- std::string const& pathUpTo,
- std::vector<std::string>::const_iterator splitPathI,
- std::vector<std::string>::const_iterator end, GhsMultiGpj::Types projType);
- static std::string GetFileNameFromPath(std::string const& path);
- void UpdateBuildFiles(const std::vector<cmGeneratorTarget*>& tgts);
- bool IsTgtForBuild(const cmGeneratorTarget* tgt);
-
- std::vector<cmGeneratedFileStream*> TargetSubProjects;
- std::map<std::string, cmGeneratedFileStream*> TargetFolderBuildStreams;
-
- std::vector<std::string> LibDirs;
-
- bool OSDirRelative;
+ void GetToolset(cmMakefile* mf, std::string& tsd, const std::string& ts);
+
+ /* top-level project */
+ void OutputTopLevelProject(cmLocalGenerator* root,
+ std::vector<cmLocalGenerator*>& generators);
+ void WriteTopLevelProject(std::ostream& fout, cmLocalGenerator* root,
+ std::vector<cmLocalGenerator*>& generators);
+ void WriteMacros(std::ostream& fout);
+ void WriteHighLevelDirectives(std::ostream& fout);
+ void WriteSubProjects(std::ostream& fout, cmLocalGenerator* root,
+ std::vector<cmLocalGenerator*>& generators);
+
+ std::string trimQuotes(std::string const& str);
+
static const char* DEFAULT_BUILD_PROGRAM;
static const char* DEFAULT_TOOLSET_ROOT;
};
+class cmGlobalGhsMultiGenerator::OrderedTargetDependSet
+ : public std::multiset<cmTargetDepend,
+ cmGlobalGhsMultiGenerator::TargetCompare>
+{
+ typedef std::multiset<cmTargetDepend,
+ cmGlobalGhsMultiGenerator::TargetCompare>
+ derived;
+
+public:
+ typedef cmGlobalGenerator::TargetDependSet TargetDependSet;
+ OrderedTargetDependSet(TargetDependSet const&, std::string const& first);
+};
+
#endif
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 57d341a..e7b0981 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -1939,7 +1939,7 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
}
}
- cmake cm(cmake::RoleInternal);
+ cmake cm(cmake::RoleInternal, cmState::Unknown);
cm.SetHomeDirectory(dir_top_src);
cm.SetHomeOutputDirectory(dir_top_bld);
std::unique_ptr<cmGlobalNinjaGenerator> ggd(
diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx
index 199c8e2..4b60279 100644
--- a/Source/cmGraphVizWriter.cxx
+++ b/Source/cmGraphVizWriter.cxx
@@ -13,6 +13,7 @@
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
@@ -172,7 +173,7 @@ cmGraphVizWriter::cmGraphVizWriter(const cmGlobalGenerator* globalGenerator)
void cmGraphVizWriter::ReadSettings(const char* settingsFileName,
const char* fallbackSettingsFileName)
{
- cmake cm(cmake::RoleScript);
+ cmake cm(cmake::RoleScript, cmState::Unknown);
cm.SetHomeDirectory("");
cm.SetHomeOutputDirectory("");
cm.GetCurrentSnapshot().SetDefaultDefinitions();
diff --git a/Source/cmLocalGhsMultiGenerator.cxx b/Source/cmLocalGhsMultiGenerator.cxx
index ab6774e..125e8b5 100644
--- a/Source/cmLocalGhsMultiGenerator.cxx
+++ b/Source/cmLocalGhsMultiGenerator.cxx
@@ -7,6 +7,7 @@
#include "cmGhsMultiTargetGenerator.h"
#include "cmGlobalGhsMultiGenerator.h"
#include "cmMakefile.h"
+#include "cmSourceFile.h"
cmLocalGhsMultiGenerator::cmLocalGhsMultiGenerator(cmGlobalGenerator* gg,
cmMakefile* mf)
@@ -18,16 +19,82 @@ cmLocalGhsMultiGenerator::~cmLocalGhsMultiGenerator()
{
}
+std::string cmLocalGhsMultiGenerator::GetTargetDirectory(
+ cmGeneratorTarget const* target) const
+{
+ std::string dir;
+ dir += target->GetName();
+ dir += ".dir";
+ return dir;
+}
+
+void cmLocalGhsMultiGenerator::GenerateTargetsDepthFirst(
+ cmGeneratorTarget* target, std::vector<cmGeneratorTarget*>& remaining)
+{
+ if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+ return;
+ }
+ // Find this target in the list of remaining targets.
+ auto it = std::find(remaining.begin(), remaining.end(), target);
+ if (it == remaining.end()) {
+ // This target was already handled.
+ return;
+ }
+ // Remove this target from the list of remaining targets because
+ // we are handling it now.
+ *it = nullptr;
+
+ cmGhsMultiTargetGenerator tg(target);
+ tg.Generate();
+}
+
void cmLocalGhsMultiGenerator::Generate()
{
- const std::vector<cmGeneratorTarget*>& tgts = this->GetGeneratorTargets();
+ std::vector<cmGeneratorTarget*> remaining = this->GetGeneratorTargets();
+ for (auto& t : remaining) {
+ if (t) {
+ GenerateTargetsDepthFirst(t, remaining);
+ }
+ }
+}
+
+void cmLocalGhsMultiGenerator::ComputeObjectFilenames(
+ std::map<cmSourceFile const*, std::string>& mapping,
+ cmGeneratorTarget const* gt)
+{
+ std::string dir_max;
+ dir_max += this->GetCurrentBinaryDirectory();
+ dir_max += "/";
+ dir_max += this->GetTargetDirectory(gt);
+ dir_max += "/";
+
+ // Count the number of object files with each name. Note that
+ // filesystem may not be case sensitive.
+ std::map<std::string, int> counts;
+
+ for (auto const& si : mapping) {
+ cmSourceFile const* sf = si.first;
+ std::string objectNameLower = cmSystemTools::LowerCase(
+ cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()));
+ objectNameLower += this->GlobalGenerator->GetLanguageOutputExtension(*sf);
+ counts[objectNameLower] += 1;
+ }
+
+ // For all source files producing duplicate names we need unique
+ // object name computation.
+ for (auto& si : mapping) {
+ cmSourceFile const* sf = si.first;
+ std::string objectName =
+ cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath());
+ objectName += this->GlobalGenerator->GetLanguageOutputExtension(*sf);
- for (std::vector<cmGeneratorTarget*>::const_iterator l = tgts.begin();
- l != tgts.end(); ++l) {
- if ((*l)->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
- continue;
+ if (counts[cmSystemTools::LowerCase(objectName)] > 1) {
+ const_cast<cmGeneratorTarget*>(gt)->AddExplicitObjectName(sf);
+ bool keptSourceExtension;
+ objectName = this->GetObjectFileNameWithoutTarget(*sf, dir_max,
+ &keptSourceExtension);
+ cmsys::SystemTools::ReplaceString(objectName, "/", "_");
}
- cmGhsMultiTargetGenerator tg(*l);
- tg.Generate();
+ si.second = objectName;
}
}
diff --git a/Source/cmLocalGhsMultiGenerator.h b/Source/cmLocalGhsMultiGenerator.h
index aa842d7..d5bec42 100644
--- a/Source/cmLocalGhsMultiGenerator.h
+++ b/Source/cmLocalGhsMultiGenerator.h
@@ -24,6 +24,17 @@ public:
* Generate the makefile for this directory.
*/
virtual void Generate();
+
+ std::string GetTargetDirectory(
+ cmGeneratorTarget const* target) const override;
+
+ void ComputeObjectFilenames(
+ std::map<cmSourceFile const*, std::string>& mapping,
+ cmGeneratorTarget const* gt = nullptr) override;
+
+private:
+ void GenerateTargetsDepthFirst(cmGeneratorTarget* target,
+ std::vector<cmGeneratorTarget*>& remaining);
};
#endif
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 274c631..3ff576e 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -3374,7 +3374,7 @@ int cmMakefile::TryCompile(const std::string& srcdir,
// make sure the same generator is used
// use this program as the cmake to be run, it should not
// be run that way but the cmake object requires a vailid path
- cmake cm(cmake::RoleProject);
+ cmake cm(cmake::RoleProject, cmState::Project);
cm.SetIsInTryCompile(true);
cmGlobalGenerator* gg =
cm.CreateGlobalGenerator(this->GetGlobalGenerator()->GetName());
diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx
index f2f4cad..c5d5d7c 100644
--- a/Source/cmQtAutoGenerator.cxx
+++ b/Source/cmQtAutoGenerator.cxx
@@ -8,6 +8,7 @@
#include "cmAlgorithms.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
+#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmSystemTools.h"
@@ -686,7 +687,7 @@ bool cmQtAutoGenerator::Run(std::string const& infoFile,
bool success = false;
{
- cmake cm(cmake::RoleScript);
+ cmake cm(cmake::RoleScript, cmState::Unknown);
cm.SetHomeOutputDirectory(InfoDir());
cm.SetHomeDirectory(InfoDir());
cm.GetCurrentSnapshot().SetDefaultDefinitions();
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
index 6dbfd10..11a3f46 100644
--- a/Source/cmServerProtocol.cxx
+++ b/Source/cmServerProtocol.cxx
@@ -130,7 +130,8 @@ bool cmServerProtocol::Activate(cmServer* server,
{
assert(server);
this->m_Server = server;
- this->m_CMakeInstance = cm::make_unique<cmake>(cmake::RoleProject);
+ this->m_CMakeInstance =
+ cm::make_unique<cmake>(cmake::RoleProject, cmState::Project);
const bool result = this->DoActivate(request, errorMessage);
if (!result) {
this->m_CMakeInstance = nullptr;
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index f664000..d4d3df5 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -539,6 +539,9 @@ const char* cmState::GetGlobalProperty(const std::string& prop)
std::string langs;
langs = cmJoin(this->EnabledLanguages, ";");
this->SetGlobalProperty("ENABLED_LANGUAGES", langs.c_str());
+ } else if (prop == "CMAKE_ROLE") {
+ std::string mode = this->GetModeString();
+ this->SetGlobalProperty("CMAKE_ROLE", mode.c_str());
}
#define STRING_LIST_ELEMENT(F) ";" #F
if (prop == "CMAKE_C_KNOWN_FEATURES") {
@@ -593,6 +596,16 @@ bool cmState::UseWindowsVSIDE() const
return this->WindowsVSIDE;
}
+void cmState::SetGhsMultiIDE(bool ghsMultiIDE)
+{
+ this->GhsMultiIDE = ghsMultiIDE;
+}
+
+bool cmState::UseGhsMultiIDE() const
+{
+ return this->GhsMultiIDE;
+}
+
void cmState::SetWatcomWMake(bool watcomWMake)
{
this->WatcomWMake = watcomWMake;
@@ -643,6 +656,40 @@ unsigned int cmState::GetCacheMinorVersion() const
return this->CacheManager->GetCacheMinorVersion();
}
+cmState::Mode cmState::GetMode() const
+{
+ return this->CurrentMode;
+}
+
+std::string cmState::GetModeString() const
+{
+ return ModeToString(this->CurrentMode);
+}
+
+void cmState::SetMode(cmState::Mode mode)
+{
+ this->CurrentMode = mode;
+}
+
+std::string cmState::ModeToString(cmState::Mode mode)
+{
+ switch (mode) {
+ case Project:
+ return "PROJECT";
+ case Script:
+ return "SCRIPT";
+ case FindPackage:
+ return "FIND_PACKAGE";
+ case CTest:
+ return "CTEST";
+ case CPack:
+ return "CPACK";
+ case Unknown:
+ return "UNKNOWN";
+ }
+ return "UNKNOWN";
+}
+
std::string const& cmState::GetBinaryDirectory() const
{
return this->BinaryDirectory;
diff --git a/Source/cmState.h b/Source/cmState.h
index abe93ed..e447485 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -35,6 +35,16 @@ public:
cmState();
~cmState();
+ enum Mode
+ {
+ Unknown,
+ Project,
+ Script,
+ FindPackage,
+ CTest,
+ CPack,
+ };
+
static const char* GetTargetTypeName(cmStateEnums::TargetType targetType);
cmStateSnapshot CreateBaseSnapshot();
@@ -154,6 +164,8 @@ public:
bool UseWindowsShell() const;
void SetWindowsVSIDE(bool windowsVSIDE);
bool UseWindowsVSIDE() const;
+ void SetGhsMultiIDE(bool ghsMultiIDE);
+ bool UseGhsMultiIDE() const;
void SetWatcomWMake(bool watcomWMake);
bool UseWatcomWMake() const;
void SetMinGWMake(bool minGWMake);
@@ -166,6 +178,12 @@ public:
unsigned int GetCacheMajorVersion() const;
unsigned int GetCacheMinorVersion() const;
+ Mode GetMode() const;
+ std::string GetModeString() const;
+ void SetMode(Mode mode);
+
+ static std::string ModeToString(Mode mode);
+
private:
friend class cmake;
void AddCacheEntry(const std::string& key, const char* value,
@@ -206,10 +224,12 @@ private:
bool IsGeneratorMultiConfig = false;
bool WindowsShell = false;
bool WindowsVSIDE = false;
+ bool GhsMultiIDE = false;
bool WatcomWMake = false;
bool MinGWMake = false;
bool NMake = false;
bool MSYSShell = false;
+ Mode CurrentMode = Unknown;
};
#endif
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index be65853..52957c1 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -3114,7 +3114,8 @@ std::string cmSystemTools::EncodeURL(std::string const& in, bool escapeSlashes)
}
bool cmSystemTools::CreateSymlink(const std::string& origName,
- const std::string& newName)
+ const std::string& newName,
+ std::string* errorMessage)
{
uv_fs_t req;
int flags = 0;
@@ -3128,7 +3129,32 @@ bool cmSystemTools::CreateSymlink(const std::string& origName,
if (err) {
std::string e =
"failed to create symbolic link '" + newName + "': " + uv_strerror(err);
- cmSystemTools::Error(e.c_str());
+ if (errorMessage) {
+ *errorMessage = std::move(e);
+ } else {
+ cmSystemTools::Error(e.c_str());
+ }
+ return false;
+ }
+
+ return true;
+}
+
+bool cmSystemTools::CreateLink(const std::string& origName,
+ const std::string& newName,
+ std::string* errorMessage)
+{
+ uv_fs_t req;
+ int err =
+ uv_fs_link(nullptr, &req, origName.c_str(), newName.c_str(), nullptr);
+ if (err) {
+ std::string e =
+ "failed to create link '" + newName + "': " + uv_strerror(err);
+ if (errorMessage) {
+ *errorMessage = std::move(e);
+ } else {
+ cmSystemTools::Error(e.c_str());
+ }
return false;
}
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index c0999e7..489811d 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -528,7 +528,14 @@ public:
/** Create a symbolic link if the platform supports it. Returns whether
creation succeeded. */
static bool CreateSymlink(const std::string& origName,
- const std::string& newName);
+ const std::string& newName,
+ std::string* errorMessage = nullptr);
+
+ /** Create a hard link if the platform supports it. Returns whether
+ creation succeeded. */
+ static bool CreateLink(const std::string& origName,
+ const std::string& newName,
+ std::string* errorMessage = nullptr);
private:
static bool s_ForceUnixPaths;
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index dd90269..ac4a4f5 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -2283,6 +2283,58 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions(
e1.Element("_ProjectFileVersion", "10.0.20506.1");
for (std::string const& config : this->Configurations) {
const std::string cond = this->CalcCondition(config);
+
+ if (ttype <= cmStateEnums::UTILITY) {
+ if (const char* workingDir = this->GeneratorTarget->GetProperty(
+ "VS_DEBUGGER_WORKING_DIRECTORY")) {
+ cmGeneratorExpression ge;
+ std::unique_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(workingDir);
+ std::string genWorkingDir =
+ cge->Evaluate(this->LocalGenerator, config);
+
+ e1.WritePlatformConfigTag("LocalDebuggerWorkingDirectory", cond,
+ genWorkingDir);
+ }
+
+ if (const char* environment =
+ this->GeneratorTarget->GetProperty("VS_DEBUGGER_ENVIRONMENT")) {
+ cmGeneratorExpression ge;
+ std::unique_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(environment);
+ std::string genEnvironment =
+ cge->Evaluate(this->LocalGenerator, config);
+
+ e1.WritePlatformConfigTag("LocalDebuggerEnvironment", cond,
+ genEnvironment);
+ }
+
+ if (const char* debuggerCommand =
+ this->GeneratorTarget->GetProperty("VS_DEBUGGER_COMMAND")) {
+
+ cmGeneratorExpression ge;
+ std::unique_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(debuggerCommand);
+ std::string genDebuggerCommand =
+ cge->Evaluate(this->LocalGenerator, config);
+
+ e1.WritePlatformConfigTag("LocalDebuggerCommand", cond,
+ genDebuggerCommand);
+ }
+
+ if (const char* commandArguments = this->GeneratorTarget->GetProperty(
+ "VS_DEBUGGER_COMMAND_ARGUMENTS")) {
+ cmGeneratorExpression ge;
+ std::unique_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(commandArguments);
+ std::string genCommandArguments =
+ cge->Evaluate(this->LocalGenerator, config);
+
+ e1.WritePlatformConfigTag("LocalDebuggerCommandArguments", cond,
+ genCommandArguments);
+ }
+ }
+
if (ttype >= cmStateEnums::UTILITY) {
e1.WritePlatformConfigTag(
"IntDir", cond, "$(Platform)\\$(Configuration)\\$(ProjectName)\\");
@@ -2347,55 +2399,6 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions(
e1.WritePlatformConfigTag("ExcludePath", cond, sdkExcludeDirectories);
}
- if (const char* workingDir = this->GeneratorTarget->GetProperty(
- "VS_DEBUGGER_WORKING_DIRECTORY")) {
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(workingDir);
- std::string genWorkingDir =
- cge->Evaluate(this->LocalGenerator, config);
-
- e1.WritePlatformConfigTag("LocalDebuggerWorkingDirectory", cond,
- genWorkingDir);
- }
-
- if (const char* environment =
- this->GeneratorTarget->GetProperty("VS_DEBUGGER_ENVIRONMENT")) {
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(environment);
- std::string genEnvironment =
- cge->Evaluate(this->LocalGenerator, config);
-
- e1.WritePlatformConfigTag("LocalDebuggerEnvironment", cond,
- genEnvironment);
- }
-
- if (const char* debuggerCommand =
- this->GeneratorTarget->GetProperty("VS_DEBUGGER_COMMAND")) {
-
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(debuggerCommand);
- std::string genDebuggerCommand =
- cge->Evaluate(this->LocalGenerator, config);
-
- e1.WritePlatformConfigTag("LocalDebuggerCommand", cond,
- genDebuggerCommand);
- }
-
- if (const char* commandArguments = this->GeneratorTarget->GetProperty(
- "VS_DEBUGGER_COMMAND_ARGUMENTS")) {
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(commandArguments);
- std::string genCommandArguments =
- cge->Evaluate(this->LocalGenerator, config);
-
- e1.WritePlatformConfigTag("LocalDebuggerCommandArguments", cond,
- genCommandArguments);
- }
-
std::string name =
cmSystemTools::GetFilenameWithoutLastExtension(targetNameFull);
e1.WritePlatformConfigTag("TargetName", cond, name);
@@ -2620,6 +2623,10 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
}
clOptions.AddDefines(targetDefines);
+ if (this->ProjectType == csproj) {
+ clOptions.AppendFlag("DefineConstants", targetDefines);
+ }
+
// Get includes for this target
if (!this->LangForClCompile.empty()) {
clOptions.AddIncludes(
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index c65bd2e..9fcfbde 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -126,7 +126,7 @@ void cmWarnUnusedCliWarning(const std::string& variable, int /*unused*/,
cm->MarkCliAsUsed(variable);
}
-cmake::cmake(Role role)
+cmake::cmake(Role role, cmState::Mode mode)
{
this->Trace = false;
this->TraceExpand = false;
@@ -140,6 +140,7 @@ cmake::cmake(Role role)
this->FileComparison = new cmFileTimeComparison;
this->State = new cmState;
+ this->State->SetMode(mode);
this->CurrentSnapshot = this->State->CreateBaseSnapshot();
this->Messenger = new cmMessenger;
@@ -2023,7 +2024,8 @@ int cmake::CheckBuildSystem()
// Read the rerun check file and use it to decide whether to do the
// global generate.
- cmake cm(RoleScript); // Actually, all we need is the `set` command.
+ // Actually, all we need is the `set` command.
+ cmake cm(RoleScript, cmState::Unknown);
cm.SetHomeDirectory("");
cm.SetHomeOutputDirectory("");
cm.GetCurrentSnapshot().SetDefaultDefinitions();
diff --git a/Source/cmake.h b/Source/cmake.h
index 9891857..cd8c622 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -15,6 +15,7 @@
#include "cmInstalledFile.h"
#include "cmListFileCache.h"
#include "cmMessageType.h"
+#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
@@ -29,7 +30,6 @@ class cmGlobalGenerator;
class cmGlobalGeneratorFactory;
class cmMakefile;
class cmMessenger;
-class cmState;
class cmVariableWatch;
struct cmDocumentationEntry;
@@ -113,7 +113,7 @@ public:
static const int DEFAULT_BUILD_PARALLEL_LEVEL = 0;
/// Default constructor
- cmake(Role role);
+ cmake(Role role, cmState::Mode mode);
/// Destructor
~cmake();
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index e52f2b3..84d1414 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -217,7 +217,7 @@ int do_cmake(int ac, char const* const* av)
doc.addCMakeStandardDocSections();
if (doc.CheckOptions(ac, av)) {
// Construct and print requested documentation.
- cmake hcm(cmake::RoleInternal);
+ cmake hcm(cmake::RoleInternal, cmState::Unknown);
hcm.SetHomeDirectory("");
hcm.SetHomeOutputDirectory("");
hcm.AddCMakePaths();
@@ -299,7 +299,7 @@ int do_cmake(int ac, char const* const* av)
}
}
if (sysinfo) {
- cmake cm(cmake::RoleProject);
+ cmake cm(cmake::RoleProject, cmState::Project);
cm.SetHomeDirectory("");
cm.SetHomeOutputDirectory("");
int ret = cm.GetSystemInformation(args);
@@ -307,7 +307,19 @@ int do_cmake(int ac, char const* const* av)
}
cmake::Role const role =
workingMode == cmake::SCRIPT_MODE ? cmake::RoleScript : cmake::RoleProject;
- cmake cm(role);
+ cmState::Mode mode = cmState::Unknown;
+ switch (workingMode) {
+ case cmake::NORMAL_MODE:
+ mode = cmState::Project;
+ break;
+ case cmake::SCRIPT_MODE:
+ mode = cmState::Script;
+ break;
+ case cmake::FIND_PACKAGE_MODE:
+ mode = cmState::FindPackage;
+ break;
+ }
+ cmake cm(role, mode);
cm.SetHomeDirectory("");
cm.SetHomeOutputDirectory("");
cmSystemTools::SetMessageCallback(cmakemainMessageCallback, &cm);
@@ -463,7 +475,7 @@ static int do_build(int ac, char const* const* av)
return 1;
}
- cmake cm(cmake::RoleInternal);
+ cmake cm(cmake::RoleInternal, cmState::Unknown);
cmSystemTools::SetMessageCallback(cmakemainMessageCallback, &cm);
cm.SetProgressCallback(cmakemainProgressCallback, &cm);
return cm.Build(jobs, dir, target, config, nativeOptions, clean);
@@ -501,7 +513,7 @@ static int do_open(int ac, char const* const* av)
return 1;
}
- cmake cm(cmake::RoleInternal);
+ cmake cm(cmake::RoleInternal, cmState::Unknown);
cmSystemTools::SetMessageCallback(cmakemainMessageCallback, &cm);
cm.SetProgressCallback(cmakemainProgressCallback, &cm);
return cm.Open(dir, false) ? 0 : 1;
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index b645ef1..ee8df35 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -9,6 +9,7 @@
#include "cmMakefile.h"
#include "cmQtAutoGeneratorMocUic.h"
#include "cmQtAutoGeneratorRcc.h"
+#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmSystemTools.h"
@@ -721,7 +722,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
std::cerr << "-E capabilities accepts no additional arguments\n";
return 1;
}
- cmake cm(cmake::RoleInternal);
+ cmake cm(cmake::RoleInternal, cmState::Unknown);
#if defined(CMAKE_BUILD_WITH_CMAKE)
std::cout << cm.ReportCapabilities(true);
#else
@@ -898,7 +899,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
const bool verbose = isCMakeVerbose();
// Create a cmake object instance to process dependencies.
- cmake cm(cmake::RoleScript); // All we need is the `set` command.
+ // All we need is the `set` command.
+ cmake cm(cmake::RoleScript, cmState::Unknown);
std::string gen;
std::string homeDir;
std::string startDir;