summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2017-10-18 13:37:36 (GMT)
committerKitware Robot <kwrobot@kitware.com>2017-10-18 13:37:59 (GMT)
commitb0b94cdec5bb201e64aac4b3877a1a635b9f1119 (patch)
tree5a10cbf8d1fc8fb96c517ae75c6c13637256bc53
parent0dba1db9d5d9f2c555c718acde5ec550503fae6f (diff)
parent96d642c7b87e303813b75aaa3412f8e532d2b925 (diff)
downloadCMake-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/cmake2
-rw-r--r--Help/manual/cmake.1.rst5
-rw-r--r--Help/release/dev/cmake-open.rst6
-rw-r--r--Modules/CMakeFindSublimeText2.cmake23
-rw-r--r--Source/QtDialog/CMakeSetupDialog.cxx36
-rw-r--r--Source/QtDialog/CMakeSetupDialog.h1
-rw-r--r--Source/QtDialog/QCMake.cxx29
-rw-r--r--Source/QtDialog/QCMake.h8
-rw-r--r--Source/cmExternalMakefileProjectGenerator.cxx7
-rw-r--r--Source/cmExternalMakefileProjectGenerator.h3
-rw-r--r--Source/cmExtraSublimeTextGenerator.cxx23
-rw-r--r--Source/cmExtraSublimeTextGenerator.h3
-rw-r--r--Source/cmGlobalGenerator.cxx10
-rw-r--r--Source/cmGlobalGenerator.h6
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx33
-rw-r--r--Source/cmGlobalVisualStudioGenerator.h3
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx34
-rw-r--r--Source/cmGlobalXCodeGenerator.h7
-rw-r--r--Source/cmake.cxx43
-rw-r--r--Source/cmake.h3
-rw-r--r--Source/cmakemain.cxx43
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
+}