diff options
Diffstat (limited to 'Source')
162 files changed, 3939 insertions, 2299 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index a7adb51..6940187 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -281,6 +281,7 @@ set(SRCS cmInstallTargetGenerator.cxx cmInstallDirectoryGenerator.h cmInstallDirectoryGenerator.cxx + cmLinkedTree.h cmListFileCache.cxx cmListFileCache.h cmListFileLexer.c @@ -299,6 +300,8 @@ set(SRCS cmMakefileUtilityTargetGenerator.cxx cmOSXBundleGenerator.cxx cmOSXBundleGenerator.h + cmOutputConverter.cxx + cmOutputConverter.h cmNewLineStyle.h cmNewLineStyle.cxx cmOrderDirectories.cxx @@ -427,6 +430,7 @@ if (WIN32) set(SRCS ${SRCS} cmCallVisualStudioMacro.cxx cmCallVisualStudioMacro.h + bindexplib.cxx ) if(NOT UNIX) @@ -731,9 +735,17 @@ endif() include (${CMake_BINARY_DIR}/Source/LocalUserOptions.cmake OPTIONAL) include (${CMake_SOURCE_DIR}/Source/LocalUserOptions.cmake OPTIONAL) -install(TARGETS cmake ctest cpack DESTINATION bin) +# Install tools + +set(_tools cmake ctest cpack) + if(APPLE) - install(TARGETS cmakexbuild DESTINATION bin) + list(APPEND _tools cmakexbuild) endif() +foreach(_tool ${_tools}) + CMake_OPTIONAL_COMPONENT(${_tool}) + install(TARGETS ${_tool} DESTINATION bin ${COMPONENT}) +endforeach() + install(FILES cmCPluginAPI.h DESTINATION ${CMAKE_DATA_DIR}/include) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 4db774f..eadcb9e 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 2) -set(CMake_VERSION_PATCH 20150602) +set(CMake_VERSION_MINOR 3) +set(CMake_VERSION_PATCH 20150709) #set(CMake_VERSION_RC 1) diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx index e141b60..6dbb245 100644 --- a/Source/CTest/cmCTestBuildHandler.cxx +++ b/Source/CTest/cmCTestBuildHandler.cxx @@ -920,7 +920,7 @@ int cmCTestBuildHandler::RunMakeCommand(const char* command, char* data; int length; - cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_PROGRESS_OUTPUT, " Each symbol represents " << tick_len << " bytes of output." << std::endl << (this->UseCTestLaunch? "" : @@ -968,7 +968,7 @@ int cmCTestBuildHandler::RunMakeCommand(const char* command, this->ProcessBuffer(0, 0, tick, tick_len, ofs, &this->BuildProcessingQueue); this->ProcessBuffer(0, 0, tick, tick_len, ofs, &this->BuildProcessingErrorQueue); - cmCTestOptionalLog(this->CTest, OUTPUT, " Size of output: " + cmCTestOptionalLog(this->CTest, HANDLER_PROGRESS_OUTPUT, " Size of output: " << ((this->BuildOutputLogSize + 512) / 1024) << "K" << std::endl, this->Quiet); @@ -1175,12 +1175,12 @@ void cmCTestBuildHandler::ProcessBuffer(const char* data, int length, while ( this->BuildOutputLogSize > (tick * tick_len) ) { tick ++; - cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, this->LastTickChar, - this->Quiet); + cmCTestOptionalLog(this->CTest, HANDLER_PROGRESS_OUTPUT, + this->LastTickChar, this->Quiet); tickDisplayed = true; if ( tick % tick_line_len == 0 && tick > 0 ) { - cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Size: " + cmCTestOptionalLog(this->CTest, HANDLER_PROGRESS_OUTPUT, " Size: " << ((this->BuildOutputLogSize + 512) / 1024) << "K" << std::endl << " ", this->Quiet); } diff --git a/Source/CTest/cmCTestGenericHandler.cxx b/Source/CTest/cmCTestGenericHandler.cxx index 81eb0a8..ad79ba2 100644 --- a/Source/CTest/cmCTestGenericHandler.cxx +++ b/Source/CTest/cmCTestGenericHandler.cxx @@ -23,6 +23,7 @@ cmCTestGenericHandler::cmCTestGenericHandler() this->SubmitIndex = 0; this->AppendXML = false; this->Quiet = false; + this->TestLoad = 0; } //---------------------------------------------------------------------- @@ -70,6 +71,7 @@ void cmCTestGenericHandler::SetPersistentOption(const std::string& op, void cmCTestGenericHandler::Initialize() { this->AppendXML = false; + this->TestLoad = 0; this->Options.clear(); t_StringToString::iterator it; for ( it = this->PersistentOptions.begin(); diff --git a/Source/CTest/cmCTestGenericHandler.h b/Source/CTest/cmCTestGenericHandler.h index 8567dd7..4b7ae79 100644 --- a/Source/CTest/cmCTestGenericHandler.h +++ b/Source/CTest/cmCTestGenericHandler.h @@ -89,6 +89,8 @@ public: void SetAppendXML(bool b) { this->AppendXML = b; } void SetQuiet(bool b) { this->Quiet = b; } bool GetQuiet() { return this->Quiet; } + void SetTestLoad(unsigned long load) { this->TestLoad = load; } + unsigned long GetTestLoad() const { return this->TestLoad; } protected: bool StartResultingXML(cmCTest::Part part, @@ -97,6 +99,7 @@ protected: bool AppendXML; bool Quiet; + unsigned long TestLoad; cmSystemTools::OutputOption HandlerVerbose; cmCTest *CTest; t_StringToString Options; diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index bd090db..4832186 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -13,12 +13,15 @@ #include "cmProcess.h" #include "cmStandardIncludes.h" #include "cmCTest.h" +#include "cmCTestScriptHandler.h" #include "cmSystemTools.h" #include <stdlib.h> #include <stack> #include <list> #include <float.h> +#include <math.h> #include <cmsys/FStream.hxx> +#include <cmsys/SystemInformation.hxx> class TestComparator { @@ -40,10 +43,12 @@ private: cmCTestMultiProcessHandler::cmCTestMultiProcessHandler() { this->ParallelLevel = 1; + this->TestLoad = 0; this->Completed = 0; this->RunningCount = 0; this->StopTimePassed = false; this->HasCycles = false; + this->SerialTestRunning = false; } cmCTestMultiProcessHandler::~cmCTestMultiProcessHandler() @@ -83,6 +88,11 @@ void cmCTestMultiProcessHandler::SetParallelLevel(size_t level) this->ParallelLevel = level < 1 ? 1 : level; } +void cmCTestMultiProcessHandler::SetTestLoad(unsigned long load) +{ + this->TestLoad = load; +} + //--------------------------------------------------------- void cmCTestMultiProcessHandler::RunTests() { @@ -172,6 +182,11 @@ void cmCTestMultiProcessHandler::LockResources(int index) this->LockedResources.insert( this->Properties[index]->LockedResources.begin(), this->Properties[index]->LockedResources.end()); + + if (this->Properties[index]->RunSerial) + { + this->SerialTestRunning = true; + } } //--------------------------------------------------------- @@ -198,17 +213,20 @@ inline size_t cmCTestMultiProcessHandler::GetProcessorsUsed(int test) { size_t processors = static_cast<int>(this->Properties[test]->Processors); - //If this is set to run serially, it must run alone. - //Also, if processors setting is set higher than the -j + //If processors setting is set higher than the -j //setting, we default to using all of the process slots. - if(this->Properties[test]->RunSerial - || processors > this->ParallelLevel) + if (processors > this->ParallelLevel) { processors = this->ParallelLevel; } return processors; } +std::string cmCTestMultiProcessHandler::GetName(int test) +{ + return this->Properties[test]->Name; +} + //--------------------------------------------------------- bool cmCTestMultiProcessHandler::StartTest(int test) { @@ -248,22 +266,136 @@ void cmCTestMultiProcessHandler::StartNextTests() return; } + // Don't start any new tests if one with the RUN_SERIAL property + // is already running. + if (this->SerialTestRunning) + { + return; + } + + bool allTestsFailedTestLoadCheck = false; + bool usedFakeLoadForTesting = false; + size_t minProcessorsRequired = this->ParallelLevel; + std::string testWithMinProcessors = ""; + + cmsys::SystemInformation info; + + unsigned long systemLoad = 0; + size_t spareLoad = 0; + if (this->TestLoad > 0) + { + // Activate possible wait. + allTestsFailedTestLoadCheck = true; + + // Check for a fake load average value used in testing. + if (const char* fake_load_value = + cmSystemTools::GetEnv("__CTEST_FAKE_LOAD_AVERAGE_FOR_TESTING")) + { + usedFakeLoadForTesting = true; + if (!cmSystemTools::StringToULong(fake_load_value, &systemLoad)) + { + cmSystemTools::Error("Failed to parse fake load value: ", + fake_load_value); + } + } + // If it's not set, look up the true load average. + else + { + systemLoad = static_cast<unsigned long>(ceil(info.GetLoadAverage())); + } + spareLoad = (this->TestLoad > systemLoad ? + this->TestLoad - systemLoad : 0); + + // Don't start more tests than the spare load can support. + if (numToStart > spareLoad) + { + numToStart = spareLoad; + } + } + TestList copy = this->SortedTests; for(TestList::iterator test = copy.begin(); test != copy.end(); ++test) { + // Take a nap if we're currently performing a RUN_SERIAL test. + if (this->SerialTestRunning) + { + break; + } + // We can only start a RUN_SERIAL test if no other tests are also running. + if (this->Properties[*test]->RunSerial && this->RunningCount > 0) + { + continue; + } + size_t processors = GetProcessorsUsed(*test); + bool testLoadOk = true; + if (this->TestLoad > 0) + { + if (processors <= spareLoad) + { + cmCTestLog(this->CTest, DEBUG, + "OK to run " << GetName(*test) << + ", it requires " << processors << + " procs & system load is: " << + systemLoad << std::endl); + allTestsFailedTestLoadCheck = false; + } + else + { + testLoadOk = false; + } + } - if(processors <= numToStart && this->StartTest(*test)) + if (processors <= minProcessorsRequired) { - if(this->StopTimePassed) - { - return; - } - numToStart -= processors; + minProcessorsRequired = processors; + testWithMinProcessors = GetName(*test); + } + + if(testLoadOk && processors <= numToStart && this->StartTest(*test)) + { + if(this->StopTimePassed) + { + return; + } + + numToStart -= processors; } else if(numToStart == 0) { - return; + break; + } + } + + if (allTestsFailedTestLoadCheck) + { + cmCTestLog(this->CTest, HANDLER_OUTPUT, "***** WAITING, "); + if (this->SerialTestRunning) + { + cmCTestLog(this->CTest, HANDLER_OUTPUT, + "Waiting for RUN_SERIAL test to finish."); + } + else + { + cmCTestLog(this->CTest, HANDLER_OUTPUT, + "System Load: " << systemLoad << ", " + "Max Allowed Load: " << this->TestLoad << ", " + "Smallest test " << testWithMinProcessors << + " requires " << minProcessorsRequired); + } + cmCTestLog(this->CTest, HANDLER_OUTPUT, "*****" << std::endl); + + if (usedFakeLoadForTesting) + { + // Break out of the infinite loop of waiting for our fake load + // to come down. + this->StopTimePassed = true; + } + else + { + // Wait between 1 and 5 seconds before trying again. + cmCTestScriptHandler::SleepInSeconds( + cmSystemTools::RandomSeed() % 5 + 1); } } } @@ -319,6 +451,11 @@ bool cmCTestMultiProcessHandler::CheckOutput() this->WriteCheckpoint(test); this->UnlockResources(test); this->RunningCount -= GetProcessorsUsed(test); + if (this->Properties[test]->RunSerial) + { + this->SerialTestRunning = false; + } + delete p; } return true; diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h index 6440fbc..ed3e155 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.h +++ b/Source/CTest/cmCTestMultiProcessHandler.h @@ -37,6 +37,7 @@ public: void SetTests(TestMap& tests, PropertiesMap& properties); // Set the max number of tests that can be run at the same time. void SetParallelLevel(size_t); + void SetTestLoad(unsigned long load); virtual void RunTests(); void PrintTestList(); void PrintLabels(); @@ -93,6 +94,7 @@ protected: bool CheckCycles(); int FindMaxIndex(); inline size_t GetProcessorsUsed(int index); + std::string GetName(int index); void LockResources(int index); void UnlockResources(int index); @@ -116,11 +118,13 @@ protected: std::set<std::string> LockedResources; std::vector<cmCTestTestHandler::cmCTestTestResult>* TestResults; size_t ParallelLevel; // max number of process that can be run at once + unsigned long TestLoad; std::set<cmCTestRunTest*> RunningTests; // current running tests cmCTestTestHandler * TestHandler; cmCTest* CTest; bool HasCycles; bool Quiet; + bool SerialTestRunning; }; #endif diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index d9e4bd4..d108592 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -57,8 +57,7 @@ bool cmCTestRunTest::CheckOutput() // Process has terminated and all output read. return false; } - else if(p == cmsysProcess_Pipe_STDOUT || - p == cmsysProcess_Pipe_STDERR) + else if(p == cmsysProcess_Pipe_STDOUT) { // Store this line of output. cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx index 1e493b0..047bd98 100644 --- a/Source/CTest/cmCTestScriptHandler.cxx +++ b/Source/CTest/cmCTestScriptHandler.cxx @@ -421,6 +421,10 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg) this->Makefile->AddDefinition("CTEST_SCRIPT_ARG", script_arg.c_str()); } +#if defined(__CYGWIN__) + this->Makefile->AddDefinition("CMAKE_LEGACY_CYGWIN_WIN32", "0"); +#endif + // always add a function blocker to update the elapsed time cmCTestScriptFunctionBlocker *f = new cmCTestScriptFunctionBlocker(); f->CTestScriptHandler = this; diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx index 8b357ac..b7d8318 100644 --- a/Source/CTest/cmCTestTestCommand.cxx +++ b/Source/CTest/cmCTestTestCommand.cxx @@ -26,6 +26,7 @@ cmCTestTestCommand::cmCTestTestCommand() this->Arguments[ctt_PARALLEL_LEVEL] = "PARALLEL_LEVEL"; this->Arguments[ctt_SCHEDULE_RANDOM] = "SCHEDULE_RANDOM"; this->Arguments[ctt_STOP_TIME] = "STOP_TIME"; + this->Arguments[ctt_TEST_LOAD] = "TEST_LOAD"; this->Arguments[ctt_LAST] = 0; this->Last = ctt_LAST; } @@ -103,6 +104,38 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler() { this->CTest->SetStopTime(this->Values[ctt_STOP_TIME]); } + + // Test load is determined by: TEST_LOAD argument, + // or CTEST_TEST_LOAD script variable, or ctest --test-load + // command line argument... in that order. + unsigned long testLoad; + const char* ctestTestLoad + = this->Makefile->GetDefinition("CTEST_TEST_LOAD"); + if(this->Values[ctt_TEST_LOAD] && *this->Values[ctt_TEST_LOAD]) + { + if (!cmSystemTools::StringToULong(this->Values[ctt_TEST_LOAD], &testLoad)) + { + testLoad = 0; + cmCTestLog(this->CTest, WARNING, "Invalid value for 'TEST_LOAD' : " + << this->Values[ctt_TEST_LOAD] << std::endl); + } + } + else if(ctestTestLoad && *ctestTestLoad) + { + if (!cmSystemTools::StringToULong(ctestTestLoad, &testLoad)) + { + testLoad = 0; + cmCTestLog(this->CTest, WARNING, + "Invalid value for 'CTEST_TEST_LOAD' : " << + ctestTestLoad << std::endl); + } + } + else + { + testLoad = this->CTest->GetTestLoad(); + } + handler->SetTestLoad(testLoad); + handler->SetQuiet(this->Quiet); return handler; } diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h index a1e5f36..0dfca97 100644 --- a/Source/CTest/cmCTestTestCommand.h +++ b/Source/CTest/cmCTestTestCommand.h @@ -60,6 +60,7 @@ protected: ctt_PARALLEL_LEVEL, ctt_SCHEDULE_RANDOM, ctt_STOP_TIME, + ctt_TEST_LOAD, ctt_LAST }; }; diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 70b7f5c..5faf001 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -656,9 +656,8 @@ int cmCTestTestHandler::ProcessHandler() void cmCTestTestHandler::PrintLabelSummary() { cmCTestTestHandler::ListOfTests::iterator it = this->TestList.begin(); - cmCTestTestHandler::TestResultsVector::iterator ri = - this->TestResults.begin(); std::map<std::string, double> labelTimes; + std::map<std::string, int> labelCounts; std::set<std::string> labels; // initialize maps std::string::size_type maxlen = 0; @@ -676,10 +675,12 @@ void cmCTestTestHandler::PrintLabelSummary() } labels.insert(*l); labelTimes[*l] = 0; + labelCounts[*l] = 0; } } } - ri = this->TestResults.begin(); + cmCTestTestHandler::TestResultsVector::iterator ri = + this->TestResults.begin(); // fill maps for(; ri != this->TestResults.end(); ++ri) { @@ -691,6 +692,7 @@ void cmCTestTestHandler::PrintLabelSummary() l != p.Labels.end(); ++l) { labelTimes[*l] += result.ExecutionTime; + ++labelCounts[*l]; } } } @@ -705,10 +707,21 @@ void cmCTestTestHandler::PrintLabelSummary() { std::string label = *i; label.resize(maxlen +3, ' '); + char buf[1024]; sprintf(buf, "%6.2f sec", labelTimes[*i]); + + std::ostringstream labelCountStr; + labelCountStr << "(" << labelCounts[*i] << " test"; + if (labelCounts[*i] > 1) + { + labelCountStr << "s"; + } + labelCountStr << ")"; + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "\n" - << label << " = " << buf, this->Quiet ); + << label << " = " << buf << " " << labelCountStr.str(), + this->Quiet ); if ( this->LogFile ) { *this->LogFile << "\n" << *i << " = " @@ -1062,6 +1075,14 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<std::string> &passed, parallel->SetParallelLevel(this->CTest->GetParallelLevel()); parallel->SetTestHandler(this); parallel->SetQuiet(this->Quiet); + if(this->TestLoad > 0) + { + parallel->SetTestLoad(this->TestLoad); + } + else + { + parallel->SetTestLoad(this->CTest->GetTestLoad()); + } *this->LogFile << "Start testing: " << this->CTest->CurrentTime() << std::endl diff --git a/Source/CTest/cmCTestUpdateHandler.cxx b/Source/CTest/cmCTestUpdateHandler.cxx index 8494d28..963e501 100644 --- a/Source/CTest/cmCTestUpdateHandler.cxx +++ b/Source/CTest/cmCTestUpdateHandler.cxx @@ -283,13 +283,13 @@ int cmCTestUpdateHandler::ProcessHandler() { xml.Content("Update command failed:\n"); xml.Content(vc->GetUpdateCommandLine()); - cmCTestLog(this->CTest, ERROR_MESSAGE, " Update command failed: " + cmCTestLog(this->CTest, HANDLER_OUTPUT, " Update command failed: " << vc->GetUpdateCommandLine() << "\n"); } xml.EndElement(); // UpdateReturnStatus xml.EndElement(); // Update xml.EndDocument(); - return numUpdated; + return updated? numUpdated : -1; } //---------------------------------------------------------------------- diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx index e1bd02b..0c25f40 100644 --- a/Source/CTest/cmProcess.cxx +++ b/Source/CTest/cmProcess.cxx @@ -62,6 +62,7 @@ bool cmProcess::StartProcess() this->WorkingDirectory.c_str()); } cmsysProcess_SetTimeout(this->Process, this->Timeout); + cmsysProcess_SetOption(this->Process, cmsysProcess_Option_MergeOutput, 1); cmsysProcess_Execute(this->Process); return (cmsysProcess_GetState(this->Process) == cmsysProcess_State_Executing); @@ -124,14 +125,10 @@ int cmProcess::GetNextOutputLine(std::string& line, double timeout) for(;;) { // Look for lines already buffered. - if(this->StdOut.GetLine(line)) + if(this->Output.GetLine(line)) { return cmsysProcess_Pipe_STDOUT; } - else if(this->StdErr.GetLine(line)) - { - return cmsysProcess_Pipe_STDERR; - } // Check for more data from the process. char* data; @@ -143,11 +140,7 @@ int cmProcess::GetNextOutputLine(std::string& line, double timeout) } else if(p == cmsysProcess_Pipe_STDOUT) { - this->StdOut.insert(this->StdOut.end(), data, data+length); - } - else if(p == cmsysProcess_Pipe_STDERR) - { - this->StdErr.insert(this->StdErr.end(), data, data+length); + this->Output.insert(this->Output.end(), data, data+length); } else // p == cmsysProcess_Pipe_None { @@ -157,14 +150,10 @@ int cmProcess::GetNextOutputLine(std::string& line, double timeout) } // Look for partial last lines. - if(this->StdOut.GetLast(line)) + if(this->Output.GetLast(line)) { return cmsysProcess_Pipe_STDOUT; } - else if(this->StdErr.GetLast(line)) - { - return cmsysProcess_Pipe_STDERR; - } // No more data. Wait for process exit. if(!cmsysProcess_WaitForExit(this->Process, &timeout)) diff --git a/Source/CTest/cmProcess.h b/Source/CTest/cmProcess.h index 1479df0..eddeeab 100644 --- a/Source/CTest/cmProcess.h +++ b/Source/CTest/cmProcess.h @@ -48,8 +48,7 @@ public: * Read one line of output but block for no more than timeout. * Returns: * cmsysProcess_Pipe_None = Process terminated and all output read - * cmsysProcess_Pipe_STDOUT = Line came from stdout - * cmsysProcess_Pipe_STDOUT = Line came from stderr + * cmsysProcess_Pipe_STDOUT = Line came from stdout or stderr * cmsysProcess_Pipe_Timeout = Timeout expired while waiting */ int GetNextOutputLine(std::string& line, double timeout); @@ -68,13 +67,11 @@ private: bool GetLine(std::string& line); bool GetLast(std::string& line); }; - Buffer StdErr; - Buffer StdOut; + Buffer Output; std::string Command; std::string WorkingDirectory; std::vector<std::string> Arguments; std::vector<const char*> ProcessArgs; - std::string Output; int Id; int ExitValue; }; diff --git a/Source/CursesDialog/CMakeLists.txt b/Source/CursesDialog/CMakeLists.txt index 7d4e88c..93ff425 100644 --- a/Source/CursesDialog/CMakeLists.txt +++ b/Source/CursesDialog/CMakeLists.txt @@ -47,4 +47,5 @@ else() target_link_libraries(ccmake cmForm) endif() -install(TARGETS ccmake DESTINATION bin) +CMake_OPTIONAL_COMPONENT(ccmake) +install(TARGETS ccmake DESTINATION bin ${COMPONENT}) diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt index 168f57d..038c411 100644 --- a/Source/QtDialog/CMakeLists.txt +++ b/Source/QtDialog/CMakeLists.txt @@ -14,6 +14,7 @@ project(QtDialog) if(POLICY CMP0020) cmake_policy(SET CMP0020 NEW) # Drop when CMake >= 2.8.11 required endif() +CMake_OPTIONAL_COMPONENT(cmake-gui) find_package(Qt5Widgets QUIET) if (Qt5Widgets_FOUND) include_directories(${Qt5Widgets_INCLUDE_DIRS}) @@ -47,7 +48,8 @@ if (Qt5Widgets_FOUND) get_filename_component(_qt_plugin_type "${_qt_plugin_type}" NAME) set(_qt_plugin_dest "PlugIns/${_qt_plugin_type}") install(FILES "${_qt_plugin_path}" - DESTINATION "${_qt_plugin_dest}") + DESTINATION "${_qt_plugin_dest}" + ${COMPONENT}) set(${_qt_plugins_var} "${${_qt_plugins_var}};\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${_qt_plugin_dest}/${_qt_plugin_file}") else() @@ -58,7 +60,8 @@ if (Qt5Widgets_FOUND) file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf" "[Paths]\nPlugins = PlugIns\n") install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf" - DESTINATION "${CMAKE_INSTALL_PREFIX}/Resources") + DESTINATION "${CMAKE_INSTALL_PREFIX}/Resources" + ${COMPONENT}) endif() if(WIN32 AND TARGET Qt5::Core) @@ -130,7 +133,8 @@ endif() if(CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL) install(FILES ${CMake_SOURCE_DIR}/Licenses/LGPLv2.1.txt - DESTINATION ${CMAKE_DATA_DIR}/Licenses) + DESTINATION ${CMAKE_DATA_DIR}/Licenses + ${COMPONENT}) set_property(SOURCE CMakeSetupDialog.cxx PROPERTY COMPILE_DEFINITIONS CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL) endif() @@ -163,27 +167,36 @@ if(APPLE) ) endif() set(CMAKE_INSTALL_DESTINATION_ARGS - BUNDLE DESTINATION "${CMAKE_BUNDLE_LOCATION}") + BUNDLE DESTINATION "${CMAKE_BUNDLE_LOCATION}" ${COMPONENT}) -install(TARGETS cmake-gui RUNTIME DESTINATION bin ${CMAKE_INSTALL_DESTINATION_ARGS}) +install(TARGETS cmake-gui + RUNTIME DESTINATION bin ${COMPONENT} + ${CMAKE_INSTALL_DESTINATION_ARGS}) if(UNIX AND NOT APPLE) foreach (size IN ITEMS 32 128) install( FILES "${CMAKE_CURRENT_SOURCE_DIR}/CMakeSetup${size}.png" DESTINATION "share/icons/hicolor/${size}x${size}/apps" + ${COMPONENT} RENAME "CMakeSetup.png") endforeach () # install a desktop file so CMake appears in the application start menu # with an icon - install(FILES CMake.desktop DESTINATION share/applications ) - install(FILES cmakecache.xml DESTINATION share/mime/packages ) + install(FILES CMake.desktop + DESTINATION share/applications + ${COMPONENT}) + install(FILES cmakecache.xml + DESTINATION share/mime/packages + ${COMPONENT}) endif() if(APPLE) - install(CODE "execute_process(COMMAND ln -s \"../MacOS/CMake\" cmake-gui - WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin)") + install(CODE " + execute_process(COMMAND ln -s \"../MacOS/CMake\" cmake-gui + WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin) + " ${COMPONENT}) endif() if(APPLE OR WIN32) @@ -197,7 +210,7 @@ if(APPLE OR WIN32) include(\"${CMake_SOURCE_DIR}/Modules/BundleUtilities.cmake\") set(BU_CHMOD_BUNDLE_ITEMS ON) fixup_bundle(\"${fixup_exe}\" \"${QT_PLUGINS}\" \"${QT_LIBRARY_DIR};${QT_BINARY_DIR}\") - ") + " ${COMPONENT}) endif() set(CMAKE_PACKAGE_QTGUI TRUE) diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx index 38d6d44..4f93a77 100644 --- a/Source/QtDialog/CMakeSetup.cxx +++ b/Source/QtDialog/CMakeSetup.cxx @@ -86,7 +86,7 @@ int main(int argc, char** argv) #if defined(Q_OS_MAC) if (argc2 == 2 && strcmp(argv2[1], "--install") == 0) { - return cmOSXInstall("/usr/bin"); + return cmOSXInstall("/usr/local/bin"); } if (argc2 == 2 && cmHasLiteralPrefix(argv2[1], "--install=")) { diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx index 426fa12..03417f3 100644 --- a/Source/QtDialog/CMakeSetupDialog.cxx +++ b/Source/QtDialog/CMakeSetupDialog.cxx @@ -425,7 +425,7 @@ void CMakeSetupDialog::doInstallForCommandLine() "\n" " PATH=\"%1\":\"$PATH\"\n" "\n" - "Or, to install symlinks to '/usr/bin', run:\n" + "Or, to install symlinks to '/usr/local/bin', run:\n" "\n" " sudo \"%2\" --install\n" "\n" @@ -445,6 +445,7 @@ void CMakeSetupDialog::doInstallForCommandLine() l->addWidget(lab); lab->setText(msg); lab->setWordWrap(false); + lab->setTextInteractionFlags(Qt::TextSelectableByMouse); QDialogButtonBox* btns = new QDialogButtonBox(QDialogButtonBox::Ok, Qt::Horizontal, &dialog); QObject::connect(btns, SIGNAL(accepted()), &dialog, SLOT(accept())); diff --git a/Source/QtIFW/CMake.Dialogs.QtGUI.qs b/Source/QtIFW/CMake.Dialogs.QtGUI.qs new file mode 100644 index 0000000..219a0a9 --- /dev/null +++ b/Source/QtIFW/CMake.Dialogs.QtGUI.qs @@ -0,0 +1,21 @@ +// Component: CMake.Dialogs.QtGUI + +function Component() +{ + // Default constructor +} + +Component.prototype.createOperations = function() +{ + // Create shortcut + if (installer.value("os") === "win") { + + component.addOperation("CreateShortcut", + installer.value("TargetDir") + "/bin/cmake-gui.exe", + installer.value("StartMenuDir") + "/CMake (cmake-gui).lnk"); + + } + + // Call default implementation + component.createOperations(); +} diff --git a/Source/QtIFW/CMake.Documentation.SphinxHTML.qs.in b/Source/QtIFW/CMake.Documentation.SphinxHTML.qs.in new file mode 100644 index 0000000..5c929e8 --- /dev/null +++ b/Source/QtIFW/CMake.Documentation.SphinxHTML.qs.in @@ -0,0 +1,21 @@ +// Component: CMake.Documentation.SphinxHTML + +function Component() +{ + // Default constructor +} + +Component.prototype.createOperations = function() +{ + // Create shortcut + if (installer.value("os") === "win") { + + component.addOperation("CreateShortcut", + installer.value("TargetDir") + "/@CMAKE_DOC_DIR@/html/index.html", + installer.value("StartMenuDir") + "/CMake Documentation.lnk"); + + } + + // Call default implementation + component.createOperations(); +} diff --git a/Source/QtIFW/CMake.qs.in b/Source/QtIFW/CMake.qs.in new file mode 100644 index 0000000..828cc7c --- /dev/null +++ b/Source/QtIFW/CMake.qs.in @@ -0,0 +1,22 @@ +function Component() +{ + // Default constructor +} + +Component.prototype.createOperations = function() +{ + // Create shortcut + if (installer.value("os") === "win") { + + component.addOperation("CreateShortcut", + installer.value("TargetDir") + "/@CMAKE_DOC_DIR@/cmake.org.html", + installer.value("StartMenuDir") + "/CMake Web Site.lnk"); + + component.addOperation("CreateShortcut", + installer.value("TargetDir") + "/cmake-maintenance.exe", + installer.value("StartMenuDir") + "/CMake Maintenance Tool.lnk"); + } + + // Call default implementation + component.createOperations(); +} diff --git a/Source/QtIFW/installscript.qs.in b/Source/QtIFW/installscript.qs.in index 570dba1..3411e34 100644 --- a/Source/QtIFW/installscript.qs.in +++ b/Source/QtIFW/installscript.qs.in @@ -5,20 +5,20 @@ function Component() Component.prototype.createOperations = function() { - // call default implementation to actually install applications! - component.createOperations(); - // Create shortcut if (installer.value("os") === "win") { @_CPACK_IFW_SHORTCUT_OPTIONAL@ component.addOperation("CreateShortcut", - installer.value("TargetDir") + "/cmake.org.html", + installer.value("TargetDir") + "/@CMAKE_DOC_DIR@/cmake.org.html", installer.value("StartMenuDir") + "/CMake Web Site.lnk"); component.addOperation("CreateShortcut", installer.value("TargetDir") + "/cmake-maintenance.exe", installer.value("StartMenuDir") + "/CMake Maintenance Tool.lnk"); } + + // Call default implementation + component.createOperations(); } diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx new file mode 100644 index 0000000..11e3f34 --- /dev/null +++ b/Source/bindexplib.cxx @@ -0,0 +1,428 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2015 Kitware, Inc. + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +/*------------------------------------------------------------------------- + Portions of this source have been derived from the 'bindexplib' tool + provided by the CERN ROOT Data Analysis Framework project (root.cern.ch). + Permission has been granted by Pere Mato <pere.mato@cern.ch> to distribute + this derived work under the CMake license. +-------------------------------------------------------------------------*/ + +/* +*---------------------------------------------------------------------- +* Program: dumpexts.exe +* Author: Gordon Chaffee +* +* History: The real functionality of this file was written by +* Matt Pietrek in 1993 in his pedump utility. I've +* modified it to dump the externals in a bunch of object +* files to create a .def file. +* +* Notes: Visual C++ puts an underscore before each exported symbol. +* This file removes them. I don't know if this is a problem +* this other compilers. If _MSC_VER is defined, +* the underscore is removed. If not, it isn't. To get a +* full dump of an object file, use the -f option. This can +* help determine the something that may be different with a +* compiler other than Visual C++. +* ====================================== +* Corrections (Axel 2006-04-04): +* Conversion to C++. Mostly. +* + * Extension (Axel 2006-03-15) + * As soon as an object file contains an /EXPORT directive (which + * is generated by the compiler when a symbol is declared as + * declspec(dllexport)) no to-be-exported symbols are printed, + * as the linker will see these directives, and if those directives + * are present we only export selectively (i.e. we trust the + * programmer). + * + * ====================================== +* ====================================== +* Corrections (Valery Fine 23/02/98): +* +* The "(vector) deleting destructor" MUST not be exported +* To recognize it the following test are introduced: +* "@@UAEPAXI@Z" scalar deleting dtor +* "@@QAEPAXI@Z" vector deleting dtor +* "AEPAXI@Z" vector deleting dtor with thunk adjustor +* ====================================== +* Corrections (Valery Fine 12/02/97): +* +* It created a wrong EXPORTS for the global pointers and constants. +* The Section Header has been involved to discover the missing information +* Now the pointers are correctly supplied supplied with "DATA" descriptor +* the constants with no extra descriptor. +* +* Corrections (Valery Fine 16/09/96): +* +* It didn't work for C++ code with global variables and class definitons +* The DumpExternalObject function has been introduced to generate .DEF file +* +* Author: Valery Fine 16/09/96 (E-mail: fine@vxcern.cern.ch) +*---------------------------------------------------------------------- +*/ + +#include <cmsys/Encoding.hxx> +#include <windows.h> +#include <stdio.h> +#include <string> +#include <fstream> +#include <iostream> + +typedef struct cmANON_OBJECT_HEADER_BIGOBJ { + /* same as ANON_OBJECT_HEADER_V2 */ + WORD Sig1; // Must be IMAGE_FILE_MACHINE_UNKNOWN + WORD Sig2; // Must be 0xffff + WORD Version; // >= 2 (implies the Flags field is present) + WORD Machine; // Actual machine - IMAGE_FILE_MACHINE_xxx + DWORD TimeDateStamp; + CLSID ClassID; // {D1BAA1C7-BAEE-4ba9-AF20-FAF66AA4DCB8} + DWORD SizeOfData; // Size of data that follows the header + DWORD Flags; // 0x1 -> contains metadata + DWORD MetaDataSize; // Size of CLR metadata + DWORD MetaDataOffset; // Offset of CLR metadata + + /* bigobj specifics */ + DWORD NumberOfSections; // extended from WORD + DWORD PointerToSymbolTable; + DWORD NumberOfSymbols; +} cmANON_OBJECT_HEADER_BIGOBJ; + +typedef struct _cmIMAGE_SYMBOL_EX { + union { + BYTE ShortName[8]; + struct { + DWORD Short; // if 0, use LongName + DWORD Long; // offset into string table + } Name; + DWORD LongName[2]; // PBYTE [2] + } N; + DWORD Value; + LONG SectionNumber; + WORD Type; + BYTE StorageClass; + BYTE NumberOfAuxSymbols; +} cmIMAGE_SYMBOL_EX; +typedef cmIMAGE_SYMBOL_EX UNALIGNED *cmPIMAGE_SYMBOL_EX; + +PIMAGE_SECTION_HEADER GetSectionHeaderOffset(PIMAGE_FILE_HEADER + pImageFileHeader) +{ + return (PIMAGE_SECTION_HEADER) + ((DWORD_PTR)pImageFileHeader + + IMAGE_SIZEOF_FILE_HEADER + + pImageFileHeader->SizeOfOptionalHeader); +} + +PIMAGE_SECTION_HEADER GetSectionHeaderOffset(cmANON_OBJECT_HEADER_BIGOBJ* + pImageFileHeader) +{ + return (PIMAGE_SECTION_HEADER) + ((DWORD_PTR)pImageFileHeader + + sizeof(cmANON_OBJECT_HEADER_BIGOBJ)); +} + +/* ++ * Utility func, strstr with size ++ */ +const char* StrNStr(const char* start, const char* find, size_t &size) { + size_t len; + const char* hint; + + if (!start || !find || !size) { + size = 0; + return 0; + } + len = strlen(find); + + while ((hint = (const char*) memchr(start, find[0], size-len+1))) { + size -= (hint - start); + if (!strncmp(hint, find, len)) + return hint; + start = hint + 1; + } + + size = 0; + return 0; +} + +template < + // cmANON_OBJECT_HEADER_BIGOBJ or IMAGE_FILE_HEADER + class ObjectHeaderType, + // cmPIMAGE_SYMBOL_EX or PIMAGE_SYMBOL + class SymbolTableType> +class DumpSymbols +{ +public: + /* + *---------------------------------------------------------------------- + * Constructor -- + * + * Initialize variables from pointer to object header. + * + *---------------------------------------------------------------------- + */ + + DumpSymbols(ObjectHeaderType* ih, + FILE* fout) { + this->ObjectImageHeader = ih; + this->SymbolTable = (SymbolTableType*) + ((DWORD_PTR)this->ObjectImageHeader + + this->ObjectImageHeader->PointerToSymbolTable); + this->FileOut = fout; + this->SectionHeaders = + GetSectionHeaderOffset(this->ObjectImageHeader); + this->ImportFlag = true; + this->SymbolCount = this->ObjectImageHeader->NumberOfSymbols; + } + + /* + *---------------------------------------------------------------------- + * HaveExportedObjects -- + * + * Returns true if export directives (declspec(dllexport)) exist. + * + *---------------------------------------------------------------------- + */ + + bool HaveExportedObjects() { + WORD i = 0; + size_t size = 0; + const char * rawdata = 0; + PIMAGE_SECTION_HEADER pDirectivesSectionHeader = 0; + PIMAGE_SECTION_HEADER pSectionHeaders = this->SectionHeaders; + for(i = 0; (i < this->ObjectImageHeader->NumberOfSections && + !pDirectivesSectionHeader); i++) + if (!strncmp((const char*)&pSectionHeaders[i].Name[0], ".drectve",8)) + pDirectivesSectionHeader = &pSectionHeaders[i]; + if (!pDirectivesSectionHeader) return 0; + + rawdata=(const char*) + this->ObjectImageHeader+pDirectivesSectionHeader->PointerToRawData; + if (!pDirectivesSectionHeader->PointerToRawData || !rawdata) return 0; + + size = pDirectivesSectionHeader->SizeOfRawData; + const char* posImportFlag = rawdata; + while ((posImportFlag = StrNStr(posImportFlag, " /EXPORT:", size))) { + const char* lookingForDict = posImportFlag + 9; + if (!strncmp(lookingForDict, "_G__cpp_",8) || + !strncmp(lookingForDict, "_G__set_cpp_",12)) { + posImportFlag = lookingForDict; + continue; + } + + const char* lookingForDATA = posImportFlag + 9; + while (*(++lookingForDATA) && *lookingForDATA != ' '); + lookingForDATA -= 5; + // ignore DATA exports + if (strncmp(lookingForDATA, ",DATA", 5)) break; + posImportFlag = lookingForDATA + 5; + } + if(posImportFlag) { + return true; + } + return false; + } + + /* + *---------------------------------------------------------------------- + * DumpObjFile -- + * + * Dump an object file's exported symbols. + *---------------------------------------------------------------------- + */ + void DumpObjFile() { + if(!HaveExportedObjects()) { + this->DumpExternalsObjects(); + } + } + + /* + *---------------------------------------------------------------------- + * DumpExternalsObjects -- + * + * Dumps a COFF symbol table from an OBJ. + *---------------------------------------------------------------------- + */ + void DumpExternalsObjects() { + unsigned i; + PSTR stringTable; + std::string symbol; + DWORD SectChar; + /* + * The string table apparently starts right after the symbol table + */ + stringTable = (PSTR)&this->SymbolTable[this->SymbolCount]; + SymbolTableType* pSymbolTable = this->SymbolTable; + for ( i=0; i < this->SymbolCount; i++ ) { + if (pSymbolTable->SectionNumber > 0 && + ( pSymbolTable->Type == 0x20 || pSymbolTable->Type == 0x0)) { + if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) { + /* + * The name of the Function entry points + */ + if (pSymbolTable->N.Name.Short != 0) { + symbol = ""; + symbol.insert(0, (const char *)pSymbolTable->N.ShortName, 8); + } else { + symbol = stringTable + pSymbolTable->N.Name.Long; + } + + // clear out any leading spaces + while (isspace(symbol[0])) symbol.erase(0,1); + // if it starts with _ and has an @ then it is a __cdecl + // so remove the @ stuff for the export + if(symbol[0] == '_') { + std::string::size_type posAt = symbol.find('@'); + if (posAt != std::string::npos) { + symbol.erase(posAt); + } + } + if (symbol[0] == '_') symbol.erase(0,1); + if (this->ImportFlag) { + this->ImportFlag = false; + fprintf(this->FileOut,"EXPORTS \n"); + } + /* + Check whether it is "Scalar deleting destructor" and + "Vector deleting destructor" + */ + const char *scalarPrefix = "??_G"; + const char *vectorPrefix = "??_E"; + // original code had a check for + // symbol.find("real@") == std::string::npos) + // but if this disallows memmber functions with the name real + // if scalarPrefix and vectorPrefix are not found then print + // the symbol + if (symbol.compare(0, 4, scalarPrefix) && + symbol.compare(0, 4, vectorPrefix) ) + { + SectChar = + this-> + SectionHeaders[pSymbolTable->SectionNumber-1].Characteristics; + if (!pSymbolTable->Type && (SectChar & IMAGE_SCN_MEM_WRITE)) { + // Read only (i.e. constants) must be excluded + fprintf(this->FileOut, "\t%s \t DATA\n", symbol.c_str()); + } else { + if ( pSymbolTable->Type || + !(SectChar & IMAGE_SCN_MEM_READ)) { + fprintf(this->FileOut, "\t%s\n", symbol.c_str()); + } else { + // printf(" strange symbol: %s \n",symbol.c_str()); + } + } + } + } + } + else if (pSymbolTable->SectionNumber == IMAGE_SYM_UNDEFINED && + !pSymbolTable->Type && 0) { + /* + * The IMPORT global variable entry points + */ + if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) { + symbol = stringTable + pSymbolTable->N.Name.Long; + while (isspace(symbol[0])) symbol.erase(0,1); + if (symbol[0] == '_') symbol.erase(0,1); + if (!this->ImportFlag) { + this->ImportFlag = true; + fprintf(this->FileOut,"IMPORTS \n"); + } + fprintf(this->FileOut, "\t%s DATA \n", symbol.c_str()+1); + } + } + + /* + * Take into account any aux symbols + */ + i += pSymbolTable->NumberOfAuxSymbols; + pSymbolTable += pSymbolTable->NumberOfAuxSymbols; + pSymbolTable++; + } + } +private: + bool ImportFlag; + FILE* FileOut; + DWORD_PTR SymbolCount; + PIMAGE_SECTION_HEADER SectionHeaders; + ObjectHeaderType* ObjectImageHeader; + SymbolTableType* SymbolTable; +}; + +bool +DumpFile(const char* filename, FILE *fout) +{ + HANDLE hFile; + HANDLE hFileMapping; + LPVOID lpFileBase; + PIMAGE_DOS_HEADER dosHeader; + + hFile = CreateFileW(cmsys::Encoding::ToWide(filename).c_str(), + GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + + if (hFile == INVALID_HANDLE_VALUE) { + fprintf(stderr, "Couldn't open file '%s' with CreateFile()\n", filename); + return false; + } + + hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); + if (hFileMapping == 0) { + CloseHandle(hFile); + fprintf(stderr, "Couldn't open file mapping with CreateFileMapping()\n"); + return false; + } + + lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0); + if (lpFileBase == 0) { + CloseHandle(hFileMapping); + CloseHandle(hFile); + fprintf(stderr, "Couldn't map view of file with MapViewOfFile()\n"); + return false; + } + + dosHeader = (PIMAGE_DOS_HEADER)lpFileBase; + if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) { + fprintf(stderr, "File is an executable. I don't dump those.\n"); + return false; + } + /* Does it look like a i386 COFF OBJ file??? */ + else if ( + ((dosHeader->e_magic == IMAGE_FILE_MACHINE_I386) || + (dosHeader->e_magic == IMAGE_FILE_MACHINE_AMD64)) + && (dosHeader->e_sp == 0) + ) { + /* + * The two tests above aren't what they look like. They're + * really checking for IMAGE_FILE_HEADER.Machine == i386 (0x14C) + * and IMAGE_FILE_HEADER.SizeOfOptionalHeader == 0; + */ + DumpSymbols<IMAGE_FILE_HEADER, IMAGE_SYMBOL> + symbolDumper((PIMAGE_FILE_HEADER) lpFileBase, fout); + symbolDumper.DumpObjFile(); + } else { + // check for /bigobj format + cmANON_OBJECT_HEADER_BIGOBJ* h = + (cmANON_OBJECT_HEADER_BIGOBJ*) lpFileBase; + if(h->Sig1 == 0x0 && h->Sig2 == 0xffff) { + DumpSymbols<cmANON_OBJECT_HEADER_BIGOBJ, cmIMAGE_SYMBOL_EX> + symbolDumper((cmANON_OBJECT_HEADER_BIGOBJ*) lpFileBase, fout); + symbolDumper.DumpObjFile(); + } else { + printf("unrecognized file format in '%s'\n", filename); + return false; + } + } + UnmapViewOfFile(lpFileBase); + CloseHandle(hFileMapping); + CloseHandle(hFile); + return true; +} diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx index 72818f5..44d0d4e 100644 --- a/Source/cmArchiveWrite.cxx +++ b/Source/cmArchiveWrite.cxx @@ -84,7 +84,8 @@ cmArchiveWrite::cmArchiveWrite( Stream(os), Archive(archive_write_new()), Disk(archive_read_disk_new()), - Verbose(false) + Verbose(false), + Format(format) { switch (c) { @@ -282,6 +283,14 @@ bool cmArchiveWrite::AddFile(const char* file, archive_entry_acl_clear(e); archive_entry_xattr_clear(e); archive_entry_set_fflags(e, 0, 0); + + if (this->Format == "pax" || this->Format == "paxr") + { + // Sparse files are a GNU tar extension. + // Do not use them in standard tar files. + archive_entry_sparse_clear(e); + } + if(archive_write_header(this->Archive, e) != ARCHIVE_OK) { this->Error = "archive_write_header: "; diff --git a/Source/cmArchiveWrite.h b/Source/cmArchiveWrite.h index 794cb28..e6f515d 100644 --- a/Source/cmArchiveWrite.h +++ b/Source/cmArchiveWrite.h @@ -84,6 +84,7 @@ private: struct archive* Archive; struct archive* Disk; bool Verbose; + std::string Format; std::string Error; std::string MTime; }; diff --git a/Source/cmCPackPropertiesGenerator.cxx b/Source/cmCPackPropertiesGenerator.cxx index cf24c13..368a0e6 100644 --- a/Source/cmCPackPropertiesGenerator.cxx +++ b/Source/cmCPackPropertiesGenerator.cxx @@ -1,6 +1,6 @@ #include "cmCPackPropertiesGenerator.h" -#include "cmLocalGenerator.h" +#include "cmOutputConverter.h" cmCPackPropertiesGenerator::cmCPackPropertiesGenerator( cmMakefile* mf, @@ -29,15 +29,15 @@ void cmCPackPropertiesGenerator::GenerateScriptForConfig(std::ostream& os, cmInstalledFile::Property const& property = i->second; os << indent << "set_property(INSTALL " << - cmLocalGenerator::EscapeForCMake(expandedFileName) << " PROPERTY " << - cmLocalGenerator::EscapeForCMake(name); + cmOutputConverter::EscapeForCMake(expandedFileName) << " PROPERTY " << + cmOutputConverter::EscapeForCMake(name); for(cmInstalledFile::ExpressionVectorType::const_iterator j = property.ValueExpressions.begin(); j != property.ValueExpressions.end(); ++j) { std::string value = (*j)->Evaluate(this->Makefile, config); - os << " " << cmLocalGenerator::EscapeForCMake(value); + os << " " << cmOutputConverter::EscapeForCMake(value); } os << ")\n"; diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx index c55ea35..591a2cd 100644 --- a/Source/cmCPluginAPI.cxx +++ b/Source/cmCPluginAPI.cxx @@ -426,8 +426,7 @@ int CCONV cmExecuteCommand(void *arg, const char *name, { // Assume all arguments are quoted. lff.Arguments.push_back( - cmListFileArgument(args[i], cmListFileArgument::Quoted, - "[CMake-Plugin]", 0)); + cmListFileArgument(args[i], cmListFileArgument::Quoted, 0)); } cmExecutionStatus status; return mf->ExecuteCommand(lff,status); @@ -526,11 +525,9 @@ void * CCONV cmCreateSourceFile(void) return (void*)new cmCPluginAPISourceFile; } -void * CCONV cmCreateNewSourceFile(void *arg) +void * CCONV cmCreateNewSourceFile(void *) { - cmMakefile *mf = static_cast<cmMakefile *>(arg); cmCPluginAPISourceFile *sf = new cmCPluginAPISourceFile; - sf->Properties.SetCMakeInstance(mf->GetCMakeInstance()); return (void*)sf; } @@ -630,11 +627,7 @@ const char * CCONV cmSourceFileGetProperty(void *arg,const char *prop) { return sf->FullPath.c_str(); } - bool chain = false; - // Ignore chain because old code will not expect it and it is a - // pain to implement here anyway. - return sf->Properties.GetPropertyValue(prop, cmProperty::SOURCE_FILE, - chain); + return sf->Properties.GetPropertyValue(prop); } } @@ -662,7 +655,7 @@ void CCONV cmSourceFileSetProperty(void *arg,const char *prop, else if(prop) { if(!value) { value = "NOTFOUND"; } - sf->Properties.SetProperty(prop, value, cmProperty::SOURCE_FILE); + sf->Properties.SetProperty(prop, value); } } @@ -801,8 +794,7 @@ void CCONV cmSourceFileSetName2(void *arg, const char* name, const char* dir, // Implement the old SetName method code here. if(headerFileOnly) { - sf->Properties.SetProperty("HEADER_FILE_ONLY", "1", - cmProperty::SOURCE_FILE); + sf->Properties.SetProperty("HEADER_FILE_ONLY", "1"); } sf->SourceName = name; std::string fname = sf->SourceName; diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index e3b7a2b..5676dda 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -294,6 +294,7 @@ cmCTest::cmCTest() this->LabelSummary = true; this->ParallelLevel = 1; this->ParallelLevelSetInCli = false; + this->TestLoad = 0; this->SubmitIndex = 0; this->Failover = false; this->BatchJobs = false; @@ -393,6 +394,11 @@ void cmCTest::SetParallelLevel(int level) this->ParallelLevel = level < 1 ? 1 : level; } +void cmCTest::SetTestLoad(unsigned long load) +{ + this->TestLoad = load; +} + //---------------------------------------------------------------------------- bool cmCTest::ShouldCompressTestOutput() { @@ -820,6 +826,20 @@ bool cmCTest::UpdateCTestConfiguration() cmSystemTools::ChangeDirectory(this->BinaryDir); } this->TimeOut = atoi(this->GetCTestConfiguration("TimeOut").c_str()); + std::string const& testLoad = this->GetCTestConfiguration("TestLoad"); + if (!testLoad.empty()) + { + unsigned long load; + if (cmSystemTools::StringToULong(testLoad.c_str(), &load)) + { + this->SetTestLoad(load); + } + else + { + cmCTestLog(this, WARNING, "Invalid value for 'Test Load' : " + << testLoad << std::endl); + } + } if ( this->ProduceXML ) { this->CompressXMLFiles = cmSystemTools::IsOn( @@ -1200,7 +1220,7 @@ int cmCTest::RunMakeCommand(const char* command, std::string& output, char* data; int length; - cmCTestLog(this, HANDLER_OUTPUT, + cmCTestLog(this, HANDLER_PROGRESS_OUTPUT, " Each . represents " << tick_len << " bytes of output" << std::endl << " " << std::flush); while(cmsysProcess_WaitForData(cp, &data, &length, 0)) @@ -1216,10 +1236,10 @@ int cmCTest::RunMakeCommand(const char* command, std::string& output, while ( output.size() > (tick * tick_len) ) { tick ++; - cmCTestLog(this, HANDLER_OUTPUT, "." << std::flush); + cmCTestLog(this, HANDLER_PROGRESS_OUTPUT, "." << std::flush); if ( tick % tick_line_len == 0 && tick > 0 ) { - cmCTestLog(this, HANDLER_OUTPUT, + cmCTestLog(this, HANDLER_PROGRESS_OUTPUT, " Size: " << int((double(output.size()) / 1024.0) + 1) << "K" << std::endl @@ -1232,7 +1252,7 @@ int cmCTest::RunMakeCommand(const char* command, std::string& output, ofs << cmCTestLogWrite(data, length); } } - cmCTestLog(this, OUTPUT, " Size of output: " + cmCTestLog(this, HANDLER_PROGRESS_OUTPUT, " Size of output: " << int(double(output.size()) / 1024.0) << "K" << std::endl); cmsysProcess_WaitForExit(cp, 0); @@ -2051,6 +2071,21 @@ bool cmCTest::HandleCommandLineArguments(size_t &i, } } + if(this->CheckArgument(arg, "--test-load") && i < args.size() - 1) + { + i++; + unsigned long load; + if (cmSystemTools::StringToULong(args[i].c_str(), &load)) + { + this->SetTestLoad(load); + } + else + { + cmCTestLog(this, WARNING, + "Invalid value for 'Test Load' : " << args[i] << std::endl); + } + } + if(this->CheckArgument(arg, "--no-compress-output")) { this->CompressTestOutput = false; @@ -3066,6 +3101,7 @@ static const char* cmCTestStringLogType[] = "DEBUG", "OUTPUT", "HANDLER_OUTPUT", + "HANDLER_PROGRESS_OUTPUT", "HANDLER_VERBOSE_OUTPUT", "WARNING", "ERROR_MESSAGE", @@ -3104,6 +3140,11 @@ void cmCTest::Log(int logType, const char* file, int line, const char* msg, { return; } + if ( logType == cmCTest::HANDLER_PROGRESS_OUTPUT && + ( this->Debug || this->ExtraVerbose ) ) + { + return; + } if ( this->OutputLogFile ) { bool display = true; diff --git a/Source/cmCTest.h b/Source/cmCTest.h index db3ea10..73c2807 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -161,6 +161,9 @@ public: int GetParallelLevel() { return this->ParallelLevel; } void SetParallelLevel(int); + unsigned long GetTestLoad() { return this->TestLoad; } + void SetTestLoad(unsigned long); + /** * Check if CTest file exists */ @@ -379,6 +382,7 @@ public: DEBUG = 0, OUTPUT, HANDLER_OUTPUT, + HANDLER_PROGRESS_OUTPUT, HANDLER_VERBOSE_OUTPUT, WARNING, ERROR_MESSAGE, @@ -499,6 +503,8 @@ private: int ParallelLevel; bool ParallelLevelSetInCli; + unsigned long TestLoad; + int CompatibilityMode; // information for the --build-and-test options diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index 108208e..54209c5 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -161,7 +161,6 @@ bool cmCacheManager::LoadCache(const std::string& path, // Format is key:type=value std::string helpString; CacheEntry e; - e.Properties.SetCMakeInstance(this->CMakeInstance); cmSystemTools::GetLineFromStream(fin, buffer); realbuffer = buffer.c_str(); while(*realbuffer != '0' && @@ -323,7 +322,6 @@ bool cmCacheManager::ReadPropertyEntry(std::string const& entryKey, { // Create an entry and store the property. CacheEntry& ne = this->Cache[key]; - ne.Properties.SetCMakeInstance(this->CMakeInstance); ne.Type = cmState::UNINITIALIZED; ne.SetProperty(*p, e.Value.c_str()); } @@ -645,7 +643,6 @@ void cmCacheManager::AddCacheEntry(const std::string& key, cmState::CacheEntryType type) { CacheEntry& e = this->Cache[key]; - e.Properties.SetCMakeInstance(this->CMakeInstance); if ( value ) { e.Value = value; @@ -744,9 +741,7 @@ cmCacheManager::CacheEntry::GetProperty(const std::string& prop) const { return this->Value.c_str(); } - bool c = false; - return - this->Properties.GetPropertyValue(prop, cmProperty::CACHE, c); + return this->Properties.GetPropertyValue(prop); } //---------------------------------------------------------------------------- @@ -763,7 +758,7 @@ void cmCacheManager::CacheEntry::SetProperty(const std::string& prop, } else { - this->Properties.SetProperty(prop, value, cmProperty::CACHE); + this->Properties.SetProperty(prop, value); } } @@ -789,7 +784,7 @@ void cmCacheManager::CacheEntry::AppendProperty(const std::string& prop, } else { - this->Properties.AppendProperty(prop, value, cmProperty::CACHE, asString); + this->Properties.AppendProperty(prop, value, asString); } } diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx index bd098a5..14e9e56 100644 --- a/Source/cmCommandArgumentParserHelper.cxx +++ b/Source/cmCommandArgumentParserHelper.cxx @@ -14,7 +14,7 @@ #include "cmSystemTools.h" #include "cmMakefile.h" #include "cmState.h" -#include "cmLocalGenerator.h" +#include "cmOutputConverter.h" #include "cmCommandArgumentLexer.h" @@ -141,8 +141,9 @@ char* cmCommandArgumentParserHelper::ExpandVariable(const char* var) { std::ostringstream msg; cmListFileContext lfc; - lfc.FilePath = this->Makefile->GetLocalGenerator() - ->Convert(this->FileName, cmLocalGenerator::HOME); + cmOutputConverter converter(this->Makefile->GetStateSnapshot()); + lfc.FilePath = converter.Convert(this->FileName, + cmOutputConverter::HOME); lfc.Line = this->FileLine; msg << "uninitialized variable \'" << var << "\'"; diff --git a/Source/cmCommandArgumentParserHelper.h b/Source/cmCommandArgumentParserHelper.h index d375ae6..387afc6 100644 --- a/Source/cmCommandArgumentParserHelper.h +++ b/Source/cmCommandArgumentParserHelper.h @@ -80,8 +80,6 @@ private: std::string::size_type InputBufferPos; std::string InputBuffer; std::vector<char> OutputBuffer; - int CurrentLine; - int Verbose; void Print(const char* place, const char* str); void SafePrintMissing(const char* str, int line, int cnt); @@ -94,12 +92,14 @@ private: std::vector<char*> Variables; const cmMakefile* Makefile; std::string Result; + std::string ErrorString; const char* FileName; + long FileLine; + int CurrentLine; + int Verbose; bool WarnUninitialized; bool CheckSystemVars; - long FileLine; bool EscapeQuotes; - std::string ErrorString; bool NoEscapeMode; bool ReplaceAtSyntax; bool RemoveEmpty; diff --git a/Source/cmComputeComponentGraph.h b/Source/cmComputeComponentGraph.h index a2ce946..4dbac4a 100644 --- a/Source/cmComputeComponentGraph.h +++ b/Source/cmComputeComponentGraph.h @@ -67,17 +67,17 @@ private: int Root; int VisitIndex; }; - int TarjanWalkId; std::vector<int> TarjanVisited; std::vector<int> TarjanComponents; std::vector<TarjanEntry> TarjanEntries; + std::vector<NodeList> Components; std::stack<int> TarjanStack; + int TarjanWalkId; int TarjanIndex; void Tarjan(); void TarjanVisit(int i); // Connected components. - std::vector<NodeList> Components; }; #endif diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h index 09b9d70..51a08c5 100644 --- a/Source/cmComputeLinkDepends.h +++ b/Source/cmComputeLinkDepends.h @@ -61,14 +61,7 @@ private: cmMakefile* Makefile; cmGlobalGenerator const* GlobalGenerator; cmake* CMakeInstance; - bool DebugMode; - - // Configuration information. - bool HasConfig; std::string Config; - cmTarget::LinkLibraryType LinkType; - - // Output information. EntryVector FinalLinkEntries; typedef cmTarget::LinkLibraryVectorType LinkLibraryVectorType; @@ -131,7 +124,7 @@ private: void OrderLinkEntires(); std::vector<char> ComponentVisited; std::vector<int> ComponentOrder; - int ComponentOrderId; + struct PendingComponent { // The real component id. Needed because the map is indexed by @@ -158,11 +151,14 @@ private: // Record of the original link line. std::vector<int> OriginalEntries; + std::set<cmTarget const*> OldWrongConfigItems; + void CheckWrongConfigItem(cmLinkItem const& item); - // Compatibility help. + int ComponentOrderId; + cmTarget::LinkLibraryType LinkType; + bool HasConfig; + bool DebugMode; bool OldLinkDirMode; - void CheckWrongConfigItem(cmLinkItem const& item); - std::set<cmTarget const*> OldWrongConfigItems; }; #endif diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index e6cbe60..1f3046a 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -16,7 +16,7 @@ #include "cmGlobalGenerator.h" #include "cmState.h" -#include "cmLocalGenerator.h" +#include "cmOutputConverter.h" #include "cmMakefile.h" #include "cmTarget.h" #include "cmake.h" @@ -246,7 +246,6 @@ cmComputeLinkInformation // Store context information. this->Target = target; this->Makefile = this->Target->GetMakefile(); - this->LocalGenerator = this->Makefile->GetLocalGenerator(); this->GlobalGenerator = this->Makefile->GetGlobalGenerator(); this->CMakeInstance = this->GlobalGenerator->GetCMakeInstance(); @@ -1395,7 +1394,8 @@ void cmComputeLinkInformation::AddFrameworkItem(std::string const& item) // Add the item using the -framework option. this->Items.push_back(Item("-framework", false)); - fw = this->LocalGenerator->EscapeForShell(fw); + cmOutputConverter converter(this->Makefile->GetStateSnapshot()); + fw = converter.EscapeForShell(fw); this->Items.push_back(Item(fw, false)); } diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h index 8847141..3afbb92 100644 --- a/Source/cmComputeLinkInformation.h +++ b/Source/cmComputeLinkInformation.h @@ -18,7 +18,6 @@ class cmake; class cmGlobalGenerator; -class cmLocalGenerator; class cmMakefile; class cmTarget; class cmOrderDirectories; @@ -75,14 +74,12 @@ private: // Context information. cmTarget const* Target; cmMakefile* Makefile; - cmLocalGenerator* LocalGenerator; cmGlobalGenerator* GlobalGenerator; cmake* CMakeInstance; // Configuration information. std::string Config; std::string LinkLanguage; - bool LinkDependsNoShared; // Modes for dealing with dependent shared libraries. enum SharedDepMode @@ -93,8 +90,6 @@ private: SharedDepModeLink // List file on link line }; - // System info. - bool UseImportLibrary; const char* LoaderFlag; std::string LibLinkFlag; std::string LibLinkFileFlag; @@ -102,22 +97,18 @@ private: std::string RuntimeFlag; std::string RuntimeSep; std::string RuntimeAlways; - bool RuntimeUseChrpath; - bool NoSONameUsesPath; - bool LinkWithRuntimePath; std::string RPathLinkFlag; SharedDepMode SharedDependencyMode; + enum LinkType { LinkUnknown, LinkStatic, LinkShared }; + void SetCurrentLinkType(LinkType lt); + // Link type adjustment. void ComputeLinkTypeInfo(); - enum LinkType { LinkUnknown, LinkStatic, LinkShared }; LinkType StartLinkType; LinkType CurrentLinkType; std::string StaticLinkTypeFlag; std::string SharedLinkTypeFlag; - bool LinkTypeEnabled; - void SetCurrentLinkType(LinkType lt); - bool ArchivesMayBeShared; // Link item parsing. void ComputeItemParserInfo(); @@ -129,7 +120,6 @@ private: cmsys::RegularExpression ExtractSharedLibraryName; cmsys::RegularExpression ExtractAnyLibraryName; std::string SharedRegexString; - bool OpenBSD; void AddLinkPrefix(const char* p); void AddLinkExtension(const char* e, LinkType type); std::string CreateExtensionRegex(std::vector<std::string> const& exts, @@ -173,20 +163,27 @@ private: std::set<std::string> OldLinkDirMask; std::vector<std::string> OldLinkDirItems; std::vector<std::string> OldUserFlagItems; - bool OldLinkDirMode; - - // CMP0060 warnings. - bool CMP0060Warn; std::set<std::string> CMP0060WarnItems; - + // Dependent library path computation. + cmOrderDirectories* OrderDependentRPath; // Runtime path computation. cmOrderDirectories* OrderRuntimeSearchPath; + + bool OldLinkDirMode; + bool OpenBSD; + bool LinkDependsNoShared; + bool UseImportLibrary; + bool RuntimeUseChrpath; + bool NoSONameUsesPath; + bool LinkWithRuntimePath; + bool LinkTypeEnabled; + bool ArchivesMayBeShared; + bool CMP0060Warn; + void AddLibraryRuntimeInfo(std::string const& fullPath, cmTarget const* target); void AddLibraryRuntimeInfo(std::string const& fullPath); - // Dependent library path computation. - cmOrderDirectories* OrderDependentRPath; }; #endif diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx index 87b47b4..c4a03a0 100644 --- a/Source/cmComputeTargetDepends.cxx +++ b/Source/cmComputeTargetDepends.cxx @@ -147,12 +147,12 @@ bool cmComputeTargetDepends::Compute() //---------------------------------------------------------------------------- void -cmComputeTargetDepends::GetTargetDirectDepends(cmTarget const* t, +cmComputeTargetDepends::GetTargetDirectDepends(cmGeneratorTarget const* t, cmTargetDependSet& deps) { // Lookup the index for this target. All targets should be known by // this point. - std::map<cmTarget const*, int>::const_iterator tii + std::map<cmGeneratorTarget const*, int>::const_iterator tii = this->TargetIndex.find(t); assert(tii != this->TargetIndex.end()); int i = tii->second; @@ -161,7 +161,7 @@ cmComputeTargetDepends::GetTargetDirectDepends(cmTarget const* t, EdgeList const& nl = this->FinalGraph[i]; for(EdgeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni) { - cmTarget const* dep = this->Targets[*ni]; + cmGeneratorTarget const* dep = this->Targets[*ni]; cmTargetDependSet::iterator di = deps.insert(dep).first; di->SetType(ni->IsStrong()); } @@ -180,9 +180,11 @@ void cmComputeTargetDepends::CollectTargets() ti != targets.end(); ++ti) { cmTarget const* target = &ti->second; + cmGeneratorTarget* gt = + this->GlobalGenerator->GetGeneratorTarget(target); int index = static_cast<int>(this->Targets.size()); - this->TargetIndex[target] = index; - this->Targets.push_back(target); + this->TargetIndex[gt] = index; + this->Targets.push_back(gt); } } } @@ -204,7 +206,7 @@ void cmComputeTargetDepends::CollectDepends() void cmComputeTargetDepends::CollectTargetDepends(int depender_index) { // Get the depender. - cmTarget const* depender = this->Targets[depender_index]; + cmGeneratorTarget const* depender = this->Targets[depender_index]; if (depender->GetType() == cmTarget::INTERFACE_LIBRARY) { return; @@ -216,10 +218,9 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) // deal with config-specific dependencies. { std::set<std::string> emitted; - cmGeneratorTarget* gt = this->GlobalGenerator->GetGeneratorTarget(depender); std::vector<std::string> configs; - depender->GetMakefile()->GetConfigurations(configs); + depender->Makefile->GetConfigurations(configs); if (configs.empty()) { configs.push_back(""); @@ -228,7 +229,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) it != configs.end(); ++it) { std::vector<cmSourceFile const*> objectFiles; - gt->GetExternalObjects(objectFiles, *it); + depender->GetExternalObjects(objectFiles, *it); for(std::vector<cmSourceFile const*>::const_iterator oi = objectFiles.begin(); oi != objectFiles.end(); ++oi) { @@ -244,15 +245,15 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) ->IssueMessage(cmake::FATAL_ERROR, "Only executables and non-OBJECT libraries may " "reference target objects.", - depender->GetBacktrace()); + depender->Target->GetBacktrace()); return; } - const_cast<cmTarget*>(depender)->AddUtility(objLib); + const_cast<cmGeneratorTarget*>(depender)->Target->AddUtility(objLib); } } cmTarget::LinkImplementation const* impl = - depender->GetLinkImplementation(*it); + depender->Target->GetLinkImplementation(*it); // A target should not depend on itself. emitted.insert(depender->GetName()); @@ -272,7 +273,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) // Loop over all utility dependencies. { - std::set<cmLinkItem> const& tutils = depender->GetUtilityItems(); + std::set<cmLinkItem> const& tutils = depender->Target->GetUtilityItems(); std::set<std::string> emitted; // A target should not depend on itself. emitted.insert(depender->GetName()); @@ -290,13 +291,14 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) //---------------------------------------------------------------------------- void cmComputeTargetDepends::AddInterfaceDepends(int depender_index, - cmTarget const* dependee, - const std::string& config, - std::set<std::string> &emitted) + const cmGeneratorTarget* dependee, + const std::string& config, + std::set<std::string> &emitted) { - cmTarget const* depender = this->Targets[depender_index]; + cmGeneratorTarget const* depender = this->Targets[depender_index]; if(cmTarget::LinkInterface const* iface = - dependee->GetLinkInterface(config, depender)) + dependee->Target->GetLinkInterface(config, + depender->Target)) { for(std::vector<cmLinkItem>::const_iterator lib = iface->Libraries.begin(); @@ -317,7 +319,7 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index, cmLinkItem const& dependee_name, std::set<std::string> &emitted) { - cmTarget const* depender = this->Targets[depender_index]; + cmGeneratorTarget const* depender = this->Targets[depender_index]; cmTarget const* dependee = dependee_name.Target; // Skip targets that will not really be linked. This is probably a // name conflict between an external library and an executable @@ -331,16 +333,17 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index, if(dependee) { - this->AddInterfaceDepends(depender_index, dependee, "", emitted); + cmGeneratorTarget* gt = + this->GlobalGenerator->GetGeneratorTarget(dependee); + this->AddInterfaceDepends(depender_index, gt, "", emitted); std::vector<std::string> configs; - depender->GetMakefile()->GetConfigurations(configs); + depender->Makefile->GetConfigurations(configs); for (std::vector<std::string>::const_iterator it = configs.begin(); it != configs.end(); ++it) { // A target should not depend on itself. emitted.insert(depender->GetName()); - this->AddInterfaceDepends(depender_index, dependee, - *it, emitted); + this->AddInterfaceDepends(depender_index, gt, *it, emitted); } } } @@ -351,7 +354,7 @@ void cmComputeTargetDepends::AddTargetDepend( bool linking) { // Get the depender. - cmTarget const* depender = this->Targets[depender_index]; + cmGeneratorTarget const* depender = this->Targets[depender_index]; // Check the target's makefile first. cmTarget const* dependee = dependee_name.Target; @@ -362,7 +365,7 @@ void cmComputeTargetDepends::AddTargetDepend( cmake::MessageType messageType = cmake::AUTHOR_WARNING; bool issueMessage = false; std::ostringstream e; - switch(depender->GetPolicyStatusCMP0046()) + switch(depender->Target->GetPolicyStatusCMP0046()) { case cmPolicies::WARN: e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0046) << "\n"; @@ -383,7 +386,7 @@ void cmComputeTargetDepends::AddTargetDepend( << "\" of target \"" << depender->GetName() << "\" does not exist."; cmListFileBacktrace const* backtrace = - depender->GetUtilityBacktrace(dependee_name); + depender->Target->GetUtilityBacktrace(dependee_name); if(backtrace) { cm->IssueMessage(messageType, e.str(), *backtrace); @@ -408,27 +411,31 @@ void cmComputeTargetDepends::AddTargetDepend( if(dependee) { - this->AddTargetDepend(depender_index, dependee, linking); + cmGeneratorTarget* gt = + this->GlobalGenerator->GetGeneratorTarget(dependee); + this->AddTargetDepend(depender_index, gt, linking); } } //---------------------------------------------------------------------------- void cmComputeTargetDepends::AddTargetDepend(int depender_index, - cmTarget const* dependee, + const cmGeneratorTarget* dependee, bool linking) { - if(dependee->IsImported() || + if(dependee->Target->IsImported() || dependee->GetType() == cmTarget::INTERFACE_LIBRARY) { // Skip IMPORTED and INTERFACE targets but follow their utility // dependencies. - std::set<cmLinkItem> const& utils = dependee->GetUtilityItems(); + std::set<cmLinkItem> const& utils = dependee->Target->GetUtilityItems(); for(std::set<cmLinkItem>::const_iterator i = utils.begin(); i != utils.end(); ++i) { if(cmTarget const* transitive_dependee = i->Target) { - this->AddTargetDepend(depender_index, transitive_dependee, false); + cmGeneratorTarget* gt = + this->GlobalGenerator->GetGeneratorTarget(transitive_dependee); + this->AddTargetDepend(depender_index, gt, false); } } } @@ -436,7 +443,7 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index, { // Lookup the index for this target. All targets should be known by // this point. - std::map<cmTarget const*, int>::const_iterator tii = + std::map<cmGeneratorTarget const*, int>::const_iterator tii = this->TargetIndex.find(dependee); assert(tii != this->TargetIndex.end()); int dependee_index = tii->second; @@ -457,13 +464,13 @@ cmComputeTargetDepends::DisplayGraph(Graph const& graph, for(int depender_index = 0; depender_index < n; ++depender_index) { EdgeList const& nl = graph[depender_index]; - cmTarget const* depender = this->Targets[depender_index]; + cmGeneratorTarget const* depender = this->Targets[depender_index]; fprintf(stderr, "target %d is [%s]\n", depender_index, depender->GetName().c_str()); for(EdgeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni) { int dependee_index = *ni; - cmTarget const* dependee = this->Targets[dependee_index]; + cmGeneratorTarget const* dependee = this->Targets[dependee_index]; fprintf(stderr, " depends on target %d [%s] (%s)\n", dependee_index, dependee->GetName().c_str(), ni->IsStrong()? "strong" : "weak"); } @@ -550,11 +557,11 @@ cmComputeTargetDepends { // Get the depender. int i = *ci; - cmTarget const* depender = this->Targets[i]; + cmGeneratorTarget const* depender = this->Targets[i]; // Describe the depender. e << " \"" << depender->GetName() << "\" of type " - << cmTarget::GetTargetTypeName(depender->GetType()) << "\n"; + << cmTarget::GetTargetTypeName(depender->Target->GetType()) << "\n"; // List its dependencies that are inside the component. EdgeList const& nl = this->InitialGraph[i]; @@ -563,7 +570,7 @@ cmComputeTargetDepends int j = *ni; if(cmap[j] == c) { - cmTarget const* dependee = this->Targets[j]; + cmGeneratorTarget const* dependee = this->Targets[j]; e << " depends on \"" << dependee->GetName() << "\"" << " (" << (ni->IsStrong()? "strong" : "weak") << ")\n"; } diff --git a/Source/cmComputeTargetDepends.h b/Source/cmComputeTargetDepends.h index 902f342..6100d97 100644 --- a/Source/cmComputeTargetDepends.h +++ b/Source/cmComputeTargetDepends.h @@ -21,7 +21,7 @@ class cmComputeComponentGraph; class cmGlobalGenerator; class cmLinkItem; -class cmTarget; +class cmGeneratorTarget; class cmTargetDependSet; /** \class cmComputeTargetDepends @@ -39,9 +39,10 @@ public: bool Compute(); - std::vector<cmTarget const*> const& + std::vector<cmGeneratorTarget const*> const& GetTargets() const { return this->Targets; } - void GetTargetDirectDepends(cmTarget const* t, cmTargetDependSet& deps); + void GetTargetDirectDepends(cmGeneratorTarget const* t, + cmTargetDependSet& deps); private: void CollectTargets(); void CollectDepends(); @@ -49,13 +50,14 @@ private: void AddTargetDepend(int depender_index, cmLinkItem const& dependee_name, bool linking); - void AddTargetDepend(int depender_index, cmTarget const* dependee, + void AddTargetDepend(int depender_index, cmGeneratorTarget const* dependee, bool linking); bool ComputeFinalDepends(cmComputeComponentGraph const& ccg); void AddInterfaceDepends(int depender_index, cmLinkItem const& dependee_name, std::set<std::string> &emitted); - void AddInterfaceDepends(int depender_index, cmTarget const* dependee, + void AddInterfaceDepends(int depender_index, + cmGeneratorTarget const* dependee, const std::string& config, std::set<std::string> &emitted); cmGlobalGenerator* GlobalGenerator; @@ -63,8 +65,8 @@ private: bool NoCycles; // Collect all targets. - std::vector<cmTarget const*> Targets; - std::map<cmTarget const*, int> TargetIndex; + std::vector<cmGeneratorTarget const*> Targets; + std::map<cmGeneratorTarget const*, int> TargetIndex; // Represent the target dependency graph. The entry at each // top-level index corresponds to a depender whose dependencies are diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index dd276a8..e1e1a5c 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -11,7 +11,7 @@ ============================================================================*/ #include "cmCoreTryCompile.h" #include "cmake.h" -#include "cmLocalGenerator.h" +#include "cmOutputConverter.h" #include "cmGlobalGenerator.h" #include "cmAlgorithms.h" #include "cmExportTryCompileFileGenerator.h" @@ -322,7 +322,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) std::string langFlags = "CMAKE_" + *li + "_FLAGS"; const char* flags = this->Makefile->GetDefinition(langFlags); fprintf(fout, "set(CMAKE_%s_FLAGS %s)\n", li->c_str(), - cmLocalGenerator::EscapeForCMake(flags?flags:"").c_str()); + cmOutputConverter::EscapeForCMake(flags?flags:"").c_str()); fprintf(fout, "set(CMAKE_%s_FLAGS \"${CMAKE_%s_FLAGS}" " ${COMPILE_DEFINITIONS}\")\n", li->c_str(), li->c_str()); } @@ -355,7 +355,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) const char* exeLinkFlags = this->Makefile->GetDefinition("CMAKE_EXE_LINKER_FLAGS"); fprintf(fout, "set(CMAKE_EXE_LINKER_FLAGS %s)\n", - cmLocalGenerator::EscapeForCMake( + cmOutputConverter::EscapeForCMake( exeLinkFlags ? exeLinkFlags : "").c_str()); } break; } diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx index 015825d..7c37e3b 100644 --- a/Source/cmCustomCommand.cxx +++ b/Source/cmCustomCommand.cxx @@ -17,7 +17,7 @@ //---------------------------------------------------------------------------- cmCustomCommand::cmCustomCommand() - : Backtrace(NULL) + : Backtrace() { this->HaveComment = false; this->EscapeOldStyle = true; @@ -26,46 +26,6 @@ cmCustomCommand::cmCustomCommand() } //---------------------------------------------------------------------------- -cmCustomCommand::cmCustomCommand(const cmCustomCommand& r): - Outputs(r.Outputs), - Byproducts(r.Byproducts), - Depends(r.Depends), - CommandLines(r.CommandLines), - HaveComment(r.HaveComment), - Comment(r.Comment), - WorkingDirectory(r.WorkingDirectory), - EscapeAllowMakeVars(r.EscapeAllowMakeVars), - EscapeOldStyle(r.EscapeOldStyle), - Backtrace(r.Backtrace), - UsesTerminal(r.UsesTerminal) -{ -} - -//---------------------------------------------------------------------------- -cmCustomCommand& cmCustomCommand::operator=(cmCustomCommand const& r) -{ - if(this == &r) - { - return *this; - } - - this->Outputs = r.Outputs; - this->Byproducts= r.Byproducts; - this->Depends = r.Depends; - this->CommandLines = r.CommandLines; - this->HaveComment = r.HaveComment; - this->Comment = r.Comment; - this->WorkingDirectory = r.WorkingDirectory; - this->EscapeAllowMakeVars = r.EscapeAllowMakeVars; - this->EscapeOldStyle = r.EscapeOldStyle; - this->ImplicitDepends = r.ImplicitDepends; - this->Backtrace = r.Backtrace; - this->UsesTerminal = r.UsesTerminal; - - return *this; -} - -//---------------------------------------------------------------------------- cmCustomCommand::cmCustomCommand(cmMakefile const* mf, const std::vector<std::string>& outputs, const std::vector<std::string>& byproducts, @@ -77,15 +37,13 @@ cmCustomCommand::cmCustomCommand(cmMakefile const* mf, Byproducts(byproducts), Depends(depends), CommandLines(commandLines), - HaveComment(comment?true:false), + Backtrace(), Comment(comment?comment:""), WorkingDirectory(workingDirectory?workingDirectory:""), + HaveComment(comment?true:false), EscapeAllowMakeVars(false), - EscapeOldStyle(true), - Backtrace(NULL) + EscapeOldStyle(true) { - this->EscapeOldStyle = true; - this->EscapeAllowMakeVars = false; if(mf) { this->Backtrace = mf->GetBacktrace(); @@ -93,11 +51,6 @@ cmCustomCommand::cmCustomCommand(cmMakefile const* mf, } //---------------------------------------------------------------------------- -cmCustomCommand::~cmCustomCommand() -{ -} - -//---------------------------------------------------------------------------- const std::vector<std::string>& cmCustomCommand::GetOutputs() const { return this->Outputs; diff --git a/Source/cmCustomCommand.h b/Source/cmCustomCommand.h index 0bfaef2..f9b38c3 100644 --- a/Source/cmCustomCommand.h +++ b/Source/cmCustomCommand.h @@ -26,8 +26,6 @@ class cmCustomCommand public: /** Default and copy constructors for STL containers. */ cmCustomCommand(); - cmCustomCommand(const cmCustomCommand& r); - cmCustomCommand& operator=(cmCustomCommand const& r); /** Main constructor specifies all information for the command. */ cmCustomCommand(cmMakefile const* mf, @@ -38,8 +36,6 @@ public: const char* comment, const char* workingDirectory); - ~cmCustomCommand(); - /** Get the output file produced by the command. */ const std::vector<std::string>& GetOutputs() const; @@ -93,13 +89,13 @@ private: std::vector<std::string> Byproducts; std::vector<std::string> Depends; cmCustomCommandLines CommandLines; - bool HaveComment; + cmListFileBacktrace Backtrace; + ImplicitDependsList ImplicitDepends; std::string Comment; std::string WorkingDirectory; + bool HaveComment; bool EscapeAllowMakeVars; bool EscapeOldStyle; - cmListFileBacktrace Backtrace; - ImplicitDependsList ImplicitDepends; bool UsesTerminal; }; diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx index d23f815..11308c6 100644 --- a/Source/cmCustomCommandGenerator.cxx +++ b/Source/cmCustomCommandGenerator.cxx @@ -13,13 +13,13 @@ #include "cmMakefile.h" #include "cmCustomCommand.h" -#include "cmLocalGenerator.h" +#include "cmOutputConverter.h" #include "cmGeneratorExpression.h" //---------------------------------------------------------------------------- cmCustomCommandGenerator::cmCustomCommandGenerator( cmCustomCommand const& cc, const std::string& config, cmMakefile* mf): - CC(cc), Config(config), Makefile(mf), LG(mf->GetLocalGenerator()), + CC(cc), Config(config), Makefile(mf), OldStyle(cc.GetEscapeOldStyle()), MakeVars(cc.GetEscapeAllowMakeVars()), GE(new cmGeneratorExpression(&cc.GetBacktrace())), DependsDone(false) { @@ -96,7 +96,8 @@ cmCustomCommandGenerator } else { - cmd += this->LG->EscapeForShell(arg, this->MakeVars); + cmOutputConverter converter(this->Makefile->GetStateSnapshot()); + cmd += converter.EscapeForShell(arg, this->MakeVars); } } } diff --git a/Source/cmCustomCommandGenerator.h b/Source/cmCustomCommandGenerator.h index b4ae014..7ad95d1 100644 --- a/Source/cmCustomCommandGenerator.h +++ b/Source/cmCustomCommandGenerator.h @@ -16,7 +16,6 @@ class cmCustomCommand; class cmMakefile; -class cmLocalGenerator; class cmGeneratorExpression; class cmCustomCommandGenerator @@ -24,7 +23,6 @@ class cmCustomCommandGenerator cmCustomCommand const& CC; std::string Config; cmMakefile* Makefile; - cmLocalGenerator* LG; bool OldStyle; bool MakeVars; cmGeneratorExpression* GE; diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx index f12116e..1b2586c 100644 --- a/Source/cmDependsFortran.cxx +++ b/Source/cmDependsFortran.cxx @@ -143,7 +143,7 @@ cmDependsFortran std::vector<std::string> definitions; cmMakefile* mf = this->LocalGenerator->GetMakefile(); if(const char* c_defines = - mf->GetDefinition("CMAKE_TARGET_DEFINITIONS")) + mf->GetDefinition("CMAKE_TARGET_DEFINITIONS_Fortran")) { cmSystemTools::ExpandListArgument(c_defines, definitions); } diff --git a/Source/cmDocumentation.h b/Source/cmDocumentation.h index 8854c36..b6c5fde 100644 --- a/Source/cmDocumentation.h +++ b/Source/cmDocumentation.h @@ -13,7 +13,6 @@ #define _cmDocumentation_h #include "cmStandardIncludes.h" -#include "cmProperty.h" #include "cmDocumentationFormatter.h" #include "cmDocumentationSection.h" #include "cmake.h" diff --git a/Source/cmExecProgramCommand.cxx b/Source/cmExecProgramCommand.cxx index e021d0b..41785c2 100644 --- a/Source/cmExecProgramCommand.cxx +++ b/Source/cmExecProgramCommand.cxx @@ -156,7 +156,7 @@ bool cmExecProgramCommand::RunCommand(const char* command, verbose = false; } -#if defined(WIN32) && !defined(__CYGWIN__) +#if defined(_WIN32) && !defined(__CYGWIN__) // if the command does not start with a quote, then // try to find the program, and if the program can not be // found use system to run the command as it must be a built in @@ -219,7 +219,7 @@ bool cmExecProgramCommand::RunCommand(const char* command, return false; } -#if defined(WIN32) && !defined(__CYGWIN__) +#if defined(_WIN32) && !defined(__CYGWIN__) if(dir) { cmsysProcess_SetWorkingDirectory(cp, dir); @@ -305,7 +305,7 @@ bool cmExecProgramCommand::RunCommand(const char* command, } if(!msg.empty()) { -#if defined(WIN32) && !defined(__CYGWIN__) +#if defined(_WIN32) && !defined(__CYGWIN__) // Old Windows process execution printed this info. msg += "\n\nfor command: "; msg += command; diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index bf18deb..568ce89 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -18,7 +18,7 @@ //---------------------------------------------------------------------------- cmExportBuildFileGenerator::cmExportBuildFileGenerator() - : Backtrace(NULL) + : Backtrace() { this->Makefile = 0; this->ExportSet = 0; diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index a51fb2a..094ad4f 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -23,12 +23,28 @@ #include "cmVersion.h" #include "cmComputeLinkInformation.h" #include "cmAlgorithms.h" +#include "cmOutputConverter.h" #include <cmsys/auto_ptr.hxx> #include <cmsys/FStream.hxx> #include <assert.h> //---------------------------------------------------------------------------- +static std::string cmExportFileGeneratorEscape(std::string const& str) +{ + // Escape a property value for writing into a .cmake file. + std::string result = cmOutputConverter::EscapeForCMake(str); + // Un-escape variable references generated by our own export code. + cmSystemTools::ReplaceString(result, + "\\${_IMPORT_PREFIX}", + "${_IMPORT_PREFIX}"); + cmSystemTools::ReplaceString(result, + "\\${CMAKE_IMPORT_LIBRARY_SUFFIX}", + "${CMAKE_IMPORT_LIBRARY_SUFFIX}"); + return result; +} + +//---------------------------------------------------------------------------- cmExportFileGenerator::cmExportFileGenerator() { this->AppendMode = false; @@ -608,7 +624,8 @@ void cmExportFileGenerator::GenerateInterfaceProperties(cmTarget const* target, for(ImportPropertyMap::const_iterator pi = properties.begin(); pi != properties.end(); ++pi) { - os << " " << pi->first << " \"" << pi->second << "\"\n"; + os << " " << pi->first << " " + << cmExportFileGeneratorEscape(pi->second) << "\n"; } os << ")\n\n"; } @@ -1112,7 +1129,8 @@ cmExportFileGenerator for(ImportPropertyMap::const_iterator pi = properties.begin(); pi != properties.end(); ++pi) { - os << " " << pi->first << " \"" << pi->second << "\"\n"; + os << " " << pi->first << " " + << cmExportFileGeneratorEscape(pi->second) << "\n"; } os << " )\n" << "\n"; @@ -1223,7 +1241,7 @@ cmExportFileGenerator ImportPropertyMap::const_iterator pi = properties.find(*li); if (pi != properties.end()) { - os << "\"" << pi->second << "\" "; + os << cmExportFileGeneratorEscape(pi->second) << " "; } } diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx index eb8d193..dfb991b 100644 --- a/Source/cmExportTryCompileFileGenerator.cxx +++ b/Source/cmExportTryCompileFileGenerator.cxx @@ -99,8 +99,6 @@ cmExportTryCompileFileGenerator::PopulateProperties(cmTarget const* target, || i->first.find("IMPORTED_LINK_DEPENDENT_LIBRARIES") == 0 || i->first.find("INTERFACE_LINK_LIBRARIES") == 0) { - const std::string libs = i->second.GetValue(); - std::string evalResult = this->FindTargets(i->first, target, emitted); @@ -118,6 +116,7 @@ cmExportTryCompileFileGenerator::PopulateProperties(cmTarget const* target, } } } + std::string cmExportTryCompileFileGenerator::InstallNameDir(cmTarget* target, const std::string& config) diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index e374387..a31e832 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -313,7 +313,7 @@ void cmExtraCodeBlocksGenerator " "<<virtualFolders<<"\n" " <Build>\n"; - this->AppendTarget(fout, "all", 0, make.c_str(), mf, compiler.c_str()); + this->AppendTarget(fout, "all", 0, make.c_str(), lgs[0], compiler.c_str()); // add all executable and library targets and some of the GLOBAL // and UTILITY targets @@ -335,7 +335,7 @@ void cmExtraCodeBlocksGenerator makefile->GetHomeOutputDirectory())==0) { this->AppendTarget(fout, ti->first, 0, - make.c_str(), makefile, compiler.c_str()); + make.c_str(), *lg, compiler.c_str()); } } break; @@ -351,7 +351,7 @@ void cmExtraCodeBlocksGenerator } this->AppendTarget(fout, ti->first, 0, - make.c_str(), makefile, compiler.c_str()); + make.c_str(), *lg, compiler.c_str()); break; case cmTarget::EXECUTABLE: case cmTarget::STATIC_LIBRARY: @@ -360,11 +360,11 @@ void cmExtraCodeBlocksGenerator case cmTarget::OBJECT_LIBRARY: { this->AppendTarget(fout, ti->first, &ti->second, - make.c_str(), makefile, compiler.c_str()); + make.c_str(), *lg, compiler.c_str()); std::string fastTarget = ti->first; fastTarget += "/fast"; this->AppendTarget(fout, fastTarget, &ti->second, - make.c_str(), makefile, compiler.c_str()); + make.c_str(), *lg, compiler.c_str()); } break; default: @@ -519,14 +519,16 @@ void cmExtraCodeBlocksGenerator // Write a dummy file for OBJECT libraries, so C::B can reference some file std::string cmExtraCodeBlocksGenerator::CreateDummyTargetFile( - cmMakefile* mf, cmTarget* target) const + cmLocalGenerator* lg, + cmTarget* target) const { + cmMakefile *mf = lg->GetMakefile(); // this file doesn't seem to be used by C::B in custom makefile mode, // but we generate a unique file for each OBJECT library so in case // C::B uses it in some way, the targets don't interfere with each other. std::string filename = mf->GetCurrentBinaryDirectory(); filename += "/"; - filename += mf->GetLocalGenerator()->GetTargetDirectory(*target); + filename += lg->GetTargetDirectory(*target); filename += "/"; filename += target->GetName(); filename += ".objlib"; @@ -547,9 +549,10 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout, const std::string& targetName, cmTarget* target, const char* make, - const cmMakefile* makefile, + const cmLocalGenerator* lg, const char* compiler) { + cmMakefile const* makefile = lg->GetMakefile(); std::string makefileName = makefile->GetCurrentBinaryDirectory(); makefileName += "/Makefile"; @@ -583,7 +586,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout, std::string location; if ( target->GetType()==cmTarget::OBJECT_LIBRARY) { - location = this->CreateDummyTargetFile(const_cast<cmMakefile*>(makefile), + location = this->CreateDummyTargetFile(const_cast<cmLocalGenerator*>(lg), target); } else @@ -618,8 +621,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout, std::set<std::string> uniqIncludeDirs; std::vector<std::string> includes; - target->GetMakefile()->GetLocalGenerator()-> - GetIncludeDirectories(includes, gtgt, "C", buildType); + lg->GetIncludeDirectories(includes, gtgt, "C", buildType); uniqIncludeDirs.insert(includes.begin(), includes.end()); diff --git a/Source/cmExtraCodeBlocksGenerator.h b/Source/cmExtraCodeBlocksGenerator.h index 97da1b8..e5ede9a 100644 --- a/Source/cmExtraCodeBlocksGenerator.h +++ b/Source/cmExtraCodeBlocksGenerator.h @@ -48,7 +48,8 @@ private: void CreateNewProjectFile(const std::vector<cmLocalGenerator*>& lgs, const std::string& filename); - std::string CreateDummyTargetFile(cmMakefile* mf, cmTarget* target) const; + std::string CreateDummyTargetFile(cmLocalGenerator* lg, + cmTarget* target) const; std::string GetCBCompilerId(const cmMakefile* mf); int GetCBTargetType(cmTarget* target); @@ -58,7 +59,7 @@ private: const std::string& targetName, cmTarget* target, const char* make, - const cmMakefile* makefile, + const cmLocalGenerator* lg, const char* compiler); }; diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 4698468..f740020 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -66,7 +66,7 @@ static mode_t mode_setuid = S_ISUID; static mode_t mode_setgid = S_ISGID; #endif -#if defined(WIN32) && defined(CMAKE_ENCODING_UTF8) +#if defined(_WIN32) && defined(CMAKE_ENCODING_UTF8) // libcurl doesn't support file:// urls for unicode filenames on Windows. // Convert string from UTF-8 to ACP if this is a file:// URL. static std::string fix_file_url_windows(const std::string& url) @@ -906,13 +906,13 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args, { switch(status) { + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: case cmPolicies::NEW: g.RecurseThroughSymlinksOff(); break; case cmPolicies::OLD: case cmPolicies::WARN: - case cmPolicies::REQUIRED_IF_USED: - case cmPolicies::REQUIRED_ALWAYS: g.RecurseThroughSymlinksOn(); break; } @@ -1044,6 +1044,8 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args, { switch (status) { + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: case cmPolicies::NEW: // Correct behavior, yay! break; @@ -1059,12 +1061,6 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args, cmPolicies::GetPolicyWarning(cmPolicies::CMP0009)); } break; - case cmPolicies::REQUIRED_IF_USED: - case cmPolicies::REQUIRED_ALWAYS: - this->SetError("policy CMP0009 error"); - this->Makefile->IssueMessage(cmake::FATAL_ERROR, - cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0009)); - return false; } } @@ -3160,7 +3156,7 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) return false; } -#if defined(WIN32) && defined(CMAKE_ENCODING_UTF8) +#if defined(_WIN32) && defined(CMAKE_ENCODING_UTF8) url = fix_file_url_windows(url); #endif @@ -3415,7 +3411,7 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args) unsigned long file_size = cmsys::SystemTools::FileLength(filename); -#if defined(WIN32) && defined(CMAKE_ENCODING_UTF8) +#if defined(_WIN32) && defined(CMAKE_ENCODING_UTF8) url = fix_file_url_windows(url); #endif diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx index 0dcda4d..e983bfb 100644 --- a/Source/cmForEachCommand.cxx +++ b/Source/cmForEachCommand.cxx @@ -13,6 +13,17 @@ #include <cmsys/auto_ptr.hxx> +cmForEachFunctionBlocker::cmForEachFunctionBlocker(cmMakefile* mf): + Makefile(mf), Depth(0) +{ + this->Makefile->PushLoopBlock(); +} + +cmForEachFunctionBlocker::~cmForEachFunctionBlocker() +{ + this->Makefile->PopLoopBlock(); +} + bool cmForEachFunctionBlocker:: IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, cmExecutionStatus &inStatus) @@ -27,8 +38,6 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, // if this is the endofreach for this statement if (!this->Depth) { - cmMakefile::LoopBlockPop loopBlockPop(&mf); - // Remove the function blocker for this scope or bail. cmsys::auto_ptr<cmFunctionBlocker> fb(mf.RemoveFunctionBlocker(this, lff)); @@ -128,7 +137,7 @@ bool cmForEachCommand } // create a function blocker - cmForEachFunctionBlocker *f = new cmForEachFunctionBlocker(); + cmForEachFunctionBlocker *f = new cmForEachFunctionBlocker(this->Makefile); if ( args.size() > 1 ) { if ( args[1] == "RANGE" ) @@ -204,15 +213,14 @@ bool cmForEachCommand } this->Makefile->AddFunctionBlocker(f); - this->Makefile->PushLoopBlock(); - return true; } //---------------------------------------------------------------------------- bool cmForEachCommand::HandleInMode(std::vector<std::string> const& args) { - cmsys::auto_ptr<cmForEachFunctionBlocker> f(new cmForEachFunctionBlocker()); + cmsys::auto_ptr<cmForEachFunctionBlocker> + f(new cmForEachFunctionBlocker(this->Makefile)); f->Args.push_back(args[0]); enum Doing { DoingNone, DoingLists, DoingItems }; @@ -250,7 +258,5 @@ bool cmForEachCommand::HandleInMode(std::vector<std::string> const& args) this->Makefile->AddFunctionBlocker(f.release()); // TODO: pass auto_ptr - this->Makefile->PushLoopBlock(); - return true; } diff --git a/Source/cmForEachCommand.h b/Source/cmForEachCommand.h index 9b7c85a..36e8808 100644 --- a/Source/cmForEachCommand.h +++ b/Source/cmForEachCommand.h @@ -19,8 +19,8 @@ class cmForEachFunctionBlocker : public cmFunctionBlocker { public: - cmForEachFunctionBlocker() {this->Depth = 0;} - virtual ~cmForEachFunctionBlocker() {} + cmForEachFunctionBlocker(cmMakefile* mf); + ~cmForEachFunctionBlocker(); virtual bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, cmExecutionStatus &); @@ -29,6 +29,7 @@ public: std::vector<std::string> Args; std::vector<cmListFileFunction> Functions; private: + cmMakefile* Makefile; int Depth; }; diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx index 001adb1..78853ce 100644 --- a/Source/cmFunctionCommand.cxx +++ b/Source/cmFunctionCommand.cxx @@ -43,6 +43,7 @@ public: newC->Args = this->Args; newC->Functions = this->Functions; newC->Policies = this->Policies; + newC->FilePath = this->FilePath; return newC; } @@ -71,9 +72,9 @@ public: std::vector<std::string> Args; std::vector<cmListFileFunction> Functions; cmPolicies::PolicyMap Policies; + std::string FilePath; }; - bool cmFunctionHelperCommand::InvokeInitialPass (const std::vector<cmListFileArgument>& args, cmExecutionStatus & inStatus) @@ -93,14 +94,9 @@ bool cmFunctionHelperCommand::InvokeInitialPass return false; } - // we push a scope on the makefile - cmMakefile::ScopePushPop varScope(this->Makefile); - cmMakefile::LexicalPushPop lexScope(this->Makefile); - static_cast<void>(varScope); - - // Push a weak policy scope which restores the policies recorded at - // function creation. - cmMakefile::PolicyPushPop polScope(this->Makefile, true, this->Policies); + cmMakefile::FunctionPushPop functionScope(this->Makefile, + this->FilePath, + this->Policies); // set the value of argc std::ostringstream strStream; @@ -145,8 +141,7 @@ bool cmFunctionHelperCommand::InvokeInitialPass { // The error message should have already included the call stack // so we do not need to report an error here. - lexScope.Quiet(); - polScope.Quiet(); + functionScope.Quiet(); inStatus.SetNestedError(true); return false; } @@ -179,19 +174,9 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, cmFunctionHelperCommand *f = new cmFunctionHelperCommand(); f->Args = this->Args; f->Functions = this->Functions; + f->FilePath = this->GetStartingContext().FilePath; mf.RecordPolicies(f->Policies); - // Set the FilePath on the arguments to match the function since it is - // not stored and the original values may be freed - for (unsigned int i = 0; i < f->Functions.size(); ++i) - { - for (unsigned int j = 0; j < f->Functions[i].Arguments.size(); ++j) - { - f->Functions[i].Arguments[j].FilePath = - f->Functions[i].FilePath.c_str(); - } - } - std::string newName = "_" + this->Args[0]; mf.GetState()->RenameCommand(this->Args[0], newName); mf.GetState()->AddCommand(f); @@ -220,7 +205,8 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf) if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endfunction")) { std::vector<std::string> expandedArguments; - mf.ExpandArguments(lff.Arguments, expandedArguments); + mf.ExpandArguments(lff.Arguments, expandedArguments, + this->GetStartingContext().FilePath.c_str()); // if the endfunction has arguments then make sure // they match the ones in the opening function command if ((expandedArguments.empty() || diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index a1c405b..3655a87 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -34,7 +34,7 @@ cmGeneratorExpression::Parse(std::string const& input) { return cmsys::auto_ptr<cmCompiledGeneratorExpression>( new cmCompiledGeneratorExpression( - this->Backtrace ? *this->Backtrace : cmListFileBacktrace(NULL), + this->Backtrace ? *this->Backtrace : cmListFileBacktrace(), input)); } diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index ff8790c..851aacd 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -35,7 +35,7 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker( const GeneratorExpressionContent *content, cmGeneratorExpressionDAGChecker *parent) : Parent(parent), Target(target), Property(property), - Content(content), Backtrace(NULL), TransitivePropertiesOnly(false) + Content(content), Backtrace(), TransitivePropertiesOnly(false) { Initialize(); } diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index e2b8c45..4494553 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -220,14 +220,20 @@ struct TagVisitor }; //---------------------------------------------------------------------------- -cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t), +cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg) + : Target(t), SourceFileFlagsConstructed(false) { this->Makefile = this->Target->GetMakefile(); - this->LocalGenerator = this->Makefile->GetLocalGenerator(); + this->LocalGenerator = lg; this->GlobalGenerator = this->Makefile->GetGlobalGenerator(); } +cmLocalGenerator* cmGeneratorTarget::GetLocalGenerator() const +{ + return this->LocalGenerator; +} + //---------------------------------------------------------------------------- int cmGeneratorTarget::GetType() const { @@ -353,6 +359,34 @@ void cmGeneratorTarget::ComputeObjectMapping() } //---------------------------------------------------------------------------- +const char* cmGeneratorTarget::GetFeature(const std::string& feature, + const std::string& config) const +{ + if(!config.empty()) + { + std::string featureConfig = feature; + featureConfig += "_"; + featureConfig += cmSystemTools::UpperCase(config); + if(const char* value = this->Target->GetProperty(featureConfig)) + { + return value; + } + } + if(const char* value = this->Target->GetProperty(feature)) + { + return value; + } + return this->LocalGenerator->GetFeature(feature, config); +} + +//---------------------------------------------------------------------------- +bool cmGeneratorTarget::GetFeatureAsBool(const std::string& feature, + const std::string& config) const +{ + return cmSystemTools::IsOn(this->GetFeature(feature, config)); +} + +//---------------------------------------------------------------------------- const std::string& cmGeneratorTarget::GetObjectName(cmSourceFile const* file) { this->ComputeObjectMapping(); @@ -677,7 +711,8 @@ cmTargetTraceDependencies e << "Evaluation output file\n \"" << sf->GetFullPath() << "\"\ndepends on the sources of a target it is used in. This " "is a dependency loop and is not allowed."; - this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); + this->GeneratorTarget + ->LocalGenerator->IssueMessage(cmake::FATAL_ERROR, e.str()); return; } if(emitted.insert(sf).second && this->SourcesQueued.insert(sf).second) @@ -983,7 +1018,7 @@ cmGeneratorTarget::GetCreateRuleVariable(std::string const& lang, case cmTarget::STATIC_LIBRARY: { std::string var = "CMAKE_" + lang + "_CREATE_STATIC_LIBRARY"; - if(this->Target->GetFeatureAsBool( + if(this->GetFeatureAsBool( "INTERPROCEDURAL_OPTIMIZATION", config)) { std::string varIPO = var + "_IPO"; diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index c79aa72..675ee9f 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -24,7 +24,9 @@ class cmTarget; class cmGeneratorTarget { public: - cmGeneratorTarget(cmTarget*); + cmGeneratorTarget(cmTarget*, cmLocalGenerator* lg); + + cmLocalGenerator* GetLocalGenerator() const; int GetType() const; std::string GetName() const; @@ -67,6 +69,11 @@ public: void ComputeObjectMapping(); + const char* GetFeature(const std::string& feature, + const std::string& config) const; + bool GetFeatureAsBool(const std::string& feature, + const std::string& config) const; + cmTarget* Target; cmMakefile* Makefile; cmLocalGenerator* LocalGenerator; diff --git a/Source/cmGetCMakePropertyCommand.cxx b/Source/cmGetCMakePropertyCommand.cxx index 76803c1..a460ca6 100644 --- a/Source/cmGetCMakePropertyCommand.cxx +++ b/Source/cmGetCMakePropertyCommand.cxx @@ -32,8 +32,7 @@ bool cmGetCMakePropertyCommand if ( args[1] == "VARIABLES" ) { - int cacheonly = 0; - std::vector<std::string> vars = this->Makefile->GetDefinitions(cacheonly); + std::vector<std::string> vars = this->Makefile->GetDefinitions(); if (!vars.empty()) { output = cmJoin(vars, ";"); @@ -52,9 +51,11 @@ bool cmGetCMakePropertyCommand } else { - const char *prop = - this->Makefile->GetState() - ->GetGlobalProperty(args[1]); + const char *prop = 0; + if (!args[1].empty()) + { + prop = this->Makefile->GetState()->GetGlobalProperty(args[1]); + } if (prop) { output = prop; diff --git a/Source/cmGetDirectoryPropertyCommand.cxx b/Source/cmGetDirectoryPropertyCommand.cxx index 4fe3318..c056d95 100644 --- a/Source/cmGetDirectoryPropertyCommand.cxx +++ b/Source/cmGetDirectoryPropertyCommand.cxx @@ -26,7 +26,6 @@ bool cmGetDirectoryPropertyCommand std::vector<std::string>::const_iterator i = args.begin(); std::string variable = *i; ++i; - std::string output = ""; // get the directory argument if there is one cmMakefile *dir = this->Makefile; @@ -79,18 +78,45 @@ bool cmGetDirectoryPropertyCommand "providing the name of the variable to get."); return false; } - output = dir->GetSafeDefinition(*i); + std::string output = dir->GetSafeDefinition(*i); this->Makefile->AddDefinition(variable, output.c_str()); return true; } - const char *prop = dir->GetProperty(*i); + const char *prop = 0; + if (!i->empty()) + { + if (*i == "DEFINITIONS") + { + switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0059)) + { + case cmPolicies::WARN: + this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, + cmPolicies::GetPolicyWarning(cmPolicies::CMP0059)); + case cmPolicies::OLD: + this->StoreResult(variable, + this->Makefile->GetDefineFlagsCMP0059()); + return true; + case cmPolicies::NEW: + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::REQUIRED_IF_USED: + break; + } + } + prop = dir->GetProperty(*i); + } + this->StoreResult(variable, prop); + return true; +} + +void cmGetDirectoryPropertyCommand::StoreResult(std::string const& variable, + const char* prop) +{ if (prop) { this->Makefile->AddDefinition(variable, prop); - return true; + return; } this->Makefile->AddDefinition(variable, ""); - return true; } diff --git a/Source/cmGetDirectoryPropertyCommand.h b/Source/cmGetDirectoryPropertyCommand.h index 6c5750a..f418886 100644 --- a/Source/cmGetDirectoryPropertyCommand.h +++ b/Source/cmGetDirectoryPropertyCommand.h @@ -40,8 +40,9 @@ public: virtual std::string GetName() const { return "get_directory_property";} cmTypeMacro(cmGetDirectoryPropertyCommand, cmCommand); -}; - +private: + void StoreResult(const std::string& variable, const char* prop); +}; #endif diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx index 250bd35..33d638b 100644 --- a/Source/cmGetPropertyCommand.cxx +++ b/Source/cmGetPropertyCommand.cxx @@ -142,8 +142,7 @@ bool cmGetPropertyCommand { // Lookup brief documentation. std::string output; - if(cmPropertyDefinition* def = - this->Makefile->GetState()-> + if(cmPropertyDefinition const* def = this->Makefile->GetState()-> GetPropertyDefinition(this->PropertyName, scope)) { output = def->GetShortDescription(); @@ -158,8 +157,7 @@ bool cmGetPropertyCommand { // Lookup full documentation. std::string output; - if(cmPropertyDefinition* def = - this->Makefile->GetState()-> + if(cmPropertyDefinition const* def = this->Makefile->GetState()-> GetPropertyDefinition(this->PropertyName, scope)) { output = def->GetFullDescription(); @@ -281,6 +279,22 @@ bool cmGetPropertyCommand::HandleDirectoryMode() } } + if (this->PropertyName == "DEFINITIONS") + { + switch(mf->GetPolicyStatus(cmPolicies::CMP0059)) + { + case cmPolicies::WARN: + mf->IssueMessage(cmake::AUTHOR_WARNING, + cmPolicies::GetPolicyWarning(cmPolicies::CMP0059)); + case cmPolicies::OLD: + return this->StoreResult(mf->GetDefineFlagsCMP0059()); + case cmPolicies::NEW: + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::REQUIRED_IF_USED: + break; + } + } + // Get the property. return this->StoreResult(mf->GetProperty(this->PropertyName)); } diff --git a/Source/cmGetSourceFilePropertyCommand.cxx b/Source/cmGetSourceFilePropertyCommand.cxx index 7667a85..46daa34 100644 --- a/Source/cmGetSourceFilePropertyCommand.cxx +++ b/Source/cmGetSourceFilePropertyCommand.cxx @@ -38,7 +38,11 @@ bool cmGetSourceFilePropertyCommand this->Makefile->AddDefinition(var, sf->GetLanguage().c_str()); return true; } - const char *prop = sf->GetPropertyForUser(args[2]); + const char *prop = 0; + if (!args[2].empty()) + { + prop = sf->GetPropertyForUser(args[2]); + } if (prop) { this->Makefile->AddDefinition(var, prop); diff --git a/Source/cmGetTargetPropertyCommand.cxx b/Source/cmGetTargetPropertyCommand.cxx index 315e851..ca40bd0 100644 --- a/Source/cmGetTargetPropertyCommand.cxx +++ b/Source/cmGetTargetPropertyCommand.cxx @@ -40,7 +40,11 @@ bool cmGetTargetPropertyCommand else if(cmTarget* tgt = this->Makefile->FindTargetToUse(targetName)) { cmTarget& target = *tgt; - const char* prop_cstr = target.GetProperty(args[2], this->Makefile); + const char* prop_cstr = 0; + if (!args[2].empty()) + { + prop_cstr = target.GetProperty(args[2], this->Makefile); + } if(prop_cstr) { prop = prop_cstr; diff --git a/Source/cmGetTestPropertyCommand.cxx b/Source/cmGetTestPropertyCommand.cxx index b3df4c3..bf34589 100644 --- a/Source/cmGetTestPropertyCommand.cxx +++ b/Source/cmGetTestPropertyCommand.cxx @@ -29,7 +29,11 @@ bool cmGetTestPropertyCommand cmTest *test = this->Makefile->GetTest(testName); if (test) { - const char *prop = test->GetProperty(args[1]); + const char *prop = 0; + if (!args[1].empty()) + { + prop = test->GetProperty(args[1]); + } if (prop) { this->Makefile->AddDefinition(var, prop); diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx index 01e2011..2f9265a 100644 --- a/Source/cmGhsMultiTargetGenerator.cxx +++ b/Source/cmGhsMultiTargetGenerator.cxx @@ -21,23 +21,24 @@ std::string const cmGhsMultiTargetGenerator::DDOption("-dynamic"); -cmGhsMultiTargetGenerator::cmGhsMultiTargetGenerator(cmTarget *target) - : Target(target) +cmGhsMultiTargetGenerator::cmGhsMultiTargetGenerator(cmGeneratorTarget *target) + : Target(target->Target) + , GeneratorTarget(target) , LocalGenerator(static_cast<cmLocalGhsMultiGenerator *>( - target->GetMakefile()->GetLocalGenerator())) - , Makefile(target->GetMakefile()) - , TargetGroup(DetermineIfTargetGroup(target)) + target->GetLocalGenerator())) + , Makefile(target->Target->GetMakefile()) + , TargetGroup(DetermineIfTargetGroup(target->Target)) , DynamicDownload(false) { - this->RelBuildFilePath = this->GetRelBuildFilePath(target); + this->RelBuildFilePath = this->GetRelBuildFilePath(target->Target); this->RelOutputFileName = this->RelBuildFilePath + this->Target->GetName() + ".a"; this->RelBuildFileName = this->RelBuildFilePath; - this->RelBuildFileName += this->GetBuildFileName(target); + this->RelBuildFileName += this->GetBuildFileName(target->Target); - std::string absPathToRoot = this->GetAbsPathToRoot(target); + std::string absPathToRoot = this->GetAbsPathToRoot(target->Target); absPathToRoot = this->AddSlashIfNeededToPath(absPathToRoot); this->AbsBuildFilePath = absPathToRoot + this->RelBuildFilePath; this->AbsBuildFileName = absPathToRoot + this->RelBuildFileName; @@ -354,11 +355,11 @@ void cmGhsMultiTargetGenerator::WriteTargetLinkLibraries() { // library directories cmTargetDependSet tds = - this->GetGlobalGenerator()->GetTargetDirectDepends(*this->Target); + this->GetGlobalGenerator()->GetTargetDirectDepends(this->GeneratorTarget); for (cmTargetDependSet::iterator tdsI = tds.begin(); tdsI != tds.end(); ++tdsI) { - const cmTarget *tg(*tdsI); + const cmTarget *tg = (*tdsI)->Target; *this->GetFolderBuildStreams() << " -L\"" << GetAbsBuildFilePath(tg) << "\"" << std::endl; } @@ -373,7 +374,6 @@ void cmGhsMultiTargetGenerator::WriteTargetLinkLibraries() cmTarget *tg(GetGlobalGenerator()->FindTarget(libName)); if (NULL != tg) { - cmGhsMultiTargetGenerator gmtg(tg); libName = tg->GetName() + ".a"; } *this->GetFolderBuildStreams() << " -l\"" << libName << "\"" diff --git a/Source/cmGhsMultiTargetGenerator.h b/Source/cmGhsMultiTargetGenerator.h index 8e81db8..c29a31e 100644 --- a/Source/cmGhsMultiTargetGenerator.h +++ b/Source/cmGhsMultiTargetGenerator.h @@ -27,7 +27,7 @@ class cmCustomCommand; class cmGhsMultiTargetGenerator { public: - cmGhsMultiTargetGenerator(cmTarget *target); + cmGhsMultiTargetGenerator(cmGeneratorTarget* target); virtual ~cmGhsMultiTargetGenerator(); @@ -100,6 +100,7 @@ private: const std::string &language); cmTarget *Target; + cmGeneratorTarget* GeneratorTarget; cmLocalGhsMultiGenerator *LocalGenerator; cmMakefile *Makefile; std::string AbsBuildFilePath; diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index cd05c54..88ac0bc 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -70,7 +70,7 @@ cmGlobalGenerator::cmGlobalGenerator(cmake* cm) this->TryCompileTimeout = 0; this->ExtraGenerator = 0; - this->CurrentLocalGenerator = 0; + this->CurrentMakefile = 0; this->TryCompileOuterMakefile = 0; } @@ -87,18 +87,16 @@ bool cmGlobalGenerator::SetGeneratorPlatform(std::string const& p, { return true; } - else - { - std::ostringstream e; - e << - "Generator\n" - " " << this->GetName() << "\n" - "does not support platform specification, but platform\n" - " " << p << "\n" - "was specified."; - mf->IssueMessage(cmake::FATAL_ERROR, e.str()); - return false; - } + + std::ostringstream e; + e << + "Generator\n" + " " << this->GetName() << "\n" + "does not support platform specification, but platform\n" + " " << p << "\n" + "was specified."; + mf->IssueMessage(cmake::FATAL_ERROR, e.str()); + return false; } bool cmGlobalGenerator::SetGeneratorToolset(std::string const& ts, @@ -108,18 +106,15 @@ bool cmGlobalGenerator::SetGeneratorToolset(std::string const& ts, { return true; } - else - { - std::ostringstream e; - e << - "Generator\n" - " " << this->GetName() << "\n" - "does not support toolset specification, but toolset\n" - " " << ts << "\n" - "was specified."; - mf->IssueMessage(cmake::FATAL_ERROR, e.str()); - return false; - } + std::ostringstream e; + e << + "Generator\n" + " " << this->GetName() << "\n" + "does not support toolset specification, but toolset\n" + " " << ts << "\n" + "was specified."; + mf->IssueMessage(cmake::FATAL_ERROR, e.str()); + return false; } std::string cmGlobalGenerator::SelectMakeProgram( @@ -569,6 +564,10 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, cmSystemTools::Error("Could not find cmake module file: ", determineCompiler.c_str()); } + if (cmSystemTools::GetFatalErrorOccured()) + { + return; + } needTestLanguage[lang] = true; // Some generators like visual studio should not use the env variables // So the global generator can specify that in this variable @@ -1106,7 +1105,8 @@ void cmGlobalGenerator::Configure() this->CMakeInstance->GetHomeOutputDirectory()); // now do it - lg->Configure(); + lg->GetMakefile()->Configure(); + lg->GetMakefile()->EnforceDirectoryLevelRules(); // update the cache entry for the number of local generators, this is used // for progress @@ -1223,6 +1223,7 @@ void cmGlobalGenerator::Generate() this->CreateDefaultGlobalTargets(&globalTargets); for (i = 0; i < this->LocalGenerators.size(); ++i) { + this->LocalGenerators[i]->ComputeObjectMaxPath(); cmMakefile* mf = this->LocalGenerators[i]->GetMakefile(); cmTargets* targets = &(mf->GetTargets()); cmTargets::iterator tit; @@ -1277,11 +1278,15 @@ void cmGlobalGenerator::Generate() // it builds by default. this->FillLocalGeneratorToTargetMap(); + for (i = 0; i < this->LocalGenerators.size(); ++i) + { + this->LocalGenerators[i]->ComputeHomeRelativeOutputPath(); + } + // Generate project files for (i = 0; i < this->LocalGenerators.size(); ++i) { - this->LocalGenerators[i]->GetMakefile()->SetGeneratingBuildSystem(); - this->SetCurrentLocalGenerator(this->LocalGenerators[i]); + this->SetCurrentMakefile(this->LocalGenerators[i]->GetMakefile()); this->LocalGenerators[i]->Generate(); if(!this->LocalGenerators[i]->GetMakefile()->IsOn( "CMAKE_SKIP_INSTALL_RULES")) @@ -1293,7 +1298,7 @@ void cmGlobalGenerator::Generate() (static_cast<float>(i)+1.0f)/ static_cast<float>(this->LocalGenerators.size())); } - this->SetCurrentLocalGenerator(0); + this->SetCurrentMakefile(0); if(!this->GenerateCPackPropertiesFile()) { @@ -1350,9 +1355,9 @@ bool cmGlobalGenerator::ComputeTargetDepends() { return false; } - std::vector<cmTarget const*> const& targets = ctd.GetTargets(); - for(std::vector<cmTarget const*>::const_iterator ti = targets.begin(); - ti != targets.end(); ++ti) + std::vector<cmGeneratorTarget const*> const& targets = ctd.GetTargets(); + for(std::vector<cmGeneratorTarget const*>::const_iterator ti + = targets.begin(); ti != targets.end(); ++ti) { ctd.GetTargetDirectDepends(*ti, this->TargetDependencies[*ti]); } @@ -1456,15 +1461,16 @@ void cmGlobalGenerator::FinalizeTargetCompileInfo() } //---------------------------------------------------------------------------- -void cmGlobalGenerator::CreateGeneratorTargets(cmMakefile *mf) +void cmGlobalGenerator::CreateGeneratorTargets(cmLocalGenerator *lg) { cmGeneratorTargetsType generatorTargets; + cmMakefile* mf = lg->GetMakefile(); cmTargets& targets = mf->GetTargets(); for(cmTargets::iterator ti = targets.begin(); ti != targets.end(); ++ti) { cmTarget* t = &ti->second; - cmGeneratorTarget* gt = new cmGeneratorTarget(t); + cmGeneratorTarget* gt = new cmGeneratorTarget(t, lg); this->ComputeTargetObjectDirectory(gt); this->GeneratorTargets[t] = gt; generatorTargets[t] = gt; @@ -1474,7 +1480,7 @@ void cmGlobalGenerator::CreateGeneratorTargets(cmMakefile *mf) j = mf->GetOwnedImportedTargets().begin(); j != mf->GetOwnedImportedTargets().end(); ++j) { - cmGeneratorTarget* gt = new cmGeneratorTarget(*j); + cmGeneratorTarget* gt = new cmGeneratorTarget(*j, lg); this->GeneratorTargets[*j] = gt; generatorTargets[*j] = gt; } @@ -1487,7 +1493,7 @@ void cmGlobalGenerator::CreateGeneratorTargets() // Construct per-target generator information. for(unsigned int i=0; i < this->LocalGenerators.size(); ++i) { - this->CreateGeneratorTargets(this->LocalGenerators[i]->GetMakefile()); + this->CreateGeneratorTargets(this->LocalGenerators[i]); } } @@ -1545,7 +1551,7 @@ void cmGlobalGenerator::CheckLocalGenerators() cmState* state = this->GetCMakeInstance()->GetState(); for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i) { - this->LocalGenerators[i]->ConfigureFinalPass(); + this->LocalGenerators[i]->GetMakefile()->ConfigureFinalPass(); cmTargets &targets = this->LocalGenerators[i]->GetMakefile()->GetTargets(); for (cmTargets::iterator l = targets.begin(); @@ -2038,19 +2044,19 @@ void cmGlobalGenerator::FillLocalGeneratorToTargetMap() clg = clg->GetParent()) { // This local generator includes the target. - std::set<cmTarget const*>& targetSet = + std::set<cmGeneratorTarget const*>& targetSet = this->LocalGeneratorToTargetMap[clg]; - targetSet.insert(&target); + cmGeneratorTarget* gt = this->GetGeneratorTarget(&target); + targetSet.insert(gt); // Add dependencies of the included target. An excluded // target may still be included if it is a dependency of a // non-excluded target. - TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(target); + TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(gt); for(TargetDependSet::const_iterator ti = tgtdeps.begin(); ti != tgtdeps.end(); ++ti) { - cmTarget const* ttt = *ti; - targetSet.insert(ttt); + targetSet.insert(*ti); } } } @@ -2443,7 +2449,6 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget( { // Package cmTarget target; - target.GetProperties().SetCMakeInstance(this->CMakeInstance); target.SetType(cmTarget::GLOBAL_TARGET, name); target.SetProperty("EXCLUDE_FROM_ALL","TRUE"); @@ -2513,9 +2518,9 @@ void cmGlobalGenerator::AppendDirectoryForConfig(const std::string&, //---------------------------------------------------------------------------- cmGlobalGenerator::TargetDependSet const& -cmGlobalGenerator::GetTargetDirectDepends(cmTarget const& target) +cmGlobalGenerator::GetTargetDirectDepends(cmGeneratorTarget const* target) { - return this->TargetDependencies[&target]; + return this->TargetDependencies[target]; } void cmGlobalGenerator::AddTarget(cmTarget* t) @@ -2615,9 +2620,10 @@ void cmGlobalGenerator::GetTargetSets(TargetDependSet& projectTargets, continue; } // put the target in the set of original targets - originalTargets.insert(target); + cmGeneratorTarget* gt = this->GetGeneratorTarget(target); + originalTargets.insert(gt); // Get the set of targets that depend on target - this->AddTargetDepends(target, projectTargets); + this->AddTargetDepends(gt, projectTargets); } } } @@ -2630,7 +2636,7 @@ bool cmGlobalGenerator::IsRootOnlyTarget(cmTarget* target) const } //---------------------------------------------------------------------------- -void cmGlobalGenerator::AddTargetDepends(cmTarget const* target, +void cmGlobalGenerator::AddTargetDepends(cmGeneratorTarget const* target, TargetDependSet& projectTargets) { // add the target itself @@ -2638,11 +2644,10 @@ void cmGlobalGenerator::AddTargetDepends(cmTarget const* target, { // This is the first time we have encountered the target. // Recursively follow its dependencies. - TargetDependSet const& ts = this->GetTargetDirectDepends(*target); + TargetDependSet const& ts = this->GetTargetDirectDepends(target); for(TargetDependSet::const_iterator i = ts.begin(); i != ts.end(); ++i) { - cmTarget const* dtarget = *i; - this->AddTargetDepends(dtarget, projectTargets); + this->AddTargetDepends(*i, projectTargets); } } } diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 979e971..398335b 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -168,11 +168,13 @@ public: const std::vector<cmLocalGenerator *>& GetLocalGenerators() const { return this->LocalGenerators;} - cmLocalGenerator* GetCurrentLocalGenerator() - {return this->CurrentLocalGenerator;} + cmMakefile* GetCurrentMakefile() const + { + return this->CurrentMakefile; + } - void SetCurrentLocalGenerator(cmLocalGenerator* lg) - {this->CurrentLocalGenerator = lg;} + void SetCurrentMakefile(cmMakefile* mf) + {this->CurrentMakefile = mf;} void AddLocalGenerator(cmLocalGenerator *lg); @@ -290,7 +292,8 @@ public: // what targets does the specified target depend on directly // via a target_link_libraries or add_dependencies - TargetDependSet const& GetTargetDirectDepends(cmTarget const& target); + TargetDependSet const& GetTargetDirectDepends( + const cmGeneratorTarget* target); /** Get per-target generator information. */ cmGeneratorTarget* GetGeneratorTarget(cmTarget const*) const; @@ -310,8 +313,6 @@ public: { return this->BinaryDirectories.insert(dir).second; } - /** Supported systems creates a GUID for the given name */ - virtual void CreateGUID(const std::string&) {} /** Return true if the generated build tree may contain multiple builds. i.e. "Can I build Debug and Release in the same tree?" */ @@ -368,7 +369,7 @@ protected: TargetDependSet& originalTargets, cmLocalGenerator* root, GeneratorVector const&); bool IsRootOnlyTarget(cmTarget* target) const; - void AddTargetDepends(cmTarget const* target, + void AddTargetDepends(const cmGeneratorTarget* target, TargetDependSet& projectTargets); void SetLanguageEnabledFlag(const std::string& l, cmMakefile* mf); void SetLanguageEnabledMaps(const std::string& l, cmMakefile* mf); @@ -398,23 +399,18 @@ protected: std::vector<std::string> depends, const char* workingDir, bool uses_terminal); - bool NeedSymbolicMark; - bool UseLinkScript; - bool ForceUnixPaths; - bool ToolSupportsColor; std::string FindMakeProgramFile; std::string ConfiguredFilesPath; cmake *CMakeInstance; std::vector<cmLocalGenerator *> LocalGenerators; - cmLocalGenerator* CurrentLocalGenerator; + cmMakefile* CurrentMakefile; // map from project name to vector of local generators in that project std::map<std::string, std::vector<cmLocalGenerator*> > ProjectMap; - std::map<cmLocalGenerator*, std::set<cmTarget const*> > + std::map<cmLocalGenerator*, std::set<cmGeneratorTarget const*> > LocalGeneratorToTargetMap; // Set of named installation components requested by the project. std::set<std::string> InstallComponents; - bool InstallTargetEnabled; // Sets of named target exports cmExportSetMap ExportSets; std::map<std::string, cmExportBuildFileGenerator*> BuildExportSets; @@ -448,7 +444,6 @@ private: cmState::Snapshot snapshot); cmMakefile* TryCompileOuterMakefile; - float FirstTimeProgress; // If you add a new map here, make sure it is copied // in EnableLanguagesFromGenerator std::map<std::string, bool> IgnoreExtensions; @@ -483,13 +478,13 @@ private: std::vector<std::string> FilesReplacedDuringGenerate; // Store computed inter-target dependencies. - typedef std::map<cmTarget const*, TargetDependSet> TargetDependMap; + typedef std::map<cmGeneratorTarget const*, TargetDependSet> TargetDependMap; TargetDependMap TargetDependencies; // Per-target generator information. cmGeneratorTargetsType GeneratorTargets; friend class cmake; - void CreateGeneratorTargets(cmMakefile* mf); + void CreateGeneratorTargets(cmLocalGenerator* lg); void CreateGeneratorTargets(); void ClearGeneratorMembers(); @@ -521,6 +516,14 @@ private: // Pool of file locks cmFileLockPool FileLockPool; #endif + +protected: + float FirstTimeProgress; + bool NeedSymbolicMark; + bool UseLinkScript; + bool ForceUnixPaths; + bool ToolSupportsColor; + bool InstallTargetEnabled; }; #endif diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 103d75a..722294b 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -949,8 +949,8 @@ cmGlobalNinjaGenerator std::set<std::string> const& utils = target->GetUtilities(); std::copy(utils.begin(), utils.end(), std::back_inserter(outputs)); } else { - cmTargetDependSet const& targetDeps = - this->GetTargetDirectDepends(*target); + cmGeneratorTarget* gt = this->GetGeneratorTarget(target); + cmTargetDependSet const& targetDeps = this->GetTargetDirectDepends(gt); for (cmTargetDependSet::const_iterator i = targetDeps.begin(); i != targetDeps.end(); ++i) { @@ -958,7 +958,7 @@ cmGlobalNinjaGenerator { continue; } - this->AppendTargetOutputs(*i, outputs); + this->AppendTargetOutputs((*i)->Target, outputs); } } } diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 4fe52dd..e6a67d3 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -529,7 +529,7 @@ cmGlobalUnixMakefileGenerator3 cmLocalUnixMakefileGenerator3* lg) { // Only subdirectories need these rules. - if(lg->IsRootMakefile()) + if(lg->GetMakefile()->IsRootMakefile()) { return; } @@ -804,7 +804,7 @@ cmGlobalUnixMakefileGenerator3 lg->AppendEcho(commands, "Built target " + name, cmLocalUnixMakefileGenerator3::EchoNormal, &progress); - this->AppendGlobalTargetDepends(depends,*gtarget->Target); + this->AppendGlobalTargetDepends(depends, gtarget); lg->WriteMakeRule(ruleFileStream, "All Build rule for target.", localName, depends, commands, true); @@ -830,9 +830,9 @@ cmGlobalUnixMakefileGenerator3 cmLocalGenerator::FULL, cmLocalGenerator::SHELL); // - std::set<cmTarget const*> emitted; + std::set<cmGeneratorTarget const*> emitted; progCmd << " " - << this->CountProgressMarksInTarget(gtarget->Target, emitted); + << this->CountProgressMarksInTarget(gtarget, emitted); commands.push_back(progCmd.str()); } std::string tmp = cmake::GetCMakeFilesDirectoryPostSlash(); @@ -908,14 +908,14 @@ cmGlobalUnixMakefileGenerator3 //---------------------------------------------------------------------------- size_t cmGlobalUnixMakefileGenerator3 -::CountProgressMarksInTarget(cmTarget const* target, - std::set<cmTarget const*>& emitted) +::CountProgressMarksInTarget(cmGeneratorTarget const* target, + std::set<cmGeneratorTarget const*>& emitted) { size_t count = 0; if(emitted.insert(target).second) { - count = this->ProgressMap[target].Marks.size(); - TargetDependSet const& depends = this->GetTargetDirectDepends(*target); + count = this->ProgressMap[target->Target].Marks.size(); + TargetDependSet const& depends = this->GetTargetDirectDepends(target); for(TargetDependSet::const_iterator di = depends.begin(); di != depends.end(); ++di) { @@ -935,10 +935,10 @@ cmGlobalUnixMakefileGenerator3 ::CountProgressMarksInAll(cmLocalUnixMakefileGenerator3* lg) { size_t count = 0; - std::set<cmTarget const*> emitted; - std::set<cmTarget const*> const& targets + std::set<cmGeneratorTarget const*> emitted; + std::set<cmGeneratorTarget const*> const& targets = this->LocalGeneratorToTargetMap[lg]; - for(std::set<cmTarget const*>::const_iterator t = targets.begin(); + for(std::set<cmGeneratorTarget const*>::const_iterator t = targets.begin(); t != targets.end(); ++t) { count += this->CountProgressMarksInTarget(*t, emitted); @@ -987,22 +987,21 @@ cmGlobalUnixMakefileGenerator3::TargetProgress void cmGlobalUnixMakefileGenerator3 ::AppendGlobalTargetDepends(std::vector<std::string>& depends, - cmTarget& target) + cmGeneratorTarget* target) { TargetDependSet const& depends_set = this->GetTargetDirectDepends(target); for(TargetDependSet::const_iterator i = depends_set.begin(); i != depends_set.end(); ++i) { // Create the target-level dependency. - cmTarget const* dep = *i; + cmGeneratorTarget const* dep = *i; if (dep->GetType() == cmTarget::INTERFACE_LIBRARY) { continue; } cmLocalUnixMakefileGenerator3* lg3 = - static_cast<cmLocalUnixMakefileGenerator3*> - (dep->GetMakefile()->GetLocalGenerator()); - std::string tgtName = lg3->GetRelativeTargetDirectory(*dep); + static_cast<cmLocalUnixMakefileGenerator3*>(dep->GetLocalGenerator()); + std::string tgtName = lg3->GetRelativeTargetDirectory(*(*dep).Target); tgtName += "/all"; depends.push_back(tgtName); } @@ -1034,7 +1033,7 @@ void cmGlobalUnixMakefileGenerator3::WriteHelpRule static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]); // for the passed in makefile or if this is the top Makefile wripte out // the targets - if (lg2 == lg || lg->IsRootMakefile()) + if (lg2 == lg || lg->GetMakefile()->IsRootMakefile()) { // for each target Generate the rule files for each target. cmTargets& targets = lg2->GetMakefile()->GetTargets(); diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index a639ff0..14adf2e 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -153,7 +153,7 @@ protected: cmLocalUnixMakefileGenerator3* lg); void AppendGlobalTargetDepends(std::vector<std::string>& depends, - cmTarget& target); + cmGeneratorTarget* target); // does this generator need a requires step for any of its targets bool NeedRequiresStep(cmTarget const&); @@ -198,8 +198,8 @@ protected: cmStrictTargetComparison> ProgressMapType; ProgressMapType ProgressMap; - size_t CountProgressMarksInTarget(cmTarget const* target, - std::set<cmTarget const*>& emitted); + size_t CountProgressMarksInTarget(cmGeneratorTarget const* target, + std::set<cmGeneratorTarget const*>& emitted); size_t CountProgressMarksInAll(cmLocalUnixMakefileGenerator3* lg); cmGeneratedFileStream *CommandDatabase; diff --git a/Source/cmGlobalVisualStudio6Generator.cxx b/Source/cmGlobalVisualStudio6Generator.cxx index 632141a..65a15ee 100644 --- a/Source/cmGlobalVisualStudio6Generator.cxx +++ b/Source/cmGlobalVisualStudio6Generator.cxx @@ -224,7 +224,7 @@ void cmGlobalVisualStudio6Generator tt = orderedProjectTargets.begin(); tt != orderedProjectTargets.end(); ++tt) { - cmTarget const* target = *tt; + cmTarget const* target = (*tt)->Target; if(target->GetType() == cmTarget::INTERFACE_LIBRARY) { continue; diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index 4dd54d0..1674e98 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -15,6 +15,7 @@ #include "cmGeneratedFileStream.h" #include "cmLocalVisualStudio7Generator.h" #include "cmMakefile.h" +#include "cmUuid.h" #include "cmake.h" #include <cmsys/Encoding.hxx> @@ -401,7 +402,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations( for(OrderedTargetDependSet::const_iterator tt = projectTargets.begin(); tt != projectTargets.end(); ++tt) { - cmTarget const* target = *tt; + cmTarget const* target = (*tt)->Target; if(target->GetType() == cmTarget::INTERFACE_LIBRARY) { continue; @@ -441,7 +442,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution( for(OrderedTargetDependSet::const_iterator tt = projectTargets.begin(); tt != projectTargets.end(); ++tt) { - cmTarget const* target = *tt; + cmTarget const* target = (*tt)->Target; if(target->GetType() == cmTarget::INTERFACE_LIBRARY) { continue; @@ -513,8 +514,6 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution( cumulativePath = cumulativePath + "/" + *iter; } - - this->CreateGUID(cumulativePath.c_str()); } if (!cumulativePath.empty()) @@ -535,7 +534,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetDepends( for(OrderedTargetDependSet::const_iterator tt = projectTargets.begin(); tt != projectTargets.end(); ++tt) { - cmTarget const* target = *tt; + cmTarget const* target = (*tt)->Target; if(target->GetType() == cmTarget::INTERFACE_LIBRARY) { continue; @@ -899,7 +898,6 @@ cmGlobalVisualStudio7Generator::WriteUtilityDepend(cmTarget const* target) fname += ".vcproj"; cmGeneratedFileStream fout(fname.c_str()); fout.SetCopyIfDifferent(true); - this->CreateGUID(pname.c_str()); std::string guid = this->GetGUID(pname.c_str()); fout << @@ -943,41 +941,29 @@ cmGlobalVisualStudio7Generator::WriteUtilityDepend(cmTarget const* target) return pname; } -std::string cmGlobalVisualStudio7Generator::GetGUID(const std::string& name) +//---------------------------------------------------------------------------- +std::string cmGlobalVisualStudio7Generator::GetGUID(std::string const& name) { - std::string guidStoreName = name; - guidStoreName += "_GUID_CMAKE"; - const char* storedGUID = - this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str()); - if(storedGUID) + std::string const& guidStoreName = name + "_GUID_CMAKE"; + if (const char* storedGUID = + this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str())) { return std::string(storedGUID); } - cmSystemTools::Error("Unknown Target referenced : ", - name.c_str()); - return ""; -} + // Compute a GUID that is deterministic but unique to the build tree. + std::string input = this->CMakeInstance->GetState()->GetBinaryDirectory(); + input += "|"; + input += name; + cmUuid uuidGenerator; -void cmGlobalVisualStudio7Generator::CreateGUID(const std::string& name) -{ - std::string guidStoreName = name; - guidStoreName += "_GUID_CMAKE"; - if(this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str())) - { - return; - } - std::string ret; - UUID uid; - unsigned short *uidstr; - UuidCreate(&uid); - UuidToStringW(&uid,&uidstr); - ret = cmsys::Encoding::ToNarrow(reinterpret_cast<wchar_t*>(uidstr)); - RpcStringFreeW(&uidstr); - ret = cmSystemTools::UpperCase(ret); - this->CMakeInstance->AddCacheEntry(guidStoreName.c_str(), - ret.c_str(), "Stored GUID", - cmState::INTERNAL); + std::vector<unsigned char> uuidNamespace; + uuidGenerator.StringToBinary( + "ee30c4be-5192-4fb0-b335-722a2dffe760", uuidNamespace); + + std::string guid = uuidGenerator.FromMd5(uuidNamespace, input); + + return cmSystemTools::UpperCase(guid); } //---------------------------------------------------------------------------- @@ -1039,12 +1025,13 @@ cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild( { return activeConfigs; } + cmGeneratorTarget* gt = this->GetGeneratorTarget(target); // inspect EXCLUDE_FROM_DEFAULT_BUILD[_<CONFIG>] properties for(std::vector<std::string>::const_iterator i = configs.begin(); i != configs.end(); ++i) { const char* propertyValue = - target->GetFeature("EXCLUDE_FROM_DEFAULT_BUILD", i->c_str()); + gt->GetFeature("EXCLUDE_FROM_DEFAULT_BUILD", i->c_str()); if(cmSystemTools::IsOff(propertyValue)) { activeConfigs.insert(*i); @@ -1058,12 +1045,12 @@ cmGlobalVisualStudio7Generator ::IsDependedOn(OrderedTargetDependSet const& projectTargets, cmTarget const* targetIn) { + cmGeneratorTarget* gtIn = this->GetGeneratorTarget(targetIn); for (OrderedTargetDependSet::const_iterator l = projectTargets.begin(); l != projectTargets.end(); ++l) { - cmTarget const& target = **l; - TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(target); - if(tgtdeps.count(targetIn)) + TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(*l); + if(tgtdeps.count(gtIn)) { return true; } diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h index c98d269..931ac9c 100644 --- a/Source/cmGlobalVisualStudio7Generator.h +++ b/Source/cmGlobalVisualStudio7Generator.h @@ -80,9 +80,8 @@ public: */ virtual void OutputSLNFile(); - ///! Create a GUID or get an existing one. - void CreateGUID(const std::string& name); - std::string GetGUID(const std::string& name); + ///! Lookup a stored GUID or compute one deterministically. + std::string GetGUID(std::string const& name); /** Append the subdirectory for the given configuration. */ virtual void AppendDirectoryForConfig(const std::string& prefix, diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index a3ebc61..f3cf36e 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -185,7 +185,6 @@ void cmGlobalVisualStudio8Generator void cmGlobalVisualStudio8Generator::Configure() { this->cmGlobalVisualStudio7Generator::Configure(); - this->CreateGUID(CMAKE_CHECK_BUILD_SYSTEM_TARGET); } //---------------------------------------------------------------------------- @@ -310,14 +309,10 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget() cmCustomCommandLine commandLine; commandLine.push_back(cmSystemTools::GetCMakeCommand()); std::string argH = "-H"; - argH += lg->Convert(mf->GetHomeDirectory(), - cmLocalGenerator::START_OUTPUT, - cmLocalGenerator::UNCHANGED, true); + argH += mf->GetHomeDirectory(); commandLine.push_back(argH); std::string argB = "-B"; - argB += lg->Convert(mf->GetHomeOutputDirectory(), - cmLocalGenerator::START_OUTPUT, - cmLocalGenerator::UNCHANGED, true); + argB += mf->GetHomeOutputDirectory(); commandLine.push_back(argB); commandLine.push_back("--check-stamp-list"); commandLine.push_back(stampList.c_str()); @@ -446,7 +441,8 @@ bool cmGlobalVisualStudio8Generator::ComputeTargetDepends() void cmGlobalVisualStudio8Generator::WriteProjectDepends( std::ostream& fout, const std::string&, const char*, cmTarget const& t) { - TargetDependSet const& unordered = this->GetTargetDirectDepends(t); + cmGeneratorTarget* gt = this->GetGeneratorTarget(&t); + TargetDependSet const& unordered = this->GetTargetDirectDepends(gt); OrderedTargetDependSet depends(unordered); for(OrderedTargetDependSet::const_iterator i = depends.begin(); i != depends.end(); ++i) diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index 585d19a..1d583eb 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -13,12 +13,14 @@ #include "cmGlobalVisualStudioGenerator.h" #include "cmCallVisualStudioMacro.h" +#include "cmGeneratedFileStream.h" #include "cmGeneratorTarget.h" #include "cmLocalVisualStudioGenerator.h" #include "cmMakefile.h" #include "cmSourceFile.h" #include "cmTarget.h" #include <cmsys/Encoding.hxx> +#include "cmAlgorithms.h" //---------------------------------------------------------------------------- cmGlobalVisualStudioGenerator::cmGlobalVisualStudioGenerator(cmake* cm) @@ -299,13 +301,14 @@ void cmGlobalVisualStudioGenerator::FillLinkClosure(cmTarget const* target, { if(linked.insert(target).second) { - TargetDependSet const& depends = this->GetTargetDirectDepends(*target); + cmGeneratorTarget* gt = this->GetGeneratorTarget(target); + TargetDependSet const& depends = this->GetTargetDirectDepends(gt); for(TargetDependSet::const_iterator di = depends.begin(); di != depends.end(); ++di) { if(di->IsLink()) { - this->FillLinkClosure(*di, linked); + this->FillLinkClosure((*di)->Target, linked); } } } @@ -338,13 +341,14 @@ void cmGlobalVisualStudioGenerator::FollowLinkDepends( { // Static library targets do not list their link dependencies so // we must follow them transitively now. - TargetDependSet const& depends = this->GetTargetDirectDepends(*target); + cmGeneratorTarget* gt = this->GetGeneratorTarget(target); + TargetDependSet const& depends = this->GetTargetDirectDepends(gt); for(TargetDependSet::const_iterator di = depends.begin(); di != depends.end(); ++di) { if(di->IsLink()) { - this->FollowLinkDepends(*di, linked); + this->FollowLinkDepends((*di)->Target, linked); } } } @@ -413,7 +417,8 @@ void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target) target.GetType() != cmTarget::MODULE_LIBRARY && target.GetType() != cmTarget::EXECUTABLE); - TargetDependSet const& depends = this->GetTargetDirectDepends(target); + cmGeneratorTarget* gt = this->GetGeneratorTarget(&target); + TargetDependSet const& depends = this->GetTargetDirectDepends(gt); // Collect implicit link dependencies (target_link_libraries). // Static libraries cannot depend on their link implementation @@ -427,7 +432,7 @@ void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target) cmTargetDepend dep = *di; if(dep.IsLink()) { - this->FollowLinkDepends(dep, linkDepends); + this->FollowLinkDepends(dep->Target, linkDepends); } } } @@ -440,7 +445,7 @@ void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target) cmTargetDepend dep = *di; if(dep.IsUtil()) { - this->FollowLinkDepends(dep, utilDepends); + this->FollowLinkDepends(dep->Target, utilDepends); } } @@ -843,7 +848,7 @@ cmGlobalVisualStudioGenerator::TargetIsFortranOnly(cmTarget const& target) //---------------------------------------------------------------------------- bool cmGlobalVisualStudioGenerator::TargetCompare -::operator()(cmTarget const* l, cmTarget const* r) const +::operator()(cmGeneratorTarget const* l, cmGeneratorTarget const* r) const { // Make sure ALL_BUILD is first so it is the default active project. if(r->GetName() == "ALL_BUILD") @@ -868,7 +873,13 @@ cmGlobalVisualStudioGenerator::OrderedTargetDependSet cmGlobalVisualStudioGenerator::OrderedTargetDependSet ::OrderedTargetDependSet(TargetSet const& targets) { - this->insert(targets.begin(), targets.end()); + for (TargetSet::const_iterator it = targets.begin(); + it != targets.end(); ++it) + { + cmGeneratorTarget* gt = + (*it)->GetMakefile()->GetGlobalGenerator()->GetGeneratorTarget(*it); + this->insert(gt); + } } std::string cmGlobalVisualStudioGenerator::ExpandCFGIntDir( @@ -887,3 +898,71 @@ std::string cmGlobalVisualStudioGenerator::ExpandCFGIntDir( } return tmp; } + +void cmGlobalVisualStudioGenerator::AddSymbolExportCommand( + cmGeneratorTarget* gt, std::vector<cmCustomCommand>& commands, + std::string const& configName) +{ + std::vector<std::string> outputs; + std::string deffile = gt->ObjectDirectory; + deffile += "/exportall.def"; + outputs.push_back(deffile); + std::vector<std::string> empty; + std::vector<cmSourceFile const*> objectSources; + gt->GetObjectSources(objectSources, configName); + std::map<cmSourceFile const*, std::string> mapping; + for(std::vector<cmSourceFile const*>::const_iterator it + = objectSources.begin(); it != objectSources.end(); ++it) + { + mapping[*it]; + } + gt->LocalGenerator-> + ComputeObjectFilenames(mapping, gt); + std::string obj_dir = gt->ObjectDirectory; + std::string cmakeCommand = cmSystemTools::GetCMakeCommand(); + cmSystemTools::ConvertToWindowsExtendedPath(cmakeCommand); + cmCustomCommandLine cmdl; + cmdl.push_back(cmakeCommand); + cmdl.push_back("-E"); + cmdl.push_back("__create_def"); + cmdl.push_back(deffile); + std::string obj_dir_expanded = obj_dir; + cmSystemTools::ReplaceString(obj_dir_expanded, + this->GetCMakeCFGIntDir(), + configName.c_str()); + std::string objs_file = obj_dir_expanded; + cmSystemTools::MakeDirectory(objs_file.c_str()); + objs_file += "/objects.txt"; + cmdl.push_back(objs_file); + cmGeneratedFileStream fout(objs_file.c_str()); + if(!fout) + { + cmSystemTools::Error("could not open ", objs_file.c_str()); + return; + } + for(std::vector<cmSourceFile const*>::const_iterator it + = objectSources.begin(); it != objectSources.end(); ++it) + { + // Find the object file name corresponding to this source file. + std::map<cmSourceFile const*, std::string>::const_iterator + map_it = mapping.find(*it); + // It must exist because we populated the mapping just above. + assert(!map_it->second.empty()); + std::string objFile = obj_dir + map_it->second; + // replace $(ConfigurationName) in the object names + cmSystemTools::ReplaceString(objFile, this->GetCMakeCFGIntDir(), + configName.c_str()); + if(cmHasLiteralSuffix(objFile, ".obj")) + { + fout << objFile << "\n"; + } + } + cmCustomCommandLines commandLines; + commandLines.push_back(cmdl); + cmCustomCommand command(gt->Target->GetMakefile(), + outputs, empty, empty, + commandLines, + "Auto build dll exports", + "."); + commands.push_back(command); +} diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h index 69b4564..8e2d6a4 100644 --- a/Source/cmGlobalVisualStudioGenerator.h +++ b/Source/cmGlobalVisualStudioGenerator.h @@ -91,7 +91,8 @@ public: class TargetSet: public std::set<cmTarget const*> {}; struct TargetCompare { - bool operator()(cmTarget const* l, cmTarget const* r) const; + bool operator()(cmGeneratorTarget const* l, + cmGeneratorTarget const* r) const; }; class OrderedTargetDependSet; @@ -102,6 +103,10 @@ public: const std::string& config) const; void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const; + + void AddSymbolExportCommand( + cmGeneratorTarget*, std::vector<cmCustomCommand>& commands, + std::string const& configName); protected: virtual void Generate(); diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 7464e90..21075bb 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -843,6 +843,10 @@ GetSourcecodeValueFromFileExtension(const std::string& _ext, { sourcecode += ".c.objc"; } + else if (ext == "swift") + { + sourcecode += ".swift"; + } else if(ext == "plist") { sourcecode += ".text.plist"; @@ -2895,10 +2899,11 @@ void cmGlobalXCodeGenerator } // Add dependencies on other CMake targets. - TargetDependSet const& deps = this->GetTargetDirectDepends(*cmtarget); + cmGeneratorTarget* gt = this->GetGeneratorTarget(cmtarget); + TargetDependSet const& deps = this->GetTargetDirectDepends(gt); for(TargetDependSet::const_iterator i = deps.begin(); i != deps.end(); ++i) { - if(cmXCodeObject* dptarget = this->FindXCodeTarget(*i)) + if(cmXCodeObject* dptarget = this->FindXCodeTarget((*i)->Target)) { this->AddDependTarget(target, dptarget); } @@ -3804,33 +3809,13 @@ void cmGlobalXCodeGenerator::GetDocumentation(cmDocumentationEntry& entry) //---------------------------------------------------------------------------- std::string cmGlobalXCodeGenerator::ConvertToRelativeForMake(const char* p) { - if ( !this->CurrentMakefile->IsOn("CMAKE_USE_RELATIVE_PATHS") ) - { - return cmSystemTools::ConvertToOutputPath(p); - } - else - { - std::string ret = - this->CurrentLocalGenerator-> - ConvertToRelativePath(this->CurrentOutputDirectoryComponents, p); - return cmSystemTools::ConvertToOutputPath(ret.c_str()); - } + return cmSystemTools::ConvertToOutputPath(p); } //---------------------------------------------------------------------------- std::string cmGlobalXCodeGenerator::ConvertToRelativeForXCode(const char* p) { - if ( !this->CurrentMakefile->IsOn("CMAKE_USE_RELATIVE_PATHS") ) - { - return cmSystemTools::ConvertToOutputPath(p); - } - else - { - std::string ret = - this->CurrentLocalGenerator-> - ConvertToRelativePath(this->ProjectOutputDirectoryComponents, p); - return cmSystemTools::ConvertToOutputPath(ret.c_str()); - } + return cmSystemTools::ConvertToOutputPath(p); } //---------------------------------------------------------------------------- diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx index 7f4c4c9..fa29b4f 100644 --- a/Source/cmGraphVizWriter.cxx +++ b/Source/cmGraphVizWriter.cxx @@ -48,6 +48,7 @@ cmGraphVizWriter::cmGraphVizWriter(const std::vector<cmLocalGenerator*>& ,GraphName("GG") ,GraphHeader("node [\n fontsize = \"12\"\n];") ,GraphNodePrefix("node") +,LocalGenerators(localGenerators) ,GenerateForExecutables(true) ,GenerateForStaticLibs(true) ,GenerateForSharedLibs(true) @@ -55,7 +56,6 @@ cmGraphVizWriter::cmGraphVizWriter(const std::vector<cmLocalGenerator*>& ,GenerateForExternals(true) ,GeneratePerTarget(true) ,GenerateDependers(true) -,LocalGenerators(localGenerators) ,HaveTargetsAndLibs(false) { } diff --git a/Source/cmGraphVizWriter.h b/Source/cmGraphVizWriter.h index a7acd0e..64de684 100644 --- a/Source/cmGraphVizWriter.h +++ b/Source/cmGraphVizWriter.h @@ -69,14 +69,6 @@ protected: std::string GraphHeader; std::string GraphNodePrefix; - bool GenerateForExecutables; - bool GenerateForStaticLibs; - bool GenerateForSharedLibs; - bool GenerateForModuleLibs; - bool GenerateForExternals; - bool GeneratePerTarget; - bool GenerateDependers; - std::vector<cmsys::RegularExpression> TargetsToIgnoreRegex; const std::vector<cmLocalGenerator*>& LocalGenerators; @@ -85,6 +77,13 @@ protected: // maps from the actual target names to node names in dot: std::map<std::string, std::string> TargetNamesNodes; + bool GenerateForExecutables; + bool GenerateForStaticLibs; + bool GenerateForSharedLibs; + bool GenerateForModuleLibs; + bool GenerateForExternals; + bool GeneratePerTarget; + bool GenerateDependers; bool HaveTargetsAndLibs; }; diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx index 3551f83..20448c1 100644 --- a/Source/cmIfCommand.cxx +++ b/Source/cmIfCommand.cxx @@ -27,7 +27,7 @@ static std::string cmIfCommandError( i != args.end(); ++i) { err += " "; - err += cmLocalGenerator::EscapeForCMake(i->GetValue()); + err += cmOutputConverter::EscapeForCMake(i->GetValue()); } err += "\n"; return err; @@ -92,10 +92,6 @@ IsFunctionBlocked(const cmListFileFunction& lff, } else { - // Place this call on the call stack. - cmMakefileCall stack_manager(&mf, this->Functions[c], status); - static_cast<void>(stack_manager); - // if trace is enabled, print the evaluated "elseif" statement if(mf.GetCMakeInstance()->GetTrace()) { @@ -119,7 +115,8 @@ IsFunctionBlocked(const cmListFileFunction& lff, { std::string err = cmIfCommandError(expandedArguments); err += errorString; - mf.IssueMessage(messType, err); + cmListFileBacktrace bt = mf.GetBacktrace(this->Functions[c]); + mf.GetCMakeInstance()->IssueMessage(messType, err, bt); if (messType == cmake::FATAL_ERROR) { cmSystemTools::SetFatalErrorOccured(); diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx index 28c27c2..ff2c6e5 100644 --- a/Source/cmInstallFilesGenerator.cxx +++ b/Source/cmInstallFilesGenerator.cxx @@ -28,9 +28,11 @@ cmInstallFilesGenerator bool optional): cmInstallGenerator(dest, configurations, component, message), Makefile(mf), - Files(files), Programs(programs), + Files(files), FilePermissions(file_permissions), - Rename(rename), Optional(optional) + Rename(rename), + Programs(programs), + Optional(optional) { // We need per-config actions if any files have generator expressions. for(std::vector<std::string>::const_iterator i = files.begin(); diff --git a/Source/cmInstallFilesGenerator.h b/Source/cmInstallFilesGenerator.h index 0dbd712..bf482d6 100644 --- a/Source/cmInstallFilesGenerator.h +++ b/Source/cmInstallFilesGenerator.h @@ -43,9 +43,9 @@ protected: cmMakefile* Makefile; std::vector<std::string> Files; - bool Programs; std::string FilePermissions; std::string Rename; + bool Programs; bool Optional; }; diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index 082a78c..5115788 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -29,7 +29,9 @@ cmInstallTargetGenerator MessageLevel message, bool optional): cmInstallGenerator(dest, configurations, component, message), Target(&t), - ImportLibrary(implib), FilePermissions(file_permissions), Optional(optional) + FilePermissions(file_permissions), + ImportLibrary(implib), + Optional(optional) { this->ActionsPerConfig = true; this->NamelinkMode = NamelinkModeNone; diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h index 075c8a4..db69220 100644 --- a/Source/cmInstallTargetGenerator.h +++ b/Source/cmInstallTargetGenerator.h @@ -14,7 +14,6 @@ #include "cmInstallGenerator.h" #include "cmTarget.h" -#include "cmGeneratorTarget.h" /** \class cmInstallTargetGenerator * \brief Generate target installation rules. @@ -100,11 +99,10 @@ protected: const std::string& toDestDirPath); cmTarget* Target; - bool ImportLibrary; std::string FilePermissions; - bool Optional; NamelinkModeType NamelinkMode; - cmGeneratorTarget* GeneratorTarget; + bool ImportLibrary; + bool Optional; }; #endif diff --git a/Source/cmLinkedTree.h b/Source/cmLinkedTree.h new file mode 100644 index 0000000..df00b30 --- /dev/null +++ b/Source/cmLinkedTree.h @@ -0,0 +1,182 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2015 Stephen Kelly <steveire@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmLinkedTree_h +#define cmLinkedTree_h + +#include "cmStandardIncludes.h" + +#include <assert.h> + +/** + @brief A adaptor for traversing a tree structure in a vector + + This class is not intended to be wholly generic like a standard library + container adaptor. Mostly it exists to facilitate code sharing for the + needs of the cmState. For example, the Truncate() method is a specific + requirement of the cmState. + + An empty cmLinkedTree provides a Root() method, and an Extend() method, + each of which return iterators. A Tree can be built up by extending + from the root, and then extending from any other iterator. + + An iterator resulting from this tree construction can be + forward-only-iterated toward the root. Extending the tree never + invalidates existing iterators. + */ +template<typename T> +class cmLinkedTree +{ + typedef typename std::vector<T>::size_type PositionType; + typedef T* PointerType; + typedef T& ReferenceType; +public: + class iterator : public std::iterator<std::forward_iterator_tag, T> + { + friend class cmLinkedTree; + cmLinkedTree* Tree; + + // The Position is always 'one past the end'. + PositionType Position; + + iterator(cmLinkedTree* tree, PositionType pos) + : Tree(tree), Position(pos) + { + + } + + public: + iterator() + : Tree(0), Position(0) + { + + } + + void operator++() + { + assert(this->Tree); + assert(this->Tree->UpPositions.size() == this->Tree->Data.size()); + assert(this->Position <= this->Tree->Data.size()); + assert(this->Position > 0); + this->Position = this->Tree->UpPositions[this->Position - 1]; + } + + PointerType operator->() const + { + assert(this->Tree); + assert(this->Tree->UpPositions.size() == this->Tree->Data.size()); + assert(this->Position <= this->Tree->Data.size()); + assert(this->Position > 0); + return this->Tree->GetPointer(this->Position - 1); + } + + PointerType operator->() + { + assert(this->Tree); + assert(this->Tree->UpPositions.size() == this->Tree->Data.size()); + assert(this->Position <= this->Tree->Data.size()); + assert(this->Position > 0); + return this->Tree->GetPointer(this->Position - 1); + } + + ReferenceType operator*() const + { + assert(this->Tree); + assert(this->Tree->UpPositions.size() == this->Tree->Data.size()); + assert(this->Position <= this->Tree->Data.size()); + assert(this->Position > 0); + return this->Tree->GetReference(this->Position - 1); + } + + ReferenceType operator*() + { + assert(this->Tree); + assert(this->Tree->UpPositions.size() == this->Tree->Data.size()); + assert(this->Position <= this->Tree->Data.size()); + assert(this->Position > 0); + return this->Tree->GetReference(this->Position - 1); + } + + bool operator==(iterator other) const + { + assert(this->Tree); + assert(this->Tree->UpPositions.size() == this->Tree->Data.size()); + assert(this->Tree == other.Tree); + return this->Position == other.Position; + } + + bool operator!=(iterator other) const + { + assert(this->Tree); + assert(this->Tree->UpPositions.size() == this->Tree->Data.size()); + return !(*this == other); + } + + bool IsValid() const + { + if (!this->Tree) + { + return false; + } + return this->Position <= this->Tree->Data.size(); + } + }; + + iterator Root() const + { + return iterator(const_cast<cmLinkedTree*>(this), 0); + } + + iterator Extend(iterator it) + { + return Extend_impl(it, T()); + } + + iterator Extend(iterator it, T t) + { + return Extend_impl(it, t); + } + + iterator Truncate() + { + assert(this->UpPositions.size() > 0); + this->UpPositions.erase(this->UpPositions.begin() + 1, + this->UpPositions.end()); + assert(this->Data.size() > 0); + this->Data.erase(this->Data.begin() + 1, this->Data.end()); + return iterator(this, 1); + } + +private: + T& GetReference(PositionType pos) + { + return this->Data[pos]; + } + + T* GetPointer(PositionType pos) + { + return &this->Data[pos]; + } + + iterator Extend_impl(iterator it, T t) + { + assert(this->UpPositions.size() == this->Data.size()); + assert(it.Position <= this->UpPositions.size()); + this->UpPositions.push_back(it.Position); + this->Data.push_back(t); + return iterator(this, this->UpPositions.size()); + } + + std::vector<T> Data; + std::vector<PositionType> UpPositions; +}; + +#endif diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index 2756cd2..1097dc2 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -234,8 +234,7 @@ bool cmListFile::ParseFile(const char* filename, { cmListFileFunction project; project.Name = "PROJECT"; - cmListFileArgument prj("Project", cmListFileArgument::Unquoted, - filename, 0); + cmListFileArgument prj("Project", cmListFileArgument::Unquoted, 0); project.Arguments.push_back(prj); this->Functions.insert(this->Functions.begin(),project); } @@ -252,7 +251,6 @@ bool cmListFileParser::ParseFunction(const char* name, long line) { // Inintialize a new function call. this->Function = cmListFileFunction(); - this->Function.FilePath = this->FileName; this->Function.Name = name; this->Function.Line = line; @@ -375,7 +373,7 @@ bool cmListFileParser::ParseFunction(const char* name, long line) bool cmListFileParser::AddArgument(cmListFileLexer_Token* token, cmListFileArgument::Delimiter delim) { - cmListFileArgument a(token->text, delim, this->FileName, token->line); + cmListFileArgument a(token->text, delim, token->line); this->Function.Arguments.push_back(a); if(this->Separation == SeparationOkay) { @@ -400,50 +398,50 @@ bool cmListFileParser::AddArgument(cmListFileLexer_Token* token, } } -void cmListFileBacktrace::Append(cmListFileContext const& context) -{ - this->push_back(context); -} - -//---------------------------------------------------------------------------- -void cmListFileBacktrace::MakeRelative() +void cmListFileBacktrace::PrintTitle(std::ostream& out) { - if (this->Relative) + if (!this->Snapshot.IsValid()) { return; } - for (cmListFileBacktrace::iterator i = this->begin(); - i != this->end(); ++i) - { - i->FilePath = this->LocalGenerator->Convert(i->FilePath, - cmLocalGenerator::HOME); - } - this->Relative = true; + cmOutputConverter converter(this->Snapshot); + cmListFileContext lfc = + cmListFileContext::FromCommandContext( + this->Context, this->Snapshot.GetExecutionListFile()); + lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME); + out << (lfc.Line ? " at " : " in ") << lfc; } -void cmListFileBacktrace::PrintTitle(std::ostream& out) +void cmListFileBacktrace::PrintCallStack(std::ostream& out) { - if (this->empty()) + if (!this->Snapshot.IsValid()) { return; } - out << (this->front().Line ? " at " : " in ") << this->front(); -} - -void cmListFileBacktrace::PrintCallStack(std::ostream& out) -{ - if (size() <= 1) + cmState::Snapshot parent = this->Snapshot.GetCallStackParent(); + if (!parent.IsValid() || parent.GetExecutionListFile().empty()) { return; } - const_iterator i = this->begin() + 1; + cmOutputConverter converter(this->Snapshot); + std::string commandName = this->Snapshot.GetEntryPointCommand(); + long commandLine = this->Snapshot.GetEntryPointLine(); + out << "Call Stack (most recent call first):\n"; - while(i != this->end()) + while(parent.IsValid()) { - cmListFileContext const& lfc = *i; + cmListFileContext lfc; + lfc.Name = commandName; + lfc.Line = commandLine; + + lfc.FilePath = converter.Convert(parent.GetExecutionListFile(), + cmOutputConverter::HOME); out << " " << lfc << "\n"; - ++i; + + commandName = parent.GetEntryPointCommand(); + commandLine = parent.GetEntryPointLine(); + parent = parent.GetCallStackParent(); } } diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h index 4a1d181..aa8a34c 100644 --- a/Source/cmListFileCache.h +++ b/Source/cmListFileCache.h @@ -14,7 +14,7 @@ #include "cmStandardIncludes.h" -class cmLocalGenerator; +#include "cmState.h" /** \class cmListFileCache * \brief A class to cache list file contents. @@ -25,6 +25,13 @@ class cmLocalGenerator; class cmMakefile; +struct cmCommandContext +{ + std::string Name; + long Line; + cmCommandContext(): Name(), Line(0) {} +}; + struct cmListFileArgument { enum Delimiter @@ -33,12 +40,11 @@ struct cmListFileArgument Quoted, Bracket }; - cmListFileArgument(): Value(), Delim(Unquoted), FilePath(0), Line(0) {} - cmListFileArgument(const cmListFileArgument& r): - Value(r.Value), Delim(r.Delim), FilePath(r.FilePath), Line(r.Line) {} - cmListFileArgument(const std::string& v, Delimiter d, const char* file, - long line): Value(v), Delim(d), - FilePath(file), Line(line) {} + cmListFileArgument(): Value(), Delim(Unquoted), Line(0) {} + cmListFileArgument(const cmListFileArgument& r) + : Value(r.Value), Delim(r.Delim), Line(r.Line) {} + cmListFileArgument(const std::string& v, Delimiter d, long line) + : Value(v), Delim(d), Line(line) {} bool operator == (const cmListFileArgument& r) const { return (this->Value == r.Value) && (this->Delim == r.Delim); @@ -49,7 +55,6 @@ struct cmListFileArgument } std::string Value; Delimiter Delim; - const char* FilePath; long Line; }; @@ -59,6 +64,16 @@ struct cmListFileContext std::string FilePath; long Line; cmListFileContext(): Name(), FilePath(), Line(0) {} + + static cmListFileContext FromCommandContext(cmCommandContext const& lfcc, + std::string const& fileName) + { + cmListFileContext lfc; + lfc.FilePath = fileName; + lfc.Line = lfcc.Line; + lfc.Name = lfcc.Name; + return lfc; + } }; std::ostream& operator<<(std::ostream&, cmListFileContext const&); @@ -66,29 +81,25 @@ bool operator<(const cmListFileContext& lhs, const cmListFileContext& rhs); bool operator==(cmListFileContext const& lhs, cmListFileContext const& rhs); bool operator!=(cmListFileContext const& lhs, cmListFileContext const& rhs); -struct cmListFileFunction: public cmListFileContext +struct cmListFileFunction: public cmCommandContext { std::vector<cmListFileArgument> Arguments; }; -class cmListFileBacktrace: private std::vector<cmListFileContext> +class cmListFileBacktrace { public: - cmListFileBacktrace(cmLocalGenerator* localGen) - : LocalGenerator(localGen) - , Relative(localGen ? false : true) + cmListFileBacktrace(cmState::Snapshot snapshot = cmState::Snapshot(), + cmCommandContext const& cc = cmCommandContext()) + : Context(cc), Snapshot(snapshot) { } - void Append(cmListFileContext const& context); - - void MakeRelative(); - void PrintTitle(std::ostream& out); void PrintCallStack(std::ostream& out); private: - cmLocalGenerator* LocalGenerator; - bool Relative; + cmCommandContext Context; + cmState::Snapshot Snapshot; }; struct cmListFile diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index eb6b871..6f98ee2 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -46,7 +46,7 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, cmLocalGenerator* parent, cmState::Snapshot snapshot) - : StateSnapshot(snapshot) + : cmOutputConverter(snapshot), StateSnapshot(snapshot) { assert(snapshot.IsValid()); this->GlobalGenerator = gg; @@ -58,9 +58,6 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, this->Makefile = new cmMakefile(this); - this->LinkScriptShell = false; - this->UseRelativePaths = false; - this->Configured = false; this->EmitUniversalBinaryFlags = true; this->BackwardsCompatibility = 0; this->BackwardsCompatibilityFinal = false; @@ -71,79 +68,20 @@ cmLocalGenerator::~cmLocalGenerator() delete this->Makefile; } -bool cmLocalGenerator::IsRootMakefile() const +void cmLocalGenerator::IssueMessage(cmake::MessageType t, + std::string const& text) const { - return !this->StateSnapshot.GetParent().IsValid(); -} + cmListFileContext lfc; + lfc.FilePath = this->StateSnapshot.GetCurrentSourceDirectory(); + lfc.FilePath += "/CMakeLists.txt"; -//---------------------------------------------------------------------------- -class cmLocalGeneratorCurrent -{ - cmGlobalGenerator* GG; - cmLocalGenerator* LG; - cmState::Snapshot Snapshot; -public: - cmLocalGeneratorCurrent(cmLocalGenerator* lg) + if(!this->GlobalGenerator->GetCMakeInstance()->GetIsInTryCompile()) { - this->GG = lg->GetGlobalGenerator(); - this->LG = this->GG->GetCurrentLocalGenerator(); - this->Snapshot = this->GG->GetCMakeInstance()->GetCurrentSnapshot(); - this->GG->GetCMakeInstance()->SetCurrentSnapshot(lg->GetStateSnapshot()); - this->GG->SetCurrentLocalGenerator(lg); -#if defined(CMAKE_BUILD_WITH_CMAKE) - this->GG->GetFileLockPool().PushFileScope(); -#endif + cmOutputConverter converter(this->StateSnapshot); + lfc.FilePath = converter.Convert(lfc.FilePath, cmLocalGenerator::HOME); } - ~cmLocalGeneratorCurrent() - { -#if defined(CMAKE_BUILD_WITH_CMAKE) - this->GG->GetFileLockPool().PopFileScope(); -#endif - this->GG->SetCurrentLocalGenerator(this->LG); - this->GG->GetCMakeInstance()->SetCurrentSnapshot(this->Snapshot); - } -}; - -//---------------------------------------------------------------------------- -void cmLocalGenerator::Configure() -{ - // Manage the global generator's current local generator. - cmLocalGeneratorCurrent clg(this); - static_cast<void>(clg); - - // make sure the CMakeFiles dir is there - std::string filesDir = this->StateSnapshot.GetCurrentBinaryDirectory(); - filesDir += cmake::GetCMakeFilesDirectory(); - cmSystemTools::MakeDirectory(filesDir.c_str()); - - std::string currentStart = this->StateSnapshot.GetCurrentSourceDirectory(); - currentStart += "/CMakeLists.txt"; - assert(cmSystemTools::FileExists(currentStart.c_str(), true)); - this->Makefile->ProcessBuildsystemFile(currentStart.c_str()); - - // at the end of the ReadListFile handle any old style subdirs - // first get all the subdirectories - std::vector<cmLocalGenerator *> subdirs = this->GetChildren(); - - // for each subdir recurse - std::vector<cmLocalGenerator *>::iterator sdi = subdirs.begin(); - for (; sdi != subdirs.end(); ++sdi) - { - if (!(*sdi)->Configured) - { - this->Makefile->ConfigureSubDirectory(*sdi); - } - } - - this->Makefile->AddCMakeDependFilesFromUser(); - - // Check whether relative paths should be used for optionally - // relative paths. - this->UseRelativePaths = this->Makefile->IsOn("CMAKE_USE_RELATIVE_PATHS"); - - this->ComputeObjectMaxPath(); - - this->Configured = true; + lfc.Line = 0; + this->GlobalGenerator->GetCMakeInstance()->IssueMessage(t, text, lfc); } //---------------------------------------------------------------------------- @@ -171,7 +109,7 @@ void cmLocalGenerator::ComputeObjectMaxPath() w << "CMAKE_OBJECT_PATH_MAX is set to " << pmax << ", which is less than the minimum of 128. " << "The value will be ignored."; - this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str()); + this->IssueMessage(cmake::AUTHOR_WARNING, w.str()); } } else @@ -180,17 +118,12 @@ void cmLocalGenerator::ComputeObjectMaxPath() w << "CMAKE_OBJECT_PATH_MAX is set to \"" << plen << "\", which fails to parse as a positive integer. " << "The value will be ignored."; - this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str()); + this->IssueMessage(cmake::AUTHOR_WARNING, w.str()); } } this->ObjectMaxPathViolations.clear(); } -void cmLocalGenerator::ConfigureFinalPass() -{ - this->Makefile->ConfigureFinalPass(); -} - void cmLocalGenerator::TraceDependencies() { std::vector<std::string> configs; @@ -522,7 +455,7 @@ void cmLocalGenerator::AddCustomCommandToCreateObject(const char* ofname, objectDir = this->Convert(objectDir,START_OUTPUT,SHELL); std::string objectFile = this->Convert(ofname,START_OUTPUT,SHELL); std::string sourceFile = - this->Convert(source.GetFullPath(),START_OUTPUT,SHELL,true); + this->ConvertToOutputFormat(source.GetFullPath(), SHELL); std::string varString = "CMAKE_"; varString += lang; varString += "_COMPILE_OBJECT"; @@ -1169,56 +1102,6 @@ void cmLocalGenerator::InsertRuleLauncher(std::string& s, cmTarget* target, //---------------------------------------------------------------------------- std::string -cmLocalGenerator::ConvertToOutputForExistingCommon(const std::string& remote, - std::string const& result, - OutputFormat format) -{ - // If this is a windows shell, the result has a space, and the path - // already exists, we can use a short-path to reference it without a - // space. - if(this->GetState()->UseWindowsShell() && result.find(' ') != result.npos && - cmSystemTools::FileExists(remote.c_str())) - { - std::string tmp; - if(cmSystemTools::GetShortPath(remote, tmp)) - { - return this->Convert(tmp, NONE, format, true); - } - } - - // Otherwise, leave it unchanged. - return result; -} - -//---------------------------------------------------------------------------- -std::string -cmLocalGenerator::ConvertToOutputForExisting(const std::string& remote, - RelativeRoot local, - OutputFormat format) -{ - // Perform standard conversion. - std::string result = this->Convert(remote, local, format, true); - - // Consider short-path. - return this->ConvertToOutputForExistingCommon(remote, result, format); -} - -//---------------------------------------------------------------------------- -std::string -cmLocalGenerator::ConvertToOutputForExisting(RelativeRoot remote, - const std::string& local, - OutputFormat format) -{ - // Perform standard conversion. - std::string result = this->Convert(remote, local, format, true); - - // Consider short-path. - const char* remotePath = this->GetRelativeRootPath(remote); - return this->ConvertToOutputForExistingCommon(remotePath, result, format); -} - -//---------------------------------------------------------------------------- -std::string cmLocalGenerator::ConvertToIncludeReference(std::string const& path, OutputFormat format, bool forceFullPaths) @@ -1316,8 +1199,7 @@ std::string cmLocalGenerator::GetIncludeFlags( { includeFlags << fwSearchFlag; } - includeFlags << this->Convert(frameworkDir, START_OUTPUT, - shellFormat, true) + includeFlags << this->ConvertToOutputFormat(frameworkDir, shellFormat) << " "; } continue; @@ -1446,7 +1328,7 @@ void cmLocalGenerator::AddCompileOptions( "higher \"" << it->first << "_STANDARD\" \"" << standard << "\". " "This is not permitted. The COMPILE_FEATURES may not both depend on " "and be depended on by the link implementation." << std::endl; - this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); + this->IssueMessage(cmake::FATAL_ERROR, e.str()); return; } } @@ -1459,7 +1341,7 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, const std::string& lang, const std::string& config, bool stripImplicitInclDirs - ) + ) const { // Need to decide whether to automatically include the source and // binary directories at the beginning of the include path. @@ -2170,7 +2052,7 @@ AddCompilerRequirementFlag(std::string &flags, cmTarget const* target, "dialect \"" << lang << standardProp << "\" " << (ext ? "(with compiler extensions)" : "") << ", but CMake " "does not know the compile flags to use to enable it."; - this->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str()); + this->IssueMessage(cmake::FATAL_ERROR, e.str()); } else { @@ -2214,7 +2096,7 @@ AddCompilerRequirementFlag(std::string &flags, cmTarget const* target, std::string e = "CMAKE_" + lang + "_STANDARD_DEFAULT is set to invalid value '" + std::string(defaultStd) + "'"; - this->Makefile->IssueMessage(cmake::INTERNAL_ERROR, e); + this->IssueMessage(cmake::INTERNAL_ERROR, e); return; } @@ -2430,7 +2312,7 @@ bool cmLocalGenerator::GetShouldUseOldFlags(bool shared, << flagsVar << " was removed.\n" << cmPolicies::GetPolicyWarning(cmPolicies::CMP0018); - this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, e.str()); + this->IssueMessage(cmake::AUTHOR_WARNING, e.str()); // fall through to OLD behaviour } case cmPolicies::OLD: @@ -2644,6 +2526,33 @@ void cmLocalGenerator::AppendFeatureOptions( } //---------------------------------------------------------------------------- +const char* cmLocalGenerator::GetFeature(const std::string& feature, + const std::string& config) +{ + // TODO: Define accumulation policy for features (prepend, append, replace). + // Currently we always replace. + if(!config.empty()) + { + std::string featureConfig = feature; + featureConfig += "_"; + featureConfig += cmSystemTools::UpperCase(config); + if(const char* value = this->Makefile->GetProperty(featureConfig)) + { + return value; + } + } + if(const char* value = this->Makefile->GetProperty(feature)) + { + return value; + } + if(cmLocalGenerator* parent = this->GetParent()) + { + return parent->GetFeature(feature, config); + } + return 0; +} + +//---------------------------------------------------------------------------- std::string cmLocalGenerator::ConstructComment(cmCustomCommandGenerator const& ccg, const char* default_comment) @@ -2675,242 +2584,6 @@ cmLocalGenerator::ConstructComment(cmCustomCommandGenerator const& ccg, } //---------------------------------------------------------------------------- -std::string -cmLocalGenerator::ConvertToOptionallyRelativeOutputPath( - const std::string& remote) -{ - return this->Convert(remote, START_OUTPUT, SHELL, true); -} - -//---------------------------------------------------------------------------- -const char* cmLocalGenerator::GetRelativeRootPath(RelativeRoot relroot) -{ - switch (relroot) - { - case HOME: return this->GetState()->GetSourceDirectory(); - case START: return this->StateSnapshot.GetCurrentSourceDirectory(); - case HOME_OUTPUT: return this->GetState()->GetBinaryDirectory(); - case START_OUTPUT: return this->StateSnapshot.GetCurrentBinaryDirectory(); - default: break; - } - return 0; -} - -//---------------------------------------------------------------------------- -std::string cmLocalGenerator::Convert(const std::string& source, - RelativeRoot relative, - OutputFormat output, - bool optional) -{ - // Convert the path to a relative path. - std::string result = source; - - if (!optional || this->UseRelativePaths) - { - switch (relative) - { - case HOME: - //result = cmSystemTools::CollapseFullPath(result.c_str()); - result = this->ConvertToRelativePath( - this->GetState()->GetSourceDirectoryComponents(), result); - break; - case START: - //result = cmSystemTools::CollapseFullPath(result.c_str()); - result = this->ConvertToRelativePath( - this->StateSnapshot.GetCurrentSourceDirectoryComponents(), result); - break; - case HOME_OUTPUT: - //result = cmSystemTools::CollapseFullPath(result.c_str()); - result = this->ConvertToRelativePath( - this->GetState()->GetBinaryDirectoryComponents(), result); - break; - case START_OUTPUT: - //result = cmSystemTools::CollapseFullPath(result.c_str()); - result = this->ConvertToRelativePath( - this->StateSnapshot.GetCurrentBinaryDirectoryComponents(), result); - break; - case FULL: - result = cmSystemTools::CollapseFullPath(result); - break; - case NONE: - break; - } - } - return this->ConvertToOutputFormat(result, output); -} - -//---------------------------------------------------------------------------- -std::string cmLocalGenerator::ConvertToOutputFormat(const std::string& source, - OutputFormat output) -{ - std::string result = source; - // Convert it to an output path. - if (output == MAKERULE) - { - result = cmSystemTools::ConvertToOutputPath(result.c_str()); - } - else if(output == SHELL || output == WATCOMQUOTE) - { - // For the MSYS shell convert drive letters to posix paths, so - // that c:/some/path becomes /c/some/path. This is needed to - // avoid problems with the shell path translation. - if(this->GetState()->UseMSYSShell() && !this->LinkScriptShell) - { - if(result.size() > 2 && result[1] == ':') - { - result[1] = result[0]; - result[0] = '/'; - } - } - if(this->GetState()->UseWindowsShell()) - { - std::replace(result.begin(), result.end(), '/', '\\'); - } - result = this->EscapeForShell(result, true, false, output == WATCOMQUOTE); - } - else if(output == RESPONSE) - { - result = this->EscapeForShell(result, false, false, false); - } - return result; -} - -//---------------------------------------------------------------------------- -std::string cmLocalGenerator::Convert(RelativeRoot remote, - const std::string& local, - OutputFormat output, - bool optional) -{ - const char* remotePath = this->GetRelativeRootPath(remote); - - // The relative root must have a path (i.e. not FULL or NONE) - assert(remotePath != 0); - - if(!local.empty() && (!optional || this->UseRelativePaths)) - { - std::vector<std::string> components; - cmSystemTools::SplitPath(local, components); - std::string result = this->ConvertToRelativePath(components, remotePath); - return this->ConvertToOutputFormat(result, output); - } - else - { - return this->ConvertToOutputFormat(remotePath, output); - } -} - -//---------------------------------------------------------------------------- -static bool cmLocalGeneratorNotAbove(const char* a, const char* b) -{ - return (cmSystemTools::ComparePath(a, b) || - cmSystemTools::IsSubDirectory(a, b)); -} - -//---------------------------------------------------------------------------- -std::string -cmLocalGenerator::ConvertToRelativePath(const std::vector<std::string>& local, - const std::string& in_remote, - bool force) -{ - // The path should never be quoted. - assert(in_remote[0] != '\"'); - - // The local path should never have a trailing slash. - assert(!local.empty() && !(local[local.size()-1] == "")); - - // If the path is already relative then just return the path. - if(!cmSystemTools::FileIsFullPath(in_remote.c_str())) - { - return in_remote; - } - - if(!force) - { - // Skip conversion if the path and local are not both in the source - // or both in the binary tree. - std::string local_path = cmSystemTools::JoinPath(local); - if(!((cmLocalGeneratorNotAbove(local_path.c_str(), - this->StateSnapshot.GetRelativePathTopBinary()) && - cmLocalGeneratorNotAbove(in_remote.c_str(), - this->StateSnapshot.GetRelativePathTopBinary())) || - (cmLocalGeneratorNotAbove(local_path.c_str(), - this->StateSnapshot.GetRelativePathTopSource()) && - cmLocalGeneratorNotAbove(in_remote.c_str(), - this->StateSnapshot.GetRelativePathTopSource())))) - { - return in_remote; - } - } - - // Identify the longest shared path component between the remote - // path and the local path. - std::vector<std::string> remote; - cmSystemTools::SplitPath(in_remote, remote); - unsigned int common=0; - while(common < remote.size() && - common < local.size() && - cmSystemTools::ComparePath(remote[common], - local[common])) - { - ++common; - } - - // If no part of the path is in common then return the full path. - if(common == 0) - { - return in_remote; - } - - // If the entire path is in common then just return a ".". - if(common == remote.size() && - common == local.size()) - { - return "."; - } - - // If the entire path is in common except for a trailing slash then - // just return a "./". - if(common+1 == remote.size() && - remote[common].empty() && - common == local.size()) - { - return "./"; - } - - // Construct the relative path. - std::string relative; - - // First add enough ../ to get up to the level of the shared portion - // of the path. Leave off the trailing slash. Note that the last - // component of local will never be empty because local should never - // have a trailing slash. - for(unsigned int i=common; i < local.size(); ++i) - { - relative += ".."; - if(i < local.size()-1) - { - relative += "/"; - } - } - - // Now add the portion of the destination path that is not included - // in the shared portion of the path. Add a slash the first time - // only if there was already something in the path. If there was a - // trailing slash in the input then the last iteration of the loop - // will add a slash followed by an empty string which will preserve - // the trailing slash in the output. - - if(!relative.empty() && !remote.empty()) - { - relative += "/"; - } - relative += cmJoin(cmRange(remote).advance(common), "/"); - - // Finally return the path. - return relative; -} - -//---------------------------------------------------------------------------- class cmInstallTargetGeneratorLocal: public cmInstallTargetGenerator { public: @@ -3151,7 +2824,7 @@ cmLocalGenerator << " " << ssin << "\n" << "cannot be safely placed under this directory. " << "The build may not work correctly."; - this->Makefile->IssueMessage(cmake::WARNING, m.str()); + this->IssueMessage(cmake::WARNING, m.str()); } } #else @@ -3195,11 +2868,6 @@ bool cmLocalGenerator::IsNMake() const return this->GetState()->UseNMake(); } -void cmLocalGenerator::SetConfiguredCMP0014(bool configured) -{ - this->Configured = configured; -} - //---------------------------------------------------------------------------- std::string cmLocalGenerator @@ -3308,150 +2976,6 @@ cmLocalGenerator } //---------------------------------------------------------------------------- -static bool cmLocalGeneratorIsShellOperator(const std::string& str) -{ - static std::set<std::string> shellOperators; - if(shellOperators.empty()) - { - shellOperators.insert("<"); - shellOperators.insert(">"); - shellOperators.insert("<<"); - shellOperators.insert(">>"); - shellOperators.insert("|"); - shellOperators.insert("||"); - shellOperators.insert("&&"); - shellOperators.insert("&>"); - shellOperators.insert("1>"); - shellOperators.insert("2>"); - shellOperators.insert("2>&1"); - shellOperators.insert("1>&2"); - } - return shellOperators.count(str) > 0; -} - -//---------------------------------------------------------------------------- -std::string cmLocalGenerator::EscapeForShell(const std::string& str, - bool makeVars, - bool forEcho, - bool useWatcomQuote) -{ - // Do not escape shell operators. - if(cmLocalGeneratorIsShellOperator(str)) - { - return str; - } - - // Compute the flags for the target shell environment. - int flags = 0; - if(this->GetState()->UseWindowsVSIDE()) - { - flags |= cmsysSystem_Shell_Flag_VSIDE; - } - else if(!this->LinkScriptShell) - { - flags |= cmsysSystem_Shell_Flag_Make; - } - if(makeVars) - { - flags |= cmsysSystem_Shell_Flag_AllowMakeVariables; - } - if(forEcho) - { - flags |= cmsysSystem_Shell_Flag_EchoWindows; - } - if(useWatcomQuote) - { - flags |= cmsysSystem_Shell_Flag_WatcomQuote; - } - if(this->GetState()->UseWatcomWMake()) - { - flags |= cmsysSystem_Shell_Flag_WatcomWMake; - } - if(this->GetState()->UseMinGWMake()) - { - flags |= cmsysSystem_Shell_Flag_MinGWMake; - } - if(this->GetState()->UseNMake()) - { - flags |= cmsysSystem_Shell_Flag_NMake; - } - - // Compute the buffer size needed. - int size = (this->GetState()->UseWindowsShell() ? - cmsysSystem_Shell_GetArgumentSizeForWindows(str.c_str(), flags) : - cmsysSystem_Shell_GetArgumentSizeForUnix(str.c_str(), flags)); - - // Compute the shell argument itself. - std::vector<char> arg(size); - if(this->GetState()->UseWindowsShell()) - { - cmsysSystem_Shell_GetArgumentForWindows(str.c_str(), &arg[0], flags); - } - else - { - cmsysSystem_Shell_GetArgumentForUnix(str.c_str(), &arg[0], flags); - } - return std::string(&arg[0]); -} - -//---------------------------------------------------------------------------- -std::string cmLocalGenerator::EscapeForCMake(const std::string& str) -{ - // Always double-quote the argument to take care of most escapes. - std::string result = "\""; - for(const char* c = str.c_str(); *c; ++c) - { - if(*c == '"') - { - // Escape the double quote to avoid ending the argument. - result += "\\\""; - } - else if(*c == '$') - { - // Escape the dollar to avoid expanding variables. - result += "\\$"; - } - else if(*c == '\\') - { - // Escape the backslash to avoid other escapes. - result += "\\\\"; - } - else - { - // Other characters will be parsed correctly. - result += *c; - } - } - result += "\""; - return result; -} - -//---------------------------------------------------------------------------- -cmLocalGenerator::FortranFormat -cmLocalGenerator::GetFortranFormat(const char* value) -{ - FortranFormat format = FortranFormatNone; - if(value && *value) - { - std::vector<std::string> fmt; - cmSystemTools::ExpandListArgument(value, fmt); - for(std::vector<std::string>::iterator fi = fmt.begin(); - fi != fmt.end(); ++fi) - { - if(*fi == "FIXED") - { - format = FortranFormatFixed; - } - if(*fi == "FREE") - { - format = FortranFormatFree; - } - } - } - return format; -} - -//---------------------------------------------------------------------------- std::string cmLocalGenerator::GetTargetDirectory(cmTarget const&) const { @@ -3481,7 +3005,7 @@ cmIML_INT_uint64_t cmLocalGenerator::GetBackwardsCompatibility() } } this->BackwardsCompatibility = CMake_VERSION_ENCODE(major, minor, patch); - this->BackwardsCompatibilityFinal = this->Configured; + this->BackwardsCompatibilityFinal = this->Makefile->IsConfigured(); } return this->BackwardsCompatibility; diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 32b17f5..98f4d3a 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -14,6 +14,8 @@ #include "cmStandardIncludes.h" #include "cmState.h" +#include "cmake.h" +#include "cmOutputConverter.h" class cmMakefile; class cmGlobalGenerator; @@ -31,26 +33,19 @@ class cmCustomCommandGenerator; * platforms. This class should never be constructed directly. A * GlobalGenerator will create it and invoke the appropriate commands on it. */ -class cmLocalGenerator +class cmLocalGenerator : public cmOutputConverter { public: cmLocalGenerator(cmGlobalGenerator* gg, cmLocalGenerator* parent, cmState::Snapshot snapshot); virtual ~cmLocalGenerator(); - /// @return whether we are processing the top CMakeLists.txt file. - bool IsRootMakefile() const; - /** * Generate the makefile for this directory. */ virtual void Generate() {} - /** - * Process the CMakeLists files for this directory to fill in the - * Makefile ivar - */ - virtual void Configure(); + virtual void ComputeHomeRelativeOutputPath() {} /** * Calls TraceVSDependencies() on all targets of this generator. @@ -60,11 +55,6 @@ public: virtual void AddHelperCommands() {} /** - * Perform any final calculations prior to generation - */ - void ConfigureFinalPass(); - - /** * Generate the install rules files in this directory. */ void GenerateInstallRules(); @@ -96,44 +86,6 @@ public: cmState* GetState() const; cmState::Snapshot GetStateSnapshot() const; - /** - * Convert something to something else. This is a centralized conversion - * routine used by the generators to handle relative paths and the like. - * The flags determine what is actually done. - * - * relative: treat the argument as a directory and convert it to make it - * relative or full or unchanged. If relative (HOME, START etc) then that - * specifies what it should be relative to. - * - * output: make the result suitable for output to a... - * - * optional: should any relative path operation be controlled by the rel - * path setting - */ - enum RelativeRoot { NONE, FULL, HOME, START, HOME_OUTPUT, START_OUTPUT }; - enum OutputFormat { UNCHANGED, MAKERULE, SHELL, WATCOMQUOTE, RESPONSE }; - std::string ConvertToOutputFormat(const std::string& source, - OutputFormat output); - std::string Convert(const std::string& remote, RelativeRoot local, - OutputFormat output = UNCHANGED, - bool optional = false); - std::string Convert(RelativeRoot remote, const std::string& local, - OutputFormat output = UNCHANGED, - bool optional = false); - - /** - * Get path for the specified relative root. - */ - const char* GetRelativeRootPath(RelativeRoot relroot); - - /** - * Convert the given path to an output path that is optionally - * relative based on the cache option CMAKE_USE_RELATIVE_PATHS. The - * remote path must use forward slashes and not already be escaped - * or quoted. - */ - std::string ConvertToOptionallyRelativeOutputPath(const std::string& remote); - ///! set/get the parent generator cmLocalGenerator* GetParent() const {return this->Parent;} @@ -194,6 +146,9 @@ public: void AppendFeatureOptions(std::string& flags, const std::string& lang, const char* feature); + const char* GetFeature(const std::string& feature, + const std::string& config); + /** \brief Get absolute path to dependency \a name * * Translate a dependency as given in CMake code to the name to @@ -209,17 +164,6 @@ public: bool GetRealDependency(const std::string& name, const std::string& config, std::string& dep); - ///! for existing files convert to output path and short path if spaces - std::string ConvertToOutputForExisting(const std::string& remote, - RelativeRoot local = START_OUTPUT, - OutputFormat format = SHELL); - - /** For existing path identified by RelativeRoot convert to output - path and short path if spaces. */ - std::string ConvertToOutputForExisting(RelativeRoot remote, - const std::string& local = "", - OutputFormat format = SHELL); - virtual std::string ConvertToIncludeReference(std::string const& path, OutputFormat format = SHELL, bool forceFullPaths = false); @@ -239,7 +183,7 @@ public: cmGeneratorTarget* target, const std::string& lang = "C", const std::string& config = "", - bool stripImplicitInclDirs = true); + bool stripImplicitInclDirs = true) const; void AddCompileOptions(std::string& flags, cmTarget* target, const std::string& lang, const std::string& config); void AddCompileDefinitions(std::set<std::string>& defines, @@ -291,40 +235,6 @@ public: const char* FilterPrefix; }; - /** Set whether to treat conversions to SHELL as a link script shell. */ - void SetLinkScriptShell(bool b) { this->LinkScriptShell = b; } - - /** Escape the given string to be used as a command line argument in - the native build system shell. Optionally allow the build - system to replace make variable references. Optionally adjust - escapes for the special case of passing to the native echo - command. */ - std::string EscapeForShell(const std::string& str, bool makeVars = false, - bool forEcho = false, - bool useWatcomQuote = false); - - /** Escape the given string as an argument in a CMake script. */ - static std::string EscapeForCMake(const std::string& str); - - enum FortranFormat - { - FortranFormatNone, - FortranFormatFixed, - FortranFormatFree - }; - FortranFormat GetFortranFormat(const char* value); - - /** - * Convert the given remote path to a relative path with respect to - * the given local path. The local path must be given in component - * form (see SystemTools::SplitPath) without a trailing slash. The - * remote path must use forward slashes and not already be escaped - * or quoted. - */ - std::string ConvertToRelativePath(const std::vector<std::string>& local, - const std::string& remote, - bool force=false); - /** * Get the relative path from the generator output directory to a * per-target support directory. @@ -392,8 +302,10 @@ public: bool IsMinGWMake() const; bool IsNMake() const; - void SetConfiguredCMP0014(bool configured); + void IssueMessage(cmake::MessageType t, std::string const& text) const; + + void ComputeObjectMaxPath(); protected: ///! put all the libraries for a target on into the given stream void OutputLinkLibraries(std::string& linkLibraries, @@ -439,7 +351,6 @@ protected: std::string& CreateSafeUniqueObjectFileName(const std::string& sin, std::string const& dir_max); - void ComputeObjectMaxPath(); virtual std::string ConvertToLinkReference(std::string const& lib, OutputFormat format = SHELL); @@ -459,9 +370,6 @@ protected: std::set<cmTarget const*> WarnCMP0063; - bool LinkScriptShell; - bool UseRelativePaths; - bool Configured; bool EmitUniversalBinaryFlags; // Hack for ExpandRuleVariable until object-oriented version is @@ -471,10 +379,6 @@ protected: cmIML_INT_uint64_t BackwardsCompatibility; bool BackwardsCompatibilityFinal; private: - std::string ConvertToOutputForExistingCommon(const std::string& remote, - std::string const& result, - OutputFormat format); - void AddSharedFlags(std::string& flags, const std::string& lang, bool shared); bool GetShouldUseOldFlags(bool shared, const std::string &lang) const; diff --git a/Source/cmLocalGhsMultiGenerator.cxx b/Source/cmLocalGhsMultiGenerator.cxx index 870b9b9..8e498dd 100644 --- a/Source/cmLocalGhsMultiGenerator.cxx +++ b/Source/cmLocalGhsMultiGenerator.cxx @@ -37,7 +37,7 @@ void cmLocalGhsMultiGenerator::Generate() { continue; } - cmGhsMultiTargetGenerator tg(l->second->Target); + cmGhsMultiTargetGenerator tg(l->second); tg.Generate(); } } diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index c08c91f..4db36fc 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -41,6 +41,15 @@ cmLocalNinjaGenerator::~cmLocalNinjaGenerator() void cmLocalNinjaGenerator::Generate() { + // Compute the path to use when referencing the current output + // directory from the top output directory. + this->HomeRelativeOutputPath = + this->Convert(this->Makefile->GetCurrentBinaryDirectory(), HOME_OUTPUT); + if(this->HomeRelativeOutputPath == ".") + { + this->HomeRelativeOutputPath = ""; + } + this->SetConfigName(); this->WriteProcessedMakefile(this->GetBuildFileStream()); @@ -49,7 +58,7 @@ void cmLocalNinjaGenerator::Generate() #endif // We do that only once for the top CMakeLists.txt file. - if(this->IsRootMakefile()) + if(this->Makefile->IsRootMakefile()) { this->WriteBuildFileTop(); @@ -91,25 +100,6 @@ void cmLocalNinjaGenerator::Generate() this->WriteCustomCommandBuildStatements(); } -// Implemented in: -// cmLocalUnixMakefileGenerator3. -// Used in: -// Source/cmMakefile.cxx -// Source/cmGlobalGenerator.cxx -void cmLocalNinjaGenerator::Configure() -{ - // Compute the path to use when referencing the current output - // directory from the top output directory. - this->HomeRelativeOutputPath = - this->Convert(this->Makefile->GetCurrentBinaryDirectory(), HOME_OUTPUT); - if(this->HomeRelativeOutputPath == ".") - { - this->HomeRelativeOutputPath = ""; - } - this->cmLocalGenerator::Configure(); - -} - // TODO: Picked up from cmLocalUnixMakefileGenerator3. Refactor it. std::string cmLocalNinjaGenerator ::GetTargetDirectory(cmTarget const& target) const @@ -308,7 +298,7 @@ void cmLocalNinjaGenerator::WriteProcessedMakefile(std::ostream& os) << "# Write statements declared in CMakeLists.txt:" << std::endl << "# " << this->Makefile->GetDefinition("CMAKE_CURRENT_LIST_FILE") << std::endl; - if(this->IsRootMakefile()) + if(this->Makefile->IsRootMakefile()) os << "# Which is the root file." << std::endl; cmGlobalNinjaGenerator::WriteDivider(os); os << std::endl; diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h index 7ae97de..ce966ff 100644 --- a/Source/cmLocalNinjaGenerator.h +++ b/Source/cmLocalNinjaGenerator.h @@ -38,8 +38,6 @@ public: virtual void Generate(); - virtual void Configure(); - virtual std::string GetTargetDirectory(cmTarget const& target) const; const cmGlobalNinjaGenerator* GetGlobalNinjaGenerator() const; diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 3eea59b..e292ba7 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -98,24 +98,6 @@ cmLocalUnixMakefileGenerator3::~cmLocalUnixMakefileGenerator3() } //---------------------------------------------------------------------------- -void cmLocalUnixMakefileGenerator3::Configure() -{ - // Compute the path to use when referencing the current output - // directory from the top output directory. - this->HomeRelativeOutputPath = - this->Convert(this->Makefile->GetCurrentBinaryDirectory(), HOME_OUTPUT); - if(this->HomeRelativeOutputPath == ".") - { - this->HomeRelativeOutputPath = ""; - } - if(!this->HomeRelativeOutputPath.empty()) - { - this->HomeRelativeOutputPath += "/"; - } - this->cmLocalGenerator::Configure(); -} - -//---------------------------------------------------------------------------- void cmLocalUnixMakefileGenerator3::Generate() { // Store the configuration name that will be generated. @@ -169,6 +151,22 @@ void cmLocalUnixMakefileGenerator3::Generate() this->WriteDirectoryInformationFile(); } +void cmLocalUnixMakefileGenerator3::ComputeHomeRelativeOutputPath() +{ + // Compute the path to use when referencing the current output + // directory from the top output directory. + this->HomeRelativeOutputPath = + this->Convert(this->Makefile->GetCurrentBinaryDirectory(), HOME_OUTPUT); + if(this->HomeRelativeOutputPath == ".") + { + this->HomeRelativeOutputPath = ""; + } + if(!this->HomeRelativeOutputPath.empty()) + { + this->HomeRelativeOutputPath += "/"; + } +} + //---------------------------------------------------------------------------- void cmLocalUnixMakefileGenerator3::ComputeObjectFilenames( std::map<cmSourceFile const*, std::string>& mapping, @@ -1259,7 +1257,7 @@ cmLocalUnixMakefileGenerator3 f != files.end(); ++f) { std::string fc = this->Convert(*f,START_OUTPUT,UNCHANGED); - fout << " " << cmLocalGenerator::EscapeForCMake(fc) << "\n"; + fout << " " << cmOutputConverter::EscapeForCMake(fc) << "\n"; } fout << ")\n"; } @@ -1845,7 +1843,6 @@ void cmLocalUnixMakefileGenerator3 std::vector<std::string> commands; // Write the all rule. - std::string dir; std::string recursiveTarget = this->Makefile->GetCurrentBinaryDirectory(); recursiveTarget += "/all"; @@ -2057,7 +2054,7 @@ void cmLocalUnixMakefileGenerator3 di != defines.end(); ++di) { cmakefileStream - << " " << cmLocalGenerator::EscapeForCMake(*di) << "\n"; + << " " << cmOutputConverter::EscapeForCMake(*di) << "\n"; } cmakefileStream << " )\n"; @@ -2111,7 +2108,7 @@ void cmLocalUnixMakefileGenerator3 tri != transformRules.end(); ++tri) { cmakefileStream << " " - << cmLocalGenerator::EscapeForCMake(*tri) << "\n"; + << cmOutputConverter::EscapeForCMake(*tri) << "\n"; } cmakefileStream << " )\n"; diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h index 988d660..b097c95 100644 --- a/Source/cmLocalUnixMakefileGenerator3.h +++ b/Source/cmLocalUnixMakefileGenerator3.h @@ -39,11 +39,7 @@ public: cmState::Snapshot snapshot); virtual ~cmLocalUnixMakefileGenerator3(); - /** - * Process the CMakeLists files for this directory to fill in the - * Makefile ivar - */ - virtual void Configure(); + virtual void ComputeHomeRelativeOutputPath(); /** * Generate the makefile for this directory. @@ -153,9 +149,6 @@ public: void AddImplicitDepends(cmTarget const& tgt, const std::string& lang, const char* obj, const char* src); - void AppendGlobalTargetDepends(std::vector<std::string>& depends, - cmTarget& target); - // write the target rules for the local Makefile into the stream void WriteLocalAllRules(std::ostream& ruleFileStream); @@ -260,26 +253,10 @@ private: ImplicitDependTargetMap ImplicitDepends; - //========================================================================== - // Configuration settings. - int MakefileVariableSize; std::string ConfigurationName; - bool MakeCommandEscapeTargetTwice; - bool BorlandMakeCurlyHack; - //========================================================================== std::string HomeRelativeOutputPath; - /* Copy the setting of CMAKE_COLOR_MAKEFILE from the makefile at the - beginning of generation to avoid many duplicate lookups. */ - bool ColorMakefile; - - /* Copy the setting of CMAKE_SKIP_PREPROCESSED_SOURCE_RULES and - CMAKE_SKIP_ASSEMBLY_SOURCE_RULES at the beginning of generation to - avoid many duplicate lookups. */ - bool SkipPreprocessedSourceRules; - bool SkipAssemblySourceRules; - struct LocalObjectEntry { cmTarget* Target; @@ -308,6 +285,13 @@ private: /* does the work for each target */ std::map<std::string, std::string> MakeVariableMap; std::map<std::string, std::string> ShortMakeVariableMap; + + int MakefileVariableSize; + bool MakeCommandEscapeTargetTwice; + bool BorlandMakeCurlyHack; + bool ColorMakefile; + bool SkipPreprocessedSourceRules; + bool SkipAssemblySourceRules; }; #endif diff --git a/Source/cmLocalVisualStudio10Generator.cxx b/Source/cmLocalVisualStudio10Generator.cxx index ad6a020..9ded83a 100644 --- a/Source/cmLocalVisualStudio10Generator.cxx +++ b/Source/cmLocalVisualStudio10Generator.cxx @@ -107,10 +107,9 @@ void cmLocalVisualStudio10Generator cmVS10XMLParser parser; parser.ParseFile(path); - // if we can not find a GUID then create one + // if we can not find a GUID then we will generate one later if(parser.GUID.empty()) { - this->GlobalGenerator->CreateGUID(name); return; } diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index ad34857..a26a1dd 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -235,13 +235,10 @@ void cmLocalVisualStudio6Generator::AddDSPBuildRule(cmTarget& tgt) comment += makefileIn; std::string args; args = "-H"; - args += this->Convert(this->Makefile->GetHomeDirectory(), - START_OUTPUT, UNCHANGED, true); + args += this->Makefile->GetHomeDirectory(); commandLine.push_back(args); args = "-B"; - args += - this->Convert(this->Makefile->GetHomeOutputDirectory(), - START_OUTPUT, UNCHANGED, true); + args += this->Makefile->GetHomeOutputDirectory(); commandLine.push_back(args); std::vector<std::string> const& listFiles = this->Makefile->GetListFiles(); @@ -498,7 +495,7 @@ void cmLocalVisualStudio6Generator // Tell MS-Dev what the source is. If the compiler knows how to // build it, then it will. fout << "SOURCE=" << - this->ConvertToOptionallyRelativeOutputPath(source.c_str()) << "\n\n"; + this->ConvertToOutputFormat(source.c_str(), SHELL) << "\n\n"; if(!depends.empty()) { // Write out the dependencies for the rule. @@ -507,7 +504,7 @@ void cmLocalVisualStudio6Generator d != depends.end(); ++d) { fout << "\\\n\t" << - this->ConvertToOptionallyRelativeOutputPath(d->c_str()); + this->ConvertToOutputFormat(d->c_str(), SHELL); } fout << "\n"; } @@ -663,7 +660,7 @@ cmLocalVisualStudio6Generator if(this->GetRealDependency(d->c_str(), config.c_str(), dep)) { fout << "\\\n\t" << - this->ConvertToOptionallyRelativeOutputPath(dep.c_str()); + this->ConvertToOutputFormat(dep.c_str(), SHELL); } } fout << "\n"; @@ -689,7 +686,7 @@ cmLocalVisualStudio6Generator ++o) { // Write a rule for every output generated by this command. - fout << this->ConvertToOptionallyRelativeOutputPath(o->c_str()) + fout << this->ConvertToOutputFormat(o->c_str(), SHELL) << " : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"\n\t"; fout << script.c_str() << "\n\n"; } @@ -906,7 +903,7 @@ cmLocalVisualStudio6Generator::GetTargetIncludeOptions(cmTarget &target, for(i = includes.begin(); i != includes.end(); ++i) { std::string tmp = - this->ConvertToOptionallyRelativeOutputPath(i->c_str()); + this->ConvertToOutputFormat(i->c_str(), SHELL); if(useShortPath) { cmSystemTools::GetShortPath(tmp.c_str(), tmp); @@ -997,14 +994,14 @@ void cmLocalVisualStudio6Generator if(libPath.size()) { std::string lpath = - this->ConvertToOptionallyRelativeOutputPath(libPath.c_str()); + this->ConvertToOutputFormat(libPath.c_str(), SHELL); if(lpath.size() == 0) { lpath = "."; } std::string lpathIntDir = libPath + "$(INTDIR)"; lpathIntDir = - this->ConvertToOptionallyRelativeOutputPath(lpathIntDir.c_str()); + this->ConvertToOutputFormat(lpathIntDir.c_str(), SHELL); if(pathEmitted.insert(lpath).second) { libOptions += " /LIBPATH:"; @@ -1030,14 +1027,14 @@ void cmLocalVisualStudio6Generator if(exePath.size()) { std::string lpath = - this->ConvertToOptionallyRelativeOutputPath(exePath.c_str()); + this->ConvertToOutputFormat(exePath.c_str(), SHELL); if(lpath.size() == 0) { lpath = "."; } std::string lpathIntDir = exePath + "$(INTDIR)"; lpathIntDir = - this->ConvertToOptionallyRelativeOutputPath(lpathIntDir.c_str()); + this->ConvertToOutputFormat(lpathIntDir.c_str(), SHELL); if(pathEmitted.insert(lpath).second) { @@ -1071,14 +1068,14 @@ void cmLocalVisualStudio6Generator path += "/"; } std::string lpath = - this->ConvertToOptionallyRelativeOutputPath(path.c_str()); + this->ConvertToOutputFormat(path.c_str(), SHELL); if(lpath.size() == 0) { lpath = "."; } std::string lpathIntDir = path + "$(INTDIR)"; lpathIntDir = - this->ConvertToOptionallyRelativeOutputPath(lpathIntDir.c_str()); + this->ConvertToOutputFormat(lpathIntDir.c_str(), SHELL); if(pathEmitted.insert(lpath).second) { libOptions += " /LIBPATH:"; @@ -1142,9 +1139,9 @@ void cmLocalVisualStudio6Generator libDebug += ".lib"; } } - lib = this->ConvertToOptionallyRelativeOutputPath(lib.c_str()); + lib = this->ConvertToOutputFormat(lib.c_str(), SHELL); libDebug = - this->ConvertToOptionallyRelativeOutputPath(libDebug.c_str()); + this->ConvertToOutputFormat(libDebug.c_str(), SHELL); if (j->second == cmTarget::GENERAL) { @@ -1367,21 +1364,21 @@ void cmLocalVisualStudio6Generator { #ifdef CM_USE_OLD_VS6 outputDirOld = - removeQuotes(this->ConvertToOptionallyRelativeOutputPath - (target.GetDirectory().c_str())); + removeQuotes(this->ConvertToOutputFormat + (target.GetDirectory().c_str(), SHELL)); #endif outputDirDebug = - removeQuotes(this->ConvertToOptionallyRelativeOutputPath( - target.GetDirectory("Debug").c_str())); + removeQuotes(this->ConvertToOutputFormat( + target.GetDirectory("Debug").c_str(), SHELL)); outputDirRelease = - removeQuotes(this->ConvertToOptionallyRelativeOutputPath( - target.GetDirectory("Release").c_str())); + removeQuotes(this->ConvertToOutputFormat( + target.GetDirectory("Release").c_str(), SHELL)); outputDirMinSizeRel = - removeQuotes(this->ConvertToOptionallyRelativeOutputPath( - target.GetDirectory("MinSizeRel").c_str())); + removeQuotes(this->ConvertToOutputFormat( + target.GetDirectory("MinSizeRel").c_str(), SHELL)); outputDirRelWithDebInfo = - removeQuotes(this->ConvertToOptionallyRelativeOutputPath( - target.GetDirectory("RelWithDebInfo").c_str())); + removeQuotes(this->ConvertToOutputFormat( + target.GetDirectory("RelWithDebInfo").c_str(), SHELL)); } else if(target.GetType() == cmTarget::OBJECT_LIBRARY) { @@ -1449,15 +1446,13 @@ void cmLocalVisualStudio6Generator targetImplibFlagMinSizeRel = "/implib:"; targetImplibFlagRelWithDebInfo = "/implib:"; targetImplibFlagDebug += - this->ConvertToOptionallyRelativeOutputPath(fullPathImpDebug.c_str()); + this->ConvertToOutputFormat(fullPathImpDebug.c_str(), SHELL); targetImplibFlagRelease += - this->ConvertToOptionallyRelativeOutputPath(fullPathImpRelease.c_str()); + this->ConvertToOutputFormat(fullPathImpRelease.c_str(), SHELL); targetImplibFlagMinSizeRel += - this->ConvertToOptionallyRelativeOutputPath( - fullPathImpMinSizeRel.c_str()); + this->ConvertToOutputFormat(fullPathImpMinSizeRel.c_str(), SHELL); targetImplibFlagRelWithDebInfo += - this->ConvertToOptionallyRelativeOutputPath( - fullPathImpRelWithDebInfo.c_str()); + this->ConvertToOutputFormat(fullPathImpRelWithDebInfo.c_str(), SHELL); } #ifdef CM_USE_OLD_VS6 @@ -1669,12 +1664,12 @@ void cmLocalVisualStudio6Generator // to convert to output path for unix to win32 conversion cmSystemTools::ReplaceString (line, "LIBRARY_OUTPUT_PATH", - removeQuotes(this->ConvertToOptionallyRelativeOutputPath - (libPath.c_str())).c_str()); + removeQuotes(this->ConvertToOutputFormat + (libPath.c_str(), SHELL)).c_str()); cmSystemTools::ReplaceString (line, "EXECUTABLE_OUTPUT_PATH", - removeQuotes(this->ConvertToOptionallyRelativeOutputPath - (exePath.c_str())).c_str()); + removeQuotes(this->ConvertToOutputFormat + (exePath.c_str(), SHELL)).c_str()); #endif if(targetBuilds || target.GetType() == cmTarget::OBJECT_LIBRARY) @@ -1884,9 +1879,9 @@ void cmLocalVisualStudio6Generator } dir += "$(IntDir)"; options += "# ADD LINK32 /LIBPATH:"; - options += this->ConvertToOptionallyRelativeOutputPath(dir.c_str()); + options += this->ConvertToOutputFormat(dir.c_str(), SHELL); options += " /LIBPATH:"; - options += this->ConvertToOptionallyRelativeOutputPath(d->c_str()); + options += this->ConvertToOutputFormat(d->c_str(), SHELL); options += "\n"; } } @@ -1897,7 +1892,7 @@ void cmLocalVisualStudio6Generator if(l->IsPath) { options += - this->ConvertToOptionallyRelativeOutputPath(l->Value.c_str()); + this->ConvertToOutputFormat(l->Value.c_str(), SHELL); } else if (!l->Target || l->Target->GetType() != cmTarget::INTERFACE_LIBRARY) @@ -1933,7 +1928,7 @@ void cmLocalVisualStudio6Generator options += "# ADD "; options += tool; options += "32 "; - options += this->ConvertToOptionallyRelativeOutputPath(oi->c_str()); + options += this->ConvertToOutputFormat(oi->c_str(), SHELL); options += "\n"; } } diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 9c031cf..a0e9e4d 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -82,8 +82,6 @@ void cmLocalVisualStudio7Generator::AddHelperCommands() // Now create GUIDs for targets cmTargets &tgts = this->Makefile->GetTargets(); - cmGlobalVisualStudio7Generator* gg = - static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator); for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++) { if(l->second.GetType() == cmTarget::INTERFACE_LIBRARY) @@ -96,10 +94,6 @@ void cmLocalVisualStudio7Generator::AddHelperCommands() this->ReadAndStoreExternalGUID( l->second.GetName().c_str(), path); } - else - { - gg->CreateGUID(l->first.c_str()); - } } @@ -305,13 +299,10 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule() comment += makefileIn; std::string args; args = "-H"; - args += this->Convert(this->Makefile->GetHomeDirectory(), - START_OUTPUT, UNCHANGED, true); + args += this->Makefile->GetHomeDirectory(); commandLine.push_back(args); args = "-B"; - args += - this->Convert(this->Makefile->GetHomeOutputDirectory(), - START_OUTPUT, UNCHANGED, true); + args += this->Makefile->GetHomeOutputDirectory(); commandLine.push_back(args); commandLine.push_back("--check-stamp-file"); std::string stampFilename = this->Convert(stampName.c_str(), FULL, @@ -1087,9 +1078,17 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, if(!this->ModuleDefinitionFile.empty()) { std::string defFile = - this->ConvertToOptionallyRelativeOutputPath(this->ModuleDefinitionFile); + this->ConvertToOutputFormat(this->ModuleDefinitionFile, SHELL); linkOptions.AddFlag("ModuleDefinitionFile", defFile.c_str()); } + if (target.GetType() == cmTarget::SHARED_LIBRARY && + this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) + { + if (target.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS")) + { + linkOptions.AddFlag("ModuleDefinitionFile", "$(IntDir)/exportall.def"); + } + } switch(target.GetType()) { case cmTarget::UNKNOWN_LIBRARY: @@ -2024,7 +2023,28 @@ void cmLocalVisualStudio7Generator // Add pre-link event. tool = this->FortranProject? "VFPreLinkEventTool":"VCPreLinkEventTool"; event.Start(tool); - event.Write(target.GetPreLinkCommands()); + bool addedPrelink = false; + if (target.GetType() == cmTarget::SHARED_LIBRARY && + this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) + { + if (target.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS")) + { + addedPrelink = true; + std::vector<cmCustomCommand> commands = + target.GetPreLinkCommands(); + cmGlobalVisualStudioGenerator* gg + = static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator); + cmGeneratorTarget* gt = + this->GlobalGenerator->GetGeneratorTarget(&target); + gg->AddSymbolExportCommand( + gt, commands, configName); + event.Write(commands); + } + } + if (!addedPrelink) + { + event.Write(target.GetPreLinkCommands()); + } cmsys::auto_ptr<cmCustomCommand> pcc( this->MaybeCreateImplibDir(target, configName, this->FortranProject)); if(pcc.get()) @@ -2234,7 +2254,7 @@ std::string cmLocalVisualStudio7Generator::EscapeForXML(const std::string& s) std::string cmLocalVisualStudio7Generator ::ConvertToXMLOutputPath(const char* path) { - std::string ret = this->ConvertToOptionallyRelativeOutputPath(path); + std::string ret = this->ConvertToOutputFormat(path, SHELL); cmSystemTools::ReplaceString(ret, "&", "&"); cmSystemTools::ReplaceString(ret, "\"", """); cmSystemTools::ReplaceString(ret, "<", "<"); @@ -2245,7 +2265,7 @@ std::string cmLocalVisualStudio7Generator std::string cmLocalVisualStudio7Generator ::ConvertToXMLOutputPathSingle(const char* path) { - std::string ret = this->ConvertToOptionallyRelativeOutputPath(path); + std::string ret = this->ConvertToOutputFormat(path, SHELL); cmSystemTools::ReplaceString(ret, "\"", ""); cmSystemTools::ReplaceString(ret, "&", "&"); cmSystemTools::ReplaceString(ret, "<", "<"); @@ -2312,12 +2332,9 @@ void cmLocalVisualStudio7Generator::ReadAndStoreExternalGUID( { cmVS7XMLParser parser; parser.ParseFile(path); - // if we can not find a GUID then create one + // if we can not find a GUID then we will generate one later if(parser.GUID.size() == 0) { - cmGlobalVisualStudio7Generator* gg = - static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator); - gg->CreateGUID(name); return; } std::string guidStoreName = name; diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx index 7ac4432..6d3054a 100644 --- a/Source/cmMacroCommand.cxx +++ b/Source/cmMacroCommand.cxx @@ -96,12 +96,9 @@ bool cmMacroHelperCommand::InvokeInitialPass return false; } - // Enforce matching logical blocks inside the macro. - cmMakefile::LexicalPushPop lexScope(this->Makefile); - - // Push a weak policy scope which restores the policies recorded at - // macro creation. - cmMakefile::PolicyPushPop polScope(this->Makefile, true, this->Policies); + cmMakefile::MacroPushPop macroScope(this->Makefile, + this->FilePath, + this->Policies); // set the value of argc std::ostringstream argcDefStream; @@ -126,10 +123,6 @@ bool cmMacroHelperCommand::InvokeInitialPass sprintf(argvName,"${ARGV%i}",j); argVs.push_back(argvName); } - if(!this->Functions.empty()) - { - this->FilePath = this->Functions[0].FilePath; - } // Invoke all the functions that were collected in the block. cmListFileFunction newLFF; // for each function @@ -139,7 +132,6 @@ bool cmMacroHelperCommand::InvokeInitialPass newLFF.Arguments.clear(); newLFF.Arguments.reserve(this->Functions[c].Arguments.size()); newLFF.Name = this->Functions[c].Name; - newLFF.FilePath = this->Functions[c].FilePath; newLFF.Line = this->Functions[c].Line; // for each argument of the current function @@ -147,10 +139,6 @@ bool cmMacroHelperCommand::InvokeInitialPass this->Functions[c].Arguments.begin(); k != this->Functions[c].Arguments.end(); ++k) { - // Set the FilePath on the arguments to match the function since it is - // not stored and the original values may be freed - k->FilePath = this->FilePath.c_str(); - cmListFileArgument arg; arg.Value = k->Value; if(k->Delim != cmListFileArgument::Bracket) @@ -181,7 +169,6 @@ bool cmMacroHelperCommand::InvokeInitialPass } } arg.Delim = k->Delim; - arg.FilePath = k->FilePath; arg.Line = k->Line; newLFF.Arguments.push_back(arg); } @@ -191,8 +178,7 @@ bool cmMacroHelperCommand::InvokeInitialPass { // The error message should have already included the call stack // so we do not need to report an error here. - lexScope.Quiet(); - polScope.Quiet(); + macroScope.Quiet(); inStatus.SetNestedError(true); return false; } @@ -230,6 +216,7 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, cmMacroHelperCommand *f = new cmMacroHelperCommand(); f->Args = this->Args; f->Functions = this->Functions; + f->FilePath = this->GetStartingContext().FilePath; mf.RecordPolicies(f->Policies); std::string newName = "_" + this->Args[0]; mf.GetState()->RenameCommand(this->Args[0], newName); @@ -259,7 +246,8 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf) if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endmacro")) { std::vector<std::string> expandedArguments; - mf.ExpandArguments(lff.Arguments, expandedArguments); + mf.ExpandArguments(lff.Arguments, expandedArguments, + this->GetStartingContext().FilePath.c_str()); // if the endmacro has arguments make sure they // match the arguments of the macro if ((expandedArguments.empty() || diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 7c74a0f..94c77e1 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -105,7 +105,7 @@ public: ++it; if(it == this->VarStack.rend()) { - cmLocalGenerator* plg = mf->GetLocalGenerator()->GetParent(); + cmLocalGenerator* plg = mf->LocalGenerator->GetParent(); if(!plg) { return false; @@ -146,7 +146,7 @@ cmMakefile::cmMakefile(cmLocalGenerator* localGenerator) this->WarnUnused = this->GetCMakeInstance()->GetWarnUnused(); this->CheckSystemVars = this->GetCMakeInstance()->GetCheckSystemVars(); - this->GeneratingBuildSystem = false; + this->Configured = false; this->SuppressWatches = false; // Setup the default include file regular expression (match everything). @@ -213,8 +213,6 @@ cmMakefile::cmMakefile(cmLocalGenerator* localGenerator) this->AddSourceGroup("Object Files", "\\.(lo|o|obj)$"); #endif - this->Properties.SetCMakeInstance(this->GetCMakeInstance()); - { const char* dir = this->GetCMakeInstance()->GetHomeDirectory(); this->AddDefinition("CMAKE_SOURCE_DIR", dir); @@ -249,11 +247,11 @@ void cmMakefile::IssueMessage(cmake::MessageType t, std::string const& text) const { // Collect context information. - if(!this->CallStack.empty()) + if(!this->ExecutionStatusStack.empty()) { if((t == cmake::FATAL_ERROR) || (t == cmake::INTERNAL_ERROR)) { - this->CallStack.back().Status->SetNestedError(true); + this->ExecutionStatusStack.back()->SetNestedError(true); } this->GetCMakeInstance()->IssueMessage(t, text, this->GetBacktrace()); } @@ -266,8 +264,8 @@ void cmMakefile::IssueMessage(cmake::MessageType t, if(!this->GetCMakeInstance()->GetIsInTryCompile()) { - lfc.FilePath = this->LocalGenerator->Convert(lfc.FilePath, - cmLocalGenerator::HOME); + cmOutputConverter converter(this->StateSnapshot); + lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME); } lfc.Line = 0; this->GetCMakeInstance()->IssueMessage(t, text, lfc); @@ -277,26 +275,36 @@ void cmMakefile::IssueMessage(cmake::MessageType t, //---------------------------------------------------------------------------- cmListFileBacktrace cmMakefile::GetBacktrace() const { - cmListFileBacktrace backtrace(this->GetLocalGenerator()); - for(CallStackType::const_reverse_iterator i = this->CallStack.rbegin(); - i != this->CallStack.rend(); ++i) + cmListFileBacktrace backtrace; + if (!this->ContextStack.empty()) { - backtrace.Append(*i->Context); + backtrace = cmListFileBacktrace(this->StateSnapshot, + *this->ContextStack.back()); } return backtrace; } //---------------------------------------------------------------------------- +cmListFileBacktrace +cmMakefile::GetBacktrace(cmCommandContext const& cc) const +{ + cmState::Snapshot snp = this->StateSnapshot; + return cmListFileBacktrace(snp, cc); +} + +//---------------------------------------------------------------------------- cmListFileContext cmMakefile::GetExecutionContext() const { - return *this->CallStack.back().Context; + return cmListFileContext::FromCommandContext( + *this->ContextStack.back(), + this->StateSnapshot.GetExecutionListFile()); } //---------------------------------------------------------------------------- void cmMakefile::PrintCommandTrace(const cmListFileFunction& lff) const { std::ostringstream msg; - msg << lff.FilePath << "(" << lff.Line << "): "; + msg << this->GetExecutionFilePath() << "(" << lff.Line << "): "; msg << lff.Name << "("; for(std::vector<cmListFileArgument>::const_iterator i = lff.Arguments.begin(); i != lff.Arguments.end(); ++i) @@ -397,12 +405,12 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff, class cmMakefile::IncludeScope { public: - IncludeScope(cmMakefile* mf, const char* fname, bool noPolicyScope); + IncludeScope(cmMakefile* mf, std::string const& filenametoread, + bool noPolicyScope); ~IncludeScope(); void Quiet() { this->ReportError = false; } private: cmMakefile* Makefile; - const char* File; bool NoPolicyScope; bool CheckCMP0011; bool ReportError; @@ -410,9 +418,10 @@ private: }; //---------------------------------------------------------------------------- -cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf, const char* fname, +cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf, + std::string const& filenametoread, bool noPolicyScope): - Makefile(mf), File(fname), NoPolicyScope(noPolicyScope), + Makefile(mf), NoPolicyScope(noPolicyScope), CheckCMP0011(false), ReportError(true) { if(!this->NoPolicyScope) @@ -446,11 +455,25 @@ cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf, const char* fname, // The included file cannot pop our policy scope. this->Makefile->PushPolicyBarrier(); + this->Makefile->ListFileStack.push_back(filenametoread); + this->Makefile->PushFunctionBlockerBarrier(); + + this->Makefile->StateSnapshot = + this->Makefile->GetState()->CreateCallStackSnapshot( + this->Makefile->StateSnapshot, + this->Makefile->ContextStack.back()->Name, + this->Makefile->ContextStack.back()->Line, + filenametoread); } //---------------------------------------------------------------------------- cmMakefile::IncludeScope::~IncludeScope() { + this->Makefile->StateSnapshot = + this->Makefile->GetState()->Pop(this->Makefile->StateSnapshot); + assert(this->Makefile->StateSnapshot.IsValid()); + + this->Makefile->PopFunctionBlockerBarrier(this->ReportError); // Enforce matching policy scopes inside the included file. this->Makefile->PopPolicyBarrier(this->ReportError); @@ -475,6 +498,7 @@ cmMakefile::IncludeScope::~IncludeScope() this->EnforceCMP0011(); } } + this->Makefile->ListFileStack.pop_back(); } //---------------------------------------------------------------------------- @@ -489,7 +513,8 @@ void cmMakefile::IncludeScope::EnforceCMP0011() { std::ostringstream w; w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0011) << "\n" - << "The included script\n " << this->File << "\n" + << "The included script\n " + << this->Makefile->ListFileStack.back() << "\n" << "affects policy settings. " << "CMake is implying the NO_POLICY_SCOPE option for compatibility, " << "so the effects are applied to the including context."; @@ -501,7 +526,8 @@ void cmMakefile::IncludeScope::EnforceCMP0011() { std::ostringstream e; e << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0011) << "\n" - << "The included script\n " << this->File << "\n" + << "The included script\n " + << this->Makefile->ListFileStack.back() << "\n" << "affects policy settings, so it requires this policy to be set."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); } @@ -515,38 +541,123 @@ void cmMakefile::IncludeScope::EnforceCMP0011() } } -bool cmMakefile::ProcessBuildsystemFile(const char* listfile) +class cmParseFileScope { - this->AddDefinition("CMAKE_PARENT_LIST_FILE", listfile); - std::string curSrc = this->GetCurrentSourceDirectory(); - return this->ReadListFile(listfile, true, - curSrc == this->GetHomeDirectory()); -} +public: + cmParseFileScope(cmMakefile* mf) + : Makefile(mf) + { + this->Makefile->ContextStack.push_back(&this->Context); + } -bool cmMakefile::ReadDependentFile(const char* listfile, bool noPolicyScope) + ~cmParseFileScope() + { + this->Makefile->ContextStack.pop_back(); + } + +private: + cmMakefile* Makefile; + cmCommandContext Context; +}; + +bool cmMakefile::ReadDependentFile(const char* filename, bool noPolicyScope) { this->AddDefinition("CMAKE_PARENT_LIST_FILE", this->GetDefinition("CMAKE_CURRENT_LIST_FILE")); - bool result = this->ReadListFile(listfile, noPolicyScope, false); - this->ListFileStack.pop_back(); - return result; + std::string filenametoread = + cmSystemTools::CollapseFullPath(filename, + this->GetCurrentSourceDirectory()); + + IncludeScope incScope(this, filenametoread, noPolicyScope); + + cmListFile listFile; + { + cmParseFileScope pfs(this); + if (!listFile.ParseFile(filenametoread.c_str(), false, this)) + { + return false; + } + } + + this->ReadListFile(listFile, filenametoread); + if(cmSystemTools::GetFatalErrorOccured()) + { + incScope.Quiet(); + } + return true; } -bool cmMakefile::ReadListFile(const char* listfile) +class cmMakefile::ListFileScope { - bool result = this->ReadListFile(listfile, true, false); - this->ListFileStack.pop_back(); - return result; -} +public: + ListFileScope(cmMakefile* mf, std::string const& filenametoread) + : Makefile(mf), ReportError(true) + { + this->Makefile->ListFileStack.push_back(filenametoread); + this->Makefile->PushPolicyBarrier(); + + long line = 0; + std::string name; + if (!this->Makefile->ContextStack.empty()) + { + line = this->Makefile->ContextStack.back()->Line; + name = this->Makefile->ContextStack.back()->Name; + } + this->Makefile->StateSnapshot = + this->Makefile->GetState()->CreateInlineListFileSnapshot( + this->Makefile->StateSnapshot, name, line, filenametoread); + assert(this->Makefile->StateSnapshot.IsValid()); + this->Makefile->PushFunctionBlockerBarrier(); + } + + ~ListFileScope() + { + this->Makefile->StateSnapshot = + this->Makefile->GetState()->Pop(this->Makefile->StateSnapshot); + assert(this->Makefile->StateSnapshot.IsValid()); + + this->Makefile->PopFunctionBlockerBarrier(this->ReportError); + this->Makefile->PopPolicyBarrier(this->ReportError); + this->Makefile->ListFileStack.pop_back(); + } + + void Quiet() { this->ReportError = false; } +private: + cmMakefile* Makefile; + bool ReportError; +}; -bool cmMakefile::ReadListFile(const char* listfile, - bool noPolicyScope, - bool requireProjectCommand) +bool cmMakefile::ReadListFile(const char* filename) { std::string filenametoread = - cmSystemTools::CollapseFullPath(listfile, + cmSystemTools::CollapseFullPath(filename, this->GetCurrentSourceDirectory()); + ListFileScope scope(this, filenametoread); + + cmListFile listFile; + { + cmParseFileScope pfs(this); + if (!listFile.ParseFile(filenametoread.c_str(), false, this)) + { + return false; + } + } + + this->ReadListFile(listFile, filenametoread); + if(cmSystemTools::GetFatalErrorOccured()) + { + scope.Quiet(); + } + return true; +} + +void cmMakefile::ReadListFile(cmListFile const& listFile, + std::string const& filenametoread) +{ + // add this list file to the list of dependencies + this->ListFiles.push_back(filenametoread); + std::string currentParentFile = this->GetSafeDefinition("CMAKE_PARENT_LIST_FILE"); std::string currentFile @@ -560,55 +671,14 @@ bool cmMakefile::ReadListFile(const char* listfile, this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE"); this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR"); - this->ListFileStack.push_back(filenametoread); - - bool res = this->ReadListFileInternal(filenametoread.c_str(), - noPolicyScope, requireProjectCommand); - - this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str()); - this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str()); - this->AddDefinition("CMAKE_CURRENT_LIST_DIR", - cmSystemTools::GetFilenamePath(currentFile).c_str()); - this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE"); - this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE"); - this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR"); - - if (res) - { - this->CheckForUnusedVariables(); - } - - return res; -} - -bool cmMakefile::ReadListFileInternal(const char* filenametoread, - bool noPolicyScope, - bool requireProjectCommand) -{ - cmListFile cacheFile; - if( !cacheFile.ParseFile(filenametoread, requireProjectCommand, this) ) - { - return false; - } - // add this list file to the list of dependencies - this->ListFiles.push_back( filenametoread); - - // Enforce balanced blocks (if/endif, function/endfunction, etc.). - { - LexicalPushPop lexScope(this); - IncludeScope incScope(this, filenametoread, noPolicyScope); - // Run the parsed commands. - const size_t numberFunctions = cacheFile.Functions.size(); + const size_t numberFunctions = listFile.Functions.size(); for(size_t i =0; i < numberFunctions; ++i) { cmExecutionStatus status; - this->ExecuteCommand(cacheFile.Functions[i],status); + this->ExecuteCommand(listFile.Functions[i],status); if(cmSystemTools::GetFatalErrorOccured()) { - // Exit early due to error. - lexScope.Quiet(); - incScope.Quiet(); break; } if(status.GetReturnInvoked()) @@ -617,16 +687,15 @@ bool cmMakefile::ReadListFileInternal(const char* filenametoread, break; } } - } - - // If this is the directory-level CMakeLists.txt file then perform - // some extra checks. - if(this->ListFileStack.size() == 1) - { - this->EnforceDirectoryLevelRules(); - } + this->CheckForUnusedVariables(); - return true; + this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str()); + this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str()); + this->AddDefinition("CMAKE_CURRENT_LIST_DIR", + cmSystemTools::GetFilenamePath(currentFile).c_str()); + this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE"); + this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE"); + this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR"); } //---------------------------------------------------------------------------- @@ -1476,10 +1545,8 @@ void cmMakefile::AddLinkDirectory(const std::string& dir) } } -void cmMakefile::InitializeFromParent() +void cmMakefile::InitializeFromParent(cmMakefile* parent) { - cmMakefile *parent = this->LocalGenerator->GetParent()->GetMakefile(); - // Initialize definitions with the closure of the parent scope. this->Internal->InitializeDefinitions(parent); @@ -1553,10 +1620,176 @@ void cmMakefile::InitializeFromParent() this->ImportedTargets = parent->ImportedTargets; } -void cmMakefile::ConfigureSubDirectory(cmLocalGenerator *lg2) +void cmMakefile::PushFunctionScope(std::string const& fileName, + const cmPolicies::PolicyMap& pm) +{ + this->StateSnapshot = + this->GetState()->CreateFunctionCallSnapshot( + this->StateSnapshot, + this->ContextStack.back()->Name, this->ContextStack.back()->Line, + fileName); + assert(this->StateSnapshot.IsValid()); + + this->Internal->PushDefinitions(); + + this->PushLoopBlockBarrier(); + +#if defined(CMAKE_BUILD_WITH_CMAKE) + this->GetGlobalGenerator()->GetFileLockPool().PushFunctionScope(); +#endif + + this->PushFunctionBlockerBarrier(); + + this->PushPolicy(true, pm); + this->PushPolicyBarrier(); +} + +void cmMakefile::PopFunctionScope(bool reportError) { - lg2->GetMakefile()->InitializeFromParent(); - std::string currentStart = lg2->GetMakefile()->GetCurrentSourceDirectory(); + this->PopPolicyBarrier(reportError); + this->PopPolicy(); + + this->StateSnapshot = this->GetState()->Pop(this->StateSnapshot); + assert(this->StateSnapshot.IsValid()); + + this->PopFunctionBlockerBarrier(reportError); + +#if defined(CMAKE_BUILD_WITH_CMAKE) + this->GetGlobalGenerator()->GetFileLockPool().PopFunctionScope(); +#endif + + this->PopLoopBlockBarrier(); + + this->CheckForUnusedVariables(); + + this->Internal->PopDefinitions(); +} + +void cmMakefile::PushMacroScope(std::string const& fileName, + const cmPolicies::PolicyMap& pm) +{ + this->StateSnapshot = + this->GetState()->CreateMacroCallSnapshot( + this->StateSnapshot, + this->ContextStack.back()->Name, this->ContextStack.back()->Line, + fileName); + assert(this->StateSnapshot.IsValid()); + + this->PushFunctionBlockerBarrier(); + + this->PushPolicy(true, pm); + this->PushPolicyBarrier(); +} + +void cmMakefile::PopMacroScope(bool reportError) +{ + this->PopPolicyBarrier(reportError); + this->PopPolicy(); + + this->StateSnapshot = this->GetState()->Pop(this->StateSnapshot); + assert(this->StateSnapshot.IsValid()); + + this->PopFunctionBlockerBarrier(reportError); +} + +bool cmMakefile::IsRootMakefile() const +{ + return !this->StateSnapshot.GetBuildsystemDirectoryParent().IsValid(); +} + +class cmMakefile::BuildsystemFileScope +{ +public: + BuildsystemFileScope(cmMakefile* mf) + : Makefile(mf), ReportError(true) + { + std::string currentStart = + this->Makefile->StateSnapshot.GetCurrentSourceDirectory(); + currentStart += "/CMakeLists.txt"; + this->Makefile->StateSnapshot.SetListFile(currentStart); + this->Makefile->ListFileStack.push_back(currentStart); + this->Makefile->PushPolicyBarrier(); + this->Makefile->PushFunctionBlockerBarrier(); + + this->GG = mf->GetGlobalGenerator(); + this->CurrentMakefile = this->GG->GetCurrentMakefile(); + this->Snapshot = this->GG->GetCMakeInstance()->GetCurrentSnapshot(); + this->GG->GetCMakeInstance()->SetCurrentSnapshot( + this->GG->GetCMakeInstance()->GetCurrentSnapshot()); + this->GG->SetCurrentMakefile(mf); +#if defined(CMAKE_BUILD_WITH_CMAKE) + this->GG->GetFileLockPool().PushFileScope(); +#endif + } + + ~BuildsystemFileScope() + { + this->Makefile->PopFunctionBlockerBarrier(this->ReportError); + this->Makefile->PopPolicyBarrier(this->ReportError); +#if defined(CMAKE_BUILD_WITH_CMAKE) + this->GG->GetFileLockPool().PopFileScope(); +#endif + this->GG->SetCurrentMakefile(this->CurrentMakefile); + this->GG->GetCMakeInstance()->SetCurrentSnapshot(this->Snapshot); + } + + void Quiet() { this->ReportError = false; } +private: + cmMakefile* Makefile; + cmGlobalGenerator* GG; + cmMakefile* CurrentMakefile; + cmState::Snapshot Snapshot; + bool ReportError; +}; + +//---------------------------------------------------------------------------- +void cmMakefile::Configure() +{ + BuildsystemFileScope scope(this); + + // make sure the CMakeFiles dir is there + std::string filesDir = this->StateSnapshot.GetCurrentBinaryDirectory(); + filesDir += cmake::GetCMakeFilesDirectory(); + cmSystemTools::MakeDirectory(filesDir.c_str()); + + std::string currentStart = this->StateSnapshot.GetCurrentSourceDirectory(); + currentStart += "/CMakeLists.txt"; + assert(cmSystemTools::FileExists(currentStart.c_str(), true)); + this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentStart.c_str()); + + cmListFile listFile; + { + cmParseFileScope pfs(this); + if (!listFile.ParseFile(currentStart.c_str(), this->IsRootMakefile(), this)) + { + this->SetConfigured(); + return; + } + } + this->ReadListFile(listFile, currentStart); + if(cmSystemTools::GetFatalErrorOccured()) + { + scope.Quiet(); + } + + // at the end handle any old style subdirs + std::vector<cmMakefile*> subdirs = this->UnConfiguredDirectories; + + // for each subdir recurse + std::vector<cmMakefile*>::iterator sdi = subdirs.begin(); + for (; sdi != subdirs.end(); ++sdi) + { + this->ConfigureSubDirectory(*sdi); + } + + this->AddCMakeDependFilesFromUser(); + this->SetConfigured(); +} + +void cmMakefile::ConfigureSubDirectory(cmMakefile *mf) +{ + mf->InitializeFromParent(this); + std::string currentStart = mf->GetCurrentSourceDirectory(); if (this->GetCMakeInstance()->GetDebugOutput()) { std::string msg=" Entering "; @@ -1594,11 +1827,12 @@ void cmMakefile::ConfigureSubDirectory(cmLocalGenerator *lg2) // NEW behavior prints the error. this->IssueMessage(cmake::FATAL_ERROR, e.str()); } - lg2->SetConfiguredCMP0014(true); + mf->SetConfigured(); return; } // finally configure the subdir - lg2->Configure(); + mf->Configure(); + if (this->GetCMakeInstance()->GetDebugOutput()) { std::string msg=" Returning to "; @@ -1619,24 +1853,32 @@ void cmMakefile::AddSubDirectory(const std::string& srcPath, } cmState::Snapshot newSnapshot = this->GetState() - ->CreateSnapshot(this->StateSnapshot); + ->CreateBuildsystemDirectorySnapshot(this->StateSnapshot, + this->ContextStack.back()->Name, + this->ContextStack.back()->Line); // create a new local generator and set its parent cmLocalGenerator *lg2 = this->GetGlobalGenerator() ->MakeLocalGenerator(newSnapshot, this->LocalGenerator); this->GetGlobalGenerator()->AddLocalGenerator(lg2); + cmMakefile* subMf = lg2->GetMakefile(); + // set the subdirs start dirs - lg2->GetMakefile()->SetCurrentSourceDirectory(srcPath); - lg2->GetMakefile()->SetCurrentBinaryDirectory(binPath); + subMf->SetCurrentSourceDirectory(srcPath); + subMf->SetCurrentBinaryDirectory(binPath); if(excludeFromAll) { - lg2->GetMakefile()->SetProperty("EXCLUDE_FROM_ALL", "TRUE"); + subMf->SetProperty("EXCLUDE_FROM_ALL", "TRUE"); } if (immediate) { - this->ConfigureSubDirectory(lg2); + this->ConfigureSubDirectory(subMf); + } + else + { + this->UnConfiguredDirectories.push_back(subMf); } } @@ -1831,7 +2073,7 @@ void cmMakefile::LogUnused(const char* reason, { std::string path; cmListFileContext lfc; - if (!this->CallStack.empty()) + if (!this->ExecutionStatusStack.empty()) { lfc = this->GetExecutionContext(); path = lfc.FilePath; @@ -1843,8 +2085,8 @@ void cmMakefile::LogUnused(const char* reason, lfc.FilePath = path; lfc.Line = 0; } - lfc.FilePath = this->LocalGenerator->Convert(lfc.FilePath, - cmLocalGenerator::HOME); + cmOutputConverter converter(this->StateSnapshot); + lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME); if (this->CheckSystemVars || cmSystemTools::IsSubDirectory(path, @@ -2116,25 +2358,10 @@ void cmMakefile::AddSourceGroup(const std::vector<std::string>& name, return; } // build the whole source group path - const char* fullname = sg->GetFullName(); - cmGlobalGenerator* gg = this->GetGlobalGenerator(); - if(strlen(fullname)) - { - std::string guidName = "SG_Filter_"; - guidName += fullname; - gg->CreateGUID(guidName); - } for(++i; i<=lastElement; ++i) { sg->AddChild(cmSourceGroup(name[i].c_str(), 0, sg->GetFullName())); sg = sg->LookupChild(name[i].c_str()); - fullname = sg->GetFullName(); - if(strlen(fullname)) - { - std::string guidName = "SG_Filter_"; - guidName += fullname; - gg->CreateGUID(guidName); - } } sg->SetGroupRegex(regex); @@ -2390,18 +2617,11 @@ const char* cmMakefile::GetSafeDefinition(const std::string& def) const return ret; } -std::vector<std::string> cmMakefile -::GetDefinitions(int cacheonly /* = 0 */) const +std::vector<std::string> cmMakefile::GetDefinitions() const { - std::vector<std::string> res; - if ( !cacheonly ) - { - res = this->Internal->ClosureKeys(); - } - std::vector<std::string> cacheKeys = - this->GetState()->GetCacheEntryKeys(); + std::vector<std::string> res = this->Internal->ClosureKeys(); + std::vector<std::string> cacheKeys = this->GetState()->GetCacheEntryKeys(); res.insert(res.end(), cacheKeys.begin(), cacheKeys.end()); - std::sort(res.begin(), res.end()); return res; } @@ -2763,8 +2983,9 @@ cmake::MessageType cmMakefile::ExpandVariablesInStringNew( { std::ostringstream msg; cmListFileContext lfc; - lfc.FilePath = this->LocalGenerator - ->Convert(filename, cmLocalGenerator::HOME); + cmOutputConverter converter(this->StateSnapshot); + lfc.FilePath = + converter.Convert(filename, cmOutputConverter::HOME); lfc.Line = line; msg << "uninitialized variable \'" << lookup << "\'"; this->GetCMakeInstance()->IssueMessage(cmake::AUTHOR_WARNING, @@ -3163,7 +3384,6 @@ void cmMakefile::PopFunctionBlockerBarrier(bool reportError) this->FunctionBlockerBarriers.back(); while(this->FunctionBlockers.size() > barrier) { - cmMakefile::LoopBlockPop loopBlockPop(this); cmsys::auto_ptr<cmFunctionBlocker> fb(this->FunctionBlockers.back()); this->FunctionBlockers.pop_back(); if(reportError) @@ -3215,11 +3435,26 @@ bool cmMakefile::IsLoopBlock() const return !this->LoopBlockCounter.empty() && this->LoopBlockCounter.top() > 0; } +std::string cmMakefile::GetExecutionFilePath() const +{ + if (this->ContextStack.empty()) + { + return std::string(); + } + assert(this->StateSnapshot.IsValid()); + return this->StateSnapshot.GetExecutionListFile(); +} + //---------------------------------------------------------------------------- bool cmMakefile::ExpandArguments( std::vector<cmListFileArgument> const& inArgs, - std::vector<std::string>& outArgs) const + std::vector<std::string>& outArgs, const char* filename) const { + std::string efp = this->GetExecutionFilePath(); + if (!filename) + { + filename = efp.c_str(); + } std::vector<cmListFileArgument>::const_iterator i; std::string value; outArgs.reserve(inArgs.size()); @@ -3234,8 +3469,7 @@ bool cmMakefile::ExpandArguments( // Expand the variables in the argument. value = i->Value; this->ExpandVariablesInString(value, false, false, false, - i->FilePath, i->Line, - false, false); + filename, i->Line, false, false); // If the argument is quoted, it should be one argument. // Otherwise, it may be a list of arguments. @@ -3254,8 +3488,13 @@ bool cmMakefile::ExpandArguments( //---------------------------------------------------------------------------- bool cmMakefile::ExpandArguments( std::vector<cmListFileArgument> const& inArgs, - std::vector<cmExpandedCommandArgument>& outArgs) const + std::vector<cmExpandedCommandArgument>& outArgs, const char* filename) const { + std::string efp = this->GetExecutionFilePath(); + if (!filename) + { + filename = efp.c_str(); + } std::vector<cmListFileArgument>::const_iterator i; std::string value; outArgs.reserve(inArgs.size()); @@ -3270,8 +3509,7 @@ bool cmMakefile::ExpandArguments( // Expand the variables in the argument. value = i->Value; this->ExpandVariablesInString(value, false, false, false, - i->FilePath, i->Line, - false, false); + filename, i->Line, false, false); // If the argument is quoted, it should be one argument. // Otherwise, it may be a list of arguments. @@ -3295,7 +3533,7 @@ bool cmMakefile::ExpandArguments( //---------------------------------------------------------------------------- void cmMakefile::AddFunctionBlocker(cmFunctionBlocker* fb) { - if(!this->CallStack.empty()) + if(!this->ExecutionStatusStack.empty()) { // Record the context in which the blocker is created. fb->SetStartingContext(this->GetExecutionContext()); @@ -3328,11 +3566,13 @@ cmMakefile::RemoveFunctionBlocker(cmFunctionBlocker* fb, if(!(*pos)->ShouldRemove(lff, *this)) { cmListFileContext const& lfc = fb->GetStartingContext(); + cmListFileContext closingContext = + cmListFileContext::FromCommandContext(lff, lfc.FilePath); std::ostringstream e; e << "A logical block opening on the line\n" << " " << lfc << "\n" << "closes on the line\n" - << " " << lff << "\n" + << " " << closingContext << "\n" << "with mis-matching arguments."; this->IssueMessage(cmake::AUTHOR_WARNING, e.str()); } @@ -3345,19 +3585,6 @@ cmMakefile::RemoveFunctionBlocker(cmFunctionBlocker* fb, return cmsys::auto_ptr<cmFunctionBlocker>(); } -//---------------------------------------------------------------------------- -cmMakefile::LexicalPushPop::LexicalPushPop(cmMakefile* mf): - Makefile(mf), ReportError(true) -{ - this->Makefile->PushFunctionBlockerBarrier(); -} - -//---------------------------------------------------------------------------- -cmMakefile::LexicalPushPop::~LexicalPushPop() -{ - this->Makefile->PopFunctionBlockerBarrier(this->ReportError); -} - const char* cmMakefile::GetHomeDirectory() const { return this->GetCMakeInstance()->GetHomeDirectory(); @@ -3982,7 +4209,7 @@ void cmMakefile::SetProperty(const std::string& prop, const char* value) } } - this->Properties.SetProperty(prop,value,cmProperty::DIRECTORY); + this->Properties.SetProperty(prop, value); } void cmMakefile::AppendProperty(const std::string& prop, @@ -4022,23 +4249,26 @@ void cmMakefile::AppendProperty(const std::string& prop, return; } - this->Properties.AppendProperty(prop,value,cmProperty::DIRECTORY,asString); + this->Properties.AppendProperty(prop, value, asString); } const char *cmMakefile::GetProperty(const std::string& prop) const { - return this->GetProperty(prop, cmProperty::DIRECTORY); + const bool chain = this->GetState()-> + IsPropertyChained(prop, cmProperty::DIRECTORY); + return this->GetProperty(prop, chain); } const char *cmMakefile::GetProperty(const std::string& prop, - cmProperty::ScopeType scope) const + bool chain) const { // watch for specific properties static std::string output; output = ""; if (prop == "PARENT_DIRECTORY") { - cmState::Snapshot parent = this->StateSnapshot.GetParent(); + cmState::Snapshot parent = + this->StateSnapshot.GetBuildsystemDirectoryParent(); if(parent.IsValid()) { return parent.GetCurrentSourceDirectory(); @@ -4055,36 +4285,20 @@ const char *cmMakefile::GetProperty(const std::string& prop, output = cmJoin(this->ListFileStack, ";"); return output.c_str(); } - else if (prop == "VARIABLES" || prop == "CACHE_VARIABLES") + else if ( prop == "CACHE_VARIABLES" ) { - int cacheonly = 0; - if ( prop == "CACHE_VARIABLES" ) - { - cacheonly = 1; - } - output = cmJoin(this->GetDefinitions(cacheonly), ";"); + output = cmJoin(this->GetState()->GetCacheEntryKeys(), ";"); return output.c_str(); } - else if (prop == "MACROS") + else if (prop == "VARIABLES") { - this->GetListOfMacros(output); + output = cmJoin(this->GetDefinitions(), ";"); return output.c_str(); } - else if (prop == "DEFINITIONS") + else if (prop == "MACROS") { - switch(this->GetPolicyStatus(cmPolicies::CMP0059)) - { - case cmPolicies::WARN: - this->IssueMessage(cmake::AUTHOR_WARNING, cmPolicies:: - GetPolicyWarning(cmPolicies::CMP0059)); - case cmPolicies::OLD: - output += this->DefineFlagsOrig; - return output.c_str(); - case cmPolicies::NEW: - case cmPolicies::REQUIRED_ALWAYS: - case cmPolicies::REQUIRED_IF_USED: - break; - } + this->GetListOfMacros(output); + return output.c_str(); } else if (prop == "LINK_DIRECTORIES") { @@ -4134,15 +4348,13 @@ const char *cmMakefile::GetProperty(const std::string& prop, return output.c_str(); } - bool chain = false; - const char *retVal = - this->Properties.GetPropertyValue(prop, scope, chain); - if (chain) + const char *retVal = this->Properties.GetPropertyValue(prop); + if (!retVal && chain) { if(this->LocalGenerator->GetParent()) { return this->LocalGenerator->GetParent()->GetMakefile()-> - GetProperty(prop, scope); + GetProperty(prop, chain); } return this->GetState()->GetGlobalProperty(prop); } @@ -4155,33 +4367,6 @@ bool cmMakefile::GetPropertyAsBool(const std::string& prop) const return cmSystemTools::IsOn(this->GetProperty(prop)); } -//---------------------------------------------------------------------------- -const char* cmMakefile::GetFeature(const std::string& feature, - const std::string& config) -{ - // TODO: Define accumulation policy for features (prepend, append, replace). - // Currently we always replace. - if(!config.empty()) - { - std::string featureConfig = feature; - featureConfig += "_"; - featureConfig += cmSystemTools::UpperCase(config); - if(const char* value = this->GetProperty(featureConfig)) - { - return value; - } - } - if(const char* value = this->GetProperty(feature)) - { - return value; - } - if(cmLocalGenerator* parent = this->LocalGenerator->GetParent()) - { - return parent->GetMakefile()->GetFeature(feature, config); - } - return 0; -} - cmTarget* cmMakefile::FindTarget(const std::string& name, bool excludeAliases) const { @@ -4597,6 +4782,16 @@ void cmMakefile::StoreMatches(cmsys::RegularExpression& re) this->MarkVariableAsUsed(nMatchesVariable); } +cmState::Snapshot cmMakefile::GetStateSnapshot() const +{ + return this->StateSnapshot; +} + +const char* cmMakefile::GetDefineFlagsCMP0059() const +{ + return this->DefineFlagsOrig.c_str(); +} + //---------------------------------------------------------------------------- cmPolicies::PolicyStatus cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id) const @@ -5358,3 +5553,44 @@ AddRequiredTargetCFeature(cmTarget *target, const std::string& feature) const } return true; } + + +cmMakefile::FunctionPushPop::FunctionPushPop(cmMakefile* mf, + const std::string& fileName, + cmPolicies::PolicyMap const& pm) + : Makefile(mf), ReportError(true) +{ + this->Makefile->PushFunctionScope(fileName, pm); +} + +cmMakefile::FunctionPushPop::~FunctionPushPop() +{ + this->Makefile->PopFunctionScope(this->ReportError); +} + + +cmMakefile::MacroPushPop::MacroPushPop(cmMakefile* mf, + const std::string& fileName, + const cmPolicies::PolicyMap& pm) + : Makefile(mf), ReportError(true) +{ + this->Makefile->PushMacroScope(fileName, pm); +} + +cmMakefile::MacroPushPop::~MacroPushPop() +{ + this->Makefile->PopMacroScope(this->ReportError); +} + +cmMakefileCall::cmMakefileCall(cmMakefile* mf, const cmCommandContext& lfc, + cmExecutionStatus& status): Makefile(mf) +{ + this->Makefile->ContextStack.push_back(&lfc); + this->Makefile->ExecutionStatusStack.push_back(&status); +} + +cmMakefileCall::~cmMakefileCall() +{ + this->Makefile->ExecutionStatusStack.pop_back(); + this->Makefile->ContextStack.pop_back(); +} diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index efd73a1..82a2279 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -14,7 +14,6 @@ #include "cmExecutionStatus.h" #include "cmListFileCache.h" -#include "cmPolicies.h" #include "cmPropertyMap.h" #include "cmSystemTools.h" #include "cmTarget.h" @@ -80,17 +79,20 @@ public: */ ~cmMakefile(); - bool ReadListFile(const char* listfile); + bool ReadListFile(const char* filename); - bool ReadDependentFile(const char* listfile, bool noPolicyScope = true); + bool ReadDependentFile(const char* filename, bool noPolicyScope = true); - bool ProcessBuildsystemFile(const char* listfile); + bool ProcessBuildsystemFile(const char* filename); /** * Add a function blocker to this makefile */ void AddFunctionBlocker(cmFunctionBlocker* fb); + /// @return whether we are processing the top CMakeLists.txt file. + bool IsRootMakefile() const; + /** * Remove the function blocker whose scope ends with the given command. * This returns ownership of the function blocker object. @@ -98,28 +100,6 @@ public: cmsys::auto_ptr<cmFunctionBlocker> RemoveFunctionBlocker(cmFunctionBlocker* fb, const cmListFileFunction& lff); - /** Push/pop a lexical (function blocker) barrier automatically. */ - class LexicalPushPop - { - public: - LexicalPushPop(cmMakefile* mf); - ~LexicalPushPop(); - void Quiet() { this->ReportError = false; } - private: - cmMakefile* Makefile; - bool ReportError; - }; - friend class LexicalPushPop; - - class LoopBlockPop - { - public: - LoopBlockPop(cmMakefile* mf) { this->Makefile = mf; } - ~LoopBlockPop() { this->Makefile->PopLoopBlock(); } - private: - cmMakefile* Makefile; - }; - /** * Try running cmake and building a file. This is used for dynalically * loaded commands, not as part of the usual build process. @@ -270,10 +250,12 @@ public: bool excludeFromAll, bool immediate); + void Configure(); + /** * Configure a subdirectory */ - void ConfigureSubDirectory(cmLocalGenerator *); + void ConfigureSubDirectory(cmMakefile* mf); /** * Add an include directory to the build. @@ -372,13 +354,6 @@ public: friend class PolicyPushPop; /** - * Get the Policies Instance - */ - cmPolicies *GetPolicies() const; - - mutable std::set<cmListFileContext> CMP0054ReportedIds; - - /** * Determine if the given context, name pair has already been reported * in context of CMP0054. */ @@ -515,7 +490,7 @@ public: * cacheonly is specified and is greater than 0, then only cache * variables will be listed. */ - std::vector<std::string> GetDefinitions(int cacheonly=0) const; + std::vector<std::string> GetDefinitions() const; /** * Test a boolean variable to see if it is true or false. @@ -572,6 +547,7 @@ public: * Get the current context backtrace. */ cmListFileBacktrace GetBacktrace() const; + cmListFileBacktrace GetBacktrace(cmCommandContext const& lfc) const; cmListFileContext GetExecutionContext() const; /** @@ -667,10 +643,12 @@ public: * variable replacement and list expansion. */ bool ExpandArguments(std::vector<cmListFileArgument> const& inArgs, - std::vector<std::string>& outArgs) const; + std::vector<std::string>& outArgs, + const char* filename = 0) const; bool ExpandArguments(std::vector<cmListFileArgument> const& inArgs, - std::vector<cmExpandedCommandArgument>& outArgs) const; + std::vector<cmExpandedCommandArgument>& outArgs, + const char* filename = 0) const; /** * Get the instance @@ -720,18 +698,14 @@ public: void AppendProperty(const std::string& prop, const char *value, bool asString=false); const char *GetProperty(const std::string& prop) const; - const char *GetProperty(const std::string& prop, - cmProperty::ScopeType scope) const; + const char *GetProperty(const std::string& prop, bool chain) const; bool GetPropertyAsBool(const std::string& prop) const; - const char* GetFeature(const std::string& feature, - const std::string& config); - // Get the properties cmPropertyMap &GetProperties() { return this->Properties; } ///! Initialize a makefile from its parent - void InitializeFromParent(); + void InitializeFromParent(cmMakefile* parent); void AddInstallGenerator(cmInstallGenerator* g) { if(g) this->InstallGenerators.push_back(g); } @@ -743,7 +717,38 @@ public: const std::vector<cmTestGenerator*>& GetTestGenerators() const { return this->TestGenerators; } - // push and pop variable scopes + class FunctionPushPop + { + public: + FunctionPushPop(cmMakefile* mf, std::string const& fileName, + cmPolicies::PolicyMap const& pm); + ~FunctionPushPop(); + + void Quiet() { this->ReportError = false; } + private: + cmMakefile* Makefile; + bool ReportError; + }; + + class MacroPushPop + { + public: + MacroPushPop(cmMakefile* mf, std::string const& fileName, + cmPolicies::PolicyMap const& pm); + ~MacroPushPop(); + + void Quiet() { this->ReportError = false; } + private: + cmMakefile* Makefile; + bool ReportError; + }; + + void PushFunctionScope(std::string const& fileName, + cmPolicies::PolicyMap const& pm); + void PopFunctionScope(bool reportError); + void PushMacroScope(std::string const& fileName, + cmPolicies::PolicyMap const& pm); + void PopMacroScope(bool reportError); void PushScope(); void PopScope(); void RaiseScope(const std::string& var, const char *value); @@ -781,8 +786,8 @@ public: return this->CompileDefinitionsEntries; } - bool IsGeneratingBuildSystem() const { return this->GeneratingBuildSystem; } - void SetGeneratingBuildSystem(){ this->GeneratingBuildSystem = true; } + bool IsConfigured() const { return this->Configured; } + void SetConfigured(){ this->Configured = true; } void AddQtUiFileWithOptions(cmSourceFile *sf); std::vector<cmSourceFile*> GetQtUiFilesWithOptions() const; @@ -816,6 +821,14 @@ public: void ClearMatches(); void StoreMatches(cmsys::RegularExpression& re); + cmState::Snapshot GetStateSnapshot() const; + + const char* GetDefineFlagsCMP0059() const; + + std::string GetExecutionFilePath() const; + + void EnforceDirectoryLevelRules() const; + protected: // add link libraries and directories to the target void AddGlobalLinkInformation(const std::string& name, cmTarget& target); @@ -823,6 +836,8 @@ protected: // Check for a an unused variable void LogUnused(const char* reason, const std::string& name) const; + mutable std::set<cmListFileContext> CMP0054ReportedIds; + std::string ProjectName; // project name // libraries, classes, and executables @@ -888,13 +903,8 @@ private: cmState::Snapshot StateSnapshot; - bool ReadListFile(const char* listfile, - bool noPolicyScope, - bool requireProjectCommand); - - bool ReadListFileInternal(const char* filenametoread, - bool noPolicyScope, - bool requireProjectCommand); + void ReadListFile(cmListFile const& listFile, + const std::string& filenametoread); bool ParseDefineFlag(std::string const& definition, bool remove); @@ -920,24 +930,17 @@ private: mutable cmsys::RegularExpression cmAtVarRegex; mutable cmsys::RegularExpression cmNamedCurly; - cmPropertyMap Properties; + std::vector<cmMakefile*> UnConfiguredDirectories; - // Unused variable flags - bool WarnUnused; - bool CheckSystemVars; + cmPropertyMap Properties; // stack of list files being read std::vector<std::string> ListFileStack; - // stack of commands being invoked. - struct CallStackEntry - { - cmListFileContext const* Context; - cmExecutionStatus* Status; - }; - typedef std::vector<CallStackEntry> CallStackType; - CallStackType CallStack; + std::vector<cmCommandContext const*> ContextStack; + std::vector<cmExecutionStatus*> ExecutionStatusStack; friend class cmMakefileCall; + friend class cmParseFileScope; std::vector<cmTarget*> ImportedTargetsOwned; TargetMap ImportedTargets; @@ -951,6 +954,10 @@ private: friend class cmCMakePolicyCommand; class IncludeScope; friend class IncludeScope; + class ListFileScope; + friend class ListFileScope; + class BuildsystemFileScope; + friend class BuildsystemFileScope; // stack of policy settings struct PolicyStackEntry: public cmPolicies::PolicyMap @@ -967,11 +974,6 @@ private: cmPolicies::PolicyStatus GetPolicyStatusInternal(cmPolicies::PolicyID id) const; - bool CheckCMP0000; - - // Enforce rules about CMakeLists.txt files. - void EnforceDirectoryLevelRules() const; - // CMP0053 == old cmake::MessageType ExpandVariablesInStringOld( std::string& errorstr, @@ -994,7 +996,6 @@ private: long line, bool removeEmpty, bool replaceAt) const; - bool GeneratingBuildSystem; /** * Old version of GetSourceFileWithOutput(const std::string&) kept for * backward-compatibility. It implements a linear search and support @@ -1040,6 +1041,11 @@ private: void CheckForUnusedVariables() const; + // Unused variable flags + bool WarnUnused; + bool CheckSystemVars; + bool CheckCMP0000; + bool Configured; mutable bool SuppressWatches; }; @@ -1049,16 +1055,9 @@ class cmMakefileCall { public: cmMakefileCall(cmMakefile* mf, - cmListFileContext const& lfc, - cmExecutionStatus& status): Makefile(mf) - { - cmMakefile::CallStackEntry entry = {&lfc, &status}; - this->Makefile->CallStack.push_back(entry); - } - ~cmMakefileCall() - { - this->Makefile->CallStack.pop_back(); - } + cmCommandContext const& lfc, + cmExecutionStatus& status); + ~cmMakefileCall(); private: cmMakefile* Makefile; }; diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index 37b297e..416063f 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -22,7 +22,7 @@ //---------------------------------------------------------------------------- cmMakefileExecutableTargetGenerator ::cmMakefileExecutableTargetGenerator(cmGeneratorTarget* target): - cmMakefileTargetGenerator(target->Target) + cmMakefileTargetGenerator(target) { this->CustomCommandDriver = OnDepends; this->Target->GetExecutableNames( diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 450f573..696dcc4 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -18,11 +18,12 @@ #include "cmSourceFile.h" #include "cmTarget.h" #include "cmake.h" +#include "cmAlgorithms.h" //---------------------------------------------------------------------------- cmMakefileLibraryTargetGenerator ::cmMakefileLibraryTargetGenerator(cmGeneratorTarget* target): - cmMakefileTargetGenerator(target->Target) + cmMakefileTargetGenerator(target) { this->CustomCommandDriver = OnDepends; if (this->Target->GetType() != cmTarget::INTERFACE_LIBRARY) @@ -563,6 +564,58 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules useResponseFileForObjects, buildObjs, depends, useWatcomQuote); + // maybe create .def file from list of objects + if (this->Target->GetType() == cmTarget::SHARED_LIBRARY && + this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) + { + if(this->Target->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS")) + { + std::string name_of_def_file = + this->Target->GetSupportDirectory(); + name_of_def_file += std::string("/") + + this->Target->GetName(); + name_of_def_file += ".def"; + std::string cmd = cmSystemTools::GetCMakeCommand(); + cmd = this->Convert(cmd, cmLocalGenerator::NONE, + cmLocalGenerator::SHELL); + cmd += " -E __create_def "; + cmd += this->Convert(name_of_def_file, + cmLocalGenerator::START_OUTPUT, + cmLocalGenerator::SHELL); + cmd += " "; + std::string objlist_file = name_of_def_file; + objlist_file += ".objs"; + cmd += this->Convert(objlist_file, + cmLocalGenerator::START_OUTPUT, + cmLocalGenerator::SHELL); + real_link_commands.push_back(cmd); + // create a list of obj files for the -E __create_def to read + cmGeneratedFileStream fout(objlist_file.c_str()); + for(std::vector<std::string>::const_iterator i = this->Objects.begin(); + i != this->Objects.end(); ++i) + { + if(cmHasLiteralSuffix(*i, ".obj")) + { + fout << *i << "\n"; + } + } + for(std::vector<std::string>::const_iterator i = + this->ExternalObjects.begin(); + i != this->ExternalObjects.end(); ++i) + { + fout << *i << "\n"; + } + // now add the def file link flag + linkFlags += " "; + linkFlags += + this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG"); + linkFlags += this->Convert(name_of_def_file, + cmLocalGenerator::START_OUTPUT, + cmLocalGenerator::SHELL); + linkFlags += " "; + } + } + cmLocalGenerator::RuleVariables vars; vars.TargetPDB = targetOutPathPDB.c_str(); diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 7b88bc7..09fad5c 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -32,7 +32,7 @@ #include <ctype.h> -cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmTarget* target) +cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmGeneratorTarget* target) : OSXBundleGenerator(0) , MacOSXContentGenerator(0) { @@ -41,16 +41,15 @@ cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmTarget* target) this->FlagFileStream = 0; this->CustomCommandDriver = OnBuild; this->FortranModuleDirectoryComputed = false; - this->Target = target; + this->Target = target->Target; this->Makefile = this->Target->GetMakefile(); this->LocalGenerator = - static_cast<cmLocalUnixMakefileGenerator3*>( - this->Makefile->GetLocalGenerator()); + static_cast<cmLocalUnixMakefileGenerator3*>(target->GetLocalGenerator()); this->ConfigName = this->LocalGenerator->ConfigurationName.c_str(); this->GlobalGenerator = static_cast<cmGlobalUnixMakefileGenerator3*>( this->LocalGenerator->GetGlobalGenerator()); - this->GeneratorTarget = this->GlobalGenerator->GetGeneratorTarget(target); + this->GeneratorTarget = target; cmake* cm = this->GlobalGenerator->GetCMakeInstance(); this->NoRuleMessages = false; if(const char* ruleStatus = cm->GetState() @@ -614,13 +613,7 @@ cmMakefileTargetGenerator } // Get the output paths for source and object files. - std::string sourceFile = source.GetFullPath(); - if(this->LocalGenerator->UseRelativePaths) - { - sourceFile = this->Convert(sourceFile, - cmLocalGenerator::START_OUTPUT); - } - sourceFile = this->Convert(sourceFile, + std::string sourceFile = this->Convert(source.GetFullPath(), cmLocalGenerator::NONE, cmLocalGenerator::SHELL); @@ -775,6 +768,25 @@ cmMakefileTargetGenerator } } + // Maybe insert a compiler launcher like ccache or distcc + if (!compileCommands.empty() && (lang == "C" || lang == "CXX")) + { + std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER"; + const char *clauncher = this->Target->GetProperty(clauncher_prop); + if (clauncher && *clauncher) + { + std::vector<std::string> launcher_cmd; + cmSystemTools::ExpandListArgument(clauncher, launcher_cmd, true); + for (std::vector<std::string>::iterator i = launcher_cmd.begin(), + e = launcher_cmd.end(); i != e; ++i) + { + *i = this->LocalGenerator->EscapeForShell(*i); + } + std::string const& run_launcher = cmJoin(launcher_cmd, " ") + " "; + compileCommands.front().insert(0, run_launcher); + } + } + // Expand placeholders in the commands. for(std::vector<std::string>::iterator i = compileCommands.begin(); i != compileCommands.end(); ++i) @@ -1132,8 +1144,8 @@ void cmMakefileTargetGenerator::WriteTargetDependRules() pi != this->MultipleOutputPairs.end(); ++pi) { *this->InfoFileStream - << " " << cmLocalGenerator::EscapeForCMake(pi->first) - << " " << cmLocalGenerator::EscapeForCMake(pi->second) + << " " << cmOutputConverter::EscapeForCMake(pi->first) + << " " << cmOutputConverter::EscapeForCMake(pi->second) << "\n"; } *this->InfoFileStream << " )\n\n"; @@ -1161,8 +1173,10 @@ void cmMakefileTargetGenerator::WriteTargetDependRules() && linkee->GetType() != cmTarget::INTERFACE_LIBRARY && emitted.insert(linkee).second) { + cmGeneratorTarget* gt = + this->GlobalGenerator->GetGeneratorTarget(linkee); + cmLocalGenerator* lg = gt->GetLocalGenerator(); cmMakefile* mf = linkee->GetMakefile(); - cmLocalGenerator* lg = mf->GetLocalGenerator(); std::string di = mf->GetCurrentBinaryDirectory(); di += "/"; di += lg->GetTargetDirectory(*linkee); @@ -1595,9 +1609,8 @@ std::string cmMakefileTargetGenerator::GetFrameworkFlags(std::string const& l) if(emitted.insert(*i).second) { flags += fwSearchFlag; - flags += this->Convert(*i, - cmLocalGenerator::START_OUTPUT, - cmLocalGenerator::SHELL, true); + flags += this->LocalGenerator + ->ConvertToOutputFormat(*i, cmLocalGenerator::SHELL); flags += " "; } } @@ -2093,13 +2106,13 @@ void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags) //---------------------------------------------------------------------------- const char* cmMakefileTargetGenerator::GetFeature(const std::string& feature) { - return this->Target->GetFeature(feature, this->ConfigName); + return this->GeneratorTarget->GetFeature(feature, this->ConfigName); } //---------------------------------------------------------------------------- bool cmMakefileTargetGenerator::GetFeatureAsBool(const std::string& feature) { - return this->Target->GetFeatureAsBool(feature, this->ConfigName); + return this->GeneratorTarget->GetFeatureAsBool(feature, this->ConfigName); } //---------------------------------------------------------------------------- diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index 58044e8..9182236 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -34,7 +34,7 @@ class cmMakefileTargetGenerator { public: // constructor to set the ivars - cmMakefileTargetGenerator(cmTarget* target); + cmMakefileTargetGenerator(cmGeneratorTarget* target); virtual ~cmMakefileTargetGenerator(); // construct using this factory call @@ -273,10 +273,9 @@ protected: std::string Convert(const std::string& source, cmLocalGenerator::RelativeRoot relative, cmLocalGenerator::OutputFormat output = - cmLocalGenerator::UNCHANGED, - bool optional = false) + cmLocalGenerator::UNCHANGED) { - return this->LocalGenerator->Convert(source, relative, output, optional); + return this->LocalGenerator->Convert(source, relative, output); } }; diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx index 25d929c..303ca63 100644 --- a/Source/cmMakefileUtilityTargetGenerator.cxx +++ b/Source/cmMakefileUtilityTargetGenerator.cxx @@ -21,7 +21,7 @@ //---------------------------------------------------------------------------- cmMakefileUtilityTargetGenerator ::cmMakefileUtilityTargetGenerator(cmGeneratorTarget* target): - cmMakefileTargetGenerator(target->Target) + cmMakefileTargetGenerator(target) { this->CustomCommandDriver = OnUtility; this->OSXBundleGenerator = new cmOSXBundleGenerator(target, diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index bbf03ff..88da09b 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -32,7 +32,7 @@ cmNinjaNormalTargetGenerator:: cmNinjaNormalTargetGenerator(cmGeneratorTarget* target) - : cmNinjaTargetGenerator(target->Target) + : cmNinjaTargetGenerator(target) , TargetNameOut() , TargetNameSO() , TargetNameReal() @@ -486,6 +486,22 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() linkPath, &genTarget, useWatcomQuote); + if(this->GetMakefile()->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS") + && target.GetType() == cmTarget::SHARED_LIBRARY) + { + if(target.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS")) + { + std::string dllname = targetOutput; + std::string name_of_def_file + = target.GetSupportDirectory(); + name_of_def_file += "/" + target.GetName(); + name_of_def_file += ".def "; + vars["LINK_FLAGS"] += " /DEF:"; + vars["LINK_FLAGS"] += this->GetLocalGenerator() + ->ConvertToOutputFormat(name_of_def_file.c_str(), + cmLocalGenerator::SHELL); + } + } this->addPoolNinjaVariable("JOB_POOL_LINK", &target, vars); @@ -600,6 +616,44 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() } } + // maybe create .def file from list of objects + if (target.GetType() == cmTarget::SHARED_LIBRARY && + this->GetMakefile()->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) + { + if(target.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS")) + { + std::string cmakeCommand = + this->GetLocalGenerator()->ConvertToOutputFormat( + cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL); + std::string dllname = targetOutput; + std::string name_of_def_file + = target.GetSupportDirectory(); + name_of_def_file += "/" + target.GetName(); + name_of_def_file += ".def"; + std::string cmd = cmakeCommand; + cmd += " -E __create_def "; + cmd += this->GetLocalGenerator() + ->ConvertToOutputFormat(name_of_def_file.c_str(), + cmLocalGenerator::SHELL); + cmd += " "; + cmNinjaDeps objs = this->GetObjects(); + std::string obj_list_file = name_of_def_file; + obj_list_file += ".objs"; + cmd += this->GetLocalGenerator() + ->ConvertToOutputFormat(obj_list_file.c_str(), + cmLocalGenerator::SHELL); + preLinkCmdLines.push_back(cmd); + // create a list of obj files for the -E __create_def to read + cmGeneratedFileStream fout(obj_list_file.c_str()); + for(cmNinjaDeps::iterator i=objs.begin(); i != objs.end(); ++i) + { + if(cmHasLiteralSuffix(*i, ".obj")) + { + fout << *i << "\n"; + } + } + } + } // If we have any PRE_LINK commands, we need to go back to HOME_OUTPUT for // the link commands. if (!preLinkCmdLines.empty()) diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 879d6b7..b18f368 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -22,6 +22,7 @@ #include "cmComputeLinkInformation.h" #include "cmSourceFile.h" #include "cmCustomCommandGenerator.h" +#include "cmAlgorithms.h" #include <algorithm> @@ -56,19 +57,18 @@ cmNinjaTargetGenerator::New(cmGeneratorTarget* target) } } -cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmTarget* target) +cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmGeneratorTarget* target) : MacOSXContentGenerator(0), OSXBundleGenerator(0), MacContentFolders(), - Target(target), - Makefile(target->GetMakefile()), + Target(target->Target), + Makefile(target->Makefile), LocalGenerator( - static_cast<cmLocalNinjaGenerator*>(Makefile->GetLocalGenerator())), + static_cast<cmLocalNinjaGenerator*>(target->GetLocalGenerator())), Objects() { - this->GeneratorTarget = - this->GetGlobalGenerator()->GetGeneratorTarget(target); + this->GeneratorTarget = target; MacOSXContentGenerator = new MacOSXContentGeneratorType(this); } @@ -107,13 +107,14 @@ std::string cmNinjaTargetGenerator::LanguageCompilerRule( // TODO: Picked up from cmMakefileTargetGenerator. Refactor it. const char* cmNinjaTargetGenerator::GetFeature(const std::string& feature) { - return this->Target->GetFeature(feature, this->GetConfigName()); + return this->GeneratorTarget->GetFeature(feature, this->GetConfigName()); } // TODO: Picked up from cmMakefileTargetGenerator. Refactor it. bool cmNinjaTargetGenerator::GetFeatureAsBool(const std::string& feature) { - return this->Target->GetFeatureAsBool(feature, this->GetConfigName()); + return this->GeneratorTarget->GetFeatureAsBool(feature, + this->GetConfigName()); } // TODO: Picked up from cmMakefileTargetGenerator. Refactor it. @@ -475,6 +476,25 @@ cmNinjaTargetGenerator } } + // Maybe insert a compiler launcher like ccache or distcc + if (!compileCmds.empty() && (lang == "C" || lang == "CXX")) + { + std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER"; + const char *clauncher = this->Target->GetProperty(clauncher_prop); + if (clauncher && *clauncher) + { + std::vector<std::string> launcher_cmd; + cmSystemTools::ExpandListArgument(clauncher, launcher_cmd, true); + for (std::vector<std::string>::iterator i = launcher_cmd.begin(), + e = launcher_cmd.end(); i != e; ++i) + { + *i = this->LocalGenerator->EscapeForShell(*i); + } + std::string const& run_launcher = cmJoin(launcher_cmd, " ") + " "; + compileCmds.front().insert(0, run_launcher); + } + } + if (!compileCmds.empty()) { compileCmds.front().insert(0, cldeps); diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h index 4e7d8b3..fc361b2 100644 --- a/Source/cmNinjaTargetGenerator.h +++ b/Source/cmNinjaTargetGenerator.h @@ -33,7 +33,7 @@ public: static cmNinjaTargetGenerator* New(cmGeneratorTarget* target); /// Build a NinjaTargetGenerator. - cmNinjaTargetGenerator(cmTarget* target); + cmNinjaTargetGenerator(cmGeneratorTarget* target); /// Destructor. virtual ~cmNinjaTargetGenerator(); diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx index 42d6b46..c3bf011 100644 --- a/Source/cmNinjaUtilityTargetGenerator.cxx +++ b/Source/cmNinjaUtilityTargetGenerator.cxx @@ -21,7 +21,7 @@ cmNinjaUtilityTargetGenerator::cmNinjaUtilityTargetGenerator( cmGeneratorTarget *target) - : cmNinjaTargetGenerator(target->Target) {} + : cmNinjaTargetGenerator(target) {} cmNinjaUtilityTargetGenerator::~cmNinjaUtilityTargetGenerator() {} diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx index a8eef82..3bc0eb7 100644 --- a/Source/cmOSXBundleGenerator.cxx +++ b/Source/cmOSXBundleGenerator.cxx @@ -22,7 +22,7 @@ cmOSXBundleGenerator(cmGeneratorTarget* target, const std::string& configName) : GT(target) , Makefile(target->Target->GetMakefile()) - , LocalGenerator(Makefile->GetLocalGenerator()) + , LocalGenerator(target->GetLocalGenerator()) , ConfigName(configName) , MacContentFolders(0) { diff --git a/Source/cmOrderDirectories.h b/Source/cmOrderDirectories.h index 07c85dd..cb5a51f 100644 --- a/Source/cmOrderDirectories.h +++ b/Source/cmOrderDirectories.h @@ -44,8 +44,6 @@ private: cmTarget const* Target; std::string Purpose; - bool Computed; - std::vector<std::string> OrderedDirectories; std::vector<cmOrderDirectoriesConstraint*> ConstraintEntries; @@ -68,8 +66,9 @@ private: void OrderDirectories(); void VisitDirectory(unsigned int i); void DiagnoseCycle(); - bool CycleDiagnosed; int WalkId; + bool CycleDiagnosed; + bool Computed; // Adjacency-list representation of runtime path ordering graph. // This maps from directory to those that must come *before* it. diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx new file mode 100644 index 0000000..b0a30a1 --- /dev/null +++ b/Source/cmOutputConverter.cxx @@ -0,0 +1,447 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmOutputConverter.h" + +#include "cmAlgorithms.h" +#include "cmake.h" + +#include <cmsys/System.h> + +#include <assert.h> + +cmOutputConverter::cmOutputConverter(cmState::Snapshot snapshot) + : StateSnapshot(snapshot), LinkScriptShell(false) +{ +} + +//---------------------------------------------------------------------------- +std::string +cmOutputConverter::ConvertToOutputForExistingCommon(const std::string& remote, + std::string const& result, + OutputFormat format) const +{ + // If this is a windows shell, the result has a space, and the path + // already exists, we can use a short-path to reference it without a + // space. + if(this->GetState()->UseWindowsShell() && result.find(' ') != result.npos && + cmSystemTools::FileExists(remote.c_str())) + { + std::string tmp; + if(cmSystemTools::GetShortPath(remote, tmp)) + { + return this->ConvertToOutputFormat(tmp, format); + } + } + + // Otherwise, leave it unchanged. + return result; +} + +//---------------------------------------------------------------------------- +std::string +cmOutputConverter::ConvertToOutputForExisting(const std::string& remote, + RelativeRoot local, + OutputFormat format) const +{ + static_cast<void>(local); + + // Perform standard conversion. + std::string result = this->ConvertToOutputFormat(remote, format); + + // Consider short-path. + return this->ConvertToOutputForExistingCommon(remote, result, format); +} + +//---------------------------------------------------------------------------- +std::string +cmOutputConverter::ConvertToOutputForExisting(RelativeRoot remote, + const std::string& local, + OutputFormat format) const +{ + // Perform standard conversion. + std::string result = this->Convert(remote, local, format, true); + + // Consider short-path. + const char* remotePath = this->GetRelativeRootPath(remote); + return this->ConvertToOutputForExistingCommon(remotePath, result, format); +} + +//---------------------------------------------------------------------------- +const char* cmOutputConverter::GetRelativeRootPath(RelativeRoot relroot) const +{ + switch (relroot) + { + case HOME: return this->GetState()->GetSourceDirectory(); + case START: return this->StateSnapshot.GetCurrentSourceDirectory(); + case HOME_OUTPUT: return this->GetState()->GetBinaryDirectory(); + case START_OUTPUT: return this->StateSnapshot.GetCurrentBinaryDirectory(); + default: break; + } + return 0; +} + +std::string cmOutputConverter::Convert(const std::string& source, + RelativeRoot relative, + OutputFormat output) const +{ + // Convert the path to a relative path. + std::string result = source; + + switch (relative) + { + case HOME: + result = this->ConvertToRelativePath( + this->GetState()->GetSourceDirectoryComponents(), result); + break; + case START: + result = this->ConvertToRelativePath( + this->StateSnapshot.GetCurrentSourceDirectoryComponents(), result); + break; + case HOME_OUTPUT: + result = this->ConvertToRelativePath( + this->GetState()->GetBinaryDirectoryComponents(), result); + break; + case START_OUTPUT: + result = this->ConvertToRelativePath( + this->StateSnapshot.GetCurrentBinaryDirectoryComponents(), result); + break; + case FULL: + result = cmSystemTools::CollapseFullPath(result); + break; + case NONE: + break; + } + return this->ConvertToOutputFormat(result, output); +} + +//---------------------------------------------------------------------------- +std::string cmOutputConverter::ConvertToOutputFormat(const std::string& source, + OutputFormat output) const +{ + std::string result = source; + // Convert it to an output path. + if (output == MAKERULE) + { + result = cmSystemTools::ConvertToOutputPath(result.c_str()); + } + else if(output == SHELL || output == WATCOMQUOTE) + { + // For the MSYS shell convert drive letters to posix paths, so + // that c:/some/path becomes /c/some/path. This is needed to + // avoid problems with the shell path translation. + if(this->GetState()->UseMSYSShell() && !this->LinkScriptShell) + { + if(result.size() > 2 && result[1] == ':') + { + result[1] = result[0]; + result[0] = '/'; + } + } + if(this->GetState()->UseWindowsShell()) + { + std::replace(result.begin(), result.end(), '/', '\\'); + } + result = this->EscapeForShell(result, true, false, output == WATCOMQUOTE); + } + else if(output == RESPONSE) + { + result = this->EscapeForShell(result, false, false, false); + } + return result; +} + +//---------------------------------------------------------------------------- +std::string cmOutputConverter::Convert(RelativeRoot remote, + const std::string& local, + OutputFormat output, + bool optional) const +{ + const char* remotePath = this->GetRelativeRootPath(remote); + + // The relative root must have a path (i.e. not FULL or NONE) + assert(remotePath != 0); + + if(!local.empty() && !optional) + { + std::vector<std::string> components; + cmSystemTools::SplitPath(local, components); + std::string result = this->ConvertToRelativePath(components, remotePath); + return this->ConvertToOutputFormat(result, output); + } + + return this->ConvertToOutputFormat(remotePath, output); +} + +//---------------------------------------------------------------------------- +static bool cmOutputConverterNotAbove(const char* a, const char* b) +{ + return (cmSystemTools::ComparePath(a, b) || + cmSystemTools::IsSubDirectory(a, b)); +} + +//---------------------------------------------------------------------------- +std::string +cmOutputConverter::ConvertToRelativePath(const std::vector<std::string>& local, + const std::string& in_remote, + bool force) const +{ + // The path should never be quoted. + assert(in_remote[0] != '\"'); + + // The local path should never have a trailing slash. + assert(!local.empty() && !(local[local.size()-1] == "")); + + // If the path is already relative then just return the path. + if(!cmSystemTools::FileIsFullPath(in_remote.c_str())) + { + return in_remote; + } + + if(!force) + { + // Skip conversion if the path and local are not both in the source + // or both in the binary tree. + std::string local_path = cmSystemTools::JoinPath(local); + if(!((cmOutputConverterNotAbove(local_path.c_str(), + this->StateSnapshot.GetRelativePathTopBinary()) && + cmOutputConverterNotAbove(in_remote.c_str(), + this->StateSnapshot.GetRelativePathTopBinary())) || + (cmOutputConverterNotAbove(local_path.c_str(), + this->StateSnapshot.GetRelativePathTopSource()) && + cmOutputConverterNotAbove(in_remote.c_str(), + this->StateSnapshot.GetRelativePathTopSource())))) + { + return in_remote; + } + } + + // Identify the longest shared path component between the remote + // path and the local path. + std::vector<std::string> remote; + cmSystemTools::SplitPath(in_remote, remote); + unsigned int common=0; + while(common < remote.size() && + common < local.size() && + cmSystemTools::ComparePath(remote[common], + local[common])) + { + ++common; + } + + // If no part of the path is in common then return the full path. + if(common == 0) + { + return in_remote; + } + + // If the entire path is in common then just return a ".". + if(common == remote.size() && + common == local.size()) + { + return "."; + } + + // If the entire path is in common except for a trailing slash then + // just return a "./". + if(common+1 == remote.size() && + remote[common].empty() && + common == local.size()) + { + return "./"; + } + + // Construct the relative path. + std::string relative; + + // First add enough ../ to get up to the level of the shared portion + // of the path. Leave off the trailing slash. Note that the last + // component of local will never be empty because local should never + // have a trailing slash. + for(unsigned int i=common; i < local.size(); ++i) + { + relative += ".."; + if(i < local.size()-1) + { + relative += "/"; + } + } + + // Now add the portion of the destination path that is not included + // in the shared portion of the path. Add a slash the first time + // only if there was already something in the path. If there was a + // trailing slash in the input then the last iteration of the loop + // will add a slash followed by an empty string which will preserve + // the trailing slash in the output. + + if(!relative.empty() && !remote.empty()) + { + relative += "/"; + } + relative += cmJoin(cmRange(remote).advance(common), "/"); + + // Finally return the path. + return relative; +} + +//---------------------------------------------------------------------------- +static bool cmOutputConverterIsShellOperator(const std::string& str) +{ + static std::set<std::string> shellOperators; + if(shellOperators.empty()) + { + shellOperators.insert("<"); + shellOperators.insert(">"); + shellOperators.insert("<<"); + shellOperators.insert(">>"); + shellOperators.insert("|"); + shellOperators.insert("||"); + shellOperators.insert("&&"); + shellOperators.insert("&>"); + shellOperators.insert("1>"); + shellOperators.insert("2>"); + shellOperators.insert("2>&1"); + shellOperators.insert("1>&2"); + } + return shellOperators.count(str) > 0; +} + +//---------------------------------------------------------------------------- +std::string cmOutputConverter::EscapeForShell(const std::string& str, + bool makeVars, + bool forEcho, + bool useWatcomQuote) const +{ + // Do not escape shell operators. + if(cmOutputConverterIsShellOperator(str)) + { + return str; + } + + // Compute the flags for the target shell environment. + int flags = 0; + if(this->GetState()->UseWindowsVSIDE()) + { + flags |= cmsysSystem_Shell_Flag_VSIDE; + } + else if(!this->LinkScriptShell) + { + flags |= cmsysSystem_Shell_Flag_Make; + } + if(makeVars) + { + flags |= cmsysSystem_Shell_Flag_AllowMakeVariables; + } + if(forEcho) + { + flags |= cmsysSystem_Shell_Flag_EchoWindows; + } + if(useWatcomQuote) + { + flags |= cmsysSystem_Shell_Flag_WatcomQuote; + } + if(this->GetState()->UseWatcomWMake()) + { + flags |= cmsysSystem_Shell_Flag_WatcomWMake; + } + if(this->GetState()->UseMinGWMake()) + { + flags |= cmsysSystem_Shell_Flag_MinGWMake; + } + if(this->GetState()->UseNMake()) + { + flags |= cmsysSystem_Shell_Flag_NMake; + } + + // Compute the buffer size needed. + int size = (this->GetState()->UseWindowsShell() ? + cmsysSystem_Shell_GetArgumentSizeForWindows(str.c_str(), flags) : + cmsysSystem_Shell_GetArgumentSizeForUnix(str.c_str(), flags)); + + // Compute the shell argument itself. + std::vector<char> arg(size); + if(this->GetState()->UseWindowsShell()) + { + cmsysSystem_Shell_GetArgumentForWindows(str.c_str(), &arg[0], flags); + } + else + { + cmsysSystem_Shell_GetArgumentForUnix(str.c_str(), &arg[0], flags); + } + return std::string(&arg[0]); +} + +//---------------------------------------------------------------------------- +std::string cmOutputConverter::EscapeForCMake(const std::string& str) +{ + // Always double-quote the argument to take care of most escapes. + std::string result = "\""; + for(const char* c = str.c_str(); *c; ++c) + { + if(*c == '"') + { + // Escape the double quote to avoid ending the argument. + result += "\\\""; + } + else if(*c == '$') + { + // Escape the dollar to avoid expanding variables. + result += "\\$"; + } + else if(*c == '\\') + { + // Escape the backslash to avoid other escapes. + result += "\\\\"; + } + else + { + // Other characters will be parsed correctly. + result += *c; + } + } + result += "\""; + return result; +} + +//---------------------------------------------------------------------------- +cmOutputConverter::FortranFormat +cmOutputConverter::GetFortranFormat(const char* value) +{ + FortranFormat format = FortranFormatNone; + if(value && *value) + { + std::vector<std::string> fmt; + cmSystemTools::ExpandListArgument(value, fmt); + for(std::vector<std::string>::iterator fi = fmt.begin(); + fi != fmt.end(); ++fi) + { + if(*fi == "FIXED") + { + format = FortranFormatFixed; + } + if(*fi == "FREE") + { + format = FortranFormatFree; + } + } + } + return format; +} + +void cmOutputConverter::SetLinkScriptShell(bool linkScriptShell) +{ + this->LinkScriptShell = linkScriptShell; +} + +cmState* cmOutputConverter::GetState() const +{ + return this->StateSnapshot.GetState(); +} diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h new file mode 100644 index 0000000..482a64b --- /dev/null +++ b/Source/cmOutputConverter.h @@ -0,0 +1,106 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmOutputConverter_h +#define cmOutputConverter_h + +#include "cmStandardIncludes.h" + +#include "cmGlobalGenerator.h" +#include "cmState.h" + +class cmOutputConverter +{ +public: + cmOutputConverter(cmState::Snapshot snapshot); + + /** + * Convert something to something else. This is a centralized conversion + * routine used by the generators to handle relative paths and the like. + * The flags determine what is actually done. + * + * relative: treat the argument as a directory and convert it to make it + * relative or full or unchanged. If relative (HOME, START etc) then that + * specifies what it should be relative to. + * + * output: make the result suitable for output to a... + * + * optional: should any relative path operation be controlled by the rel + * path setting + */ + enum RelativeRoot { NONE, FULL, HOME, START, HOME_OUTPUT, START_OUTPUT }; + enum OutputFormat { UNCHANGED, MAKERULE, SHELL, WATCOMQUOTE, RESPONSE }; + std::string ConvertToOutputFormat(const std::string& source, + OutputFormat output) const; + std::string Convert(const std::string& remote, RelativeRoot local, + OutputFormat output = UNCHANGED) const; + std::string Convert(RelativeRoot remote, const std::string& local, + OutputFormat output = UNCHANGED, + bool optional = false) const; + + /** + * Get path for the specified relative root. + */ + const char* GetRelativeRootPath(RelativeRoot relroot) const; + + ///! for existing files convert to output path and short path if spaces + std::string ConvertToOutputForExisting(const std::string& remote, + RelativeRoot local = START_OUTPUT, + OutputFormat format = SHELL) const; + + /** For existing path identified by RelativeRoot convert to output + path and short path if spaces. */ + std::string ConvertToOutputForExisting(RelativeRoot remote, + const std::string& local = "", + OutputFormat format = SHELL) const; + + void SetLinkScriptShell(bool linkScriptShell); + + std::string EscapeForShell(const std::string& str, + bool makeVars = false, + bool forEcho = false, + bool useWatcomQuote = false) const; + + static std::string EscapeForCMake(const std::string& str); + + enum FortranFormat + { + FortranFormatNone, + FortranFormatFixed, + FortranFormatFree + }; + static FortranFormat GetFortranFormat(const char* value); + + /** + * Convert the given remote path to a relative path with respect to + * the given local path. The local path must be given in component + * form (see SystemTools::SplitPath) without a trailing slash. The + * remote path must use forward slashes and not already be escaped + * or quoted. + */ + std::string ConvertToRelativePath(const std::vector<std::string>& local, + const std::string& in_remote, + bool force = false) const; + +private: + cmState* GetState() const; + + std::string ConvertToOutputForExistingCommon(const std::string& remote, + std::string const& result, + OutputFormat format) const; + +private: + cmState::Snapshot StateSnapshot; + + bool LinkScriptShell; +}; + +#endif diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index f8d61db..5026893 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -343,29 +343,24 @@ cmPolicies::GetRequiredAlwaysPolicyError(cmPolicies::PolicyID id) return e.str(); } -cmPolicies::PolicyMap::PolicyMap() -{ - this->UNDEFINED.set(); -} - cmPolicies::PolicyStatus cmPolicies::PolicyMap::Get(cmPolicies::PolicyID id) const { PolicyStatus status = cmPolicies::WARN; - if (this->OLD[id]) + if (this->Status[(POLICY_STATUS_COUNT * id) + OLD]) { status = cmPolicies::OLD; } - else if (this->NEW[id]) + else if (this->Status[(POLICY_STATUS_COUNT * id) + NEW]) { status = cmPolicies::NEW; } - else if (this->REQUIRED_ALWAYS[id]) + else if (this->Status[(POLICY_STATUS_COUNT * id) + REQUIRED_ALWAYS]) { status = cmPolicies::REQUIRED_ALWAYS; } - else if (this->REQUIRED_IF_USED[id]) + else if (this->Status[(POLICY_STATUS_COUNT * id) + REQUIRED_IF_USED]) { status = cmPolicies::REQUIRED_IF_USED; } @@ -375,19 +370,25 @@ cmPolicies::PolicyMap::Get(cmPolicies::PolicyID id) const void cmPolicies::PolicyMap::Set(cmPolicies::PolicyID id, cmPolicies::PolicyStatus status) { - this->UNDEFINED.reset(id); - this->OLD[id] = (status == cmPolicies::OLD); - this->NEW[id] = (status == cmPolicies::NEW); - this->REQUIRED_ALWAYS[id] = (status == cmPolicies::REQUIRED_ALWAYS); - this->REQUIRED_IF_USED[id] = (status == cmPolicies::REQUIRED_IF_USED); + this->Status[(POLICY_STATUS_COUNT * id) + OLD] = (status == OLD); + this->Status[(POLICY_STATUS_COUNT * id) + WARN] = (status == WARN); + this->Status[(POLICY_STATUS_COUNT * id) + NEW] = (status == NEW); + this->Status[(POLICY_STATUS_COUNT * id) + REQUIRED_ALWAYS] = + (status == REQUIRED_ALWAYS); + this->Status[(POLICY_STATUS_COUNT * id) + REQUIRED_IF_USED] = + (status == REQUIRED_IF_USED); } bool cmPolicies::PolicyMap::IsDefined(cmPolicies::PolicyID id) const { - return !this->UNDEFINED[id]; + return this->Status[(POLICY_STATUS_COUNT * id) + OLD] + || this->Status[(POLICY_STATUS_COUNT * id) + WARN] + || this->Status[(POLICY_STATUS_COUNT * id) + NEW] + || this->Status[(POLICY_STATUS_COUNT * id) + REQUIRED_ALWAYS] + || this->Status[(POLICY_STATUS_COUNT * id) + REQUIRED_IF_USED]; } bool cmPolicies::PolicyMap::IsEmpty() const { - return !this->UNDEFINED.none(); + return this->Status.none(); } diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 00d857a..8a3c27d 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -244,6 +244,7 @@ public: REQUIRED_IF_USED, REQUIRED_ALWAYS ///< Issue an error unless user sets policy status to NEW. }; +#define POLICY_STATUS_COUNT 5 /// Policy identifiers enum PolicyID @@ -281,18 +282,13 @@ public: /** Represent a set of policy values. */ struct PolicyMap { - PolicyMap(); PolicyStatus Get(PolicyID id) const; void Set(PolicyID id, PolicyStatus status); bool IsDefined(PolicyID id) const; bool IsEmpty() const; private: - std::bitset<cmPolicies::CMPCOUNT> UNDEFINED; - std::bitset<cmPolicies::CMPCOUNT> OLD; - std::bitset<cmPolicies::CMPCOUNT> NEW; - std::bitset<cmPolicies::CMPCOUNT> REQUIRED_IF_USED; - std::bitset<cmPolicies::CMPCOUNT> REQUIRED_ALWAYS; + std::bitset<cmPolicies::CMPCOUNT * POLICY_STATUS_COUNT> Status; }; }; diff --git a/Source/cmProcessTools.cxx b/Source/cmProcessTools.cxx index d2f7bf3..15d9ed0 100644 --- a/Source/cmProcessTools.cxx +++ b/Source/cmProcessTools.cxx @@ -44,7 +44,7 @@ void cmProcessTools::RunProcess(struct cmsysProcess_s* cp, //---------------------------------------------------------------------------- cmProcessTools::LineParser::LineParser(char sep, bool ignoreCR): - Separator(sep), IgnoreCR(ignoreCR), Log(0), Prefix(0), LineEnd('\0') + Log(0), Prefix(0), Separator(sep), LineEnd('\0'), IgnoreCR(ignoreCR) { } diff --git a/Source/cmProcessTools.h b/Source/cmProcessTools.h index 439726d..23833ca 100644 --- a/Source/cmProcessTools.h +++ b/Source/cmProcessTools.h @@ -51,12 +51,12 @@ public: /** Configure logging of lines as they are extracted. */ void SetLog(std::ostream* log, const char* prefix); protected: - char Separator; - bool IgnoreCR; std::ostream* Log; const char* Prefix; - char LineEnd; std::string Line; + char Separator; + char LineEnd; + bool IgnoreCR; virtual bool ProcessChunk(const char* data, int length); /** Implement in a subclass to process one line of input. It diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx index 176cb0d..46d7e01 100644 --- a/Source/cmProjectCommand.cxx +++ b/Source/cmProjectCommand.cxx @@ -53,7 +53,7 @@ bool cmProjectCommand // CMAKE_PROJECT_NAME will match PROJECT_NAME, and cmake --build // will work. if(!this->Makefile->GetDefinition("CMAKE_PROJECT_NAME") - || (this->Makefile->GetLocalGenerator()->IsRootMakefile())) + || (this->Makefile->IsRootMakefile())) { this->Makefile->AddDefinition("CMAKE_PROJECT_NAME", args[0].c_str()); this->Makefile->AddCacheDefinition @@ -233,7 +233,6 @@ bool cmProjectCommand const char* include = this->Makefile->GetDefinition(extraInclude); if(include) { - std::string fullFilePath; bool readit = this->Makefile->ReadDependentFile(include); if(!readit && !cmSystemTools::GetFatalErrorOccured()) diff --git a/Source/cmProperty.cxx b/Source/cmProperty.cxx index 40976db..ef57068 100644 --- a/Source/cmProperty.cxx +++ b/Source/cmProperty.cxx @@ -12,17 +12,14 @@ #include "cmProperty.h" #include "cmSystemTools.h" -void cmProperty::Set(const std::string& name, const char *value) +void cmProperty::Set(const char *value) { - this->Name = name; this->Value = value; this->ValueHasBeenSet = true; } -void cmProperty::Append(const std::string& name, const char *value, - bool asString) +void cmProperty::Append(const char *value, bool asString) { - this->Name = name; if(!this->Value.empty() && *value && !asString) { this->Value += ";"; diff --git a/Source/cmProperty.h b/Source/cmProperty.h index 659c4c3..e026372 100644 --- a/Source/cmProperty.h +++ b/Source/cmProperty.h @@ -21,11 +21,10 @@ public: TEST, VARIABLE, CACHED_VARIABLE, INSTALL }; // set this property - void Set(const std::string& name, const char *value); + void Set(const char *value); // append to this property - void Append(const std::string& name, const char *value, - bool asString = false); + void Append(const char *value, bool asString = false); // get the value const char *GetValue() const; @@ -34,7 +33,6 @@ public: cmProperty() { this->ValueHasBeenSet = false; } protected: - std::string Name; std::string Value; bool ValueHasBeenSet; }; diff --git a/Source/cmPropertyDefinitionMap.cxx b/Source/cmPropertyDefinitionMap.cxx index 3875318..776fad1 100644 --- a/Source/cmPropertyDefinitionMap.cxx +++ b/Source/cmPropertyDefinitionMap.cxx @@ -29,9 +29,9 @@ void cmPropertyDefinitionMap } } -bool cmPropertyDefinitionMap::IsPropertyDefined(const std::string& name) +bool cmPropertyDefinitionMap::IsPropertyDefined(const std::string& name) const { - cmPropertyDefinitionMap::iterator it = this->find(name); + cmPropertyDefinitionMap::const_iterator it = this->find(name); if (it == this->end()) { return false; @@ -40,9 +40,9 @@ bool cmPropertyDefinitionMap::IsPropertyDefined(const std::string& name) return true; } -bool cmPropertyDefinitionMap::IsPropertyChained(const std::string& name) +bool cmPropertyDefinitionMap::IsPropertyChained(const std::string& name) const { - cmPropertyDefinitionMap::iterator it = this->find(name); + cmPropertyDefinitionMap::const_iterator it = this->find(name); if (it == this->end()) { return false; diff --git a/Source/cmPropertyDefinitionMap.h b/Source/cmPropertyDefinitionMap.h index 00c7328..f95c721 100644 --- a/Source/cmPropertyDefinitionMap.h +++ b/Source/cmPropertyDefinitionMap.h @@ -27,10 +27,10 @@ public: bool chain); // has a named property been defined - bool IsPropertyDefined(const std::string& name); + bool IsPropertyDefined(const std::string& name) const; // is a named property set to chain - bool IsPropertyChained(const std::string& name); + bool IsPropertyChained(const std::string& name) const; }; #endif diff --git a/Source/cmPropertyMap.cxx b/Source/cmPropertyMap.cxx index 070f6f1..ef09dbc 100644 --- a/Source/cmPropertyMap.cxx +++ b/Source/cmPropertyMap.cxx @@ -14,6 +14,8 @@ #include "cmake.h" #include "cmState.h" +#include <assert.h> + cmProperty *cmPropertyMap::GetOrCreateProperty(const std::string& name) { cmPropertyMap::iterator it = this->find(name); @@ -29,54 +31,39 @@ cmProperty *cmPropertyMap::GetOrCreateProperty(const std::string& name) return prop; } -void cmPropertyMap::SetProperty(const std::string& name, const char *value, - cmProperty::ScopeType scope) +void cmPropertyMap::SetProperty(const std::string& name, const char *value) { if(!value) { this->erase(name); return; } - (void)scope; cmProperty *prop = this->GetOrCreateProperty(name); - prop->Set(name,value); + prop->Set(value); } void cmPropertyMap::AppendProperty(const std::string& name, const char* value, - cmProperty::ScopeType scope, bool asString) + bool asString) { // Skip if nothing to append. if(!value || !*value) { return; } - (void)scope; cmProperty *prop = this->GetOrCreateProperty(name); - prop->Append(name,value,asString); + prop->Append(value,asString); } const char *cmPropertyMap -::GetPropertyValue(const std::string& name, - cmProperty::ScopeType scope, - bool &chain) const +::GetPropertyValue(const std::string& name) const { - chain = false; - if (name.empty()) - { - return 0; - } + assert(!name.empty()); cmPropertyMap::const_iterator it = this->find(name); if (it == this->end()) { - // should we chain up? - if (this->CMakeInstance) - { - chain = this->CMakeInstance->GetState()-> - IsPropertyChained(name,scope); - } return 0; } return it->second.GetValue(); diff --git a/Source/cmPropertyMap.h b/Source/cmPropertyMap.h index 02d4235..a9062db 100644 --- a/Source/cmPropertyMap.h +++ b/Source/cmPropertyMap.h @@ -14,29 +14,17 @@ #include "cmProperty.h" -class cmake; - class cmPropertyMap : public std::map<std::string,cmProperty> { public: cmProperty *GetOrCreateProperty(const std::string& name); - void SetProperty(const std::string& name, const char *value, - cmProperty::ScopeType scope); + void SetProperty(const std::string& name, const char *value); void AppendProperty(const std::string& name, const char* value, - cmProperty::ScopeType scope, bool asString=false); - - const char *GetPropertyValue(const std::string& name, - cmProperty::ScopeType scope, - bool &chain) const; - - void SetCMakeInstance(cmake *cm) { this->CMakeInstance = cm; } - - cmPropertyMap() { this->CMakeInstance = 0;} + bool asString=false); -private: - cmake *CMakeInstance; + const char *GetPropertyValue(const std::string& name) const; }; #endif diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index cbb06cd..32b9566 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -368,8 +368,7 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmTarget* target) #if defined(_WIN32) && !defined(__CYGWIN__) bool usePRE_BUILD = false; - cmLocalGenerator* localGen = makefile->GetLocalGenerator(); - cmGlobalGenerator* gg = localGen->GetGlobalGenerator(); + cmGlobalGenerator* gg = makefile->GetGlobalGenerator(); if(gg->GetName().find("Visual Studio") != std::string::npos) { cmGlobalVisualStudioGenerator* vsgg = @@ -440,6 +439,9 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmTarget* target) this->ListQt4RccInputs(sf, depends); } #if defined(_WIN32) && !defined(__CYGWIN__) + // Cannot use PRE_BUILD because the resource files themselves + // may not be sources within the target so VS may not know the + // target needs to re-build at all. usePRE_BUILD = false; #endif } @@ -466,31 +468,11 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmTarget* target) else #endif { - cmTarget* autogenTarget = 0; - if (!rcc_output.empty() && !isNinja) - { - std::vector<std::string> no_byproducts; - makefile->AddCustomCommandToOutput(rcc_output, no_byproducts, - depends, "", - commandLines, 0, - workingDirectory.c_str(), - false, false); - - cmCustomCommandLines no_commands; - autogenTarget = makefile->AddUtilityCommand( - autogenTargetName, true, - workingDirectory.c_str(), rcc_output, - no_commands, false, autogenComment.c_str()); - - } - else - { - autogenTarget = makefile->AddUtilityCommand( + cmTarget* autogenTarget = makefile->AddUtilityCommand( autogenTargetName, true, workingDirectory.c_str(), /*byproducts=*/rcc_output, depends, commandLines, false, autogenComment.c_str()); - } // Set target folder const char* autogenFolder = makefile->GetState() @@ -522,10 +504,10 @@ static void GetCompileDefinitionsAndDirectories(cmTarget const* target, std::string &defs) { cmMakefile* makefile = target->GetMakefile(); - cmLocalGenerator* localGen = makefile->GetLocalGenerator(); + cmGlobalGenerator* globalGen = makefile->GetGlobalGenerator(); std::vector<std::string> includeDirs; - cmGeneratorTarget *gtgt = localGen->GetGlobalGenerator() - ->GetGeneratorTarget(target); + cmGeneratorTarget *gtgt = globalGen->GetGeneratorTarget(target); + cmLocalGenerator *localGen = gtgt->GetLocalGenerator(); // Get the include dirs for this target, without stripping the implicit // include dirs off, see http://public.kitware.com/Bug/view.php?id=13667 localGen->GetIncludeDirectories(includeDirs, gtgt, "CXX", config, false); @@ -550,9 +532,9 @@ void cmQtAutoGenerators::SetupAutoGenerateTarget(cmTarget const* target) std::string autogenTargetName = getAutogenTargetName(target); makefile->AddDefinition("_moc_target_name", - cmLocalGenerator::EscapeForCMake(autogenTargetName).c_str()); + cmOutputConverter::EscapeForCMake(autogenTargetName).c_str()); makefile->AddDefinition("_origin_target_name", - cmLocalGenerator::EscapeForCMake(target->GetName()).c_str()); + cmOutputConverter::EscapeForCMake(target->GetName()).c_str()); std::string targetDir = getAutogenTargetDir(target); @@ -582,7 +564,7 @@ void cmQtAutoGenerators::SetupAutoGenerateTarget(cmTarget const* target) this->SetupSourceFiles(target); } makefile->AddDefinition("_cpp_files", - cmLocalGenerator::EscapeForCMake(this->Sources).c_str()); + cmOutputConverter::EscapeForCMake(this->Sources).c_str()); if (target->GetPropertyAsBool("AUTOMOC")) { this->SetupAutoMocTarget(target, autogenTargetName, @@ -609,7 +591,7 @@ void cmQtAutoGenerators::SetupAutoGenerateTarget(cmTarget const* target) // Ensure we have write permission in case .in was read-only. mode_t perm = 0; -#if defined(WIN32) && !defined(__CYGWIN__) +#if defined(_WIN32) && !defined(__CYGWIN__) mode_t mode_write = S_IWRITE; #else mode_t mode_write = S_IWUSR; @@ -764,11 +746,11 @@ void cmQtAutoGenerators::SetupAutoMocTarget(cmTarget const* target, const char* tmp = target->GetProperty("AUTOMOC_MOC_OPTIONS"); std::string _moc_options = (tmp!=0 ? tmp : ""); makefile->AddDefinition("_moc_options", - cmLocalGenerator::EscapeForCMake(_moc_options).c_str()); + cmOutputConverter::EscapeForCMake(_moc_options).c_str()); makefile->AddDefinition("_skip_moc", - cmLocalGenerator::EscapeForCMake(this->SkipMoc).c_str()); + cmOutputConverter::EscapeForCMake(this->SkipMoc).c_str()); makefile->AddDefinition("_moc_headers", - cmLocalGenerator::EscapeForCMake(this->Headers).c_str()); + cmOutputConverter::EscapeForCMake(this->Headers).c_str()); bool relaxedMode = makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE"); makefile->AddDefinition("_moc_relaxed_mode", relaxedMode ? "TRUE" : "FALSE"); @@ -780,9 +762,9 @@ void cmQtAutoGenerators::SetupAutoMocTarget(cmTarget const* target, _moc_incs, _moc_compile_defs); makefile->AddDefinition("_moc_incs", - cmLocalGenerator::EscapeForCMake(_moc_incs).c_str()); + cmOutputConverter::EscapeForCMake(_moc_incs).c_str()); makefile->AddDefinition("_moc_compile_defs", - cmLocalGenerator::EscapeForCMake(_moc_compile_defs).c_str()); + cmOutputConverter::EscapeForCMake(_moc_compile_defs).c_str()); for (std::vector<std::string>::const_iterator li = configs.begin(); li != configs.end(); ++li) @@ -795,7 +777,7 @@ void cmQtAutoGenerators::SetupAutoMocTarget(cmTarget const* target, if (config_moc_incs != _moc_incs) { configIncludes[*li] = - cmLocalGenerator::EscapeForCMake(config_moc_incs); + cmOutputConverter::EscapeForCMake(config_moc_incs); if(_moc_incs.empty()) { _moc_incs = config_moc_incs; @@ -804,7 +786,7 @@ void cmQtAutoGenerators::SetupAutoMocTarget(cmTarget const* target, if (config_moc_compile_defs != _moc_compile_defs) { configDefines[*li] = - cmLocalGenerator::EscapeForCMake(config_moc_compile_defs); + cmOutputConverter::EscapeForCMake(config_moc_compile_defs); if(_moc_compile_defs.empty()) { _moc_compile_defs = config_moc_compile_defs; @@ -906,7 +888,7 @@ void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget const* target, skipped.insert(skipVec.begin(), skipVec.end()); makefile->AddDefinition("_skip_uic", - cmLocalGenerator::EscapeForCMake(this->SkipUic).c_str()); + cmOutputConverter::EscapeForCMake(this->SkipUic).c_str()); std::vector<cmSourceFile*> uiFilesWithOptions = makefile->GetQtUiFilesWithOptions(); @@ -920,7 +902,7 @@ void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget const* target, if (!_uic_opts.empty()) { - _uic_opts = cmLocalGenerator::EscapeForCMake(_uic_opts); + _uic_opts = cmOutputConverter::EscapeForCMake(_uic_opts); makefile->AddDefinition("_uic_target_options", _uic_opts.c_str()); } for (std::vector<std::string>::const_iterator li = configs.begin(); @@ -931,7 +913,7 @@ void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget const* target, if (config_uic_opts != _uic_opts) { configUicOptions[*li] = - cmLocalGenerator::EscapeForCMake(config_uic_opts); + cmOutputConverter::EscapeForCMake(config_uic_opts); if(_uic_opts.empty()) { _uic_opts = config_uic_opts; @@ -966,9 +948,9 @@ void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget const* target, } makefile->AddDefinition("_qt_uic_options_files", - cmLocalGenerator::EscapeForCMake(uiFileFiles).c_str()); + cmOutputConverter::EscapeForCMake(uiFileFiles).c_str()); makefile->AddDefinition("_qt_uic_options_options", - cmLocalGenerator::EscapeForCMake(uiFileOptions).c_str()); + cmOutputConverter::EscapeForCMake(uiFileOptions).c_str()); std::string targetName = target->GetName(); if (strcmp(qtVersion, "5") == 0) @@ -1141,15 +1123,15 @@ void cmQtAutoGenerators::SetupAutoRccTarget(cmTarget const* target) } } makefile->AddDefinition("_qt_rcc_inputs_" + target->GetName(), - cmLocalGenerator::EscapeForCMake(qrcInputs).c_str()); + cmOutputConverter::EscapeForCMake(qrcInputs).c_str()); makefile->AddDefinition("_rcc_files", - cmLocalGenerator::EscapeForCMake(_rcc_files).c_str()); + cmOutputConverter::EscapeForCMake(_rcc_files).c_str()); makefile->AddDefinition("_qt_rcc_options_files", - cmLocalGenerator::EscapeForCMake(rccFileFiles).c_str()); + cmOutputConverter::EscapeForCMake(rccFileFiles).c_str()); makefile->AddDefinition("_qt_rcc_options_options", - cmLocalGenerator::EscapeForCMake(rccFileOptions).c_str()); + cmOutputConverter::EscapeForCMake(rccFileOptions).c_str()); makefile->AddDefinition("_qt_rcc_executable", this->GetRccExecutable(target).c_str()); @@ -1215,7 +1197,7 @@ bool cmQtAutoGenerators::Run(const std::string& targetDirectory, cmLocalGenerator* lg = gg.MakeLocalGenerator(); lg->GetMakefile()->SetCurrentBinaryDirectory(targetDirectory); lg->GetMakefile()->SetCurrentSourceDirectory(targetDirectory); - gg.SetCurrentLocalGenerator(lg); + gg.SetCurrentMakefile(lg->GetMakefile()); this->ReadAutogenInfoFile(lg->GetMakefile(), targetDirectory, config); this->ReadOldMocDefinitionsFile(lg->GetMakefile(), targetDirectory); @@ -1434,7 +1416,7 @@ cmQtAutoGenerators::WriteOldMocDefinitionsFile( outfile.open(filename.c_str(), std::ios::trunc); outfile << "set(AM_OLD_COMPILE_SETTINGS " - << cmLocalGenerator::EscapeForCMake( + << cmOutputConverter::EscapeForCMake( this->CurrentCompileSettingsStr) << ")\n"; outfile.close(); diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h index f74e3c5..4c0fcbc 100644 --- a/Source/cmQtAutoGenerators.h +++ b/Source/cmQtAutoGenerators.h @@ -105,7 +105,6 @@ private: std::string SkipMoc; std::string SkipUic; std::string Headers; - bool IncludeProjectDirsBefore; std::string Srcdir; std::string Builddir; std::string MocExecutable; @@ -131,6 +130,7 @@ private: std::map<std::string, std::string> RccOptions; std::map<std::string, std::vector<std::string> > RccInputs; + bool IncludeProjectDirsBefore; bool Verbose; bool ColorOutput; bool RunMocFailed; @@ -138,7 +138,6 @@ private: bool RunRccFailed; bool GenerateAll; bool RelaxedMode; - }; #endif diff --git a/Source/cmSetTestsPropertiesCommand.cxx b/Source/cmSetTestsPropertiesCommand.cxx index e9cfacc..53dc5a8 100644 --- a/Source/cmSetTestsPropertiesCommand.cxx +++ b/Source/cmSetTestsPropertiesCommand.cxx @@ -85,8 +85,10 @@ bool cmSetTestsPropertiesCommand unsigned int k; for (k = 0; k < propertyPairs.size(); k = k + 2) { - test->SetProperty(propertyPairs[k], - propertyPairs[k+1].c_str()); + if (!propertyPairs[k].empty()) + { + test->SetProperty(propertyPairs[k], propertyPairs[k+1].c_str()); + } } } else diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx index 724ab39..86f0a7a 100644 --- a/Source/cmSourceFile.cxx +++ b/Source/cmSourceFile.cxx @@ -22,7 +22,6 @@ cmSourceFile::cmSourceFile(cmMakefile* mf, const std::string& name): Location(mf, name) { this->CustomCommand = 0; - this->Properties.SetCMakeInstance(mf->GetCMakeInstance()); this->FindFullPathFailed = false; this->IsUiFile = (".ui" == cmSystemTools::GetFilenameLastExtension(this->Location.GetName())); @@ -299,7 +298,7 @@ bool cmSourceFile::Matches(cmSourceFileLocation const& loc) //---------------------------------------------------------------------------- void cmSourceFile::SetProperty(const std::string& prop, const char* value) { - this->Properties.SetProperty(prop, value, cmProperty::SOURCE_FILE); + this->Properties.SetProperty(prop, value); if (this->IsUiFile) { @@ -315,8 +314,7 @@ void cmSourceFile::SetProperty(const std::string& prop, const char* value) void cmSourceFile::AppendProperty(const std::string& prop, const char* value, bool asString) { - this->Properties.AppendProperty(prop, value, cmProperty::SOURCE_FILE, - asString); + this->Properties.AppendProperty(prop, value, asString); } //---------------------------------------------------------------------------- @@ -362,13 +360,16 @@ const char* cmSourceFile::GetProperty(const std::string& prop) const } } - bool chain = false; - const char *retVal = - this->Properties.GetPropertyValue(prop, cmProperty::SOURCE_FILE, chain); - if (chain) + const char *retVal = this->Properties.GetPropertyValue(prop); + if (!retVal) { cmMakefile const* mf = this->Location.GetMakefile(); - return mf->GetProperty(prop,cmProperty::SOURCE_FILE); + const bool chain = mf->GetState()-> + IsPropertyChained(prop, cmProperty::SOURCE_FILE); + if (chain) + { + return mf->GetProperty(prop, chain); + } } return retVal; diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h index f898260..1433b54 100644 --- a/Source/cmSourceFile.h +++ b/Source/cmSourceFile.h @@ -107,8 +107,9 @@ private: std::string Extension; std::string Language; std::string FullPath; - bool FindFullPathFailed; std::string ObjectLibrary; + std::vector<std::string> Depends; + bool FindFullPathFailed; bool IsUiFile; bool FindFullPath(std::string* error); @@ -116,7 +117,6 @@ private: void CheckExtension(); void CheckLanguage(std::string const& ext); - std::vector<std::string> Depends; static const std::string propLANGUAGE; }; diff --git a/Source/cmState.cxx b/Source/cmState.cxx index 58885d3..d918f65 100644 --- a/Source/cmState.cxx +++ b/Source/cmState.cxx @@ -18,6 +18,34 @@ #include <assert.h> +struct cmState::SnapshotDataType +{ + cmState::PositionType CallStackParent; + cmState::PositionType DirectoryParent; + cmState::SnapshotType SnapshotType; + cmLinkedTree<std::string>::iterator ExecutionListFile; + cmLinkedTree<cmState::BuildsystemDirectoryStateType>::iterator + BuildSystemDirectory; + std::string EntryPointCommand; + long EntryPointLine; +}; + +struct cmState::BuildsystemDirectoryStateType +{ + std::string Location; + std::string OutputLocation; + + std::vector<std::string> CurrentSourceDirectoryComponents; + std::vector<std::string> CurrentBinaryDirectoryComponents; + // The top-most directories for relative path conversion. Both the + // source and destination location of a relative path conversion + // must be underneath one of these directories (both under source or + // both under binary) in order for the relative path to be evaluated + // safely by the build tools. + std::string RelativePathTopSource; + std::string RelativePathTopBinary; +}; + cmState::cmState(cmake* cm) : CMakeInstance(cm), IsInTryCompile(false), @@ -195,34 +223,14 @@ void cmState::RemoveCacheEntryProperty(std::string const& key, ->GetCacheIterator(key.c_str()).SetProperty(propertyName, (void*)0); } -void cmState::Reset() +cmState::Snapshot cmState::Reset() { this->GlobalProperties.clear(); this->PropertyDefinitions.clear(); - assert(this->Locations.size() > 0); - assert(this->OutputLocations.size() > 0); - assert(this->ParentPositions.size() > 0); - assert(this->CurrentSourceDirectoryComponents.size() > 0); - assert(this->CurrentBinaryDirectoryComponents.size() > 0); - assert(this->RelativePathTopSource.size() > 0); - assert(this->RelativePathTopBinary.size() > 0); - - this->Locations.erase(this->Locations.begin() + 1, this->Locations.end()); - this->OutputLocations.erase(this->OutputLocations.begin() + 1, - this->OutputLocations.end()); - this->ParentPositions.erase(this->ParentPositions.begin() + 1, - this->ParentPositions.end()); - this->CurrentSourceDirectoryComponents.erase( - this->CurrentSourceDirectoryComponents.begin() + 1, - this->CurrentSourceDirectoryComponents.end()); - this->CurrentBinaryDirectoryComponents.erase( - this->CurrentBinaryDirectoryComponents.begin() + 1, - this->CurrentBinaryDirectoryComponents.end()); - this->RelativePathTopSource.erase(this->RelativePathTopSource.begin() + 1, - this->RelativePathTopSource.end()); - this->RelativePathTopBinary.erase(this->RelativePathTopBinary.begin() + 1, - this->RelativePathTopBinary.end()); + this->BuildsystemDirectory.Truncate(); + PositionType pos = this->SnapshotData.Truncate(); + this->ExecutionListFiles.Truncate(); this->DefineProperty ("RULE_LAUNCH_COMPILE", cmProperty::DIRECTORY, @@ -243,6 +251,8 @@ void cmState::Reset() this->DefineProperty ("RULE_LAUNCH_CUSTOM", cmProperty::TARGET, "", "", true); + + return Snapshot(this, pos); } void cmState::DefineProperty(const std::string& name, @@ -256,27 +266,41 @@ void cmState::DefineProperty(const std::string& name, chained); } -cmPropertyDefinition *cmState +cmPropertyDefinition const* cmState ::GetPropertyDefinition(const std::string& name, - cmProperty::ScopeType scope) + cmProperty::ScopeType scope) const { if (this->IsPropertyDefined(name,scope)) { - return &(this->PropertyDefinitions[scope][name]); + cmPropertyDefinitionMap const& defs = + this->PropertyDefinitions.find(scope)->second; + return &defs.find(name)->second; } return 0; } bool cmState::IsPropertyDefined(const std::string& name, - cmProperty::ScopeType scope) + cmProperty::ScopeType scope) const { - return this->PropertyDefinitions[scope].IsPropertyDefined(name); + std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::const_iterator it + = this->PropertyDefinitions.find(scope); + if (it == this->PropertyDefinitions.end()) + { + return false; + } + return it->second.IsPropertyDefined(name); } bool cmState::IsPropertyChained(const std::string& name, - cmProperty::ScopeType scope) + cmProperty::ScopeType scope) const { - return this->PropertyDefinitions[scope].IsPropertyChained(name); + std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::const_iterator it + = this->PropertyDefinitions.find(scope); + if (it == this->PropertyDefinitions.end()) + { + return false; + } + return it->second.IsPropertyChained(name); } void cmState::SetLanguageEnabled(std::string const& l) @@ -424,14 +448,13 @@ void cmState::RemoveUserDefinedCommands() void cmState::SetGlobalProperty(const std::string& prop, const char* value) { - this->GlobalProperties.SetProperty(prop, value, cmProperty::GLOBAL); + this->GlobalProperties.SetProperty(prop, value); } void cmState::AppendGlobalProperty(const std::string& prop, const char* value, bool asString) { - this->GlobalProperties.AppendProperty(prop, value, - cmProperty::GLOBAL, asString); + this->GlobalProperties.AppendProperty(prop, value, asString); } const char *cmState::GetGlobalProperty(const std::string& prop) @@ -469,9 +492,7 @@ const char *cmState::GetGlobalProperty(const std::string& prop) return FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT) + 1; } #undef STRING_LIST_ELEMENT - bool dummy = false; - return this->GlobalProperties.GetPropertyValue(prop, cmProperty::GLOBAL, - dummy); + return this->GlobalProperties.GetPropertyValue(prop); } bool cmState::GetGlobalPropertyAsBool(const std::string& prop) @@ -590,7 +611,7 @@ void cmState::Snapshot::ComputeRelativePathTopSource() snapshots.push_back(snapshot); while (true) { - snapshot = snapshot.GetParent(); + snapshot = snapshot.GetBuildsystemDirectoryParent(); if (snapshot.IsValid()) { snapshots.push_back(snapshot); @@ -612,7 +633,7 @@ void cmState::Snapshot::ComputeRelativePathTopSource() result = currentSource; } } - this->State->RelativePathTopSource[this->Position] = result; + this->Position->BuildSystemDirectory->RelativePathTopSource = result; } void cmState::Snapshot::ComputeRelativePathTopBinary() @@ -622,7 +643,7 @@ void cmState::Snapshot::ComputeRelativePathTopBinary() snapshots.push_back(snapshot); while (true) { - snapshot = snapshot.GetParent(); + snapshot = snapshot.GetBuildsystemDirectoryParent(); if (snapshot.IsValid()) { snapshots.push_back(snapshot); @@ -651,31 +672,126 @@ void cmState::Snapshot::ComputeRelativePathTopBinary() // is a network path. if(result.size() < 2 || result.substr(0, 2) != "//") { - this->State->RelativePathTopBinary[this->Position] = result; + this->Position->BuildSystemDirectory->RelativePathTopBinary = result; } else { - this->State->RelativePathTopBinary[this->Position] = ""; + this->Position->BuildSystemDirectory->RelativePathTopBinary = ""; } } -cmState::Snapshot cmState::CreateSnapshot(Snapshot originSnapshot) +cmState::Snapshot cmState::CreateBaseSnapshot() +{ + PositionType pos = this->SnapshotData.Extend(this->SnapshotData.Root()); + pos->DirectoryParent = this->SnapshotData.Root(); + pos->SnapshotType = BuildsystemDirectoryType; + pos->BuildSystemDirectory = + this->BuildsystemDirectory.Extend(this->BuildsystemDirectory.Root()); + pos->ExecutionListFile = + this->ExecutionListFiles.Extend(this->ExecutionListFiles.Root()); + return cmState::Snapshot(this, pos); +} + +cmState::Snapshot +cmState::CreateBuildsystemDirectorySnapshot(Snapshot originSnapshot, + std::string const& entryPointCommand, + long entryPointLine) +{ + assert(originSnapshot.IsValid()); + PositionType pos = this->SnapshotData.Extend(originSnapshot.Position); + pos->CallStackParent = originSnapshot.Position; + pos->EntryPointLine = entryPointLine; + pos->EntryPointCommand = entryPointCommand; + pos->DirectoryParent = originSnapshot.Position; + pos->SnapshotType = BuildsystemDirectoryType; + pos->BuildSystemDirectory = + this->BuildsystemDirectory.Extend( + originSnapshot.Position->BuildSystemDirectory); + pos->ExecutionListFile = + this->ExecutionListFiles.Extend( + originSnapshot.Position->ExecutionListFile); + return cmState::Snapshot(this, pos); +} + +cmState::Snapshot +cmState::CreateFunctionCallSnapshot(cmState::Snapshot originSnapshot, + std::string const& entryPointCommand, + long entryPointLine, + std::string const& fileName) +{ + PositionType pos = this->SnapshotData.Extend(originSnapshot.Position, + *originSnapshot.Position); + pos->CallStackParent = originSnapshot.Position; + pos->EntryPointLine = entryPointLine; + pos->EntryPointCommand = entryPointCommand; + pos->SnapshotType = FunctionCallType; + pos->ExecutionListFile = this->ExecutionListFiles.Extend( + originSnapshot.Position->ExecutionListFile, fileName); + return cmState::Snapshot(this, pos); +} + + +cmState::Snapshot +cmState::CreateMacroCallSnapshot(cmState::Snapshot originSnapshot, + std::string const& entryPointCommand, + long entryPointLine, + std::string const& fileName) { - if (!originSnapshot.IsValid()) + PositionType pos = this->SnapshotData.Extend(originSnapshot.Position, + *originSnapshot.Position); + pos->CallStackParent = originSnapshot.Position; + pos->EntryPointLine = entryPointLine; + pos->EntryPointCommand = entryPointCommand; + pos->SnapshotType = MacroCallType; + pos->ExecutionListFile = this->ExecutionListFiles.Extend( + originSnapshot.Position->ExecutionListFile, fileName); + return cmState::Snapshot(this, pos); +} + +cmState::Snapshot +cmState::CreateCallStackSnapshot(cmState::Snapshot originSnapshot, + const std::string& entryPointCommand, + long entryPointLine, + const std::string& fileName) +{ + PositionType pos = this->SnapshotData.Extend(originSnapshot.Position, + *originSnapshot.Position); + pos->CallStackParent = originSnapshot.Position; + pos->EntryPointLine = entryPointLine; + pos->EntryPointCommand = entryPointCommand; + pos->SnapshotType = CallStackType; + pos->ExecutionListFile = this->ExecutionListFiles.Extend( + originSnapshot.Position->ExecutionListFile, fileName); + return cmState::Snapshot(this, pos); +} + +cmState::Snapshot +cmState::CreateInlineListFileSnapshot(cmState::Snapshot originSnapshot, + const std::string& entryPointCommand, + long entryPointLine, + const std::string& fileName) +{ + PositionType pos = this->SnapshotData.Extend(originSnapshot.Position, + *originSnapshot.Position); + pos->CallStackParent = originSnapshot.Position; + pos->EntryPointLine = entryPointLine; + pos->EntryPointCommand = entryPointCommand; + pos->SnapshotType = InlineListFileType; + pos->ExecutionListFile = this->ExecutionListFiles.Extend( + originSnapshot.Position->ExecutionListFile, fileName); + return cmState::Snapshot(this, pos); +} + +cmState::Snapshot cmState::Pop(cmState::Snapshot originSnapshot) +{ + PositionType pos = originSnapshot.Position; + PositionType prevPos = pos; + ++prevPos; + if (prevPos == this->SnapshotData.Root()) { - originSnapshot.State = this; + return Snapshot(this, prevPos); } - PositionType pos = this->ParentPositions.size(); - this->ParentPositions.push_back(originSnapshot.Position); - this->Locations.resize(this->Locations.size() + 1); - this->OutputLocations.resize(this->OutputLocations.size() + 1); - this->CurrentSourceDirectoryComponents.resize( - this->CurrentSourceDirectoryComponents.size() + 1); - this->CurrentBinaryDirectoryComponents.resize( - this->CurrentBinaryDirectoryComponents.size() + 1); - this->RelativePathTopSource.resize(this->RelativePathTopSource.size() + 1); - this->RelativePathTopBinary.resize(this->RelativePathTopBinary.size() + 1); - return cmState::Snapshot(this, pos); + return Snapshot(this, originSnapshot.Position->CallStackParent); } cmState::Snapshot::Snapshot(cmState* state, PositionType position) @@ -687,92 +803,141 @@ cmState::Snapshot::Snapshot(cmState* state, PositionType position) const char* cmState::Snapshot::GetCurrentSourceDirectory() const { - return this->State->Locations[this->Position].c_str(); + return this->Position->BuildSystemDirectory->Location.c_str(); } void cmState::Snapshot::SetCurrentSourceDirectory(std::string const& dir) { assert(this->State); - assert(this->State->Locations.size() > this->Position); - this->State->Locations[this->Position] = dir; - cmSystemTools::ConvertToUnixSlashes( - this->State->Locations[this->Position]); - this->State->Locations[this->Position] = - cmSystemTools::CollapseFullPath(this->State->Locations[this->Position]); + std::string& loc = this->Position->BuildSystemDirectory->Location; + loc = dir; + cmSystemTools::ConvertToUnixSlashes(loc); + loc = cmSystemTools::CollapseFullPath(loc); cmSystemTools::SplitPath( - this->State->Locations[this->Position], - this->State->CurrentSourceDirectoryComponents[this->Position]); + loc, + this->Position->BuildSystemDirectory->CurrentSourceDirectoryComponents); this->ComputeRelativePathTopSource(); } const char* cmState::Snapshot::GetCurrentBinaryDirectory() const { - return this->State->OutputLocations[this->Position].c_str(); + return this->Position->BuildSystemDirectory->OutputLocation.c_str(); } void cmState::Snapshot::SetCurrentBinaryDirectory(std::string const& dir) { - assert(this->State->OutputLocations.size() > this->Position); - this->State->OutputLocations[this->Position] = dir; - cmSystemTools::ConvertToUnixSlashes( - this->State->OutputLocations[this->Position]); - this->State->OutputLocations[this->Position] = - cmSystemTools::CollapseFullPath( - this->State->OutputLocations[this->Position]); + std::string& loc = this->Position->BuildSystemDirectory->OutputLocation; + loc = dir; + cmSystemTools::ConvertToUnixSlashes(loc); + loc = cmSystemTools::CollapseFullPath(loc); cmSystemTools::SplitPath( - this->State->OutputLocations[this->Position], - this->State->CurrentBinaryDirectoryComponents[this->Position]); + loc, + this->Position->BuildSystemDirectory->CurrentBinaryDirectoryComponents); this->ComputeRelativePathTopBinary(); } +void cmState::Snapshot::SetListFile(const std::string& listfile) +{ + *this->Position->ExecutionListFile = listfile; +} + std::vector<std::string> const& -cmState::Snapshot::GetCurrentSourceDirectoryComponents() +cmState::Snapshot::GetCurrentSourceDirectoryComponents() const { - return this->State->CurrentSourceDirectoryComponents[this->Position]; + return this->Position->BuildSystemDirectory + ->CurrentSourceDirectoryComponents; } std::vector<std::string> const& -cmState::Snapshot::GetCurrentBinaryDirectoryComponents() +cmState::Snapshot::GetCurrentBinaryDirectoryComponents() const { - return this->State->CurrentBinaryDirectoryComponents[this->Position]; + return this->Position->BuildSystemDirectory + ->CurrentBinaryDirectoryComponents; } const char* cmState::Snapshot::GetRelativePathTopSource() const { - return this->State->RelativePathTopSource[this->Position].c_str(); + return this->Position->BuildSystemDirectory->RelativePathTopSource.c_str(); } const char* cmState::Snapshot::GetRelativePathTopBinary() const { - return this->State->RelativePathTopBinary[this->Position].c_str(); + return this->Position->BuildSystemDirectory->RelativePathTopBinary.c_str(); } void cmState::Snapshot::SetRelativePathTopSource(const char* dir) { - this->State->RelativePathTopSource[this->Position] = dir; + this->Position->BuildSystemDirectory->RelativePathTopSource = dir; } void cmState::Snapshot::SetRelativePathTopBinary(const char* dir) { - this->State->RelativePathTopBinary[this->Position] = dir; + this->Position->BuildSystemDirectory->RelativePathTopBinary = dir; +} + +std::string cmState::Snapshot::GetExecutionListFile() const +{ + return *this->Position->ExecutionListFile; +} + +std::string cmState::Snapshot::GetEntryPointCommand() const +{ + return this->Position->EntryPointCommand; +} + +long cmState::Snapshot::GetEntryPointLine() const +{ + return this->Position->EntryPointLine; } bool cmState::Snapshot::IsValid() const { - return this->State ? true : false; + return this->State && this->Position.IsValid() + ? this->Position != this->State->SnapshotData.Root() + : false; } -cmState::Snapshot cmState::Snapshot::GetParent() const +cmState::Snapshot cmState::Snapshot::GetBuildsystemDirectoryParent() const { Snapshot snapshot; - if (!this->State || this->Position == 0) + if (!this->State || this->Position == this->State->SnapshotData.Root()) { return snapshot; } - PositionType parentPos = this->State->ParentPositions[this->Position]; - snapshot = Snapshot(this->State, parentPos); + PositionType parentPos = this->Position->DirectoryParent; + if (parentPos != this->State->SnapshotData.Root()) + { + snapshot = Snapshot(this->State, parentPos); + } return snapshot; } + +cmState::Snapshot cmState::Snapshot::GetCallStackParent() const +{ + assert(this->State); + assert(this->Position != this->State->SnapshotData.Root()); + + Snapshot snapshot; + if (this->Position->SnapshotType == cmState::BuildsystemDirectoryType) + { + return snapshot; + } + + PositionType parentPos = this->Position; + ++parentPos; + if (parentPos == this->State->SnapshotData.Root()) + { + return snapshot; + } + + snapshot = Snapshot(this->State, parentPos); + return snapshot; +} + +cmState* cmState::Snapshot::GetState() const +{ + return this->State; +} diff --git a/Source/cmState.h b/Source/cmState.h index 77a066f..473a194 100644 --- a/Source/cmState.h +++ b/Source/cmState.h @@ -15,37 +15,59 @@ #include "cmStandardIncludes.h" #include "cmPropertyDefinitionMap.h" #include "cmPropertyMap.h" +#include "cmLinkedTree.h" class cmake; class cmCommand; class cmState { - typedef std::vector<std::string>::size_type PositionType; + struct SnapshotDataType; + typedef cmLinkedTree<SnapshotDataType>::iterator PositionType; friend class Snapshot; public: cmState(cmake* cm); ~cmState(); + enum SnapshotType + { + BuildsystemDirectoryType, + FunctionCallType, + MacroCallType, + CallStackType, + InlineListFileType + }; + class Snapshot { public: - Snapshot(cmState* state = 0, PositionType position = 0); + Snapshot(cmState* state = 0, PositionType position = PositionType()); const char* GetCurrentSourceDirectory() const; void SetCurrentSourceDirectory(std::string const& dir); const char* GetCurrentBinaryDirectory() const; void SetCurrentBinaryDirectory(std::string const& dir); - std::vector<std::string> const& GetCurrentSourceDirectoryComponents(); - std::vector<std::string> const& GetCurrentBinaryDirectoryComponents(); + void SetListFile(std::string const& listfile); + + std::vector<std::string> const& + GetCurrentSourceDirectoryComponents() const; + std::vector<std::string> const& + GetCurrentBinaryDirectoryComponents() const; const char* GetRelativePathTopSource() const; const char* GetRelativePathTopBinary() const; void SetRelativePathTopSource(const char* dir); void SetRelativePathTopBinary(const char* dir); + std::string GetExecutionListFile() const; + std::string GetEntryPointCommand() const; + long GetEntryPointLine() const; + bool IsValid() const; - Snapshot GetParent() const; + Snapshot GetBuildsystemDirectoryParent() const; + Snapshot GetCallStackParent() const; + + cmState* GetState() const; private: void ComputeRelativePathTopSource(); @@ -57,7 +79,28 @@ public: cmState::PositionType Position; }; - Snapshot CreateSnapshot(Snapshot originSnapshot); + Snapshot CreateBaseSnapshot(); + Snapshot + CreateBuildsystemDirectorySnapshot(Snapshot originSnapshot, + std::string const& entryPointCommand, + long entryPointLine); + Snapshot CreateFunctionCallSnapshot(Snapshot originSnapshot, + std::string const& entryPointCommand, + long entryPointLine, + std::string const& fileName); + Snapshot CreateMacroCallSnapshot(Snapshot originSnapshot, + std::string const& entryPointCommand, + long entryPointLine, + std::string const& fileName); + Snapshot CreateCallStackSnapshot(Snapshot originSnapshot, + std::string const& entryPointCommand, + long entryPointLine, + std::string const& fileName); + Snapshot CreateInlineListFileSnapshot(Snapshot originSnapshot, + const std::string& entryPointCommand, + long entryPointLine, + std::string const& fileName); + Snapshot Pop(Snapshot originSnapshot); enum CacheEntryType{ BOOL=0, PATH, FILEPATH, STRING, INTERNAL,STATIC, UNINITIALIZED }; @@ -93,7 +136,7 @@ public: void RemoveCacheEntryProperty(std::string const& key, std::string const& propertyName); - void Reset(); + Snapshot Reset(); // Define a property void DefineProperty(const std::string& name, cmProperty::ScopeType scope, const char *ShortDescription, @@ -101,12 +144,14 @@ public: bool chain = false); // get property definition - cmPropertyDefinition *GetPropertyDefinition - (const std::string& name, cmProperty::ScopeType scope); + cmPropertyDefinition const* GetPropertyDefinition + (const std::string& name, cmProperty::ScopeType scope) const; // Is a property defined? - bool IsPropertyDefined(const std::string& name, cmProperty::ScopeType scope); - bool IsPropertyChained(const std::string& name, cmProperty::ScopeType scope); + bool IsPropertyDefined(const std::string& name, + cmProperty::ScopeType scope) const; + bool IsPropertyChained(const std::string& name, + cmProperty::ScopeType scope) const; void SetLanguageEnabled(std::string const& l); bool GetLanguageEnabled(std::string const& l) const; @@ -157,19 +202,13 @@ private: std::map<std::string, cmCommand*> Commands; cmPropertyMap GlobalProperties; cmake* CMakeInstance; - std::vector<std::string> Locations; - std::vector<std::string> OutputLocations; - std::vector<PositionType> ParentPositions; - - std::vector<std::vector<std::string> > CurrentSourceDirectoryComponents; - std::vector<std::vector<std::string> > CurrentBinaryDirectoryComponents; - // The top-most directories for relative path conversion. Both the - // source and destination location of a relative path conversion - // must be underneath one of these directories (both under source or - // both under binary) in order for the relative path to be evaluated - // safely by the build tools. - std::vector<std::string> RelativePathTopSource; - std::vector<std::string> RelativePathTopBinary; + + struct BuildsystemDirectoryStateType; + cmLinkedTree<BuildsystemDirectoryStateType> BuildsystemDirectory; + + cmLinkedTree<std::string> ExecutionListFiles; + + cmLinkedTree<SnapshotDataType> SnapshotData; std::vector<std::string> SourceDirectoryComponents; std::vector<std::string> BinaryDirectoryComponents; diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx index edc6afc..efc1f16 100644 --- a/Source/cmStringCommand.cxx +++ b/Source/cmStringCommand.cxx @@ -74,6 +74,10 @@ bool cmStringCommand { return this->HandleLengthCommand(args); } + else if(subCommand == "APPEND") + { + return this->HandleAppendCommand(args); + } else if(subCommand == "CONCAT") { return this->HandleConcatCommand(args); @@ -730,6 +734,34 @@ bool cmStringCommand } //---------------------------------------------------------------------------- +bool cmStringCommand::HandleAppendCommand(std::vector<std::string> const& args) +{ + if(args.size() < 2) + { + this->SetError("sub-command APPEND requires at least one argument."); + return false; + } + + // Skip if nothing to append. + if(args.size() < 3) + { + return true; + } + + const std::string& variable = args[1]; + + std::string value; + const char* oldValue = this->Makefile->GetDefinition(variable); + if(oldValue) + { + value = oldValue; + } + value += cmJoin(cmRange(args).advance(2), std::string()); + this->Makefile->AddDefinition(variable, value.c_str()); + return true; +} + +//---------------------------------------------------------------------------- bool cmStringCommand ::HandleConcatCommand(std::vector<std::string> const& args) { diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h index 9c75095..3ed17eb 100644 --- a/Source/cmStringCommand.h +++ b/Source/cmStringCommand.h @@ -67,6 +67,7 @@ protected: bool HandleReplaceCommand(std::vector<std::string> const& args); bool HandleLengthCommand(std::vector<std::string> const& args); bool HandleSubstringCommand(std::vector<std::string> const& args); + bool HandleAppendCommand(std::vector<std::string> const& args); bool HandleConcatCommand(std::vector<std::string> const& args); bool HandleStripCommand(std::vector<std::string> const& args); bool HandleRandomCommand(std::vector<std::string> const& args); diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index e2adabe..7230a64 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -2955,3 +2955,12 @@ bool cmSystemTools::StringToLong(const char* str, long* value) *value = strtol(str, &endp, 10); return (*endp == '\0') && (endp != str) && (errno == 0); } + +//---------------------------------------------------------------------------- +bool cmSystemTools::StringToULong(const char* str, unsigned long* value) +{ + errno = 0; + char *endp; + *value = strtoul(str, &endp, 10); + return (*endp == '\0') && (endp != str) && (errno == 0); +} diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 6feb6c5..8ebb4e3 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -469,6 +469,7 @@ public: /** Convert string to long. Expected that the whole string is an integer */ static bool StringToLong(const char* str, long* value); + static bool StringToULong(const char* str, unsigned long* value); #ifdef _WIN32 struct WindowsFileRetry diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 2d34747..3353fbd 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -13,7 +13,7 @@ #include "cmake.h" #include "cmMakefile.h" #include "cmSourceFile.h" -#include "cmLocalGenerator.h" +#include "cmOutputConverter.h" #include "cmGlobalGenerator.h" #include "cmComputeLinkInformation.h" #include "cmListFileCache.h" @@ -94,13 +94,13 @@ class cmTargetInternals { public: cmTargetInternals() - : Backtrace(NULL) + : Backtrace() { this->PolicyWarnedCMP0022 = false; this->UtilityItemsDone = false; } cmTargetInternals(cmTargetInternals const&) - : Backtrace(NULL) + : Backtrace() { this->PolicyWarnedCMP0022 = false; this->UtilityItemsDone = false; @@ -239,13 +239,6 @@ cmTargetInternals::~cmTargetInternals() //---------------------------------------------------------------------------- cmTarget::cmTarget() { -#define INITIALIZE_TARGET_POLICY_MEMBER(POLICY) \ - this->PolicyStatus ## POLICY = cmPolicies::WARN; - - CM_FOR_EACH_TARGET_POLICY(INITIALIZE_TARGET_POLICY_MEMBER) - -#undef INITIALIZE_TARGET_POLICY_MEMBER - this->Makefile = 0; #if defined(_WIN32) && !defined(__CYGWIN__) this->LinkLibrariesForVS6Analyzed = false; @@ -286,9 +279,6 @@ void cmTarget::SetMakefile(cmMakefile* mf) // Set our makefile. this->Makefile = mf; - // set the cmake instance of the properties - this->Properties.SetCMakeInstance(mf->GetCMakeInstance()); - // Check whether this is a DLL platform. this->DLLPlatform = (this->Makefile->IsOn("WIN32") || this->Makefile->IsOn("CYGWIN") || @@ -333,10 +323,12 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->SetPropertyDefault("MACOSX_BUNDLE", 0); this->SetPropertyDefault("MACOSX_RPATH", 0); this->SetPropertyDefault("NO_SYSTEM_FROM_IMPORTED", 0); + this->SetPropertyDefault("C_COMPILER_LAUNCHER", 0); this->SetPropertyDefault("C_INCLUDE_WHAT_YOU_USE", 0); this->SetPropertyDefault("C_STANDARD", 0); this->SetPropertyDefault("C_STANDARD_REQUIRED", 0); this->SetPropertyDefault("C_EXTENSIONS", 0); + this->SetPropertyDefault("CXX_COMPILER_LAUNCHER", 0); this->SetPropertyDefault("CXX_INCLUDE_WHAT_YOU_USE", 0); this->SetPropertyDefault("CXX_STANDARD", 0); this->SetPropertyDefault("CXX_STANDARD_REQUIRED", 0); @@ -437,26 +429,25 @@ void cmTarget::SetMakefile(cmMakefile* mf) { this->SetProperty("POSITION_INDEPENDENT_CODE", "True"); } + if(this->TargetTypeValue == cmTarget::SHARED_LIBRARY) + { + this->SetPropertyDefault("WINDOWS_EXPORT_ALL_SYMBOLS", 0); + } + if (this->GetType() != INTERFACE_LIBRARY && this->GetType() != UTILITY) { this->SetPropertyDefault("POSITION_INDEPENDENT_CODE", 0); } // Record current policies for later use. -#define CAPTURE_TARGET_POLICY(POLICY) \ - this->PolicyStatus ## POLICY = \ - this->Makefile->GetPolicyStatus(cmPolicies::POLICY); - - CM_FOR_EACH_TARGET_POLICY(CAPTURE_TARGET_POLICY) - -#undef CAPTURE_TARGET_POLICY + this->Makefile->RecordPolicies(this->PolicyMap); if (this->TargetTypeValue == INTERFACE_LIBRARY) { // This policy is checked in a few conditions. The properties relevant // to the policy are always ignored for INTERFACE_LIBRARY targets, // so ensure that the conditions don't lead to nonsense. - this->PolicyStatusCMP0022 = cmPolicies::NEW; + this->PolicyMap.Set(cmPolicies::CMP0022, cmPolicies::NEW); } if (this->GetType() != INTERFACE_LIBRARY && this->GetType() != UTILITY) @@ -764,7 +755,7 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files, "SOURCES") != debugProperties.end(); - if (this->Makefile->IsGeneratingBuildSystem()) + if (this->Makefile->IsConfigured()) { this->DebugSourcesDone = true; } @@ -1231,7 +1222,8 @@ static std::string targetNameGenex(const std::string& lib) } //---------------------------------------------------------------------------- -bool cmTarget::PushTLLCommandTrace(TLLSignature signature) +bool cmTarget::PushTLLCommandTrace(TLLSignature signature, + cmListFileContext const& lfc) { bool ret = true; if (!this->TLLCommands.empty()) @@ -1241,7 +1233,6 @@ bool cmTarget::PushTLLCommandTrace(TLLSignature signature) ret = false; } } - cmListFileContext lfc = this->Makefile->GetExecutionContext(); if (this->TLLCommands.empty() || this->TLLCommands.back().second != lfc) { this->TLLCommands.push_back(std::make_pair(signature, lfc)); @@ -1257,14 +1248,14 @@ void cmTarget::GetTllSignatureTraces(std::ostringstream &s, : "plain"); s << "The uses of the " << sigString << " signature are here:\n"; typedef std::vector<std::pair<TLLSignature, cmListFileContext> > Container; - cmLocalGenerator* lg = this->GetMakefile()->GetLocalGenerator(); + cmOutputConverter converter(this->GetMakefile()->GetStateSnapshot()); for(Container::const_iterator it = this->TLLCommands.begin(); it != this->TLLCommands.end(); ++it) { if (it->first == sig) { cmListFileContext lfc = it->second; - lfc.FilePath = lg->Convert(lfc.FilePath, cmLocalGenerator::HOME); + lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME); s << " * " << lfc << std::endl; } } @@ -1775,7 +1766,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) } else { - this->Properties.SetProperty(prop, value, cmProperty::TARGET); + this->Properties.SetProperty(prop, value); this->MaybeInvalidatePropertyCache(prop); } } @@ -1863,7 +1854,7 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value, } else { - this->Properties.AppendProperty(prop, value, cmProperty::TARGET, asString); + this->Properties.AppendProperty(prop, value, asString); this->MaybeInvalidatePropertyCache(prop); } } @@ -2112,7 +2103,7 @@ cmTarget::GetIncludeDirectories(const std::string& config, "INCLUDE_DIRECTORIES") != debugProperties.end(); - if (this->Makefile->IsGeneratingBuildSystem()) + if (this->Makefile->IsConfigured()) { this->DebugIncludesDone = true; } @@ -2283,7 +2274,7 @@ void cmTarget::GetCompileOptions(std::vector<std::string> &result, "COMPILE_OPTIONS") != debugProperties.end(); - if (this->Makefile->IsGeneratingBuildSystem()) + if (this->Makefile->IsConfigured()) { this->DebugCompileOptionsDone = true; } @@ -2354,7 +2345,7 @@ void cmTarget::GetCompileDefinitions(std::vector<std::string> &list, "COMPILE_DEFINITIONS") != debugProperties.end(); - if (this->Makefile->IsGeneratingBuildSystem()) + if (this->Makefile->IsConfigured()) { this->DebugCompileDefinitionsDone = true; } @@ -2455,7 +2446,7 @@ void cmTarget::GetCompileFeatures(std::vector<std::string> &result, "COMPILE_FEATURES") != debugProperties.end(); - if (this->Makefile->IsGeneratingBuildSystem()) + if (this->Makefile->IsConfigured()) { this->DebugCompileFeaturesDone = true; } @@ -2820,34 +2811,6 @@ void cmTarget::GetTargetVersion(bool soversion, } //---------------------------------------------------------------------------- -const char* cmTarget::GetFeature(const std::string& feature, - const std::string& config) const -{ - if(!config.empty()) - { - std::string featureConfig = feature; - featureConfig += "_"; - featureConfig += cmSystemTools::UpperCase(config); - if(const char* value = this->GetProperty(featureConfig)) - { - return value; - } - } - if(const char* value = this->GetProperty(feature)) - { - return value; - } - return this->Makefile->GetFeature(feature, config); -} - -//---------------------------------------------------------------------------- -bool cmTarget::GetFeatureAsBool(const std::string& feature, - const std::string& config) const -{ - return cmSystemTools::IsOn(this->GetFeature(feature, config)); -} - -//---------------------------------------------------------------------------- bool cmTarget::HandleLocationPropertyPolicy(cmMakefile* context) const { if (this->IsImported()) @@ -2944,8 +2907,7 @@ const char *cmTarget::GetProperty(const std::string& prop, // cannot take into account the per-configuration name of the // target because the configuration type may not be known at // CMake time. - this->Properties.SetProperty(propLOCATION, this->GetLocationForBuild(), - cmProperty::TARGET); + this->Properties.SetProperty(propLOCATION, this->GetLocationForBuild()); } // Support "LOCATION_<CONFIG>". @@ -2956,9 +2918,7 @@ const char *cmTarget::GetProperty(const std::string& prop, return 0; } const char* configName = prop.c_str() + 9; - this->Properties.SetProperty(prop, - this->GetLocation(configName), - cmProperty::TARGET); + this->Properties.SetProperty(prop, this->GetLocation(configName)); } // Support "<CONFIG>_LOCATION". else if(cmHasLiteralSuffix(prop, "_LOCATION")) @@ -2970,9 +2930,7 @@ const char *cmTarget::GetProperty(const std::string& prop, { return 0; } - this->Properties.SetProperty(prop, - this->GetLocation(configName), - cmProperty::TARGET); + this->Properties.SetProperty(prop, this->GetLocation(configName)); } } } @@ -3174,17 +3132,19 @@ const char *cmTarget::GetProperty(const std::string& prop, } } } - this->Properties.SetProperty("SOURCES", ss.str().c_str(), - cmProperty::TARGET); + this->Properties.SetProperty("SOURCES", ss.str().c_str()); } } - bool chain = false; - const char *retVal = - this->Properties.GetPropertyValue(prop, cmProperty::TARGET, chain); - if (chain) + const char *retVal = this->Properties.GetPropertyValue(prop); + if (!retVal) { - return this->Makefile->GetProperty(prop, cmProperty::TARGET); + const bool chain = this->GetMakefile()->GetState()-> + IsPropertyChained(prop, cmProperty::TARGET); + if (chain) + { + return this->Makefile->GetProperty(prop, chain); + } } return retVal; } @@ -4863,7 +4823,7 @@ cmTarget::ReportPropertyOrigin(const std::string &p, p) != debugProperties.end(); - if (this->Makefile->IsGeneratingBuildSystem()) + if (this->Makefile->IsConfigured()) { this->DebugCompatiblePropertiesDone[p] = true; } @@ -5937,8 +5897,8 @@ cmTargetInternals::ComputeLinkInterfaceLibraries( // libraries and executables that export symbols. const char* explicitLibraries = 0; std::string linkIfaceProp; - if(thisTarget->PolicyStatusCMP0022 != cmPolicies::OLD && - thisTarget->PolicyStatusCMP0022 != cmPolicies::WARN) + if(thisTarget->GetPolicyStatusCMP0022() != cmPolicies::OLD && + thisTarget->GetPolicyStatusCMP0022() != cmPolicies::WARN) { // CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES. linkIfaceProp = "INTERFACE_LINK_LIBRARIES"; @@ -5964,7 +5924,7 @@ cmTargetInternals::ComputeLinkInterfaceLibraries( } if(explicitLibraries && - thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN && + thisTarget->GetPolicyStatusCMP0022() == cmPolicies::WARN && !this->PolicyWarnedCMP0022) { // Compare the explicitly set old link interface properties to the @@ -6008,8 +5968,8 @@ cmTargetInternals::ComputeLinkInterfaceLibraries( iface.Libraries, iface.HadHeadSensitiveCondition); } - else if (thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN - || thisTarget->PolicyStatusCMP0022 == cmPolicies::OLD) + else if (thisTarget->GetPolicyStatusCMP0022() == cmPolicies::WARN + || thisTarget->GetPolicyStatusCMP0022() == cmPolicies::OLD) // If CMP0022 is NEW then the plain tll signature sets the // INTERFACE_LINK_LIBRARIES, so if we get here then the project // cleared the property explicitly and we should not fall back @@ -6020,7 +5980,7 @@ cmTargetInternals::ComputeLinkInterfaceLibraries( thisTarget->GetLinkImplementationLibrariesInternal(config, headTarget); iface.Libraries.insert(iface.Libraries.end(), impl->Libraries.begin(), impl->Libraries.end()); - if(thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN && + if(thisTarget->GetPolicyStatusCMP0022() == cmPolicies::WARN && !this->PolicyWarnedCMP0022 && !usage_requirements_only) { // Compare the link implementation fallback link interface to the @@ -6112,8 +6072,8 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget, } } } - else if (thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN - || thisTarget->PolicyStatusCMP0022 == cmPolicies::OLD) + else if (thisTarget->GetPolicyStatusCMP0022() == cmPolicies::WARN + || thisTarget->GetPolicyStatusCMP0022() == cmPolicies::OLD) { // The link implementation is the default link interface. cmTarget::LinkImplementationLibraries const* @@ -6433,7 +6393,7 @@ std::string cmTarget::CheckCMP0004(std::string const& item) const if(lib != item) { cmake* cm = this->Makefile->GetCMakeInstance(); - switch(this->PolicyStatusCMP0004) + switch(this->GetPolicyStatusCMP0004()) { case cmPolicies::WARN: { diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 2150b83..1920312 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -66,7 +66,7 @@ public: class cmLinkImplItem: public cmLinkItem { public: - cmLinkImplItem(): cmLinkItem(), Backtrace(0), FromGenex(false) {} + cmLinkImplItem(): cmLinkItem(), Backtrace(), FromGenex(false) {} cmLinkImplItem(std::string const& n, cmTarget const* t, cmListFileBacktrace const& bt, @@ -144,7 +144,7 @@ public: #define DECLARE_TARGET_POLICY(POLICY) \ cmPolicies::PolicyStatus GetPolicyStatus ## POLICY () const \ - { return this->PolicyStatus ## POLICY; } + { return this->PolicyMap.Get(cmPolicies::POLICY); } CM_FOR_EACH_TARGET_POLICY(DECLARE_TARGET_POLICY) @@ -207,7 +207,8 @@ public: KeywordTLLSignature, PlainTLLSignature }; - bool PushTLLCommandTrace(TLLSignature signature); + bool PushTLLCommandTrace(TLLSignature signature, + cmListFileContext const& lfc); void GetTllSignatureTraces(std::ostringstream &s, TLLSignature sig) const; void MergeLinkLibraries( cmMakefile& mf, const std::string& selfname, @@ -260,11 +261,6 @@ public: bool GetPropertyAsBool(const std::string& prop) const; void CheckProperty(const std::string& prop, cmMakefile* context) const; - const char* GetFeature(const std::string& feature, - const std::string& config) const; - bool GetFeatureAsBool(const std::string& feature, - const std::string& config) const; - bool IsImported() const {return this->IsImportedTarget;} void GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const; @@ -642,12 +638,6 @@ public: private: bool HandleLocationPropertyPolicy(cmMakefile* context) const; - // The set of include directories that are marked as system include - // directories. - std::set<std::string> SystemIncludeDirectories; - - std::vector<std::pair<TLLSignature, cmListFileContext> > TLLCommands; - #if defined(_WIN32) && !defined(__CYGWIN__) /** * A list of direct dependencies. Use in conjunction with DependencyMap. @@ -742,40 +732,48 @@ private: void GetSourceFiles(std::vector<std::string> &files, const std::string& config) const; private: + mutable cmPropertyMap Properties; + std::set<std::string> SystemIncludeDirectories; + std::set<std::string> LinkDirectoriesEmmitted; + std::set<std::string> Utilities; + mutable std::set<std::string> LinkImplicitNullProperties; + std::map<std::string, cmListFileBacktrace> UtilityBacktraces; + mutable std::map<std::string, bool> DebugCompatiblePropertiesDone; + mutable std::map<std::string, std::string> MaxLanguageStandards; + cmPolicies::PolicyMap PolicyMap; std::string Name; + std::string InstallPath; + std::string RuntimeInstallPath; + mutable std::string ExportMacro; + std::vector<std::string> LinkDirectories; std::vector<cmCustomCommand> PreBuildCommands; std::vector<cmCustomCommand> PreLinkCommands; std::vector<cmCustomCommand> PostBuildCommands; - TargetType TargetTypeValue; + std::vector<std::pair<TLLSignature, cmListFileContext> > TLLCommands; LinkLibraryVectorType PrevLinkedLibraries; + LinkLibraryVectorType OriginalLinkLibraries; #if defined(_WIN32) && !defined(__CYGWIN__) LinkLibraryVectorType LinkLibrariesForVS6; - bool LinkLibrariesForVS6Analyzed; #endif - std::vector<std::string> LinkDirectories; - std::set<std::string> LinkDirectoriesEmmitted; + cmMakefile* Makefile; + cmTargetInternalPointer Internal; + TargetType TargetTypeValue; bool HaveInstallRule; - std::string InstallPath; - std::string RuntimeInstallPath; - mutable std::string ExportMacro; - std::set<std::string> Utilities; - std::map<std::string, cmListFileBacktrace> UtilityBacktraces; bool RecordDependencies; - mutable cmPropertyMap Properties; - LinkLibraryVectorType OriginalLinkLibraries; bool DLLPlatform; bool IsAndroid; bool IsApple; bool IsImportedTarget; + bool BuildInterfaceIncludesAppended; mutable bool DebugIncludesDone; - mutable std::map<std::string, bool> DebugCompatiblePropertiesDone; mutable bool DebugCompileOptionsDone; mutable bool DebugCompileDefinitionsDone; mutable bool DebugSourcesDone; mutable bool DebugCompileFeaturesDone; - mutable std::set<std::string> LinkImplicitNullProperties; - mutable std::map<std::string, std::string> MaxLanguageStandards; - bool BuildInterfaceIncludesAppended; + mutable bool LinkImplementationLanguageIsContextDependent; +#if defined(_WIN32) && !defined(__CYGWIN__) + bool LinkLibrariesForVS6Analyzed; +#endif // Cache target output paths for each configuration. struct OutputInfo; @@ -825,23 +823,10 @@ private: void ProcessSourceExpression(std::string const& expr); - // The cmMakefile instance that owns this target. This should - // always be set. - cmMakefile* Makefile; - - // Policy status recorded when target was created. -#define TARGET_POLICY_MEMBER(POLICY) \ - cmPolicies::PolicyStatus PolicyStatus ## POLICY; - - CM_FOR_EACH_TARGET_POLICY(TARGET_POLICY_MEMBER) - -#undef TARGET_POLICY_MEMBER - // Internal representation details. friend class cmTargetInternals; friend class cmGeneratorTarget; friend class cmTargetTraceDependencies; - cmTargetInternalPointer Internal; void ComputeVersionedName(std::string& vName, std::string const& prefix, @@ -849,8 +834,6 @@ private: std::string const& suffix, std::string const& name, const char* version) const; - - mutable bool LinkImplementationLanguageIsContextDependent; }; #ifdef CMAKE_BUILD_WITH_CMAKE diff --git a/Source/cmTargetDepend.h b/Source/cmTargetDepend.h index 1feb072..c5059ee 100644 --- a/Source/cmTargetDepend.h +++ b/Source/cmTargetDepend.h @@ -14,23 +14,24 @@ #include "cmStandardIncludes.h" -class cmTarget; +class cmGeneratorTarget; /** One edge in the global target dependency graph. It may be marked as a 'link' or 'util' edge or both. */ class cmTargetDepend { - cmTarget const* Target; + cmGeneratorTarget const* Target; // The set order depends only on the Target, so we use // mutable members to acheive a map with set syntax. mutable bool Link; mutable bool Util; public: - cmTargetDepend(cmTarget const* t): Target(t), Link(false), Util(false) {} - operator cmTarget const*() const { return this->Target; } - cmTarget const* operator->() const { return this->Target; } - cmTarget const& operator*() const { return *this->Target; } + cmTargetDepend(cmGeneratorTarget const* t) + : Target(t), Link(false), Util(false) {} + operator cmGeneratorTarget const*() const { return this->Target; } + cmGeneratorTarget const* operator->() const { return this->Target; } + cmGeneratorTarget const& operator*() const { return *this->Target; } friend bool operator < (cmTargetDepend const& l, cmTargetDepend const& r) { return l.Target < r.Target; } void SetType(bool strong) const diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx index df37d66..b57b921 100644 --- a/Source/cmTargetLinkLibrariesCommand.cxx +++ b/Source/cmTargetLinkLibrariesCommand.cxx @@ -368,7 +368,8 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, || this->CurrentProcessingState == ProcessingKeywordPublicInterface || this->CurrentProcessingState == ProcessingKeywordLinkInterface) ? cmTarget::KeywordTLLSignature : cmTarget::PlainTLLSignature; - if (!this->Target->PushTLLCommandTrace(sig)) + if (!this->Target->PushTLLCommandTrace( + sig, this->Makefile->GetExecutionContext())) { std::ostringstream e; const char *modal = 0; diff --git a/Source/cmTest.cxx b/Source/cmTest.cxx index ff5d411..6fcd0dc 100644 --- a/Source/cmTest.cxx +++ b/Source/cmTest.cxx @@ -21,7 +21,6 @@ cmTest::cmTest(cmMakefile* mf) { this->Makefile = mf; this->OldStyle = true; - this->Properties.SetCMakeInstance(mf->GetCMakeInstance()); } //---------------------------------------------------------------------------- @@ -50,12 +49,15 @@ void cmTest::SetCommand(std::vector<std::string> const& command) //---------------------------------------------------------------------------- const char *cmTest::GetProperty(const std::string& prop) const { - bool chain = false; - const char *retVal = - this->Properties.GetPropertyValue(prop, cmProperty::TEST, chain); - if (chain) + const char *retVal = this->Properties.GetPropertyValue(prop); + if (!retVal) { - return this->Makefile->GetProperty(prop,cmProperty::TEST); + const bool chain = this->Makefile->GetState()-> + IsPropertyChained(prop, cmProperty::TEST); + if (chain) + { + return this->Makefile->GetProperty(prop, chain); + } } return retVal; } @@ -69,12 +71,12 @@ bool cmTest::GetPropertyAsBool(const std::string& prop) const //---------------------------------------------------------------------------- void cmTest::SetProperty(const std::string& prop, const char* value) { - this->Properties.SetProperty(prop, value, cmProperty::TEST); + this->Properties.SetProperty(prop, value); } //---------------------------------------------------------------------------- void cmTest::AppendProperty(const std::string& prop, const char* value, bool asString) { - this->Properties.AppendProperty(prop, value, cmProperty::TEST, asString); + this->Properties.AppendProperty(prop, value, asString); } diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx index 7e11d8c..546ad71 100644 --- a/Source/cmTestGenerator.cxx +++ b/Source/cmTestGenerator.cxx @@ -12,7 +12,7 @@ #include "cmTestGenerator.h" #include "cmGeneratorExpression.h" -#include "cmLocalGenerator.h" +#include "cmOutputConverter.h" #include "cmMakefile.h" #include "cmSystemTools.h" #include "cmTarget.h" @@ -97,13 +97,13 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, cmSystemTools::ExpandListArgument(emulator, emulatorWithArgs); std::string emulatorExe(emulatorWithArgs[0]); cmSystemTools::ConvertToUnixSlashes(emulatorExe); - os << cmLocalGenerator::EscapeForCMake(emulatorExe) << " "; + os << cmOutputConverter::EscapeForCMake(emulatorExe) << " "; for(std::vector<std::string>::const_iterator ei = emulatorWithArgs.begin()+1; ei != emulatorWithArgs.end(); ++ei) { - os << cmLocalGenerator::EscapeForCMake(*ei) << " "; + os << cmOutputConverter::EscapeForCMake(*ei) << " "; } } } @@ -115,11 +115,11 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, } // Generate the command line with full escapes. - os << cmLocalGenerator::EscapeForCMake(exe); + os << cmOutputConverter::EscapeForCMake(exe); for(std::vector<std::string>::const_iterator ci = command.begin()+1; ci != command.end(); ++ci) { - os << " " << cmLocalGenerator::EscapeForCMake( + os << " " << cmOutputConverter::EscapeForCMake( ge.Parse(*ci)->Evaluate(mf, config)); } @@ -136,7 +136,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, i != pm.end(); ++i) { os << " " << i->first - << " " << cmLocalGenerator::EscapeForCMake( + << " " << cmOutputConverter::EscapeForCMake( ge.Parse(i->second.GetValue())->Evaluate(mf, config)); } os << ")" << std::endl; @@ -206,7 +206,7 @@ void cmTestGenerator::GenerateOldStyle(std::ostream& fout, i != pm.end(); ++i) { fout << " " << i->first - << " " << cmLocalGenerator::EscapeForCMake(i->second.GetValue()); + << " " << cmOutputConverter::EscapeForCMake(i->second.GetValue()); } fout << ")" << std::endl; } diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx index 9473008..98a397c 100644 --- a/Source/cmVariableWatchCommand.cxx +++ b/Source/cmVariableWatchCommand.cxx @@ -49,30 +49,26 @@ static void cmVariableWatchCommandVariableAccessed( newLFF.Arguments.clear(); newLFF.Arguments.push_back( cmListFileArgument(variable, cmListFileArgument::Quoted, - "unknown", 9999)); + 9999)); newLFF.Arguments.push_back( cmListFileArgument(accessString, cmListFileArgument::Quoted, - "unknown", 9999)); + 9999)); newLFF.Arguments.push_back( cmListFileArgument(newValue?newValue:"", cmListFileArgument::Quoted, - "unknown", 9999)); + 9999)); newLFF.Arguments.push_back( cmListFileArgument(currentListFile, cmListFileArgument::Quoted, - "unknown", 9999)); + 9999)); newLFF.Arguments.push_back( cmListFileArgument(stack, cmListFileArgument::Quoted, - "unknown", 9999)); + 9999)); newLFF.Name = data->Command; - newLFF.FilePath = "Some weird path"; newLFF.Line = 9999; cmExecutionStatus status; if(!makefile->ExecuteCommand(newLFF,status)) { - arg.FilePath = "Unknown"; - arg.Line = 0; std::ostringstream error; - error << "Error in cmake code at\n" - << arg.FilePath << ":" << arg.Line << ":\n" + error << "Error in cmake code at\nUnknown:0:\n" << "A command failed during the invocation of callback \"" << data->Command << "\"."; cmSystemTools::Error(error.str().c_str()); diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 5dfdb14..a2f9bca 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -176,9 +176,8 @@ cmVisualStudio10TargetGenerator(cmTarget* target, this->Makefile->GetConfigurations(this->Configurations); this->LocalGenerator = (cmLocalVisualStudio7Generator*) - this->Makefile->GetLocalGenerator(); + this->GeneratorTarget->GetLocalGenerator(); this->Name = this->Target->GetName(); - this->GlobalGenerator->CreateGUID(this->Name.c_str()); this->GUID = this->GlobalGenerator->GetGUID(this->Name.c_str()); this->Platform = gg->GetPlatformName(); this->NsightTegra = gg->IsNsightTegra(); @@ -923,10 +922,7 @@ cmVisualStudio10TargetGenerator::ConvertPath(std::string const& path, return forceRelative ? cmSystemTools::RelativePath( this->Makefile->GetCurrentBinaryDirectory(), path.c_str()) - : this->LocalGenerator->Convert(path.c_str(), - cmLocalGenerator::START_OUTPUT, - cmLocalGenerator::UNCHANGED, - /* optional = */ true); + : path.c_str(); } void cmVisualStudio10TargetGenerator::ConvertToWindowsSlash(std::string& s) @@ -1084,7 +1080,6 @@ void cmVisualStudio10TargetGenerator::WriteGroups() (*this->BuildFileStream) << name << "\">\n"; std::string guidName = "SG_Filter_"; guidName += name; - this->GlobalGenerator->CreateGUID(guidName.c_str()); this->WriteString("<UniqueIdentifier>", 3); std::string guid = this->GlobalGenerator->GetGUID(guidName.c_str()); @@ -1099,7 +1094,6 @@ void cmVisualStudio10TargetGenerator::WriteGroups() { this->WriteString("<Filter Include=\"Object Libraries\">\n", 2); std::string guidName = "SG_Filter_Object Libraries"; - this->GlobalGenerator->CreateGUID(guidName.c_str()); this->WriteString("<UniqueIdentifier>", 3); std::string guid = this->GlobalGenerator->GetGUID(guidName.c_str()); @@ -1112,7 +1106,6 @@ void cmVisualStudio10TargetGenerator::WriteGroups() { this->WriteString("<Filter Include=\"Resource Files\">\n", 2); std::string guidName = "SG_Filter_Resource Files"; - this->GlobalGenerator->CreateGUID(guidName.c_str()); this->WriteString("<UniqueIdentifier>", 3); std::string guid = this->GlobalGenerator->GetGUID(guidName.c_str()); @@ -2473,6 +2466,15 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config) "%(IgnoreSpecificDefaultLibraries)"); } + if (this->Target->GetType() == cmTarget::SHARED_LIBRARY && + this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) + { + if (this->Target->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS")) + { + linkOptions.AddFlag("ModuleDefinitionFile", "$(IntDir)exportall.def"); + } + } + this->LinkOptions[config] = pOptions.release(); return true; } @@ -2620,8 +2622,25 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups() void cmVisualStudio10TargetGenerator::WriteEvents(std::string const& configName) { - this->WriteEvent("PreLinkEvent", - this->Target->GetPreLinkCommands(), configName); + bool addedPrelink = false; + if (this->Target->GetType() == cmTarget::SHARED_LIBRARY && + this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) + { + if (this->Target->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS")) + { + addedPrelink = true; + std::vector<cmCustomCommand> commands = + this->Target->GetPreLinkCommands(); + this->GlobalGenerator->AddSymbolExportCommand( + this->GeneratorTarget, commands, configName); + this->WriteEvent("PreLinkEvent", commands, configName); + } + } + if (!addedPrelink) + { + this->WriteEvent("PreLinkEvent", + this->Target->GetPreLinkCommands(), configName); + } this->WriteEvent("PreBuildEvent", this->Target->GetPreBuildCommands(), configName); this->WriteEvent("PostBuildEvent", @@ -2667,7 +2686,7 @@ void cmVisualStudio10TargetGenerator::WriteEvent( void cmVisualStudio10TargetGenerator::WriteProjectReferences() { cmGlobalGenerator::TargetDependSet const& unordered - = this->GlobalGenerator->GetTargetDirectDepends(*this->Target); + = this->GlobalGenerator->GetTargetDirectDepends(this->GeneratorTarget); typedef cmGlobalVisualStudioGenerator::OrderedTargetDependSet OrderedTargetDependSet; OrderedTargetDependSet depends(unordered); @@ -2675,7 +2694,7 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences() for( OrderedTargetDependSet::const_iterator i = depends.begin(); i != depends.end(); ++i) { - cmTarget const* dt = *i; + cmTarget const* dt = (*i)->Target; if(dt->GetType() == cmTarget::INTERFACE_LIBRARY) { continue; diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx index 5170ead..012c580 100644 --- a/Source/cmWhileCommand.cxx +++ b/Source/cmWhileCommand.cxx @@ -12,6 +12,17 @@ #include "cmWhileCommand.h" #include "cmConditionEvaluator.h" +cmWhileFunctionBlocker::cmWhileFunctionBlocker(cmMakefile* mf): + Makefile(mf), Depth(0) +{ + this->Makefile->PushLoopBlock(); +} + +cmWhileFunctionBlocker::~cmWhileFunctionBlocker() +{ + this->Makefile->PopLoopBlock(); +} + bool cmWhileFunctionBlocker:: IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, cmExecutionStatus &inStatus) @@ -27,8 +38,6 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, // if this is the endwhile for this while loop then execute if (!this->Depth) { - cmMakefile::LoopBlockPop loopBlockPop(&mf); - // Remove the function blocker for this scope or bail. cmsys::auto_ptr<cmFunctionBlocker> fb(mf.RemoveFunctionBlocker(this, lff)); @@ -140,12 +149,10 @@ bool cmWhileCommand } // create a function blocker - cmWhileFunctionBlocker *f = new cmWhileFunctionBlocker(); + cmWhileFunctionBlocker *f = new cmWhileFunctionBlocker(this->Makefile); f->Args = args; this->Makefile->AddFunctionBlocker(f); - this->Makefile->PushLoopBlock(); - return true; } diff --git a/Source/cmWhileCommand.h b/Source/cmWhileCommand.h index 9fafffc..85a0bd3 100644 --- a/Source/cmWhileCommand.h +++ b/Source/cmWhileCommand.h @@ -19,8 +19,8 @@ class cmWhileFunctionBlocker : public cmFunctionBlocker { public: - cmWhileFunctionBlocker() {this->Depth=0;} - virtual ~cmWhileFunctionBlocker() {} + cmWhileFunctionBlocker(cmMakefile* mf); + ~cmWhileFunctionBlocker(); virtual bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, cmExecutionStatus &); @@ -29,6 +29,7 @@ public: std::vector<cmListFileArgument> Args; std::vector<cmListFileFunction> Functions; private: + cmMakefile* Makefile; int Depth; }; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 23803ef..7bf3832 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -134,7 +134,7 @@ cmake::cmake() this->Policies = new cmPolicies(); this->State = new cmState(this); - this->CurrentSnapshot = this->State->CreateSnapshot(cmState::Snapshot()); + this->CurrentSnapshot = this->State->CreateBaseSnapshot(); #ifdef __APPLE__ struct rlimit rlp; @@ -186,7 +186,7 @@ cmake::~cmake() void cmake::CleanupCommandsAndMacros() { - this->State->Reset(); + this->CurrentSnapshot = this->State->Reset(); this->State->RemoveUserDefinedCommands(); } @@ -370,6 +370,7 @@ void cmake::ReadListFile(const std::vector<std::string>& args, // read in the list file to fill the cache if(path) { + this->CurrentSnapshot = this->State->Reset(); std::string homeDir = this->GetHomeDirectory(); std::string homeOutputDir = this->GetHomeOutputDirectory(); this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory()); @@ -482,7 +483,7 @@ bool cmake::FindPackage(const std::vector<std::string>& args) std::string linkPath; std::string flags; std::string linkFlags; - gg->CreateGeneratorTargets(mf); + gg->CreateGeneratorTargets(lg.get()); cmGeneratorTarget *gtgt = gg->GetGeneratorTarget(tgt); lg->GetTargetFlags(linkLibs, frameworkPath, linkPath, flags, linkFlags, gtgt, false); @@ -1437,33 +1438,6 @@ int cmake::ActualConfigure() cmState::PATH); } } - if(!this->State - ->GetInitializedCacheValue("CMAKE_USE_RELATIVE_PATHS")) - { - this->State->AddCacheEntry - ("CMAKE_USE_RELATIVE_PATHS", "OFF", - "If true, cmake will use relative paths in makefiles and projects.", - cmState::BOOL); - if (!this->State->GetCacheEntryProperty("CMAKE_USE_RELATIVE_PATHS", - "ADVANCED")) - { - this->State->SetCacheEntryProperty("CMAKE_USE_RELATIVE_PATHS", - "ADVANCED", "1"); - } - } - - if(cmSystemTools::GetFatalErrorOccured()) - { - const char* makeProgram = - this->State->GetInitializedCacheValue("CMAKE_MAKE_PROGRAM"); - if (!makeProgram || cmSystemTools::IsOff(makeProgram)) - { - // We must have a bad generator selection. Wipe the cache entry so the - // user can select another. - this->State->RemoveCacheEntry("CMAKE_GENERATOR"); - this->State->RemoveCacheEntry("CMAKE_EXTRA_GENERATOR"); - } - } cmMakefile* mf=this->GlobalGenerator->GetLocalGenerators()[0]->GetMakefile(); if (mf->IsOn("CTEST_USE_LAUNCHERS") @@ -2519,7 +2493,6 @@ void cmake::IssueMessage(cmake::MessageType t, std::string const& text, cmListFileBacktrace const& bt) { cmListFileBacktrace backtrace = bt; - backtrace.MakeRelative(); std::ostringstream msg; if (!this->PrintMessagePreamble(t, msg)) diff --git a/Source/cmake.h b/Source/cmake.h index 12b7e68..f0f9411 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -222,9 +222,6 @@ class cmake ///! this is called by generators to update the progress void UpdateProgress(const char *msg, float prog); - ///! get the cmake policies instance - cmPolicies *GetPolicies() {return this->Policies;} - ///! Get the variable watch object cmVariableWatch* GetVariableWatch() { return this->VariableWatch; } @@ -301,7 +298,7 @@ class cmake /** Display a message to the user. */ void IssueMessage(cmake::MessageType t, std::string const& text, - cmListFileBacktrace const& backtrace = cmListFileBacktrace(NULL)); + cmListFileBacktrace const& backtrace = cmListFileBacktrace()); void IssueMessage(cmake::MessageType t, std::string const& text, cmListFileContext const& lfc); diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index e5f4700..c94ffec 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -113,12 +113,7 @@ static cmMakefile* cmakemainGetMakefile(void *clientdata) cmGlobalGenerator* gg=cm->GetGlobalGenerator(); if (gg) { - cmLocalGenerator* lg=gg->GetCurrentLocalGenerator(); - if (lg) - { - cmMakefile* mf = lg->GetMakefile(); - return mf; - } + return gg->GetCurrentMakefile(); } } return 0; @@ -425,7 +420,7 @@ static int do_build(int ac, char const* const* av) switch (doing) { case DoingDir: - dir = av[i]; + dir = cmSystemTools::CollapseFullPath(av[i]); doing = DoingNone; break; case DoingTarget: diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 3ea2186..63838b4 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -34,6 +34,10 @@ #include <time.h> #include <stdlib.h> // required for atoi +#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE) +// defined in binexplib.cxx +bool DumpFile(const char* filename, FILE *fout); +#endif void CMakeCommandUsage(const char* program) { @@ -211,6 +215,41 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) return 0; } +#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE) + else if(args[1] == "__create_def") + { + if(args.size() < 4) + { + std::cerr << + "__create_def Usage: -E __create_def outfile.def objlistfile\n"; + return 1; + } + FILE* fout = cmsys::SystemTools::Fopen(args[2].c_str(), "w+"); + if(!fout) + { + std::cerr << "could not open output .def file: " << args[2].c_str() + << "\n"; + return 1; + } + cmsys::ifstream fin(args[3].c_str(), + std::ios::in | std::ios::binary); + if(!fin) + { + std::cerr << "could not open object list file: " << args[3].c_str() + << "\n"; + return 1; + } + std::string objfile; + while(cmSystemTools::GetLineFromStream(fin, objfile)) + { + if (!DumpFile(objfile.c_str(), fout)) + { + return 1; + } + } + return 0; + } +#endif // run include what you use command and then run the compile // command. This is an internal undocumented option and should // only be used by CMake itself when running iwyu. diff --git a/Source/ctest.cxx b/Source/ctest.cxx index e784759..afcbd61 100644 --- a/Source/ctest.cxx +++ b/Source/ctest.cxx @@ -98,6 +98,7 @@ static const char * cmDocumentationOptions[][2] = {"--test-command", "The test to run with the --build-and-test option."}, {"--test-timeout", "The time limit in seconds, internal use only."}, + {"--test-load", "CPU load threshold for starting new parallel tests."}, {"--tomorrow-tag", "Nightly or experimental starts with next day tag."}, {"--ctest-config", "The configuration file used to initialize CTest state " "when submitting dashboards."}, diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt index c88e888..7eb678b 100644 --- a/Source/kwsys/CMakeLists.txt +++ b/Source/kwsys/CMakeLists.txt @@ -786,6 +786,15 @@ IF(KWSYS_USE_SystemInformation) SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY COMPILE_DEFINITIONS KWSYS_BUILD_SHARED=1) ENDIF() + + IF(UNIX AND NOT CYGWIN) + KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_GETLOADAVG + "Checking whether CXX compiler has getloadavg" DIRECT) + IF(KWSYS_CXX_HAS_GETLOADAVG) + SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY + COMPILE_DEFINITIONS KWSYS_CXX_HAS_GETLOADAVG=1) + ENDIF() + ENDIF() ENDIF() #----------------------------------------------------------------------------- diff --git a/Source/kwsys/CONTRIBUTING.rst b/Source/kwsys/CONTRIBUTING.rst index e097b76..960eea4 100644 --- a/Source/kwsys/CONTRIBUTING.rst +++ b/Source/kwsys/CONTRIBUTING.rst @@ -29,7 +29,7 @@ License We do not require any formal copyright assignment or contributor license agreement. Any contributions intentionally sent upstream are presumed -to be offerred under terms of the OSI-approved BSD 3-clause License. +to be offered under terms of the OSI-approved BSD 3-clause License. See `Copyright.txt`_ for details. .. _`Copyright.txt`: Copyright.txt diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c index f630171..a7dd2ca 100644 --- a/Source/kwsys/ProcessWin32.c +++ b/Source/kwsys/ProcessWin32.c @@ -11,14 +11,12 @@ ============================================================================*/ #include "kwsysPrivate.h" #include KWSYS_HEADER(Process.h) -#include KWSYS_HEADER(System.h) #include KWSYS_HEADER(Encoding.h) /* Work-around CMake dependency scanning limitation. This must duplicate the above list of headers. */ #if 0 # include "Process.h.in" -# include "System.h.in" # include "Encoding_c.h.in" #endif @@ -120,11 +118,6 @@ static void kwsysProcessSetupPipeNative(HANDLE native, PHANDLE handle); static void kwsysProcessCleanupHandle(PHANDLE h); static void kwsysProcessCleanup(kwsysProcess* cp, int error); static void kwsysProcessCleanErrorMessage(kwsysProcess* cp); -static int kwsysProcessComputeCommandLength(kwsysProcess* cp, - char const* const* command); -static void kwsysProcessComputeCommandLine(kwsysProcess* cp, - char const* const* command, - char* cmd); static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout, kwsysProcessTime* timeoutTime); static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime, @@ -602,37 +595,69 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command) } } - /* We need to construct a single string representing the command - and its arguments. We will surround each argument containing - spaces with double-quotes. Inside a double-quoted argument, we - need to escape double-quotes and all backslashes before them. - We also need to escape backslashes at the end of an argument - because they come before the closing double-quote for the - argument. */ - { - /* First determine the length of the final string. */ - int length = kwsysProcessComputeCommandLength(cp, command); - - /* Allocate enough space for the command. We do not need an extra - byte for the terminating null because we allocated a space for - the first argument that we will not use. */ - char* new_cmd = malloc(length); - if(!new_cmd) + if (cp->Verbatim) { - /* Out of memory. */ + /* Copy the verbatim command line into the buffer. */ + newCommands[cp->NumberOfCommands] = kwsysEncoding_DupToWide(*command); + } + else + { + /* Encode the arguments so CommandLineToArgvW can decode + them from the command line string in the child. */ + char buffer[32768]; /* CreateProcess max command-line length. */ + char* end = buffer + sizeof(buffer); + char* out = buffer; + char const* const* a; + for (a = command; *a; ++a) + { + int quote = !**a; /* Quote the empty string. */ + int slashes = 0; + char const* c; + if (a != command && out != end) { *out++ = ' '; } + for (c = *a; !quote && *c; ++c) + { quote = (*c == ' ' || *c == '\t'); } + if (quote && out != end) { *out++ = '"'; } + for (c = *a; *c; ++c) + { + if (*c == '\\') + { + ++slashes; + } + else + { + if (*c == '"') + { + // Add n+1 backslashes to total 2n+1 before internal '"'. + while(slashes-- >= 0 && out != end) { *out++ = '\\'; } + } + slashes = 0; + } + if (out != end) { *out++ = *c; } + } + if (quote) + { + // Add n backslashes to total 2n before ending '"'. + while (slashes-- > 0 && out != end) { *out++ = '\\'; } + if (out != end) { *out++ = '"'; } + } + } + if(out != end) + { + *out = '\0'; + newCommands[cp->NumberOfCommands] = kwsysEncoding_DupToWide(buffer); + } + else + { + newCommands[cp->NumberOfCommands] = 0; + } + } + if (!newCommands[cp->NumberOfCommands]) + { + /* Out of memory or command line too long. */ free(newCommands); return 0; } - /* Construct the command line in the allocated buffer. */ - kwsysProcessComputeCommandLine(cp, command, - new_cmd); - - newCommands[cp->NumberOfCommands] = kwsysEncoding_DupToWide(new_cmd); - free(new_cmd); - } - - /* Save the new array of commands. */ free(cp->Commands); cp->Commands = newCommands; @@ -1962,66 +1987,6 @@ void kwsysProcessCleanErrorMessage(kwsysProcess* cp) } /*--------------------------------------------------------------------------*/ -int kwsysProcessComputeCommandLength(kwsysProcess* cp, - char const* const* command) -{ - int length = 0; - if(cp->Verbatim) - { - /* Treat the first argument as a verbatim command line. Use its - length directly and add space for the null-terminator. */ - length = (int)strlen(*command)+1; - } - else - { - /* Compute the length of the command line when it is converted to - a single string. Space for the null-terminator is allocated by - the whitespace character allocated for the first argument that - will not be used. */ - char const* const* arg; - for(arg = command; *arg; ++arg) - { - /* Add the length of this argument. It already includes room - for a separating space or terminating null. */ - length += kwsysSystem_Shell_GetArgumentSizeForWindows(*arg, 0); - } - } - - return length; -} - -/*--------------------------------------------------------------------------*/ -void kwsysProcessComputeCommandLine(kwsysProcess* cp, - char const* const* command, - char* cmd) -{ - if(cp->Verbatim) - { - /* Copy the verbatim command line into the buffer. */ - strcpy(cmd, *command); - } - else - { - /* Construct the command line in the allocated buffer. */ - char const* const* arg; - for(arg = command; *arg; ++arg) - { - /* Add the separating space if this is not the first argument. */ - if(arg != command) - { - *cmd++ = ' '; - } - - /* Add the current argument. */ - cmd = kwsysSystem_Shell_GetArgumentForWindows(*arg, cmd, 0); - } - - /* Add the terminating null character to the command line. */ - *cmd = 0; - } -} - -/*--------------------------------------------------------------------------*/ /* Get the time at which either the process or user timeout will expire. Returns 1 if the user timeout is first, and 0 otherwise. */ int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout, diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx index b0434f4..6e81b0b 100644 --- a/Source/kwsys/SystemInformation.cxx +++ b/Source/kwsys/SystemInformation.cxx @@ -81,6 +81,11 @@ typedef int siginfo_t; # include <errno.h> // extern int errno; #endif +#if defined (__CYGWIN__) && !defined(_WIN32) +# include <windows.h> +# undef _WIN32 +#endif + #ifdef __FreeBSD__ # include <sys/sysctl.h> # include <fenv.h> @@ -366,6 +371,8 @@ public: const char *procLimitEnvVarName); LongLong GetProcMemoryUsed(); + double GetLoadAverage(); + // enable/disable stack trace signal handler. static void SetStackTraceOnError(int enable); @@ -820,6 +827,11 @@ SystemInformation::LongLong SystemInformation::GetProcMemoryUsed() return this->Implementation->GetProcMemoryUsed(); } +double SystemInformation::GetLoadAverage() +{ + return this->Implementation->GetLoadAverage(); +} + SystemInformation::LongLong SystemInformation::GetProcessId() { return this->Implementation->GetProcessId(); @@ -1490,6 +1502,60 @@ void SymbolProperties::Initialize(void *address) } #endif // don't define this class if we're not using it +// -------------------------------------------------------------------------- +#if defined(_WIN32) || defined(__CYGWIN__) +# define KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes +#endif +#if defined(_MSC_VER) && _MSC_VER < 1310 +# undef KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes +#endif +#if defined(KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes) +double calculateCPULoad(unsigned __int64 idleTicks, + unsigned __int64 totalTicks) +{ + static double previousLoad = -0.0; + static unsigned __int64 previousIdleTicks = 0; + static unsigned __int64 previousTotalTicks = 0; + + unsigned __int64 const idleTicksSinceLastTime = + idleTicks - previousIdleTicks; + unsigned __int64 const totalTicksSinceLastTime = + totalTicks - previousTotalTicks; + + double load; + if (previousTotalTicks == 0 || totalTicksSinceLastTime == 0) + { + // No new information. Use previous result. + load = previousLoad; + } + else + { + // Calculate load since last time. + load = 1.0 - double(idleTicksSinceLastTime) / totalTicksSinceLastTime; + + // Smooth if possible. + if (previousLoad > 0) + { + load = 0.25 * load + 0.75 * previousLoad; + } + } + + previousLoad = load; + previousIdleTicks = idleTicks; + previousTotalTicks = totalTicks; + + return load; +} + +unsigned __int64 fileTimeToUInt64(FILETIME const& ft) +{ + LARGE_INTEGER out; + out.HighPart = ft.dwHighDateTime; + out.LowPart = ft.dwLowDateTime; + return out.QuadPart; +} +#endif + } // anonymous namespace @@ -3612,6 +3678,38 @@ SystemInformationImplementation::GetProcMemoryUsed() #endif } +double SystemInformationImplementation::GetLoadAverage() +{ +#if defined(KWSYS_CXX_HAS_GETLOADAVG) + double loadavg[3] = { 0.0, 0.0, 0.0 }; + if (getloadavg(loadavg, 3) > 0) + { + return loadavg[0]; + } + return -0.0; +#elif defined(KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes) + // Old windows.h headers do not provide GetSystemTimes. + typedef BOOL (WINAPI *GetSystemTimesType)(LPFILETIME, LPFILETIME, + LPFILETIME); + static GetSystemTimesType pGetSystemTimes = + (GetSystemTimesType)GetProcAddress(GetModuleHandleW(L"kernel32"), + "GetSystemTimes"); + FILETIME idleTime, kernelTime, userTime; + if (pGetSystemTimes && pGetSystemTimes(&idleTime, &kernelTime, &userTime)) + { + unsigned __int64 const idleTicks = + fileTimeToUInt64(idleTime); + unsigned __int64 const totalTicks = + fileTimeToUInt64(kernelTime) + fileTimeToUInt64(userTime); + return calculateCPULoad(idleTicks, totalTicks) * GetNumberOfPhysicalCPU(); + } + return -0.0; +#else + // Not implemented on this platform. + return -0.0; +#endif +} + /** Get the process id of the running process. */ diff --git a/Source/kwsys/SystemInformation.hxx.in b/Source/kwsys/SystemInformation.hxx.in index a9fd05d..4acdc4f 100644 --- a/Source/kwsys/SystemInformation.hxx.in +++ b/Source/kwsys/SystemInformation.hxx.in @@ -130,6 +130,10 @@ public: // Get system RAM used by this process id in units of KiB. LongLong GetProcMemoryUsed(); + // Return the load average of the machine or -0.0 if it cannot + // be determined. + double GetLoadAverage(); + // enable/disable stack trace signal handler. In order to // produce an informative stack trace the application should // be dynamically linked and compiled with debug symbols. diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index c834e34..fed1c9c 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -4408,7 +4408,7 @@ bool SystemTools::FileIsFullPath(const char* in_name, size_t len) bool SystemTools::GetShortPath(const kwsys_stl::string& path, kwsys_stl::string& shortPath) { -#if defined(WIN32) && !defined(__CYGWIN__) +#if defined(_WIN32) && !defined(__CYGWIN__) const int size = int(path.size()) +1; // size of return char *tempPath = new char[size]; // create a buffer DWORD ret; diff --git a/Source/kwsys/kwsysPlatformTestsCXX.cxx b/Source/kwsys/kwsysPlatformTestsCXX.cxx index 82620da..1596fe4 100644 --- a/Source/kwsys/kwsysPlatformTestsCXX.cxx +++ b/Source/kwsys/kwsysPlatformTestsCXX.cxx @@ -452,6 +452,19 @@ int main() } #endif +#ifdef TEST_KWSYS_CXX_HAS_GETLOADAVG +// Match feature definitions from SystemInformation.cxx +#if (defined(__GNUC__) || defined(__PGI)) && !defined(_GNU_SOURCE) +# define _GNU_SOURCE +#endif +#include <stdlib.h> +int main() +{ + double loadavg[3] = { 0.0, 0.0, 0.0 }; + return getloadavg(loadavg, 3); +} +#endif + #ifdef TEST_KWSYS_CXX_HAS_RLIMIT64 # if defined(KWSYS_HAS_LFS) # define _LARGEFILE_SOURCE diff --git a/Source/kwsys/testSystemInformation.cxx b/Source/kwsys/testSystemInformation.cxx index 53d51ac..fc8ea55 100644 --- a/Source/kwsys/testSystemInformation.cxx +++ b/Source/kwsys/testSystemInformation.cxx @@ -87,6 +87,7 @@ int testSystemInformation(int, char*[]) printMethod3(info, GetProcMemoryAvailable("KWSHL","KWSPL"), "KiB"); printMethod3(info, GetHostMemoryUsed(), "KiB"); printMethod3(info, GetProcMemoryUsed(), "KiB"); + printMethod(info, GetLoadAverage); for (long int i = 0; i <= 31; i++) { |