diff options
author | Brad King <brad.king@kitware.com> | 2017-10-18 13:37:36 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2017-10-18 13:37:59 (GMT) |
commit | b0b94cdec5bb201e64aac4b3877a1a635b9f1119 (patch) | |
tree | 5a10cbf8d1fc8fb96c517ae75c6c13637256bc53 | |
parent | 0dba1db9d5d9f2c555c718acde5ec550503fae6f (diff) | |
parent | 96d642c7b87e303813b75aaa3412f8e532d2b925 (diff) | |
download | CMake-b0b94cdec5bb201e64aac4b3877a1a635b9f1119.zip CMake-b0b94cdec5bb201e64aac4b3877a1a635b9f1119.tar.gz CMake-b0b94cdec5bb201e64aac4b3877a1a635b9f1119.tar.bz2 |
Merge topic 'cmake-open'
96d642c7 cmake-gui: Use cmake::Open to open generated project
5de37a4a cmake: Add --open option for IDE generators
Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Ruslan Baratov <ruslan_baratov@yahoo.com>
Merge-request: !1337
-rw-r--r-- | Auxiliary/bash-completion/cmake | 2 | ||||
-rw-r--r-- | Help/manual/cmake.1.rst | 5 | ||||
-rw-r--r-- | Help/release/dev/cmake-open.rst | 6 | ||||
-rw-r--r-- | Modules/CMakeFindSublimeText2.cmake | 23 | ||||
-rw-r--r-- | Source/QtDialog/CMakeSetupDialog.cxx | 36 | ||||
-rw-r--r-- | Source/QtDialog/CMakeSetupDialog.h | 1 | ||||
-rw-r--r-- | Source/QtDialog/QCMake.cxx | 29 | ||||
-rw-r--r-- | Source/QtDialog/QCMake.h | 8 | ||||
-rw-r--r-- | Source/cmExternalMakefileProjectGenerator.cxx | 7 | ||||
-rw-r--r-- | Source/cmExternalMakefileProjectGenerator.h | 3 | ||||
-rw-r--r-- | Source/cmExtraSublimeTextGenerator.cxx | 23 | ||||
-rw-r--r-- | Source/cmExtraSublimeTextGenerator.h | 3 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.cxx | 10 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.h | 6 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudioGenerator.cxx | 33 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudioGenerator.h | 3 | ||||
-rw-r--r-- | Source/cmGlobalXCodeGenerator.cxx | 34 | ||||
-rw-r--r-- | Source/cmGlobalXCodeGenerator.h | 7 | ||||
-rw-r--r-- | Source/cmake.cxx | 43 | ||||
-rw-r--r-- | Source/cmake.h | 3 | ||||
-rw-r--r-- | Source/cmakemain.cxx | 43 |
21 files changed, 299 insertions, 29 deletions
diff --git a/Auxiliary/bash-completion/cmake b/Auxiliary/bash-completion/cmake index 0a862fa..5d67b0b 100644 --- a/Auxiliary/bash-completion/cmake +++ b/Auxiliary/bash-completion/cmake @@ -96,7 +96,7 @@ _cmake() _filedir return ;; - --build) + --build|--open) _filedir -d return ;; diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index 6a21683..ff8c6c7 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -11,6 +11,7 @@ Synopsis cmake [<options>] (<path-to-source> | <path-to-existing-build>) cmake [(-D <var>=<value>)...] -P <cmake-script-file> cmake --build <dir> [<options>...] [-- <build-tool-options>...] + cmake --open <dir> cmake -E <command> [<options>...] cmake --find-package <options>... @@ -51,6 +52,10 @@ Options ``--build <dir>`` See `Build Tool Mode`_. +``--open <dir>`` + Open the generated project in the associated application. This is + only supported by some generators. + ``-N`` View mode only. diff --git a/Help/release/dev/cmake-open.rst b/Help/release/dev/cmake-open.rst new file mode 100644 index 0000000..a8f77ae --- /dev/null +++ b/Help/release/dev/cmake-open.rst @@ -0,0 +1,6 @@ +cmake-open +---------- + +* The :manual:`cmake(1)` ``--open <dir>`` command line option can now + be used to open generated IDE projects like Visual Studio solutions + or Xcode projects. diff --git a/Modules/CMakeFindSublimeText2.cmake b/Modules/CMakeFindSublimeText2.cmake new file mode 100644 index 0000000..022d010 --- /dev/null +++ b/Modules/CMakeFindSublimeText2.cmake @@ -0,0 +1,23 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + + +# This file is included in CMakeSystemSpecificInformation.cmake if +# the Sublime Text 2 extra generator has been selected. + +find_program(CMAKE_SUBLIMETEXT_EXECUTABLE + NAMES subl3 subl sublime_text + PATHS + "/Applications/Sublime Text.app/Contents/SharedSupport/bin" + "/Applications/Sublime Text 3.app/Contents/SharedSupport/bin" + "/Applications/Sublime Text 2.app/Contents/SharedSupport/bin" + "$ENV{HOME}/Applications/Sublime Text.app/Contents/SharedSupport/bin" + "$ENV{HOME}/Applications/Sublime Text 3.app/Contents/SharedSupport/bin" + "$ENV{HOME}/Applications/Sublime Text 2.app/Contents/SharedSupport/bin" + "/opt/sublime_text" + "/opt/sublime_text_3" + DOC "The Sublime Text executable") + +if(CMAKE_SUBLIMETEXT_EXECUTABLE) + set(CMAKE_OPEN_PROJECT_COMMAND "${CMAKE_SUBLIMETEXT_EXECUTABLE} --project <PROJECT_FILE>" ) +endif() diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx index bbb2395..5be9ec3 100644 --- a/Source/QtDialog/CMakeSetupDialog.cxx +++ b/Source/QtDialog/CMakeSetupDialog.cxx @@ -188,6 +188,9 @@ CMakeSetupDialog::CMakeSetupDialog() connect(this->Output, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(doOutputContextMenu(const QPoint&))); + // disable open project button + this->OpenProjectButton->setDisabled(true); + // start the cmake worker thread this->CMakeThread = new QCMakeThread(this); QObject::connect(this->CMakeThread, SIGNAL(cmakeInitialized()), this, @@ -249,6 +252,10 @@ void CMakeSetupDialog::initialize() SIGNAL(outputMessage(QString)), this, SLOT(message(QString))); + QObject::connect(this->CMakeThread->cmakeInstance(), + SIGNAL(openPossible(bool)), this->OpenProjectButton, + SLOT(setEnabled(bool))); + QObject::connect(this->groupedCheck, SIGNAL(toggled(bool)), this, SLOT(setGroupedView(bool))); QObject::connect(this->advancedCheck, SIGNAL(toggled(bool)), this, @@ -492,24 +499,10 @@ void CMakeSetupDialog::doGenerate() this->ConfigureNeeded = true; } -QString CMakeSetupDialog::getProjectFilename() -{ - QStringList nameFilter; - nameFilter << "*.sln" - << "*.xcodeproj"; - QDir directory(this->BinaryDirectory->currentText()); - QStringList nlnFile = directory.entryList(nameFilter); - - if (nlnFile.count() == 1) { - return this->BinaryDirectory->currentText() + "/" + nlnFile.at(0); - } - - return QString(); -} - void CMakeSetupDialog::doOpenProject() { - QDesktopServices::openUrl(QUrl::fromLocalFile(this->getProjectFilename())); + QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(), "open", + Qt::QueuedConnection); } void CMakeSetupDialog::closeEvent(QCloseEvent* e) @@ -630,11 +623,6 @@ void CMakeSetupDialog::updateBinaryDirectory(const QString& dir) this->BinaryDirectory->setEditText(dir); this->BinaryDirectory->blockSignals(false); } - if (!this->getProjectFilename().isEmpty()) { - this->OpenProjectButton->setEnabled(true); - } else { - this->OpenProjectButton->setEnabled(false); - } } void CMakeSetupDialog::doBinaryBrowse() @@ -1039,9 +1027,6 @@ void CMakeSetupDialog::enterState(CMakeSetupDialog::State s) this->GenerateButton->setEnabled(true); this->GenerateAction->setEnabled(true); this->ConfigureButton->setEnabled(true); - if (!this->getProjectFilename().isEmpty()) { - this->OpenProjectButton->setEnabled(true); - } this->ConfigureButton->setText(tr("&Configure")); this->GenerateButton->setText(tr("&Generate")); } else if (s == ReadyGenerate) { @@ -1049,9 +1034,6 @@ void CMakeSetupDialog::enterState(CMakeSetupDialog::State s) this->GenerateButton->setEnabled(true); this->GenerateAction->setEnabled(true); this->ConfigureButton->setEnabled(true); - if (!this->getProjectFilename().isEmpty()) { - this->OpenProjectButton->setEnabled(true); - } this->ConfigureButton->setText(tr("&Configure")); this->GenerateButton->setText(tr("&Generate")); } diff --git a/Source/QtDialog/CMakeSetupDialog.h b/Source/QtDialog/CMakeSetupDialog.h index 0da28d8..7b767e5 100644 --- a/Source/QtDialog/CMakeSetupDialog.h +++ b/Source/QtDialog/CMakeSetupDialog.h @@ -31,7 +31,6 @@ protected slots: void initialize(); void doConfigure(); void doGenerate(); - QString getProjectFilename(); void doOpenProject(); void doInstallForCommandLine(); void doHelp(); diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx index d473d9b..7e94a27 100644 --- a/Source/QtDialog/QCMake.cxx +++ b/Source/QtDialog/QCMake.cxx @@ -115,6 +115,8 @@ void QCMake::setBinaryDirectory(const QString& _dir) if (toolset) { this->setToolset(QString::fromLocal8Bit(toolset)); } + + checkOpenPossible(); } } @@ -183,6 +185,26 @@ void QCMake::generate() #endif emit this->generateDone(err); + checkOpenPossible(); +} + +void QCMake::open() +{ +#ifdef Q_OS_WIN + UINT lastErrorMode = SetErrorMode(0); +#endif + + InterruptFlag = 0; + cmSystemTools::ResetErrorOccuredFlag(); + + auto successful = this->CMakeInstance->Open( + this->BinaryDirectory.toLocal8Bit().data(), false); + +#ifdef Q_OS_WIN + SetErrorMode(lastErrorMode); +#endif + + emit this->openDone(successful); } void QCMake::setProperties(const QCMakePropertyList& newProps) @@ -450,3 +472,10 @@ void QCMake::setWarnUnusedMode(bool value) { this->WarnUnusedMode = value; } + +void QCMake::checkOpenPossible() +{ + auto data = this->BinaryDirectory.toLocal8Bit().data(); + auto possible = this->CMakeInstance->Open(data, true); + emit openPossible(possible); +} diff --git a/Source/QtDialog/QCMake.h b/Source/QtDialog/QCMake.h index 3b8cea7..6fae7e3 100644 --- a/Source/QtDialog/QCMake.h +++ b/Source/QtDialog/QCMake.h @@ -80,6 +80,8 @@ public slots: void configure(); /// generate the files void generate(); + /// open the project + void open(); /// set the property values void setProperties(const QCMakePropertyList&); /// interrupt the configure or generate process (if connecting, make a direct @@ -111,6 +113,8 @@ public slots: void setWarnUninitializedMode(bool value); /// set whether to run cmake with warnings about unused variables void setWarnUnusedMode(bool value); + /// check if project IDE open is possible and emit openPossible signal + void checkOpenPossible(); public: /// get the list of cache properties @@ -151,6 +155,10 @@ signals: void debugOutputChanged(bool); /// signal when the toolset changes void toolsetChanged(const QString& toolset); + /// signal when open is done + void openDone(bool successful); + /// signal when open is done + void openPossible(bool possible); protected: cmake* CMakeInstance; diff --git a/Source/cmExternalMakefileProjectGenerator.cxx b/Source/cmExternalMakefileProjectGenerator.cxx index 825ec65..fecd821 100644 --- a/Source/cmExternalMakefileProjectGenerator.cxx +++ b/Source/cmExternalMakefileProjectGenerator.cxx @@ -24,6 +24,13 @@ std::string cmExternalMakefileProjectGenerator::CreateFullGeneratorName( return fullName; } +bool cmExternalMakefileProjectGenerator::Open( + const std::string& /*bindir*/, const std::string& /*projectName*/, + bool /*dryRun*/) +{ + return false; +} + cmExternalMakefileProjectGeneratorFactory:: cmExternalMakefileProjectGeneratorFactory(const std::string& n, const std::string& doc) diff --git a/Source/cmExternalMakefileProjectGenerator.h b/Source/cmExternalMakefileProjectGenerator.h index a1734ee..7f332a8 100644 --- a/Source/cmExternalMakefileProjectGenerator.h +++ b/Source/cmExternalMakefileProjectGenerator.h @@ -55,6 +55,9 @@ public: void SetName(const std::string& n) { Name = n; } std::string GetName() const { return Name; } + virtual bool Open(const std::string& bindir, const std::string& projectName, + bool dryRun); + protected: ///! Contains the names of the global generators support by this generator. std::vector<std::string> SupportedGlobalGenerators; diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx index 73a9c85..3d72ae3 100644 --- a/Source/cmExtraSublimeTextGenerator.cxx +++ b/Source/cmExtraSublimeTextGenerator.cxx @@ -400,3 +400,26 @@ std::string cmExtraSublimeTextGenerator::ComputeDefines( return definesString; } + +bool cmExtraSublimeTextGenerator::Open(const std::string& bindir, + const std::string& projectName, + bool dryRun) +{ + const char* sublExecutable = + this->GlobalGenerator->GetCMakeInstance()->GetCacheDefinition( + "CMAKE_SUBLIMETEXT_EXECUTABLE"); + if (!sublExecutable) { + return false; + } + if (cmSystemTools::IsNOTFOUND(sublExecutable)) { + return false; + } + + std::string filename = bindir + "/" + projectName + ".sublime-project"; + if (dryRun) { + return cmSystemTools::FileExists(filename, true); + } + + return cmSystemTools::RunSingleCommand( + { sublExecutable, "--project", filename }); +} diff --git a/Source/cmExtraSublimeTextGenerator.h b/Source/cmExtraSublimeTextGenerator.h index 7fb304e..57ba1cf 100644 --- a/Source/cmExtraSublimeTextGenerator.h +++ b/Source/cmExtraSublimeTextGenerator.h @@ -65,6 +65,9 @@ private: std::string ComputeDefines(cmSourceFile* source, cmLocalGenerator* lg, cmGeneratorTarget* gtgt); + bool Open(const std::string& bindir, const std::string& projectName, + bool dryRun) override; + bool ExcludeBuildFolder; std::string EnvSettings; }; diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 05efff3..38669c9 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1824,6 +1824,16 @@ int cmGlobalGenerator::Build(const std::string& /*unused*/, return retVal; } +bool cmGlobalGenerator::Open(const std::string& bindir, + const std::string& projectName, bool dryRun) +{ + if (this->ExtraGenerator) { + return this->ExtraGenerator->Open(bindir, projectName, dryRun); + } + + return false; +} + std::string cmGlobalGenerator::GenerateCMakeBuildCommand( const std::string& target, const std::string& config, const std::string& native, bool ignoreErrors) diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 18ca682..04e9dc1 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -162,6 +162,12 @@ public: std::vector<std::string> const& nativeOptions = std::vector<std::string>()); + /** + * Open a generated IDE project given the following information. + */ + virtual bool Open(const std::string& bindir, const std::string& projectName, + bool dryRun); + virtual void GenerateBuildCommand( std::vector<std::string>& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index 0651536..b752f84 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -4,7 +4,10 @@ #include "cmGlobalVisualStudioGenerator.h" #include "cmsys/Encoding.hxx" +#include <future> #include <iostream> +#include <objbase.h> +#include <shellapi.h> #include <windows.h> #include "cmAlgorithms.h" @@ -928,3 +931,33 @@ void cmGlobalVisualStudioGenerator::AddSymbolExportCommand( commandLines, "Auto build dll exports", "."); commands.push_back(command); } + +static bool OpenSolution(std::string sln) +{ + HRESULT comInitialized = + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); + if (FAILED(comInitialized)) { + return false; + } + + HINSTANCE hi = + ShellExecuteA(NULL, "open", sln.c_str(), NULL, NULL, SW_SHOWNORMAL); + + CoUninitialize(); + + return reinterpret_cast<intptr_t>(hi) > 32; +} + +bool cmGlobalVisualStudioGenerator::Open(const std::string& bindir, + const std::string& projectName, + bool dryRun) +{ + std::string buildDir = cmSystemTools::ConvertToOutputPath(bindir.c_str()); + std::string sln = buildDir + "\\" + projectName + ".sln"; + + if (dryRun) { + return cmSystemTools::FileExists(sln, true); + } + + return std::async(std::launch::async, OpenSolution, sln).get(); +} diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h index 62bfd3b..55a6813 100644 --- a/Source/cmGlobalVisualStudioGenerator.h +++ b/Source/cmGlobalVisualStudioGenerator.h @@ -131,6 +131,9 @@ public: std::vector<cmCustomCommand>& commands, std::string const& configName); + bool Open(const std::string& bindir, const std::string& projectName, + bool dryRun) override; + protected: virtual void AddExtraIDETargets(); diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index c79ee47..e5471f2 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -35,6 +35,11 @@ struct cmLinkImplementation; +#if defined(CMAKE_BUILD_WITH_CMAKE) && defined(__APPLE__) +#define HAVE_APPLICATION_SERVICES +#include <ApplicationServices/ApplicationServices.h> +#endif + #if defined(CMAKE_BUILD_WITH_CMAKE) #include "cmXMLParser.h" @@ -287,6 +292,35 @@ void cmGlobalXCodeGenerator::EnableLanguage( this->ComputeArchitectures(mf); } +bool cmGlobalXCodeGenerator::Open(const std::string& bindir, + const std::string& projectName, bool dryRun) +{ + bool ret = false; + +#ifdef HAVE_APPLICATION_SERVICES + std::string url = bindir + "/" + projectName + ".xcodeproj"; + + if (dryRun) { + return cmSystemTools::FileExists(url, false); + } + + CFStringRef cfStr = CFStringCreateWithCString( + kCFAllocatorDefault, url.c_str(), kCFStringEncodingUTF8); + if (cfStr) { + CFURLRef cfUrl = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfStr, + kCFURLPOSIXPathStyle, true); + if (cfUrl) { + OSStatus err = LSOpenCFURLRef(cfUrl, nullptr); + ret = err == noErr; + CFRelease(cfUrl); + } + CFRelease(cfStr); + } +#endif + + return ret; +} + void cmGlobalXCodeGenerator::GenerateBuildCommand( std::vector<std::string>& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& /*projectDir*/, diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index e9ca91c..b758e97 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -55,6 +55,13 @@ public: */ void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*, bool optional) override; + + /** + * Open a generated IDE project given the following information. + */ + bool Open(const std::string& bindir, const std::string& projectName, + bool dryRun) override; + /** * Try running cmake and building a file. This is used for dynalically * loaded commands, not as part of the usual build process. diff --git a/Source/cmake.cxx b/Source/cmake.cxx index fd7151f..d7ed772 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -2425,6 +2425,49 @@ int cmake::Build(const std::string& dir, const std::string& target, nativeOptions); } +bool cmake::Open(const std::string& dir, bool dryRun) +{ + this->SetHomeDirectory(""); + this->SetHomeOutputDirectory(""); + if (!cmSystemTools::FileIsDirectory(dir)) { + std::cerr << "Error: " << dir << " is not a directory\n"; + return false; + } + + std::string cachePath = FindCacheFile(dir); + if (!this->LoadCache(cachePath)) { + std::cerr << "Error: could not load cache\n"; + return false; + } + const char* genName = this->State->GetCacheEntryValue("CMAKE_GENERATOR"); + if (!genName) { + std::cerr << "Error: could not find CMAKE_GENERATOR in Cache\n"; + return false; + } + const char* extraGenName = + this->State->GetInitializedCacheValue("CMAKE_EXTRA_GENERATOR"); + std::string fullName = + cmExternalMakefileProjectGenerator::CreateFullGeneratorName( + genName, extraGenName ? extraGenName : ""); + + std::unique_ptr<cmGlobalGenerator> gen( + this->CreateGlobalGenerator(fullName)); + if (!gen.get()) { + std::cerr << "Error: could create CMAKE_GENERATOR \"" << fullName + << "\"\n"; + return false; + } + + const char* cachedProjectName = + this->State->GetCacheEntryValue("CMAKE_PROJECT_NAME"); + if (!cachedProjectName) { + std::cerr << "Error: could not find CMAKE_PROJECT_NAME in Cache\n"; + return false; + } + + return gen->Open(dir, cachedProjectName, dryRun); +} + void cmake::WatchUnusedCli(const std::string& var) { #ifdef CMAKE_BUILD_WITH_CMAKE diff --git a/Source/cmake.h b/Source/cmake.h index b31b6f5..ed3ebe0 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -401,6 +401,9 @@ public: const std::string& config, const std::vector<std::string>& nativeOptions, bool clean); + ///! run the --open option + bool Open(const std::string& dir, bool dryRun); + void UnwatchUnusedCli(const std::string& var); void WatchUnusedCli(const std::string& var); diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index a1dfc3e..59b908a 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -66,6 +66,7 @@ static const char* cmDocumentationOptions[][2] = { { "-E", "CMake command mode." }, { "-L[A][H]", "List non-advanced cached variables." }, { "--build <dir>", "Build a CMake-generated project binary tree." }, + { "--open <dir>", "Open generated project in the associated application." }, { "-N", "View mode only." }, { "-P <file>", "Process script mode." }, { "--find-package", "Run in pkg-config like mode." }, @@ -100,6 +101,7 @@ static int do_command(int ac, char const* const* av) int do_cmake(int ac, char const* const* av); static int do_build(int ac, char const* const* av); +static int do_open(int ac, char const* const* av); static cmMakefile* cmakemainGetMakefile(void* clientdata) { @@ -186,6 +188,9 @@ int main(int ac, char const* const* av) if (strcmp(av[1], "--build") == 0) { return do_build(ac, av); } + if (strcmp(av[1], "--open") == 0) { + return do_open(ac, av); + } if (strcmp(av[1], "-E") == 0) { return do_command(ac, av); } @@ -423,3 +428,41 @@ static int do_build(int ac, char const* const* av) return cm.Build(dir, target, config, nativeOptions, clean); #endif } + +static int do_open(int ac, char const* const* av) +{ +#ifndef CMAKE_BUILD_WITH_CMAKE + std::cerr << "This cmake does not support --open\n"; + return -1; +#else + std::string dir; + + enum Doing + { + DoingNone, + DoingDir, + }; + Doing doing = DoingDir; + for (int i = 2; i < ac; ++i) { + switch (doing) { + case DoingDir: + dir = cmSystemTools::CollapseFullPath(av[i]); + doing = DoingNone; + break; + default: + std::cerr << "Unknown argument " << av[i] << std::endl; + dir.clear(); + break; + } + } + if (dir.empty()) { + std::cerr << "Usage: cmake --open <dir>\n"; + return 1; + } + + cmake cm(cmake::RoleInternal); + cmSystemTools::SetMessageCallback(cmakemainMessageCallback, &cm); + cm.SetProgressCallback(cmakemainProgressCallback, &cm); + return cm.Open(dir, false) ? 0 : 1; +#endif +} |