summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt14
-rw-r--r--Source/cmConnection.cxx173
-rw-r--r--Source/cmConnection.h137
-rw-r--r--Source/cmFileMonitor.cxx383
-rw-r--r--Source/cmFileMonitor.h35
-rw-r--r--Source/cmJsonObjectDictionary.h45
-rw-r--r--Source/cmJsonObjects.cxx692
-rw-r--r--Source/cmJsonObjects.h24
-rw-r--r--Source/cmPipeConnection.cxx71
-rw-r--r--Source/cmPipeConnection.h29
-rw-r--r--Source/cmServer.cxx570
-rw-r--r--Source/cmServer.h162
-rw-r--r--Source/cmServerConnection.cxx165
-rw-r--r--Source/cmServerConnection.h67
-rw-r--r--Source/cmServerDictionary.h67
-rw-r--r--Source/cmServerProtocol.cxx760
-rw-r--r--Source/cmServerProtocol.h162
-rw-r--r--Source/cmake.cxx2
-rw-r--r--Source/cmcmd.cxx48
19 files changed, 3 insertions, 3603 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 2946022..91dd4f1 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -1156,20 +1156,6 @@ add_executable(cmake cmakemain.cxx cmcmd.cxx cmcmd.h ${MANIFEST_FILE})
list(APPEND _tools cmake)
target_link_libraries(cmake CMakeLib)
-add_library(CMakeServerLib
- cmConnection.h cmConnection.cxx
- cmFileMonitor.cxx cmFileMonitor.h
- cmJsonObjectDictionary.h
- cmJsonObjects.h
- cmJsonObjects.cxx
- cmPipeConnection.cxx cmPipeConnection.h
- cmServer.cxx cmServer.h
- cmServerConnection.cxx cmServerConnection.h
- cmServerProtocol.cxx cmServerProtocol.h
- )
-target_link_libraries(CMakeServerLib CMakeLib)
-target_link_libraries(cmake CMakeServerLib)
-
# Build CTest executable
add_executable(ctest ctest.cxx ${MANIFEST_FILE})
list(APPEND _tools ctest)
diff --git a/Source/cmConnection.cxx b/Source/cmConnection.cxx
deleted file mode 100644
index e4d0cf1..0000000
--- a/Source/cmConnection.cxx
+++ /dev/null
@@ -1,173 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmConnection.h"
-
-#include <cassert>
-#include <cstring>
-
-#include <cm3p/uv.h>
-
-#include "cmServer.h"
-
-struct write_req_t
-{
- uv_write_t req;
- uv_buf_t buf;
-};
-
-void cmEventBasedConnection::on_alloc_buffer(uv_handle_t* handle,
- size_t suggested_size,
- uv_buf_t* buf)
-{
- (void)(handle);
-#ifndef __clang_analyzer__
- char* rawBuffer = new char[suggested_size];
- *buf = uv_buf_init(rawBuffer, static_cast<unsigned int>(suggested_size));
-#else
- (void)(suggested_size);
- (void)(buf);
-#endif /* __clang_analyzer__ */
-}
-
-void cmEventBasedConnection::on_read(uv_stream_t* stream, ssize_t nread,
- const uv_buf_t* buf)
-{
- auto conn = static_cast<cmEventBasedConnection*>(stream->data);
- if (conn) {
- if (nread >= 0) {
- conn->ReadData(std::string(buf->base, buf->base + nread));
- } else {
- conn->OnDisconnect(static_cast<int>(nread));
- }
- }
-
- delete[](buf->base);
-}
-
-void cmEventBasedConnection::on_close(uv_handle_t* /*handle*/)
-{
-}
-
-void cmEventBasedConnection::on_write(uv_write_t* req, int status)
-{
- (void)(status);
-
- // Free req and buffer
- write_req_t* wr = reinterpret_cast<write_req_t*>(req);
- delete[](wr->buf.base);
- delete wr;
-}
-
-void cmEventBasedConnection::on_new_connection(uv_stream_t* stream, int status)
-{
- (void)(status);
- auto conn = static_cast<cmEventBasedConnection*>(stream->data);
-
- if (conn) {
- conn->Connect(stream);
- }
-}
-
-bool cmEventBasedConnection::IsOpen() const
-{
- return this->WriteStream != nullptr;
-}
-
-void cmEventBasedConnection::WriteData(const std::string& _data)
-{
-#ifndef NDEBUG
- auto curr_thread_id = uv_thread_self();
- assert(this->Server);
- assert(uv_thread_equal(&curr_thread_id, &this->Server->ServeThreadId));
-#endif
-
-#ifndef __clang_analyzer__
- auto data = _data;
- assert(this->WriteStream.get());
- if (BufferStrategy) {
- data = BufferStrategy->BufferOutMessage(data);
- }
-
- auto ds = data.size();
-
- write_req_t* req = new write_req_t;
- req->req.data = this;
- req->buf = uv_buf_init(new char[ds], static_cast<unsigned int>(ds));
- memcpy(req->buf.base, data.c_str(), ds);
- uv_write(reinterpret_cast<uv_write_t*>(req), this->WriteStream, &req->buf, 1,
- on_write);
-#else
- (void)(_data);
-#endif /* __clang_analyzer__ */
-}
-
-void cmEventBasedConnection::ReadData(const std::string& data)
-{
- this->RawReadBuffer += data;
- if (BufferStrategy) {
- std::string packet = BufferStrategy->BufferMessage(this->RawReadBuffer);
- while (!packet.empty()) {
- ProcessRequest(packet);
- packet = BufferStrategy->BufferMessage(this->RawReadBuffer);
- }
- } else {
- ProcessRequest(this->RawReadBuffer);
- this->RawReadBuffer.clear();
- }
-}
-
-cmEventBasedConnection::cmEventBasedConnection(
- cmConnectionBufferStrategy* bufferStrategy)
- : BufferStrategy(bufferStrategy)
-{
-}
-
-void cmEventBasedConnection::Connect(uv_stream_t* server)
-{
- (void)server;
- Server->OnConnected(nullptr);
-}
-
-void cmEventBasedConnection::OnDisconnect(int onerror)
-{
- (void)onerror;
- this->OnConnectionShuttingDown();
- if (this->Server) {
- this->Server->OnDisconnect(this);
- }
-}
-
-cmConnection::~cmConnection() = default;
-
-bool cmConnection::OnConnectionShuttingDown()
-{
- this->Server = nullptr;
- return true;
-}
-
-void cmConnection::SetServer(cmServerBase* s)
-{
- Server = s;
-}
-
-void cmConnection::ProcessRequest(const std::string& request)
-{
- Server->ProcessRequest(this, request);
-}
-
-bool cmConnection::OnServeStart(std::string* errString)
-{
- (void)errString;
- return true;
-}
-
-bool cmEventBasedConnection::OnConnectionShuttingDown()
-{
- if (this->WriteStream.get()) {
- this->WriteStream->data = nullptr;
- }
-
- WriteStream.reset();
-
- return true;
-}
diff --git a/Source/cmConnection.h b/Source/cmConnection.h
deleted file mode 100644
index 5335a7f..0000000
--- a/Source/cmConnection.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-
-#pragma once
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <cstddef>
-#include <memory>
-#include <string>
-
-#include <cm3p/uv.h>
-
-#include "cmUVHandlePtr.h"
-
-class cmServerBase;
-
-/***
- * Given a sequence of bytes with any kind of buffering, instances of this
- * class arrange logical chunks according to whatever the use case is for
- * the connection.
- */
-class cmConnectionBufferStrategy
-{
-public:
- virtual ~cmConnectionBufferStrategy();
-
- /***
- * Called whenever with an active raw buffer. If a logical chunk
- * becomes available, that chunk is returned and that portion is
- * removed from the rawBuffer
- *
- * @param rawBuffer in/out parameter. Receive buffer; the buffer strategy is
- * free to manipulate this buffer anyway it needs to.
- *
- * @return Next chunk from the stream. Returns the empty string if a chunk
- * isn't ready yet. Users of this interface should repeatedly call this
- * function until an empty string is returned since its entirely possible
- * multiple chunks come in a single raw buffer.
- */
- virtual std::string BufferMessage(std::string& rawBuffer) = 0;
-
- /***
- * Called to properly buffer an outgoing message.
- *
- * @param rawBuffer Message to format in the correct way
- *
- * @return Formatted message
- */
- virtual std::string BufferOutMessage(const std::string& rawBuffer) const
- {
- return rawBuffer;
- };
- /***
- * Resets the internal state of the buffering
- */
- virtual void clear();
-
- // TODO: There should be a callback / flag set for errors
-};
-
-class cmConnection
-{
-public:
- cmConnection() = default;
-
- cmConnection(cmConnection const&) = delete;
- cmConnection& operator=(cmConnection const&) = delete;
-
- virtual void WriteData(const std::string& data) = 0;
-
- virtual ~cmConnection();
-
- virtual bool OnConnectionShuttingDown();
-
- virtual bool IsOpen() const = 0;
-
- virtual void SetServer(cmServerBase* s);
-
- virtual void ProcessRequest(const std::string& request);
-
- virtual bool OnServeStart(std::string* pString);
-
-protected:
- cmServerBase* Server = nullptr;
-};
-
-/***
- * Abstraction of a connection; ties in event callbacks from libuv and notifies
- * the server when appropriate
- */
-class cmEventBasedConnection : public cmConnection
-{
-
-public:
- /***
- * @param bufferStrategy If no strategy is given, it will process the raw
- * chunks as they come in. The connection
- * owns the pointer given.
- */
- cmEventBasedConnection(cmConnectionBufferStrategy* bufferStrategy = nullptr);
-
- virtual void Connect(uv_stream_t* server);
-
- virtual void ReadData(const std::string& data);
-
- bool IsOpen() const override;
-
- void WriteData(const std::string& data) override;
- bool OnConnectionShuttingDown() override;
-
- virtual void OnDisconnect(int errorCode);
-
- static void on_close(uv_handle_t* handle);
-
- template <typename T>
- static void on_close_delete(uv_handle_t* handle)
- {
- delete reinterpret_cast<T*>(handle);
- }
-
-protected:
- cm::uv_stream_ptr WriteStream;
-
- std::string RawReadBuffer;
-
- std::unique_ptr<cmConnectionBufferStrategy> BufferStrategy;
-
- static void on_read(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf);
-
- static void on_write(uv_write_t* req, int status);
-
- static void on_new_connection(uv_stream_t* stream, int status);
-
- static void on_alloc_buffer(uv_handle_t* handle, size_t suggested_size,
- uv_buf_t* buf);
-};
diff --git a/Source/cmFileMonitor.cxx b/Source/cmFileMonitor.cxx
deleted file mode 100644
index 8cfdb2d..0000000
--- a/Source/cmFileMonitor.cxx
+++ /dev/null
@@ -1,383 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmFileMonitor.h"
-
-#include <cassert>
-#include <cstddef>
-#include <unordered_map>
-#include <utility>
-
-#include <cm/memory>
-
-#include "cmsys/SystemTools.hxx"
-
-namespace {
-void on_directory_change(uv_fs_event_t* handle, const char* filename,
- int events, int status);
-void on_fs_close(uv_handle_t* handle);
-} // namespace
-
-class cmIBaseWatcher
-{
-public:
- virtual ~cmIBaseWatcher() = default;
-
- virtual void Trigger(const std::string& pathSegment, int events,
- int status) const = 0;
- virtual std::string Path() const = 0;
- virtual uv_loop_t* Loop() const = 0;
-
- virtual void StartWatching() = 0;
- virtual void StopWatching() = 0;
-
- virtual std::vector<std::string> WatchedFiles() const = 0;
- virtual std::vector<std::string> WatchedDirectories() const = 0;
-};
-
-class cmVirtualDirectoryWatcher : public cmIBaseWatcher
-{
-public:
- ~cmVirtualDirectoryWatcher() override = default;
-
- cmIBaseWatcher* Find(const std::string& ps)
- {
- const auto i = this->Children.find(ps);
- return (i == this->Children.end()) ? nullptr : i->second.get();
- }
-
- void Trigger(const std::string& pathSegment, int events,
- int status) const final
- {
- if (pathSegment.empty()) {
- for (auto const& child : this->Children) {
- child.second->Trigger(std::string(), events, status);
- }
- } else {
- const auto i = this->Children.find(pathSegment);
- if (i != this->Children.end()) {
- i->second->Trigger(std::string(), events, status);
- }
- }
- }
-
- void StartWatching() override
- {
- for (auto const& child : this->Children) {
- child.second->StartWatching();
- }
- }
-
- void StopWatching() override
- {
- for (auto const& child : this->Children) {
- child.second->StopWatching();
- }
- }
-
- std::vector<std::string> WatchedFiles() const final
- {
- std::vector<std::string> result;
- for (auto const& child : this->Children) {
- for (std::string const& f : child.second->WatchedFiles()) {
- result.push_back(f);
- }
- }
- return result;
- }
-
- std::vector<std::string> WatchedDirectories() const override
- {
- std::vector<std::string> result;
- for (auto const& child : this->Children) {
- for (std::string const& dir : child.second->WatchedDirectories()) {
- result.push_back(dir);
- }
- }
- return result;
- }
-
- void Reset() { this->Children.clear(); }
-
- void AddChildWatcher(const std::string& ps, cmIBaseWatcher* watcher)
- {
- assert(!ps.empty());
- assert(this->Children.find(ps) == this->Children.end());
- assert(watcher);
-
- this->Children.emplace(ps, std::unique_ptr<cmIBaseWatcher>(watcher));
- }
-
-private:
- std::unordered_map<std::string, std::unique_ptr<cmIBaseWatcher>>
- Children; // owned!
-};
-
-// Root of all the different (on windows!) root directories:
-class cmRootWatcher : public cmVirtualDirectoryWatcher
-{
-public:
- cmRootWatcher(uv_loop_t* loop)
- : mLoop(loop)
- {
- assert(loop);
- }
-
- std::string Path() const final
- {
- assert(false);
- return std::string();
- }
- uv_loop_t* Loop() const final { return this->mLoop; }
-
-private:
- uv_loop_t* const mLoop; // no ownership!
-};
-
-// Real directories:
-class cmRealDirectoryWatcher : public cmVirtualDirectoryWatcher
-{
-public:
- cmRealDirectoryWatcher(cmVirtualDirectoryWatcher* p, const std::string& ps)
- : Parent(p)
- , PathSegment(ps)
- {
- assert(p);
- assert(!ps.empty());
-
- p->AddChildWatcher(ps, this);
- }
-
- void StartWatching() final
- {
- if (!this->Handle) {
- this->Handle = new uv_fs_event_t;
-
- uv_fs_event_init(this->Loop(), this->Handle);
- this->Handle->data = this;
- uv_fs_event_start(this->Handle, &on_directory_change, Path().c_str(), 0);
- }
- cmVirtualDirectoryWatcher::StartWatching();
- }
-
- void StopWatching() final
- {
- if (this->Handle) {
- uv_fs_event_stop(this->Handle);
- if (!uv_is_closing(reinterpret_cast<uv_handle_t*>(this->Handle))) {
- uv_close(reinterpret_cast<uv_handle_t*>(this->Handle), &on_fs_close);
- }
- this->Handle = nullptr;
- }
- cmVirtualDirectoryWatcher::StopWatching();
- }
-
- uv_loop_t* Loop() const final { return this->Parent->Loop(); }
-
- std::vector<std::string> WatchedDirectories() const override
- {
- std::vector<std::string> result = { Path() };
- for (std::string const& dir :
- cmVirtualDirectoryWatcher::WatchedDirectories()) {
- result.push_back(dir);
- }
- return result;
- }
-
-protected:
- cmVirtualDirectoryWatcher* const Parent;
- const std::string PathSegment;
-
-private:
- uv_fs_event_t* Handle = nullptr; // owner!
-};
-
-// Root directories:
-class cmRootDirectoryWatcher : public cmRealDirectoryWatcher
-{
-public:
- cmRootDirectoryWatcher(cmRootWatcher* p, const std::string& ps)
- : cmRealDirectoryWatcher(p, ps)
- {
- }
-
- std::string Path() const final { return this->PathSegment; }
-};
-
-// Normal directories below root:
-class cmDirectoryWatcher : public cmRealDirectoryWatcher
-{
-public:
- cmDirectoryWatcher(cmRealDirectoryWatcher* p, const std::string& ps)
- : cmRealDirectoryWatcher(p, ps)
- {
- }
-
- std::string Path() const final
- {
- return this->Parent->Path() + this->PathSegment + "/";
- }
-};
-
-class cmFileWatcher : public cmIBaseWatcher
-{
-public:
- cmFileWatcher(cmRealDirectoryWatcher* p, const std::string& ps,
- cmFileMonitor::Callback cb)
- : Parent(p)
- , PathSegment(ps)
- , CbList({ std::move(cb) })
- {
- assert(p);
- assert(!ps.empty());
- p->AddChildWatcher(ps, this);
- }
-
- void StartWatching() final {}
-
- void StopWatching() final {}
-
- void AppendCallback(cmFileMonitor::Callback const& cb)
- {
- this->CbList.push_back(cb);
- }
-
- std::string Path() const final
- {
- return this->Parent->Path() + this->PathSegment;
- }
-
- std::vector<std::string> WatchedDirectories() const final { return {}; }
-
- std::vector<std::string> WatchedFiles() const final
- {
- return { this->Path() };
- }
-
- void Trigger(const std::string& ps, int events, int status) const final
- {
- assert(ps.empty());
- assert(status == 0);
- static_cast<void>(ps);
-
- const std::string path = this->Path();
- for (cmFileMonitor::Callback const& cb : this->CbList) {
- cb(path, events, status);
- }
- }
-
- uv_loop_t* Loop() const final { return this->Parent->Loop(); }
-
-private:
- cmRealDirectoryWatcher* Parent;
- const std::string PathSegment;
- std::vector<cmFileMonitor::Callback> CbList;
-};
-
-namespace {
-
-void on_directory_change(uv_fs_event_t* handle, const char* filename,
- int events, int status)
-{
- const cmIBaseWatcher* const watcher =
- static_cast<const cmIBaseWatcher*>(handle->data);
- const std::string pathSegment(filename ? filename : "");
- watcher->Trigger(pathSegment, events, status);
-}
-
-void on_fs_close(uv_handle_t* handle)
-{
- delete reinterpret_cast<uv_fs_event_t*>(handle);
-}
-
-} // namespace
-
-cmFileMonitor::cmFileMonitor(uv_loop_t* l)
- : Root(cm::make_unique<cmRootWatcher>(l))
-{
-}
-
-cmFileMonitor::~cmFileMonitor() = default;
-
-void cmFileMonitor::MonitorPaths(const std::vector<std::string>& paths,
- Callback const& cb)
-{
- for (std::string const& p : paths) {
- std::vector<std::string> pathSegments;
- cmsys::SystemTools::SplitPath(p, pathSegments, true);
- const bool pathIsFile = !cmsys::SystemTools::FileIsDirectory(p);
-
- const size_t segmentCount = pathSegments.size();
- if (segmentCount < 2) { // Expect at least rootdir and filename
- continue;
- }
- cmVirtualDirectoryWatcher* currentWatcher = this->Root.get();
- for (size_t i = 0; i < segmentCount; ++i) {
- assert(currentWatcher);
-
- const bool fileSegment = (i == segmentCount - 1 && pathIsFile);
- const bool rootSegment = (i == 0);
- assert(
- !(fileSegment &&
- rootSegment)); // Can not be both filename and root part of the path!
-
- const std::string& currentSegment = pathSegments[i];
- if (currentSegment.empty()) {
- continue;
- }
-
- cmIBaseWatcher* nextWatcher = currentWatcher->Find(currentSegment);
- if (!nextWatcher) {
- if (rootSegment) { // Root part
- assert(currentWatcher == this->Root.get());
- nextWatcher =
- new cmRootDirectoryWatcher(this->Root.get(), currentSegment);
- assert(currentWatcher->Find(currentSegment) == nextWatcher);
- } else if (fileSegment) { // File part
- assert(currentWatcher != this->Root.get());
- nextWatcher = new cmFileWatcher(
- dynamic_cast<cmRealDirectoryWatcher*>(currentWatcher),
- currentSegment, cb);
- assert(currentWatcher->Find(currentSegment) == nextWatcher);
- } else { // Any normal directory in between
- nextWatcher = new cmDirectoryWatcher(
- dynamic_cast<cmRealDirectoryWatcher*>(currentWatcher),
- currentSegment);
- assert(currentWatcher->Find(currentSegment) == nextWatcher);
- }
- } else {
- if (fileSegment) {
- auto filePtr = dynamic_cast<cmFileWatcher*>(nextWatcher);
- assert(filePtr);
- filePtr->AppendCallback(cb);
- continue;
- }
- }
- currentWatcher = dynamic_cast<cmVirtualDirectoryWatcher*>(nextWatcher);
- }
- }
- this->Root->StartWatching();
-}
-
-void cmFileMonitor::StopMonitoring()
-{
- this->Root->StopWatching();
- this->Root->Reset();
-}
-
-std::vector<std::string> cmFileMonitor::WatchedFiles() const
-{
- std::vector<std::string> result;
- if (this->Root) {
- result = this->Root->WatchedFiles();
- }
- return result;
-}
-
-std::vector<std::string> cmFileMonitor::WatchedDirectories() const
-{
- std::vector<std::string> result;
- if (this->Root) {
- result = this->Root->WatchedDirectories();
- }
- return result;
-}
diff --git a/Source/cmFileMonitor.h b/Source/cmFileMonitor.h
deleted file mode 100644
index fc75b0c..0000000
--- a/Source/cmFileMonitor.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#pragma once
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <functional>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <cm3p/uv.h>
-
-class cmRootWatcher;
-
-class cmFileMonitor
-{
-
-public:
- cmFileMonitor(uv_loop_t* l);
- ~cmFileMonitor();
-
- cmFileMonitor(cmFileMonitor const&) = delete;
- cmFileMonitor& operator=(cmFileMonitor const&) = delete;
-
- using Callback = std::function<void(const std::string&, int, int)>;
- void MonitorPaths(const std::vector<std::string>& paths, Callback const& cb);
- void StopMonitoring();
-
- std::vector<std::string> WatchedFiles() const;
- std::vector<std::string> WatchedDirectories() const;
-
-private:
- std::unique_ptr<cmRootWatcher> Root;
-};
diff --git a/Source/cmJsonObjectDictionary.h b/Source/cmJsonObjectDictionary.h
deleted file mode 100644
index 8a2b529..0000000
--- a/Source/cmJsonObjectDictionary.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#pragma once
-
-#include <string>
-
-// Vocabulary:
-
-static const std::string kARTIFACTS_KEY = "artifacts";
-static const std::string kBUILD_DIRECTORY_KEY = "buildDirectory";
-static const std::string kCOMPILE_FLAGS_KEY = "compileFlags";
-static const std::string kCONFIGURATIONS_KEY = "configurations";
-static const std::string kDEFINES_KEY = "defines";
-static const std::string kFILE_GROUPS_KEY = "fileGroups";
-static const std::string kFRAMEWORK_PATH_KEY = "frameworkPath";
-static const std::string kFULL_NAME_KEY = "fullName";
-static const std::string kINCLUDE_PATH_KEY = "includePath";
-static const std::string kIS_CMAKE_KEY = "isCMake";
-static const std::string kIS_GENERATED_KEY = "isGenerated";
-static const std::string kIS_SYSTEM_KEY = "isSystem";
-static const std::string kIS_TEMPORARY_KEY = "isTemporary";
-static const std::string kKEY_KEY = "key";
-static const std::string kLANGUAGE_KEY = "language";
-static const std::string kLINKER_LANGUAGE_KEY = "linkerLanguage";
-static const std::string kLINK_FLAGS_KEY = "linkFlags";
-static const std::string kLINK_LANGUAGE_FLAGS_KEY = "linkLanguageFlags";
-static const std::string kLINK_LIBRARIES_KEY = "linkLibraries";
-static const std::string kLINK_PATH_KEY = "linkPath";
-static const std::string kNAME_KEY = "name";
-static const std::string kPATH_KEY = "path";
-static const std::string kPROJECTS_KEY = "projects";
-static const std::string kPROPERTIES_KEY = "properties";
-static const std::string kSOURCE_DIRECTORY_KEY = "sourceDirectory";
-static const std::string kSOURCES_KEY = "sources";
-static const std::string kSYSROOT_KEY = "sysroot";
-static const std::string kTARGETS_KEY = "targets";
-static const std::string kTYPE_KEY = "type";
-static const std::string kVALUE_KEY = "value";
-static const std::string kHAS_INSTALL_RULE = "hasInstallRule";
-static const std::string kINSTALL_PATHS = "installPaths";
-static const std::string kCTEST_NAME = "ctestName";
-static const std::string kCTEST_COMMAND = "ctestCommand";
-static const std::string kCTEST_INFO = "ctestInfo";
-static const std::string kMINIMUM_CMAKE_VERSION = "minimumCMakeVersion";
-static const std::string kIS_GENERATOR_PROVIDED_KEY = "isGeneratorProvided";
diff --git a/Source/cmJsonObjects.cxx b/Source/cmJsonObjects.cxx
deleted file mode 100644
index 3a7ae0c..0000000
--- a/Source/cmJsonObjects.cxx
+++ /dev/null
@@ -1,692 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmJsonObjects.h" // IWYU pragma: keep
-
-#include <algorithm>
-#include <cassert>
-#include <cstddef>
-#include <functional>
-#include <limits>
-#include <map>
-#include <memory>
-#include <set>
-#include <string>
-#include <unordered_map>
-#include <utility>
-#include <vector>
-
-#include <cmext/algorithm>
-
-#include "cmGeneratorExpression.h"
-#include "cmGeneratorTarget.h"
-#include "cmGlobalGenerator.h"
-#include "cmInstallGenerator.h"
-#include "cmInstallSubdirectoryGenerator.h"
-#include "cmInstallTargetGenerator.h"
-#include "cmJsonObjectDictionary.h"
-#include "cmJsonObjects.h"
-#include "cmLinkLineComputer.h"
-#include "cmLocalGenerator.h"
-#include "cmMakefile.h"
-#include "cmProperty.h"
-#include "cmPropertyMap.h"
-#include "cmSourceFile.h"
-#include "cmState.h"
-#include "cmStateDirectory.h"
-#include "cmStateSnapshot.h"
-#include "cmStateTypes.h"
-#include "cmStringAlgorithms.h"
-#include "cmSystemTools.h"
-#include "cmTarget.h"
-#include "cmTest.h"
-#include "cmake.h"
-
-namespace {
-
-std::vector<std::string> getConfigurations(const cmake* cm)
-{
- std::vector<std::string> configurations;
- const auto& makefiles = cm->GetGlobalGenerator()->GetMakefiles();
- if (makefiles.empty()) {
- return configurations;
- }
-
- return makefiles[0]->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
-}
-
-bool hasString(const Json::Value& v, const std::string& s)
-{
- return !v.isNull() &&
- std::any_of(v.begin(), v.end(),
- [s](const Json::Value& i) { return i.asString() == s; });
-}
-
-template <class T>
-Json::Value fromStringList(const T& in)
-{
- Json::Value result = Json::arrayValue;
- for (std::string const& i : in) {
- result.append(i);
- }
- return result;
-}
-
-} // namespace
-
-void cmGetCMakeInputs(const cmGlobalGenerator* gg,
- const std::string& sourceDir,
- const std::string& buildDir,
- std::vector<std::string>* internalFiles,
- std::vector<std::string>* explicitFiles,
- std::vector<std::string>* tmpFiles)
-{
- const std::string cmakeRootDir = cmSystemTools::GetCMakeRoot() + '/';
- auto const& makefiles = gg->GetMakefiles();
- for (const auto& mf : makefiles) {
- for (std::string const& lf : mf->GetListFiles()) {
-
- const std::string startOfFile = lf.substr(0, cmakeRootDir.size());
- const bool isInternal = (startOfFile == cmakeRootDir);
- const bool isTemporary =
- !isInternal && (cmHasPrefix(lf, buildDir + '/'));
-
- std::string toAdd = lf;
- if (!sourceDir.empty()) {
- const std::string& relative =
- cmSystemTools::RelativePath(sourceDir, lf);
- if (toAdd.size() > relative.size()) {
- toAdd = relative;
- }
- }
-
- if (isInternal) {
- if (internalFiles) {
- internalFiles->push_back(std::move(toAdd));
- }
- } else {
- if (isTemporary) {
- if (tmpFiles) {
- tmpFiles->push_back(std::move(toAdd));
- }
- } else {
- if (explicitFiles) {
- explicitFiles->push_back(std::move(toAdd));
- }
- }
- }
- }
- }
-}
-
-Json::Value cmDumpCMakeInputs(const cmake* cm)
-{
- const cmGlobalGenerator* gg = cm->GetGlobalGenerator();
- const std::string& buildDir = cm->GetHomeOutputDirectory();
- const std::string& sourceDir = cm->GetHomeDirectory();
-
- std::vector<std::string> internalFiles;
- std::vector<std::string> explicitFiles;
- std::vector<std::string> tmpFiles;
- cmGetCMakeInputs(gg, sourceDir, buildDir, &internalFiles, &explicitFiles,
- &tmpFiles);
-
- Json::Value array = Json::arrayValue;
-
- Json::Value tmp = Json::objectValue;
- tmp[kIS_CMAKE_KEY] = true;
- tmp[kIS_TEMPORARY_KEY] = false;
- tmp[kSOURCES_KEY] = fromStringList(internalFiles);
- array.append(tmp);
-
- tmp = Json::objectValue;
- tmp[kIS_CMAKE_KEY] = false;
- tmp[kIS_TEMPORARY_KEY] = false;
- tmp[kSOURCES_KEY] = fromStringList(explicitFiles);
- array.append(tmp);
-
- tmp = Json::objectValue;
- tmp[kIS_CMAKE_KEY] = false;
- tmp[kIS_TEMPORARY_KEY] = true;
- tmp[kSOURCES_KEY] = fromStringList(tmpFiles);
- array.append(tmp);
-
- return array;
-}
-
-class LanguageData
-{
-public:
- bool operator==(const LanguageData& other) const;
-
- void SetDefines(const std::set<std::string>& defines);
-
- bool IsGenerated = false;
- std::string Language;
- std::string Flags;
- std::vector<std::string> Defines;
- std::vector<std::pair<std::string, bool>> IncludePathList;
-};
-
-bool LanguageData::operator==(const LanguageData& other) const
-{
- return Language == other.Language && Defines == other.Defines &&
- Flags == other.Flags && IncludePathList == other.IncludePathList &&
- IsGenerated == other.IsGenerated;
-}
-
-void LanguageData::SetDefines(const std::set<std::string>& defines)
-{
- std::vector<std::string> result;
- result.reserve(defines.size());
- for (std::string const& i : defines) {
- result.push_back(i);
- }
- std::sort(result.begin(), result.end());
- Defines = std::move(result);
-}
-
-namespace std {
-
-template <>
-struct hash<LanguageData>
-{
- std::size_t operator()(const LanguageData& in) const
- {
- using std::hash;
- size_t result =
- hash<std::string>()(in.Language) ^ hash<std::string>()(in.Flags);
- for (auto const& i : in.IncludePathList) {
- result = result ^
- (hash<std::string>()(i.first) ^
- (i.second ? std::numeric_limits<size_t>::max() : 0));
- }
- for (auto const& i : in.Defines) {
- result = result ^ hash<std::string>()(i);
- }
- result =
- result ^ (in.IsGenerated ? std::numeric_limits<size_t>::max() : 0);
- return result;
- }
-};
-
-} // namespace std
-
-static Json::Value DumpSourceFileGroup(const LanguageData& data,
- const std::vector<std::string>& files,
- const std::string& baseDir)
-{
- Json::Value result = Json::objectValue;
-
- if (!data.Language.empty()) {
- result[kLANGUAGE_KEY] = data.Language;
- if (!data.Flags.empty()) {
- result[kCOMPILE_FLAGS_KEY] = data.Flags;
- }
- if (!data.IncludePathList.empty()) {
- Json::Value includes = Json::arrayValue;
- for (auto const& i : data.IncludePathList) {
- Json::Value tmp = Json::objectValue;
- tmp[kPATH_KEY] = i.first;
- if (i.second) {
- tmp[kIS_SYSTEM_KEY] = i.second;
- }
- includes.append(tmp);
- }
- result[kINCLUDE_PATH_KEY] = includes;
- }
- if (!data.Defines.empty()) {
- result[kDEFINES_KEY] = fromStringList(data.Defines);
- }
- }
-
- result[kIS_GENERATED_KEY] = data.IsGenerated;
-
- Json::Value sourcesValue = Json::arrayValue;
- for (auto const& i : files) {
- const std::string relPath = cmSystemTools::RelativePath(baseDir, i);
- sourcesValue.append(relPath.size() < i.size() ? relPath : i);
- }
-
- result[kSOURCES_KEY] = sourcesValue;
- return result;
-}
-
-static Json::Value DumpSourceFilesList(
- cmGeneratorTarget* target, const std::string& config,
- const std::map<std::string, LanguageData>& languageDataMap)
-{
- // Collect sourcefile groups:
-
- std::vector<cmSourceFile*> files;
- target->GetSourceFiles(files, config);
-
- std::unordered_map<LanguageData, std::vector<std::string>> fileGroups;
- for (cmSourceFile* file : files) {
- LanguageData fileData;
- fileData.Language = file->GetOrDetermineLanguage();
- if (!fileData.Language.empty()) {
- const LanguageData& ld = languageDataMap.at(fileData.Language);
- cmLocalGenerator* lg = target->GetLocalGenerator();
- cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target,
- fileData.Language);
-
- std::string compileFlags = ld.Flags;
- const std::string COMPILE_FLAGS("COMPILE_FLAGS");
- if (cmProp cflags = file->GetProperty(COMPILE_FLAGS)) {
- lg->AppendFlags(compileFlags,
- genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS));
- }
- const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
- if (cmProp coptions = file->GetProperty(COMPILE_OPTIONS)) {
- lg->AppendCompileOptions(
- compileFlags, genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS));
- }
- fileData.Flags = compileFlags;
-
- // Add include directories from source file properties.
- std::vector<std::string> includes;
-
- const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
- if (cmProp cincludes = file->GetProperty(INCLUDE_DIRECTORIES)) {
- const std::string& evaluatedIncludes =
- genexInterpreter.Evaluate(*cincludes, INCLUDE_DIRECTORIES);
- lg->AppendIncludeDirectories(includes, evaluatedIncludes, *file);
-
- for (const auto& include : includes) {
- fileData.IncludePathList.emplace_back(
- include,
- target->IsSystemIncludeDirectory(include, config,
- fileData.Language));
- }
- }
-
- fileData.IncludePathList.insert(fileData.IncludePathList.end(),
- ld.IncludePathList.begin(),
- ld.IncludePathList.end());
-
- const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
- std::set<std::string> defines;
- if (cmProp defs = file->GetProperty(COMPILE_DEFINITIONS)) {
- lg->AppendDefines(
- defines, genexInterpreter.Evaluate(*defs, COMPILE_DEFINITIONS));
- }
-
- const std::string defPropName =
- "COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(config);
- if (cmProp config_defs = file->GetProperty(defPropName)) {
- lg->AppendDefines(
- defines,
- genexInterpreter.Evaluate(*config_defs, COMPILE_DEFINITIONS));
- }
-
- defines.insert(ld.Defines.begin(), ld.Defines.end());
-
- fileData.SetDefines(defines);
- }
-
- fileData.IsGenerated = file->GetIsGenerated();
- std::vector<std::string>& groupFileList = fileGroups[fileData];
- groupFileList.push_back(file->ResolveFullPath());
- }
-
- const std::string& baseDir = target->Makefile->GetCurrentSourceDirectory();
- Json::Value result = Json::arrayValue;
- for (auto const& it : fileGroups) {
- Json::Value group = DumpSourceFileGroup(it.first, it.second, baseDir);
- if (!group.isNull()) {
- result.append(group);
- }
- }
-
- return result;
-}
-
-static Json::Value DumpCTestInfo(cmLocalGenerator* lg, cmTest* testInfo,
- const std::string& config)
-{
- Json::Value result = Json::objectValue;
- result[kCTEST_NAME] = testInfo->GetName();
-
- // Concat command entries together. After the first should be the arguments
- // for the command
- std::string command;
- for (auto const& cmd : testInfo->GetCommand()) {
- command.append(cmd);
- command.append(" ");
- }
-
- // Remove any config specific variables from the output.
- result[kCTEST_COMMAND] =
- cmGeneratorExpression::Evaluate(command, lg, config);
-
- // Build up the list of properties that may have been specified
- Json::Value properties = Json::arrayValue;
- for (auto& prop : testInfo->GetProperties().GetList()) {
- Json::Value entry = Json::objectValue;
- entry[kKEY_KEY] = prop.first;
-
- // Remove config variables from the value too.
- entry[kVALUE_KEY] =
- cmGeneratorExpression::Evaluate(prop.second, lg, config);
- properties.append(entry);
- }
- result[kPROPERTIES_KEY] = properties;
-
- return result;
-}
-
-static void DumpMakefileTests(cmLocalGenerator* lg, const std::string& config,
- Json::Value* result)
-{
- auto mf = lg->GetMakefile();
- std::vector<cmTest*> tests;
- mf->GetTests(config, tests);
- for (auto test : tests) {
- Json::Value tmp = DumpCTestInfo(lg, test, config);
- if (!tmp.isNull()) {
- result->append(tmp);
- }
- }
-}
-
-static Json::Value DumpCTestProjectList(const cmake* cm,
- std::string const& config)
-{
- Json::Value result = Json::arrayValue;
-
- auto globalGen = cm->GetGlobalGenerator();
-
- for (const auto& projectIt : globalGen->GetProjectMap()) {
- Json::Value pObj = Json::objectValue;
- pObj[kNAME_KEY] = projectIt.first;
-
- Json::Value tests = Json::arrayValue;
-
- // Gather tests for every generator
- for (const auto& lg : projectIt.second) {
- // Make sure they're generated.
- lg->GenerateTestFiles();
- DumpMakefileTests(lg, config, &tests);
- }
-
- pObj[kCTEST_INFO] = tests;
-
- result.append(pObj);
- }
-
- return result;
-}
-
-static Json::Value DumpCTestConfiguration(const cmake* cm,
- const std::string& config)
-{
- Json::Value result = Json::objectValue;
- result[kNAME_KEY] = config;
-
- result[kPROJECTS_KEY] = DumpCTestProjectList(cm, config);
-
- return result;
-}
-
-static Json::Value DumpCTestConfigurationsList(const cmake* cm)
-{
- Json::Value result = Json::arrayValue;
-
- for (const std::string& c : getConfigurations(cm)) {
- result.append(DumpCTestConfiguration(cm, c));
- }
-
- return result;
-}
-
-Json::Value cmDumpCTestInfo(const cmake* cm)
-{
- Json::Value result = Json::objectValue;
- result[kCONFIGURATIONS_KEY] = DumpCTestConfigurationsList(cm);
- return result;
-}
-
-static Json::Value DumpTarget(cmGeneratorTarget* target,
- const std::string& config)
-{
- cmLocalGenerator* lg = target->GetLocalGenerator();
-
- const cmStateEnums::TargetType type = target->GetType();
- const std::string typeName = cmState::GetTargetTypeName(type);
-
- Json::Value ttl = Json::arrayValue;
- ttl.append("EXECUTABLE");
- ttl.append("STATIC_LIBRARY");
- ttl.append("SHARED_LIBRARY");
- ttl.append("MODULE_LIBRARY");
- ttl.append("OBJECT_LIBRARY");
- ttl.append("UTILITY");
- ttl.append("INTERFACE_LIBRARY");
-
- if (!hasString(ttl, typeName) || target->IsImported()) {
- return Json::Value();
- }
-
- Json::Value result = Json::objectValue;
- result[kNAME_KEY] = target->GetName();
- result[kIS_GENERATOR_PROVIDED_KEY] =
- target->Target->GetIsGeneratorProvided();
- result[kTYPE_KEY] = typeName;
- result[kSOURCE_DIRECTORY_KEY] = lg->GetCurrentSourceDirectory();
- result[kBUILD_DIRECTORY_KEY] = lg->GetCurrentBinaryDirectory();
-
- if (type == cmStateEnums::INTERFACE_LIBRARY) {
- return result;
- }
-
- result[kFULL_NAME_KEY] = target->GetFullName(config);
-
- if (target->Target->GetHaveInstallRule()) {
- result[kHAS_INSTALL_RULE] = true;
-
- Json::Value installPaths = Json::arrayValue;
- for (const auto& installGenerator :
- target->Makefile->GetInstallGenerators()) {
- auto installTargetGenerator =
- dynamic_cast<cmInstallTargetGenerator*>(installGenerator.get());
- if (installTargetGenerator != nullptr &&
- installTargetGenerator->GetTarget()->Target == target->Target) {
- auto dest = installTargetGenerator->GetDestination(config);
-
- std::string installPath;
- if (!dest.empty() && cmSystemTools::FileIsFullPath(dest)) {
- installPath = dest;
- } else {
- installPath = cmStrCat(
- target->Makefile->GetSafeDefinition("CMAKE_INSTALL_PREFIX"), '/',
- dest);
- }
-
- installPaths.append(installPath);
- }
- }
-
- result[kINSTALL_PATHS] = installPaths;
- }
-
- if (target->HaveWellDefinedOutputFiles()) {
- Json::Value artifacts = Json::arrayValue;
- artifacts.append(
- target->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact));
- if (target->HasImportLibrary(config)) {
- artifacts.append(
- target->GetFullPath(config, cmStateEnums::ImportLibraryArtifact));
- }
- if (target->IsDLLPlatform()) {
- const cmGeneratorTarget::OutputInfo* output =
- target->GetOutputInfo(config);
- if (output && !output->PdbDir.empty()) {
- artifacts.append(output->PdbDir + '/' + target->GetPDBName(config));
- }
- }
- result[kARTIFACTS_KEY] = artifacts;
-
- result[kLINKER_LANGUAGE_KEY] = target->GetLinkerLanguage(config);
-
- std::string linkLibs;
- std::string linkFlags;
- std::string linkLanguageFlags;
- std::string frameworkPath;
- std::string linkPath;
- cmLinkLineComputer linkLineComputer(lg,
- lg->GetStateSnapshot().GetDirectory());
- lg->GetTargetFlags(&linkLineComputer, config, linkLibs, linkLanguageFlags,
- linkFlags, frameworkPath, linkPath, target);
-
- linkLibs = cmTrimWhitespace(linkLibs);
- linkFlags = cmTrimWhitespace(linkFlags);
- linkLanguageFlags = cmTrimWhitespace(linkLanguageFlags);
- frameworkPath = cmTrimWhitespace(frameworkPath);
- linkPath = cmTrimWhitespace(linkPath);
-
- if (!cmTrimWhitespace(linkLibs).empty()) {
- result[kLINK_LIBRARIES_KEY] = linkLibs;
- }
- if (!cmTrimWhitespace(linkFlags).empty()) {
- result[kLINK_FLAGS_KEY] = linkFlags;
- }
- if (!cmTrimWhitespace(linkLanguageFlags).empty()) {
- result[kLINK_LANGUAGE_FLAGS_KEY] = linkLanguageFlags;
- }
- if (!frameworkPath.empty()) {
- result[kFRAMEWORK_PATH_KEY] = frameworkPath;
- }
- if (!linkPath.empty()) {
- result[kLINK_PATH_KEY] = linkPath;
- }
- const std::string sysroot =
- lg->GetMakefile()->GetSafeDefinition("CMAKE_SYSROOT");
- if (!sysroot.empty()) {
- result[kSYSROOT_KEY] = sysroot;
- }
- }
-
- std::set<std::string> languages;
- target->GetLanguages(languages, config);
- std::map<std::string, LanguageData> languageDataMap;
-
- for (std::string const& lang : languages) {
- LanguageData& ld = languageDataMap[lang];
- ld.Language = lang;
- lg->GetTargetCompileFlags(target, config, lang, ld.Flags);
- std::set<std::string> defines;
- lg->GetTargetDefines(target, config, lang, defines);
- ld.SetDefines(defines);
- std::vector<std::string> includePathList;
- lg->GetIncludeDirectories(includePathList, target, lang, config);
- for (std::string const& i : includePathList) {
- ld.IncludePathList.emplace_back(
- i, target->IsSystemIncludeDirectory(i, config, lang));
- }
- }
-
- Json::Value sourceGroupsValue =
- DumpSourceFilesList(target, config, languageDataMap);
- if (!sourceGroupsValue.empty()) {
- result[kFILE_GROUPS_KEY] = sourceGroupsValue;
- }
-
- return result;
-}
-
-static Json::Value DumpTargetsList(
- const std::vector<cmLocalGenerator*>& generators, const std::string& config)
-{
- Json::Value result = Json::arrayValue;
-
- std::vector<cmGeneratorTarget*> targetList;
- for (auto const& lgIt : generators) {
- cm::append(targetList, lgIt->GetGeneratorTargets());
- }
- std::sort(targetList.begin(), targetList.end());
-
- for (cmGeneratorTarget* target : targetList) {
- Json::Value tmp = DumpTarget(target, config);
- if (!tmp.isNull()) {
- result.append(tmp);
- }
- }
-
- return result;
-}
-
-static Json::Value DumpProjectList(const cmake* cm, std::string const& config)
-{
- Json::Value result = Json::arrayValue;
-
- auto globalGen = cm->GetGlobalGenerator();
-
- for (auto const& projectIt : globalGen->GetProjectMap()) {
- Json::Value pObj = Json::objectValue;
- pObj[kNAME_KEY] = projectIt.first;
-
- // All Projects must have at least one local generator
- assert(!projectIt.second.empty());
- const cmLocalGenerator* lg = projectIt.second.at(0);
-
- // Project structure information:
- const cmMakefile* mf = lg->GetMakefile();
- auto minVersion = mf->GetSafeDefinition("CMAKE_MINIMUM_REQUIRED_VERSION");
- pObj[kMINIMUM_CMAKE_VERSION] = minVersion;
- pObj[kSOURCE_DIRECTORY_KEY] = mf->GetCurrentSourceDirectory();
- pObj[kBUILD_DIRECTORY_KEY] = mf->GetCurrentBinaryDirectory();
- pObj[kTARGETS_KEY] = DumpTargetsList(projectIt.second, config);
-
- // For a project-level install rule it might be defined in any of its
- // associated generators.
- bool hasInstallRule = false;
- for (const auto generator : projectIt.second) {
- for (const auto& installGen :
- generator->GetMakefile()->GetInstallGenerators()) {
- if (!dynamic_cast<cmInstallSubdirectoryGenerator*>(installGen.get())) {
- hasInstallRule = true;
- break;
- }
- }
-
- if (hasInstallRule) {
- break;
- }
- }
-
- pObj[kHAS_INSTALL_RULE] = hasInstallRule;
-
- result.append(pObj);
- }
-
- return result;
-}
-
-static Json::Value DumpConfiguration(const cmake* cm,
- const std::string& config)
-{
- Json::Value result = Json::objectValue;
- result[kNAME_KEY] = config;
-
- result[kPROJECTS_KEY] = DumpProjectList(cm, config);
-
- return result;
-}
-
-static Json::Value DumpConfigurationsList(const cmake* cm)
-{
- Json::Value result = Json::arrayValue;
-
- for (std::string const& c : getConfigurations(cm)) {
- result.append(DumpConfiguration(cm, c));
- }
-
- return result;
-}
-
-Json::Value cmDumpCodeModel(const cmake* cm)
-{
- Json::Value result = Json::objectValue;
- result[kCONFIGURATIONS_KEY] = DumpConfigurationsList(cm);
- return result;
-}
diff --git a/Source/cmJsonObjects.h b/Source/cmJsonObjects.h
deleted file mode 100644
index 80a4834..0000000
--- a/Source/cmJsonObjects.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#pragma once
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <string>
-#include <vector>
-
-#include <cm3p/json/value.h>
-
-class cmake;
-class cmGlobalGenerator;
-
-extern void cmGetCMakeInputs(const cmGlobalGenerator* gg,
- const std::string& sourceDir,
- const std::string& buildDir,
- std::vector<std::string>* internalFiles,
- std::vector<std::string>* explicitFiles,
- std::vector<std::string>* tmpFiles);
-
-extern Json::Value cmDumpCodeModel(const cmake* cm);
-extern Json::Value cmDumpCTestInfo(const cmake* cm);
-extern Json::Value cmDumpCMakeInputs(const cmake* cm);
diff --git a/Source/cmPipeConnection.cxx b/Source/cmPipeConnection.cxx
deleted file mode 100644
index 1eede13..0000000
--- a/Source/cmPipeConnection.cxx
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmPipeConnection.h"
-
-#include <utility>
-
-#include "cmServer.h"
-
-cmPipeConnection::cmPipeConnection(std::string name,
- cmConnectionBufferStrategy* bufferStrategy)
- : cmEventBasedConnection(bufferStrategy)
- , PipeName(std::move(name))
-{
-}
-
-void cmPipeConnection::Connect(uv_stream_t* server)
-{
- if (this->WriteStream.get()) {
- // Accept and close all pipes but the first:
- cm::uv_pipe_ptr rejectPipe;
-
- rejectPipe.init(*this->Server->GetLoop(), 0);
- uv_accept(server, rejectPipe);
-
- return;
- }
-
- cm::uv_pipe_ptr ClientPipe;
- ClientPipe.init(*this->Server->GetLoop(), 0,
- static_cast<cmEventBasedConnection*>(this));
-
- if (uv_accept(server, ClientPipe) != 0) {
- return;
- }
-
- uv_read_start(ClientPipe, on_alloc_buffer, on_read);
- WriteStream = std::move(ClientPipe);
- Server->OnConnected(this);
-}
-
-bool cmPipeConnection::OnServeStart(std::string* errorMessage)
-{
- this->ServerPipe.init(*this->Server->GetLoop(), 0,
- static_cast<cmEventBasedConnection*>(this));
-
- int r;
- if ((r = uv_pipe_bind(this->ServerPipe, this->PipeName.c_str())) != 0) {
- *errorMessage = std::string("Internal Error with ") + this->PipeName +
- ": " + uv_err_name(r);
- return false;
- }
-
- if ((r = uv_listen(this->ServerPipe, 1, on_new_connection)) != 0) {
- *errorMessage = std::string("Internal Error listening on ") +
- this->PipeName + ": " + uv_err_name(r);
- return false;
- }
-
- return cmConnection::OnServeStart(errorMessage);
-}
-
-bool cmPipeConnection::OnConnectionShuttingDown()
-{
- if (this->WriteStream.get()) {
- this->WriteStream->data = nullptr;
- }
-
- this->ServerPipe.reset();
-
- return cmEventBasedConnection::OnConnectionShuttingDown();
-}
diff --git a/Source/cmPipeConnection.h b/Source/cmPipeConnection.h
deleted file mode 100644
index 1215716..0000000
--- a/Source/cmPipeConnection.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#pragma once
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <string>
-
-#include <cm3p/uv.h>
-
-#include "cmConnection.h"
-#include "cmUVHandlePtr.h"
-
-class cmPipeConnection : public cmEventBasedConnection
-{
-public:
- cmPipeConnection(std::string name,
- cmConnectionBufferStrategy* bufferStrategy = nullptr);
-
- bool OnServeStart(std::string* pString) override;
-
- bool OnConnectionShuttingDown() override;
-
- void Connect(uv_stream_t* server) override;
-
-private:
- const std::string PipeName;
- cm::uv_pipe_ptr ServerPipe;
-};
diff --git a/Source/cmServer.cxx b/Source/cmServer.cxx
deleted file mode 100644
index 7f97406..0000000
--- a/Source/cmServer.cxx
+++ /dev/null
@@ -1,570 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmServer.h"
-
-#include <algorithm>
-#include <cassert>
-#include <csignal>
-#include <cstdint>
-#include <iostream>
-#include <mutex>
-#include <utility>
-
-#include <cm/memory>
-#include <cm/shared_mutex>
-
-#include <cm3p/json/reader.h>
-#include <cm3p/json/writer.h>
-
-#include "cmsys/FStream.hxx"
-
-#include "cmConnection.h"
-#include "cmFileMonitor.h"
-#include "cmJsonObjectDictionary.h"
-#include "cmServerDictionary.h"
-#include "cmServerProtocol.h"
-#include "cmSystemTools.h"
-#include "cmake.h"
-
-void on_signal(uv_signal_t* signal, int signum)
-{
- auto conn = static_cast<cmServerBase*>(signal->data);
- conn->OnSignal(signum);
-}
-
-static void on_walk_to_shutdown(uv_handle_t* handle, void* arg)
-{
- (void)arg;
- assert(uv_is_closing(handle));
- if (!uv_is_closing(handle)) {
- uv_close(handle, &cmEventBasedConnection::on_close);
- }
-}
-
-class cmServer::DebugInfo
-{
-public:
- DebugInfo()
- : StartTime(uv_hrtime())
- {
- }
-
- bool PrintStatistics = false;
-
- std::string OutputFile;
- uint64_t StartTime;
-};
-
-cmServer::cmServer(cmConnection* conn, bool supportExperimental)
- : cmServerBase(conn)
- , SupportExperimental(supportExperimental)
-{
- // Register supported protocols:
- this->RegisterProtocol(cm::make_unique<cmServerProtocol1>());
-}
-
-cmServer::~cmServer()
-{
- Close();
-}
-
-void cmServer::ProcessRequest(cmConnection* connection,
- const std::string& input)
-{
- Json::Reader reader;
- Json::Value value;
- if (!reader.parse(input, value)) {
- this->WriteParseError(connection, "Failed to parse JSON input.");
- return;
- }
-
- std::unique_ptr<DebugInfo> debug;
- Json::Value debugValue = value["debug"];
- if (!debugValue.isNull()) {
- debug = cm::make_unique<DebugInfo>();
- debug->OutputFile = debugValue["dumpToFile"].asString();
- debug->PrintStatistics = debugValue["showStats"].asBool();
- }
-
- const cmServerRequest request(this, connection, value[kTYPE_KEY].asString(),
- value[kCOOKIE_KEY].asString(), value);
-
- if (request.Type.empty()) {
- cmServerResponse response(request);
- response.SetError("No type given in request.");
- this->WriteResponse(connection, response, nullptr);
- return;
- }
-
- cmSystemTools::SetMessageCallback(
- [&request](const std::string& msg, const char* title) {
- reportMessage(msg, title, request);
- });
-
- if (this->Protocol) {
- this->Protocol->CMakeInstance()->SetProgressCallback(
- [&request](const std::string& msg, float prog) {
- reportProgress(msg, prog, request);
- });
- this->WriteResponse(connection, this->Protocol->Process(request),
- debug.get());
- } else {
- this->WriteResponse(connection, this->SetProtocolVersion(request),
- debug.get());
- }
-}
-
-void cmServer::RegisterProtocol(std::unique_ptr<cmServerProtocol> protocol)
-{
- if (protocol->IsExperimental() && !this->SupportExperimental) {
- protocol.reset();
- return;
- }
- auto version = protocol->ProtocolVersion();
- assert(version.first >= 0);
- assert(version.second >= 0);
- auto it = std::find_if(
- this->SupportedProtocols.begin(), this->SupportedProtocols.end(),
- [version](const std::unique_ptr<cmServerProtocol>& p) {
- return p->ProtocolVersion() == version;
- });
- if (it == this->SupportedProtocols.end()) {
- this->SupportedProtocols.push_back(std::move(protocol));
- }
-}
-
-void cmServer::PrintHello(cmConnection* connection) const
-{
- Json::Value hello = Json::objectValue;
- hello[kTYPE_KEY] = "hello";
-
- Json::Value& protocolVersions = hello[kSUPPORTED_PROTOCOL_VERSIONS] =
- Json::arrayValue;
-
- for (auto const& proto : this->SupportedProtocols) {
- auto version = proto->ProtocolVersion();
- Json::Value tmp = Json::objectValue;
- tmp[kMAJOR_KEY] = version.first;
- tmp[kMINOR_KEY] = version.second;
- if (proto->IsExperimental()) {
- tmp[kIS_EXPERIMENTAL_KEY] = true;
- }
- protocolVersions.append(tmp);
- }
-
- this->WriteJsonObject(connection, hello, nullptr);
-}
-
-void cmServer::reportProgress(const std::string& msg, float progress,
- const cmServerRequest& request)
-{
- if (progress < 0.0f || progress > 1.0f) {
- request.ReportMessage(msg, "");
- } else {
- request.ReportProgress(0, static_cast<int>(progress * 1000), 1000, msg);
- }
-}
-
-void cmServer::reportMessage(const std::string& msg, const char* title,
- const cmServerRequest& request)
-{
- std::string titleString;
- if (title) {
- titleString = title;
- }
- request.ReportMessage(msg, titleString);
-}
-
-cmServerResponse cmServer::SetProtocolVersion(const cmServerRequest& request)
-{
- if (request.Type != kHANDSHAKE_TYPE) {
- return request.ReportError("Waiting for type \"" + kHANDSHAKE_TYPE +
- "\".");
- }
-
- Json::Value requestedProtocolVersion = request.Data[kPROTOCOL_VERSION_KEY];
- if (requestedProtocolVersion.isNull()) {
- return request.ReportError("\"" + kPROTOCOL_VERSION_KEY +
- "\" is required for \"" + kHANDSHAKE_TYPE +
- "\".");
- }
-
- if (!requestedProtocolVersion.isObject()) {
- return request.ReportError("\"" + kPROTOCOL_VERSION_KEY +
- "\" must be a JSON object.");
- }
-
- Json::Value majorValue = requestedProtocolVersion[kMAJOR_KEY];
- if (!majorValue.isInt()) {
- return request.ReportError("\"" + kMAJOR_KEY +
- "\" must be set and an integer.");
- }
-
- Json::Value minorValue = requestedProtocolVersion[kMINOR_KEY];
- if (!minorValue.isNull() && !minorValue.isInt()) {
- return request.ReportError("\"" + kMINOR_KEY +
- "\" must be unset or an integer.");
- }
-
- const int major = majorValue.asInt();
- const int minor = minorValue.isNull() ? -1 : minorValue.asInt();
- if (major < 0) {
- return request.ReportError("\"" + kMAJOR_KEY + "\" must be >= 0.");
- }
- if (!minorValue.isNull() && minor < 0) {
- return request.ReportError("\"" + kMINOR_KEY +
- "\" must be >= 0 when set.");
- }
-
- this->Protocol =
- cmServer::FindMatchingProtocol(this->SupportedProtocols, major, minor);
- if (!this->Protocol) {
- return request.ReportError("Protocol version not supported.");
- }
-
- std::string errorMessage;
- if (!this->Protocol->Activate(this, request, &errorMessage)) {
- this->Protocol = nullptr;
- return request.ReportError("Failed to activate protocol version: " +
- errorMessage);
- }
- return request.Reply(Json::objectValue);
-}
-
-bool cmServer::Serve(std::string* errorMessage)
-{
- if (this->SupportedProtocols.empty()) {
- *errorMessage =
- "No protocol versions defined. Maybe you need --experimental?";
- return false;
- }
- assert(!this->Protocol);
-
- return cmServerBase::Serve(errorMessage);
-}
-
-cmFileMonitor* cmServer::FileMonitor() const
-{
- return fileMonitor.get();
-}
-
-void cmServer::WriteJsonObject(const Json::Value& jsonValue,
- const DebugInfo* debug) const
-{
- cm::shared_lock<cm::shared_mutex> lock(ConnectionsMutex);
- for (auto& connection : this->Connections) {
- WriteJsonObject(connection.get(), jsonValue, debug);
- }
-}
-
-void cmServer::WriteJsonObject(cmConnection* connection,
- const Json::Value& jsonValue,
- const DebugInfo* debug) const
-{
- Json::FastWriter writer;
-
- auto beforeJson = uv_hrtime();
- std::string result = writer.write(jsonValue);
-
- if (debug) {
- Json::Value copy = jsonValue;
- if (debug->PrintStatistics) {
- Json::Value stats = Json::objectValue;
- auto endTime = uv_hrtime();
-
- stats["jsonSerialization"] = double(endTime - beforeJson) / 1000000.0;
- stats["totalTime"] = double(endTime - debug->StartTime) / 1000000.0;
- stats["size"] = static_cast<int>(result.size());
- if (!debug->OutputFile.empty()) {
- stats["dumpFile"] = debug->OutputFile;
- }
-
- copy["zzzDebug"] = stats;
-
- result = writer.write(copy); // Update result to include debug info
- }
-
- if (!debug->OutputFile.empty()) {
- cmsys::ofstream myfile(debug->OutputFile.c_str());
- myfile << result;
- }
- }
-
- connection->WriteData(result);
-}
-
-cmServerProtocol* cmServer::FindMatchingProtocol(
- const std::vector<std::unique_ptr<cmServerProtocol>>& protocols, int major,
- int minor)
-{
- cmServerProtocol* bestMatch = nullptr;
- for (const auto& protocol : protocols) {
- auto version = protocol->ProtocolVersion();
- if (major != version.first) {
- continue;
- }
- if (minor == version.second) {
- return protocol.get();
- }
- if (!bestMatch || bestMatch->ProtocolVersion().second < version.second) {
- bestMatch = protocol.get();
- }
- }
- return minor < 0 ? bestMatch : nullptr;
-}
-
-void cmServer::WriteProgress(const cmServerRequest& request, int min,
- int current, int max,
- const std::string& message) const
-{
- assert(min <= current && current <= max);
- assert(message.length() != 0);
-
- Json::Value obj = Json::objectValue;
- obj[kTYPE_KEY] = kPROGRESS_TYPE;
- obj[kREPLY_TO_KEY] = request.Type;
- obj[kCOOKIE_KEY] = request.Cookie;
- obj[kPROGRESS_MESSAGE_KEY] = message;
- obj[kPROGRESS_MINIMUM_KEY] = min;
- obj[kPROGRESS_MAXIMUM_KEY] = max;
- obj[kPROGRESS_CURRENT_KEY] = current;
-
- this->WriteJsonObject(request.Connection, obj, nullptr);
-}
-
-void cmServer::WriteMessage(const cmServerRequest& request,
- const std::string& message,
- const std::string& title) const
-{
- if (message.empty()) {
- return;
- }
-
- Json::Value obj = Json::objectValue;
- obj[kTYPE_KEY] = kMESSAGE_TYPE;
- obj[kREPLY_TO_KEY] = request.Type;
- obj[kCOOKIE_KEY] = request.Cookie;
- obj[kMESSAGE_KEY] = message;
- if (!title.empty()) {
- obj[kTITLE_KEY] = title;
- }
-
- WriteJsonObject(request.Connection, obj, nullptr);
-}
-
-void cmServer::WriteParseError(cmConnection* connection,
- const std::string& message) const
-{
- Json::Value obj = Json::objectValue;
- obj[kTYPE_KEY] = kERROR_TYPE;
- obj[kERROR_MESSAGE_KEY] = message;
- obj[kREPLY_TO_KEY] = "";
- obj[kCOOKIE_KEY] = "";
-
- this->WriteJsonObject(connection, obj, nullptr);
-}
-
-void cmServer::WriteSignal(const std::string& name,
- const Json::Value& data) const
-{
- assert(data.isObject());
- Json::Value obj = data;
- obj[kTYPE_KEY] = kSIGNAL_TYPE;
- obj[kREPLY_TO_KEY] = "";
- obj[kCOOKIE_KEY] = "";
- obj[kNAME_KEY] = name;
-
- WriteJsonObject(obj, nullptr);
-}
-
-void cmServer::WriteResponse(cmConnection* connection,
- const cmServerResponse& response,
- const DebugInfo* debug) const
-{
- assert(response.IsComplete());
-
- Json::Value obj = response.Data();
- obj[kCOOKIE_KEY] = response.Cookie;
- obj[kTYPE_KEY] = response.IsError() ? kERROR_TYPE : kREPLY_TYPE;
- obj[kREPLY_TO_KEY] = response.Type;
- if (response.IsError()) {
- obj[kERROR_MESSAGE_KEY] = response.ErrorMessage();
- }
-
- this->WriteJsonObject(connection, obj, debug);
-}
-
-void cmServer::OnConnected(cmConnection* connection)
-{
- PrintHello(connection);
-}
-
-void cmServer::OnServeStart()
-{
- cmServerBase::OnServeStart();
- fileMonitor = std::make_shared<cmFileMonitor>(GetLoop());
-}
-
-void cmServer::StartShutDown()
-{
- if (fileMonitor) {
- fileMonitor->StopMonitoring();
- fileMonitor.reset();
- }
- cmServerBase::StartShutDown();
-}
-
-static void __start_thread(void* arg)
-{
- auto server = static_cast<cmServerBase*>(arg);
- std::string error;
- bool success = server->Serve(&error);
- if (!success || !error.empty()) {
- std::cerr << "Error during serve: " << error << std::endl;
- }
-}
-
-bool cmServerBase::StartServeThread()
-{
- ServeThreadRunning = true;
- uv_thread_create(&ServeThread, __start_thread, this);
- return true;
-}
-
-static void __shutdownThread(uv_async_t* arg)
-{
- auto server = static_cast<cmServerBase*>(arg->data);
- server->StartShutDown();
-}
-
-bool cmServerBase::Serve(std::string* errorMessage)
-{
-#ifndef NDEBUG
- uv_thread_t blank_thread_t = {};
- assert(uv_thread_equal(&blank_thread_t, &ServeThreadId));
- ServeThreadId = uv_thread_self();
-#endif
-
- errorMessage->clear();
-
- ShutdownSignal.init(Loop, __shutdownThread, this);
-
- SIGINTHandler.init(Loop, this);
- SIGHUPHandler.init(Loop, this);
-
- SIGINTHandler.start(&on_signal, SIGINT);
- SIGHUPHandler.start(&on_signal, SIGHUP);
-
- OnServeStart();
-
- {
- cm::shared_lock<cm::shared_mutex> lock(ConnectionsMutex);
- for (auto& connection : Connections) {
- if (!connection->OnServeStart(errorMessage)) {
- return false;
- }
- }
- }
-
- if (uv_run(&Loop, UV_RUN_DEFAULT) != 0) {
- // It is important we don't ever let the event loop exit with open handles
- // at best this is a memory leak, but it can also introduce race conditions
- // which can hang the program.
- assert(false && "Event loop stopped in unclean state.");
-
- *errorMessage = "Internal Error: Event loop stopped in unclean state.";
- return false;
- }
-
- return true;
-}
-
-void cmServerBase::OnConnected(cmConnection*)
-{
-}
-
-void cmServerBase::OnServeStart()
-{
-}
-
-void cmServerBase::StartShutDown()
-{
- ShutdownSignal.reset();
- SIGINTHandler.reset();
- SIGHUPHandler.reset();
-
- {
- std::unique_lock<cm::shared_mutex> lock(ConnectionsMutex);
- for (auto& connection : Connections) {
- connection->OnConnectionShuttingDown();
- }
- Connections.clear();
- }
-
- uv_walk(&Loop, on_walk_to_shutdown, nullptr);
-}
-
-bool cmServerBase::OnSignal(int signum)
-{
- (void)signum;
- StartShutDown();
- return true;
-}
-
-cmServerBase::cmServerBase(cmConnection* connection)
-{
- auto err = uv_loop_init(&Loop);
- (void)err;
- Loop.data = this;
- assert(err == 0);
-
- AddNewConnection(connection);
-}
-
-void cmServerBase::Close()
-{
- if (Loop.data) {
- if (ServeThreadRunning) {
- this->ShutdownSignal.send();
- uv_thread_join(&ServeThread);
- }
-
- uv_loop_close(&Loop);
- Loop.data = nullptr;
- }
-}
-cmServerBase::~cmServerBase()
-{
- Close();
-}
-
-void cmServerBase::AddNewConnection(cmConnection* ownedConnection)
-{
- {
- std::unique_lock<cm::shared_mutex> lock(ConnectionsMutex);
- Connections.emplace_back(ownedConnection);
- }
- ownedConnection->SetServer(this);
-}
-
-uv_loop_t* cmServerBase::GetLoop()
-{
- return &Loop;
-}
-
-void cmServerBase::OnDisconnect(cmConnection* pConnection)
-{
- auto pred = [pConnection](const std::unique_ptr<cmConnection>& m) {
- return m.get() == pConnection;
- };
- {
- std::unique_lock<cm::shared_mutex> lock(ConnectionsMutex);
- Connections.erase(
- std::remove_if(Connections.begin(), Connections.end(), pred),
- Connections.end());
- }
-
- if (Connections.empty()) {
- this->ShutdownSignal.send();
- }
-}
diff --git a/Source/cmServer.h b/Source/cmServer.h
deleted file mode 100644
index 9543329..0000000
--- a/Source/cmServer.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#pragma once
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <cm/shared_mutex>
-
-#include <cm3p/json/value.h>
-#include <cm3p/uv.h>
-
-#include "cmUVHandlePtr.h"
-
-class cmConnection;
-class cmFileMonitor;
-class cmServerProtocol;
-class cmServerRequest;
-class cmServerResponse;
-
-/***
- * This essentially hold and manages a libuv event queue and responds to
- * messages
- * on any of its connections.
- */
-class cmServerBase
-{
-public:
- cmServerBase(cmConnection* connection);
- virtual ~cmServerBase();
-
- virtual void AddNewConnection(cmConnection* ownedConnection);
-
- /***
- * The main override responsible for tailoring behavior towards
- * whatever the given server is supposed to do
- *
- * This should almost always be called by the given connections
- * directly.
- *
- * @param connection The connection the request was received on
- * @param request The actual request
- */
- virtual void ProcessRequest(cmConnection* connection,
- const std::string& request) = 0;
- virtual void OnConnected(cmConnection* connection);
-
- /***
- * Start a dedicated thread. If this is used to start the server, it will
- * join on the
- * servers dtor.
- */
- virtual bool StartServeThread();
- virtual bool Serve(std::string* errorMessage);
-
- virtual void OnServeStart();
- virtual void StartShutDown();
-
- virtual bool OnSignal(int signum);
- uv_loop_t* GetLoop();
- void Close();
- void OnDisconnect(cmConnection* pConnection);
-
-protected:
- mutable cm::shared_mutex ConnectionsMutex;
- std::vector<std::unique_ptr<cmConnection>> Connections;
-
- bool ServeThreadRunning = false;
- uv_thread_t ServeThread;
- cm::uv_async_ptr ShutdownSignal;
-#ifndef NDEBUG
-public:
- // When the server starts it will mark down it's current thread ID,
- // which is useful in other contexts to just assert that operations
- // are performed on that same thread.
- uv_thread_t ServeThreadId = {};
-
-protected:
-#endif
-
- uv_loop_t Loop;
-
- cm::uv_signal_ptr SIGINTHandler;
- cm::uv_signal_ptr SIGHUPHandler;
-};
-
-class cmServer : public cmServerBase
-{
-public:
- class DebugInfo;
-
- cmServer(cmConnection* conn, bool supportExperimental);
- ~cmServer() override;
-
- cmServer(cmServer const&) = delete;
- cmServer& operator=(cmServer const&) = delete;
-
- bool Serve(std::string* errorMessage) override;
-
- cmFileMonitor* FileMonitor() const;
-
-private:
- void RegisterProtocol(std::unique_ptr<cmServerProtocol> protocol);
-
- // Callbacks from cmServerConnection:
-
- void ProcessRequest(cmConnection* connection,
- const std::string& request) override;
- std::shared_ptr<cmFileMonitor> fileMonitor;
-
-public:
- void OnServeStart() override;
-
- void StartShutDown() override;
-
-public:
- void OnConnected(cmConnection* connection) override;
-
-private:
- static void reportProgress(const std::string& msg, float progress,
- const cmServerRequest& request);
- static void reportMessage(const std::string& msg, const char* title,
- const cmServerRequest& request);
-
- // Handle requests:
- cmServerResponse SetProtocolVersion(const cmServerRequest& request);
-
- void PrintHello(cmConnection* connection) const;
-
- // Write responses:
- void WriteProgress(const cmServerRequest& request, int min, int current,
- int max, const std::string& message) const;
- void WriteMessage(const cmServerRequest& request, const std::string& message,
- const std::string& title) const;
- void WriteResponse(cmConnection* connection,
- const cmServerResponse& response,
- const DebugInfo* debug) const;
- void WriteParseError(cmConnection* connection,
- const std::string& message) const;
- void WriteSignal(const std::string& name, const Json::Value& obj) const;
-
- void WriteJsonObject(Json::Value const& jsonValue,
- const DebugInfo* debug) const;
-
- void WriteJsonObject(cmConnection* connection, Json::Value const& jsonValue,
- const DebugInfo* debug) const;
-
- static cmServerProtocol* FindMatchingProtocol(
- const std::vector<std::unique_ptr<cmServerProtocol>>& protocols, int major,
- int minor);
-
- const bool SupportExperimental;
-
- cmServerProtocol* Protocol = nullptr;
- std::vector<std::unique_ptr<cmServerProtocol>> SupportedProtocols;
-
- friend class cmServerProtocol;
- friend class cmServerRequest;
-};
diff --git a/Source/cmServerConnection.cxx b/Source/cmServerConnection.cxx
deleted file mode 100644
index b4f41a0..0000000
--- a/Source/cmServerConnection.cxx
+++ /dev/null
@@ -1,165 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmConfigure.h"
-
-#include "cmServerConnection.h"
-
-#include <cm3p/uv.h>
-
-#include "cmServer.h"
-#include "cmServerDictionary.h"
-
-#ifdef _WIN32
-# include "io.h"
-#else
-# include <unistd.h>
-#endif
-#include <cassert>
-#include <utility>
-
-cmStdIoConnection::cmStdIoConnection(
- cmConnectionBufferStrategy* bufferStrategy)
- : cmEventBasedConnection(bufferStrategy)
-{
-}
-
-cm::uv_stream_ptr cmStdIoConnection::SetupStream(int file_id)
-{
- switch (uv_guess_handle(file_id)) {
- case UV_TTY: {
- cm::uv_tty_ptr tty;
- tty.init(*this->Server->GetLoop(), file_id, file_id == 0,
- static_cast<cmEventBasedConnection*>(this));
- uv_tty_set_mode(tty, UV_TTY_MODE_NORMAL);
- return { std::move(tty) };
- }
- case UV_FILE:
- if (file_id == 0) {
- return nullptr;
- }
- // Intentional fallthrough; stdin can _not_ be treated as a named
- // pipe, however stdout can be.
- CM_FALLTHROUGH;
- case UV_NAMED_PIPE: {
- cm::uv_pipe_ptr pipe;
- pipe.init(*this->Server->GetLoop(), 0,
- static_cast<cmEventBasedConnection*>(this));
- uv_pipe_open(pipe, file_id);
- return { std::move(pipe) };
- }
- default:
- assert(false && "Unable to determine stream type");
- return nullptr;
- }
-}
-
-void cmStdIoConnection::SetServer(cmServerBase* s)
-{
- cmConnection::SetServer(s);
- if (!s) {
- return;
- }
-
- this->ReadStream = SetupStream(0);
- this->WriteStream = SetupStream(1);
-}
-
-void shutdown_connection(uv_prepare_t* prepare)
-{
- cmStdIoConnection* connection =
- static_cast<cmStdIoConnection*>(prepare->data);
-
- if (!uv_is_closing(reinterpret_cast<uv_handle_t*>(prepare))) {
- uv_close(reinterpret_cast<uv_handle_t*>(prepare),
- &cmEventBasedConnection::on_close_delete<uv_prepare_t>);
- }
- connection->OnDisconnect(0);
-}
-
-bool cmStdIoConnection::OnServeStart(std::string* pString)
-{
- Server->OnConnected(this);
- if (this->ReadStream.get()) {
- uv_read_start(this->ReadStream, on_alloc_buffer, on_read);
- } else if (uv_guess_handle(0) == UV_FILE) {
- char buffer[1024];
- while (auto len = read(0, buffer, sizeof(buffer))) {
- ReadData(std::string(buffer, buffer + len));
- }
-
- // We can't start the disconnect from here, add a prepare hook to do that
- // for us
- auto prepare = new uv_prepare_t();
- prepare->data = this;
- uv_prepare_init(Server->GetLoop(), prepare);
- uv_prepare_start(prepare, shutdown_connection);
- }
- return cmConnection::OnServeStart(pString);
-}
-
-bool cmStdIoConnection::OnConnectionShuttingDown()
-{
- if (ReadStream.get()) {
- uv_read_stop(ReadStream);
- ReadStream->data = nullptr;
- }
-
- this->ReadStream.reset();
-
- cmEventBasedConnection::OnConnectionShuttingDown();
-
- return true;
-}
-
-cmServerPipeConnection::cmServerPipeConnection(const std::string& name)
- : cmPipeConnection(name, new cmServerBufferStrategy)
-{
-}
-
-cmServerStdIoConnection::cmServerStdIoConnection()
- : cmStdIoConnection(new cmServerBufferStrategy)
-{
-}
-
-cmConnectionBufferStrategy::~cmConnectionBufferStrategy() = default;
-
-void cmConnectionBufferStrategy::clear()
-{
-}
-
-std::string cmServerBufferStrategy::BufferOutMessage(
- const std::string& rawBuffer) const
-{
- return std::string("\n") + kSTART_MAGIC + std::string("\n") + rawBuffer +
- kEND_MAGIC + std::string("\n");
-}
-
-std::string cmServerBufferStrategy::BufferMessage(std::string& RawReadBuffer)
-{
- for (;;) {
- auto needle = RawReadBuffer.find('\n');
-
- if (needle == std::string::npos) {
- return "";
- }
- std::string line = RawReadBuffer.substr(0, needle);
- const auto ls = line.size();
- if (ls > 1 && line.at(ls - 1) == '\r') {
- line.erase(ls - 1, 1);
- }
- RawReadBuffer.erase(RawReadBuffer.begin(),
- RawReadBuffer.begin() + static_cast<long>(needle) + 1);
- if (line == kSTART_MAGIC) {
- RequestBuffer.clear();
- continue;
- }
- if (line == kEND_MAGIC) {
- std::string rtn;
- rtn.swap(this->RequestBuffer);
- return rtn;
- }
-
- this->RequestBuffer += line;
- this->RequestBuffer += "\n";
- }
-}
diff --git a/Source/cmServerConnection.h b/Source/cmServerConnection.h
deleted file mode 100644
index a70edb4..0000000
--- a/Source/cmServerConnection.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#pragma once
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <string>
-
-#include "cmConnection.h"
-#include "cmPipeConnection.h"
-#include "cmUVHandlePtr.h"
-
-class cmServerBase;
-
-/***
- * This connection buffer strategy accepts messages in the form of
- * [== "CMake Server" ==[
-{
- ... some JSON message ...
-}
-]== "CMake Server" ==]
- * and only passes on the core json; it discards the envelope.
- */
-class cmServerBufferStrategy : public cmConnectionBufferStrategy
-{
-public:
- std::string BufferMessage(std::string& rawBuffer) override;
- std::string BufferOutMessage(const std::string& rawBuffer) const override;
-
-private:
- std::string RequestBuffer;
-};
-
-/***
- * Generic connection over std io interfaces -- tty
- */
-class cmStdIoConnection : public cmEventBasedConnection
-{
-public:
- cmStdIoConnection(cmConnectionBufferStrategy* bufferStrategy);
-
- void SetServer(cmServerBase* s) override;
-
- bool OnConnectionShuttingDown() override;
-
- bool OnServeStart(std::string* pString) override;
-
-private:
- cm::uv_stream_ptr SetupStream(int file_id);
- cm::uv_stream_ptr ReadStream;
-};
-
-/***
- * These specific connections use the cmake server
- * buffering strategy.
- */
-class cmServerStdIoConnection : public cmStdIoConnection
-{
-public:
- cmServerStdIoConnection();
-};
-
-class cmServerPipeConnection : public cmPipeConnection
-{
-public:
- cmServerPipeConnection(const std::string& name);
-};
diff --git a/Source/cmServerDictionary.h b/Source/cmServerDictionary.h
deleted file mode 100644
index 961e4b7..0000000
--- a/Source/cmServerDictionary.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#pragma once
-
-#include <string>
-
-// Vocabulary:
-
-static const std::string kDIRTY_SIGNAL = "dirty";
-static const std::string kFILE_CHANGE_SIGNAL = "fileChange";
-
-static const std::string kCACHE_TYPE = "cache";
-static const std::string kCMAKE_INPUTS_TYPE = "cmakeInputs";
-static const std::string kCODE_MODEL_TYPE = "codemodel";
-static const std::string kCOMPUTE_TYPE = "compute";
-static const std::string kCONFIGURE_TYPE = "configure";
-static const std::string kERROR_TYPE = "error";
-static const std::string kFILESYSTEM_WATCHERS_TYPE = "fileSystemWatchers";
-static const std::string kGLOBAL_SETTINGS_TYPE = "globalSettings";
-static const std::string kHANDSHAKE_TYPE = "handshake";
-static const std::string kMESSAGE_TYPE = "message";
-static const std::string kPROGRESS_TYPE = "progress";
-static const std::string kREPLY_TYPE = "reply";
-static const std::string kSET_GLOBAL_SETTINGS_TYPE = "setGlobalSettings";
-static const std::string kSIGNAL_TYPE = "signal";
-static const std::string kCTEST_INFO_TYPE = "ctestInfo";
-
-static const std::string kBUILD_FILES_KEY = "buildFiles";
-static const std::string kCACHE_ARGUMENTS_KEY = "cacheArguments";
-static const std::string kCACHE_KEY = "cache";
-static const std::string kCAPABILITIES_KEY = "capabilities";
-static const std::string kCHECK_SYSTEM_VARS_KEY = "checkSystemVars";
-static const std::string kCMAKE_ROOT_DIRECTORY_KEY = "cmakeRootDirectory";
-static const std::string kCOOKIE_KEY = "cookie";
-static const std::string kDEBUG_OUTPUT_KEY = "debugOutput";
-static const std::string kERROR_MESSAGE_KEY = "errorMessage";
-static const std::string kEXTRA_GENERATOR_KEY = "extraGenerator";
-static const std::string kGENERATOR_KEY = "generator";
-static const std::string kIS_EXPERIMENTAL_KEY = "isExperimental";
-static const std::string kKEYS_KEY = "keys";
-static const std::string kMAJOR_KEY = "major";
-static const std::string kMESSAGE_KEY = "message";
-static const std::string kMINOR_KEY = "minor";
-static const std::string kPLATFORM_KEY = "platform";
-static const std::string kPROGRESS_CURRENT_KEY = "progressCurrent";
-static const std::string kPROGRESS_MAXIMUM_KEY = "progressMaximum";
-static const std::string kPROGRESS_MESSAGE_KEY = "progressMessage";
-static const std::string kPROGRESS_MINIMUM_KEY = "progressMinimum";
-static const std::string kPROTOCOL_VERSION_KEY = "protocolVersion";
-static const std::string kREPLY_TO_KEY = "inReplyTo";
-static const std::string kSUPPORTED_PROTOCOL_VERSIONS =
- "supportedProtocolVersions";
-static const std::string kTITLE_KEY = "title";
-static const std::string kTOOLSET_KEY = "toolset";
-static const std::string kTRACE_EXPAND_KEY = "traceExpand";
-static const std::string kTRACE_KEY = "trace";
-static const std::string kWARN_UNINITIALIZED_KEY = "warnUninitialized";
-static const std::string kWARN_UNUSED_CLI_KEY = "warnUnusedCli";
-static const std::string kWARN_UNUSED_KEY = "warnUnused";
-static const std::string kWATCHED_DIRECTORIES_KEY = "watchedDirectories";
-static const std::string kWATCHED_FILES_KEY = "watchedFiles";
-
-static const std::string kSTART_MAGIC = "[== \"CMake Server\" ==[";
-static const std::string kEND_MAGIC = "]== \"CMake Server\" ==]";
-
-static const std::string kRENAME_PROPERTY_VALUE = "rename";
-static const std::string kCHANGE_PROPERTY_VALUE = "change";
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
deleted file mode 100644
index e586fd9..0000000
--- a/Source/cmServerProtocol.cxx
+++ /dev/null
@@ -1,760 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmServerProtocol.h"
-
-#include <algorithm>
-#include <cassert>
-#include <functional>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include <cm/memory>
-#include <cmext/algorithm>
-
-#include <cm3p/uv.h>
-
-#include "cmExternalMakefileProjectGenerator.h"
-#include "cmFileMonitor.h"
-#include "cmGlobalGenerator.h"
-#include "cmJsonObjectDictionary.h"
-#include "cmJsonObjects.h"
-#include "cmMessageType.h"
-#include "cmProperty.h"
-#include "cmServer.h"
-#include "cmServerDictionary.h"
-#include "cmState.h"
-#include "cmSystemTools.h"
-#include "cmake.h"
-
-// Get rid of some windows macros:
-#undef max
-
-namespace {
-
-std::vector<std::string> toStringList(const Json::Value& in)
-{
- std::vector<std::string> result;
- for (auto const& it : in) {
- result.push_back(it.asString());
- }
- return result;
-}
-
-} // namespace
-
-cmServerRequest::cmServerRequest(cmServer* server, cmConnection* connection,
- std::string t, std::string c, Json::Value d)
- : Type(std::move(t))
- , Cookie(std::move(c))
- , Data(std::move(d))
- , Connection(connection)
- , m_Server(server)
-{
-}
-
-void cmServerRequest::ReportProgress(int min, int current, int max,
- const std::string& message) const
-{
- this->m_Server->WriteProgress(*this, min, current, max, message);
-}
-
-void cmServerRequest::ReportMessage(const std::string& message,
- const std::string& title) const
-{
- m_Server->WriteMessage(*this, message, title);
-}
-
-cmServerResponse cmServerRequest::Reply(const Json::Value& data) const
-{
- cmServerResponse response(*this);
- response.SetData(data);
- return response;
-}
-
-cmServerResponse cmServerRequest::ReportError(const std::string& message) const
-{
- cmServerResponse response(*this);
- response.SetError(message);
- return response;
-}
-
-cmServerResponse::cmServerResponse(const cmServerRequest& request)
- : Type(request.Type)
- , Cookie(request.Cookie)
-{
-}
-
-void cmServerResponse::SetData(const Json::Value& data)
-{
- assert(this->m_Payload == PAYLOAD_UNKNOWN);
- if (!data[kCOOKIE_KEY].isNull() || !data[kTYPE_KEY].isNull()) {
- this->SetError("Response contains cookie or type field.");
- return;
- }
- this->m_Payload = PAYLOAD_DATA;
- this->m_Data = data;
-}
-
-void cmServerResponse::SetError(const std::string& message)
-{
- assert(this->m_Payload == PAYLOAD_UNKNOWN);
- this->m_Payload = PAYLOAD_ERROR;
- this->m_ErrorMessage = message;
-}
-
-bool cmServerResponse::IsComplete() const
-{
- return this->m_Payload != PAYLOAD_UNKNOWN;
-}
-
-bool cmServerResponse::IsError() const
-{
- assert(this->m_Payload != PAYLOAD_UNKNOWN);
- return this->m_Payload == PAYLOAD_ERROR;
-}
-
-std::string cmServerResponse::ErrorMessage() const
-{
- if (this->m_Payload == PAYLOAD_ERROR) {
- return this->m_ErrorMessage;
- }
- return std::string();
-}
-
-Json::Value cmServerResponse::Data() const
-{
- assert(this->m_Payload != PAYLOAD_UNKNOWN);
- return this->m_Data;
-}
-
-bool cmServerProtocol::Activate(cmServer* server,
- const cmServerRequest& request,
- std::string* errorMessage)
-{
- assert(server);
- this->m_Server = server;
- this->m_CMakeInstance =
- cm::make_unique<cmake>(cmake::RoleProject, cmState::Project);
- this->m_WarnUnused = false;
- const bool result = this->DoActivate(request, errorMessage);
- if (!result) {
- this->m_CMakeInstance = nullptr;
- }
- return result;
-}
-
-cmFileMonitor* cmServerProtocol::FileMonitor() const
-{
- return this->m_Server ? this->m_Server->FileMonitor() : nullptr;
-}
-
-void cmServerProtocol::SendSignal(const std::string& name,
- const Json::Value& data) const
-{
- if (this->m_Server) {
- this->m_Server->WriteSignal(name, data);
- }
-}
-
-cmake* cmServerProtocol::CMakeInstance() const
-{
- return this->m_CMakeInstance.get();
-}
-
-bool cmServerProtocol::DoActivate(const cmServerRequest& /*request*/,
- std::string* /*errorMessage*/)
-{
- return true;
-}
-
-std::pair<int, int> cmServerProtocol1::ProtocolVersion() const
-{
- return { 1, 2 };
-}
-
-static void setErrorMessage(std::string* errorMessage, const std::string& text)
-{
- if (errorMessage) {
- *errorMessage = text;
- }
-}
-
-static bool getOrTestHomeDirectory(cmState* state, std::string& value,
- std::string* errorMessage)
-{
- const std::string cachedValue =
- *state->GetCacheEntryValue("CMAKE_HOME_DIRECTORY");
- if (value.empty()) {
- value = cachedValue;
- return true;
- }
- const std::string suffix = "/CMakeLists.txt";
- const std::string cachedValueCML = cachedValue + suffix;
- const std::string valueCML = value + suffix;
- if (!cmSystemTools::SameFile(valueCML, cachedValueCML)) {
- setErrorMessage(errorMessage,
- std::string("\"CMAKE_HOME_DIRECTORY\" is set but "
- "incompatible with configured "
- "source directory value."));
- return false;
- }
- return true;
-}
-
-static bool getOrTestValue(cmState* state, const std::string& key,
- std::string& value,
- const std::string& keyDescription,
- std::string* errorMessage)
-{
- const std::string cachedValue = state->GetSafeCacheEntryValue(key);
- if (value.empty()) {
- value = cachedValue;
- }
- if (!cachedValue.empty() && cachedValue != value) {
- setErrorMessage(errorMessage,
- std::string("\"") + key +
- "\" is set but incompatible with configured " +
- keyDescription + " value.");
- return false;
- }
- return true;
-}
-
-bool cmServerProtocol1::DoActivate(const cmServerRequest& request,
- std::string* errorMessage)
-{
- std::string sourceDirectory = request.Data[kSOURCE_DIRECTORY_KEY].asString();
- std::string buildDirectory = request.Data[kBUILD_DIRECTORY_KEY].asString();
- std::string generator = request.Data[kGENERATOR_KEY].asString();
- std::string extraGenerator = request.Data[kEXTRA_GENERATOR_KEY].asString();
- std::string toolset = request.Data[kTOOLSET_KEY].asString();
- std::string platform = request.Data[kPLATFORM_KEY].asString();
-
- // normalize source and build directory
- if (!sourceDirectory.empty()) {
- sourceDirectory = cmSystemTools::CollapseFullPath(sourceDirectory);
- cmSystemTools::ConvertToUnixSlashes(sourceDirectory);
- }
- if (!buildDirectory.empty()) {
- buildDirectory = cmSystemTools::CollapseFullPath(buildDirectory);
- cmSystemTools::ConvertToUnixSlashes(buildDirectory);
- }
-
- if (buildDirectory.empty()) {
- setErrorMessage(errorMessage,
- std::string("\"") + kBUILD_DIRECTORY_KEY +
- "\" is missing.");
- return false;
- }
-
- cmake* cm = CMakeInstance();
- if (cmSystemTools::PathExists(buildDirectory)) {
- if (!cmSystemTools::FileIsDirectory(buildDirectory)) {
- setErrorMessage(errorMessage,
- std::string("\"") + kBUILD_DIRECTORY_KEY +
- "\" exists but is not a directory.");
- return false;
- }
-
- const std::string cachePath = cmake::FindCacheFile(buildDirectory);
- if (cm->LoadCache(cachePath)) {
- cmState* state = cm->GetState();
-
- // Check generator:
- if (!getOrTestValue(state, "CMAKE_GENERATOR", generator, "generator",
- errorMessage)) {
- return false;
- }
-
- // check extra generator:
- if (!getOrTestValue(state, "CMAKE_EXTRA_GENERATOR", extraGenerator,
- "extra generator", errorMessage)) {
- return false;
- }
-
- // check sourcedir:
- if (!getOrTestHomeDirectory(state, sourceDirectory, errorMessage)) {
- return false;
- }
-
- // check toolset:
- if (!getOrTestValue(state, "CMAKE_GENERATOR_TOOLSET", toolset, "toolset",
- errorMessage)) {
- return false;
- }
-
- // check platform:
- if (!getOrTestValue(state, "CMAKE_GENERATOR_PLATFORM", platform,
- "platform", errorMessage)) {
- return false;
- }
- }
- }
-
- if (sourceDirectory.empty()) {
- setErrorMessage(errorMessage,
- std::string("\"") + kSOURCE_DIRECTORY_KEY +
- "\" is unset but required.");
- return false;
- }
- if (!cmSystemTools::FileIsDirectory(sourceDirectory)) {
- setErrorMessage(errorMessage,
- std::string("\"") + kSOURCE_DIRECTORY_KEY +
- "\" is not a directory.");
- return false;
- }
- if (generator.empty()) {
- setErrorMessage(errorMessage,
- std::string("\"") + kGENERATOR_KEY +
- "\" is unset but required.");
- return false;
- }
-
- std::vector<cmake::GeneratorInfo> generators;
- cm->GetRegisteredGenerators(generators);
- auto baseIt = std::find_if(generators.begin(), generators.end(),
- [&generator](const cmake::GeneratorInfo& info) {
- return info.name == generator;
- });
- if (baseIt == generators.end()) {
- setErrorMessage(errorMessage,
- std::string("Generator \"") + generator +
- "\" not supported.");
- return false;
- }
- auto extraIt = std::find_if(
- generators.begin(), generators.end(),
- [&generator, &extraGenerator](const cmake::GeneratorInfo& info) {
- return info.baseName == generator && info.extraName == extraGenerator;
- });
- if (extraIt == generators.end()) {
- setErrorMessage(errorMessage,
- std::string("The combination of generator \"" + generator +
- "\" and extra generator \"" + extraGenerator +
- "\" is not supported."));
- return false;
- }
- if (!extraIt->supportsToolset && !toolset.empty()) {
- setErrorMessage(errorMessage,
- std::string("Toolset was provided but is not supported by "
- "the requested generator."));
- return false;
- }
- if (!extraIt->supportsPlatform && !platform.empty()) {
- setErrorMessage(errorMessage,
- std::string("Platform was provided but is not supported "
- "by the requested generator."));
- return false;
- }
-
- this->GeneratorInfo =
- GeneratorInformation(generator, extraGenerator, toolset, platform,
- sourceDirectory, buildDirectory);
-
- this->m_State = STATE_ACTIVE;
- return true;
-}
-
-void cmServerProtocol1::HandleCMakeFileChanges(const std::string& path,
- int event, int status)
-{
- assert(status == 0);
- static_cast<void>(status);
-
- if (!m_isDirty) {
- m_isDirty = true;
- SendSignal(kDIRTY_SIGNAL, Json::objectValue);
- }
- Json::Value obj = Json::objectValue;
- obj[kPATH_KEY] = path;
- Json::Value properties = Json::arrayValue;
- if (event & UV_RENAME) {
- properties.append(kRENAME_PROPERTY_VALUE);
- }
- if (event & UV_CHANGE) {
- properties.append(kCHANGE_PROPERTY_VALUE);
- }
-
- obj[kPROPERTIES_KEY] = properties;
- SendSignal(kFILE_CHANGE_SIGNAL, obj);
-}
-
-cmServerResponse cmServerProtocol1::Process(const cmServerRequest& request)
-{
- assert(this->m_State >= STATE_ACTIVE);
-
- if (request.Type == kCACHE_TYPE) {
- return this->ProcessCache(request);
- }
- if (request.Type == kCMAKE_INPUTS_TYPE) {
- return this->ProcessCMakeInputs(request);
- }
- if (request.Type == kCODE_MODEL_TYPE) {
- return this->ProcessCodeModel(request);
- }
- if (request.Type == kCOMPUTE_TYPE) {
- return this->ProcessCompute(request);
- }
- if (request.Type == kCONFIGURE_TYPE) {
- return this->ProcessConfigure(request);
- }
- if (request.Type == kFILESYSTEM_WATCHERS_TYPE) {
- return this->ProcessFileSystemWatchers(request);
- }
- if (request.Type == kGLOBAL_SETTINGS_TYPE) {
- return this->ProcessGlobalSettings(request);
- }
- if (request.Type == kSET_GLOBAL_SETTINGS_TYPE) {
- return this->ProcessSetGlobalSettings(request);
- }
- if (request.Type == kCTEST_INFO_TYPE) {
- return this->ProcessCTests(request);
- }
-
- return request.ReportError("Unknown command!");
-}
-
-bool cmServerProtocol1::IsExperimental() const
-{
- return true;
-}
-
-cmServerResponse cmServerProtocol1::ProcessCache(
- const cmServerRequest& request)
-{
- cmState* state = this->CMakeInstance()->GetState();
-
- Json::Value result = Json::objectValue;
-
- std::vector<std::string> allKeys = state->GetCacheEntryKeys();
-
- Json::Value list = Json::arrayValue;
- std::vector<std::string> keys = toStringList(request.Data[kKEYS_KEY]);
- if (keys.empty()) {
- keys = allKeys;
- } else {
- for (auto const& i : keys) {
- if (!cm::contains(allKeys, i)) {
- return request.ReportError("Key \"" + i + "\" not found in cache.");
- }
- }
- }
- std::sort(keys.begin(), keys.end());
- for (auto const& key : keys) {
- Json::Value entry = Json::objectValue;
- entry[kKEY_KEY] = key;
- entry[kTYPE_KEY] =
- cmState::CacheEntryTypeToString(state->GetCacheEntryType(key));
- entry[kVALUE_KEY] = *state->GetCacheEntryValue(key);
-
- Json::Value props = Json::objectValue;
- bool haveProperties = false;
- for (auto const& prop : state->GetCacheEntryPropertyList(key)) {
- haveProperties = true;
- props[prop] = *state->GetCacheEntryProperty(key, prop);
- }
- if (haveProperties) {
- entry[kPROPERTIES_KEY] = props;
- }
-
- list.append(entry);
- }
-
- result[kCACHE_KEY] = list;
- return request.Reply(result);
-}
-
-cmServerResponse cmServerProtocol1::ProcessCMakeInputs(
- const cmServerRequest& request)
-{
- if (this->m_State < STATE_CONFIGURED) {
- return request.ReportError("This instance was not yet configured.");
- }
-
- const cmake* cm = this->CMakeInstance();
- const std::string cmakeRootDir = cmSystemTools::GetCMakeRoot();
- const std::string& sourceDir = cm->GetHomeDirectory();
-
- Json::Value result = Json::objectValue;
- result[kSOURCE_DIRECTORY_KEY] = sourceDir;
- result[kCMAKE_ROOT_DIRECTORY_KEY] = cmakeRootDir;
- result[kBUILD_FILES_KEY] = cmDumpCMakeInputs(cm);
- return request.Reply(result);
-}
-
-cmServerResponse cmServerProtocol1::ProcessCodeModel(
- const cmServerRequest& request)
-{
- if (this->m_State != STATE_COMPUTED) {
- return request.ReportError("No build system was generated yet.");
- }
-
- return request.Reply(cmDumpCodeModel(this->CMakeInstance()));
-}
-
-cmServerResponse cmServerProtocol1::ProcessCompute(
- const cmServerRequest& request)
-{
- if (this->m_State > STATE_CONFIGURED) {
- return request.ReportError("This build system was already generated.");
- }
- if (this->m_State < STATE_CONFIGURED) {
- return request.ReportError("This project was not configured yet.");
- }
-
- cmake* cm = this->CMakeInstance();
- int ret = cm->Generate();
-
- if (ret < 0) {
- return request.ReportError("Failed to compute build system.");
- }
- m_State = STATE_COMPUTED;
- return request.Reply(Json::Value());
-}
-
-cmServerResponse cmServerProtocol1::ProcessConfigure(
- const cmServerRequest& request)
-{
- if (this->m_State == STATE_INACTIVE) {
- return request.ReportError("This instance is inactive.");
- }
-
- FileMonitor()->StopMonitoring();
-
- std::string errorMessage;
- cmake* cm = this->CMakeInstance();
- this->GeneratorInfo.SetupGenerator(cm, &errorMessage);
- if (!errorMessage.empty()) {
- return request.ReportError(errorMessage);
- }
-
- // Make sure the types of cacheArguments matches (if given):
- std::vector<std::string> cacheArgs = { "unused" };
- bool cacheArgumentsError = false;
- const Json::Value passedArgs = request.Data[kCACHE_ARGUMENTS_KEY];
- if (!passedArgs.isNull()) {
- if (passedArgs.isString()) {
- cacheArgs.push_back(passedArgs.asString());
- } else if (passedArgs.isArray()) {
- for (auto const& arg : passedArgs) {
- if (!arg.isString()) {
- cacheArgumentsError = true;
- break;
- }
- cacheArgs.push_back(arg.asString());
- }
- } else {
- cacheArgumentsError = true;
- }
- }
- if (cacheArgumentsError) {
- request.ReportError(
- "cacheArguments must be unset, a string or an array of strings.");
- }
-
- std::string sourceDir = cm->GetHomeDirectory();
- const std::string buildDir = cm->GetHomeOutputDirectory();
-
- cmGlobalGenerator* gg = cm->GetGlobalGenerator();
-
- if (buildDir.empty()) {
- return request.ReportError("No build directory set via Handshake.");
- }
-
- if (cm->LoadCache(buildDir)) {
- // build directory has been set up before
- cmProp cachedSourceDir =
- cm->GetState()->GetInitializedCacheValue("CMAKE_HOME_DIRECTORY");
- if (!cachedSourceDir) {
- return request.ReportError("No CMAKE_HOME_DIRECTORY found in cache.");
- }
- if (sourceDir.empty()) {
- sourceDir = *cachedSourceDir;
- cm->SetHomeDirectory(sourceDir);
- }
-
- cmProp cachedGenerator =
- cm->GetState()->GetInitializedCacheValue("CMAKE_GENERATOR");
- if (cachedGenerator) {
- if (gg && gg->GetName() != *cachedGenerator) {
- return request.ReportError("Configured generator does not match with "
- "CMAKE_GENERATOR found in cache.");
- }
- }
- } else {
- // build directory has not been set up before
- if (sourceDir.empty()) {
- return request.ReportError("No sourceDirectory set via "
- "setGlobalSettings and no cache found in "
- "buildDirectory.");
- }
- }
-
- cmSystemTools::ResetErrorOccuredFlag(); // Reset error state
-
- if (cm->AddCMakePaths() != 1) {
- return request.ReportError("Failed to set CMake paths.");
- }
-
- if (!cm->SetCacheArgs(cacheArgs)) {
- return request.ReportError("cacheArguments could not be set.");
- }
-
- int ret = cm->Configure();
- cm->IssueMessage(
- MessageType::DEPRECATION_WARNING,
- "The 'cmake-server(7)' is deprecated. "
- "Please port clients to use the 'cmake-file-api(7)' instead.");
- if (ret < 0) {
- return request.ReportError("Configuration failed.");
- }
-
- std::vector<std::string> toWatchList;
- cmGetCMakeInputs(gg, std::string(), buildDir, nullptr, &toWatchList,
- nullptr);
-
- FileMonitor()->MonitorPaths(toWatchList,
- [this](const std::string& p, int e, int s) {
- this->HandleCMakeFileChanges(p, e, s);
- });
-
- m_State = STATE_CONFIGURED;
- m_isDirty = false;
- return request.Reply(Json::Value());
-}
-
-cmServerResponse cmServerProtocol1::ProcessGlobalSettings(
- const cmServerRequest& request)
-{
- cmake* cm = this->CMakeInstance();
- Json::Value obj = Json::objectValue;
-
- // Capabilities information:
- obj[kCAPABILITIES_KEY] = cm->ReportCapabilitiesJson();
-
- obj[kDEBUG_OUTPUT_KEY] = cm->GetDebugOutput();
- obj[kTRACE_KEY] = cm->GetTrace();
- obj[kTRACE_EXPAND_KEY] = cm->GetTraceExpand();
- obj[kWARN_UNINITIALIZED_KEY] = cm->GetWarnUninitialized();
- obj[kWARN_UNUSED_KEY] = m_WarnUnused;
- obj[kWARN_UNUSED_CLI_KEY] = cm->GetWarnUnusedCli();
- obj[kCHECK_SYSTEM_VARS_KEY] = cm->GetCheckSystemVars();
-
- obj[kSOURCE_DIRECTORY_KEY] = this->GeneratorInfo.SourceDirectory;
- obj[kBUILD_DIRECTORY_KEY] = this->GeneratorInfo.BuildDirectory;
-
- // Currently used generator:
- obj[kGENERATOR_KEY] = this->GeneratorInfo.GeneratorName;
- obj[kEXTRA_GENERATOR_KEY] = this->GeneratorInfo.ExtraGeneratorName;
-
- return request.Reply(obj);
-}
-
-static void setBool(const cmServerRequest& request, const std::string& key,
- std::function<void(bool)> const& setter)
-{
- if (request.Data[key].isNull()) {
- return;
- }
- setter(request.Data[key].asBool());
-}
-
-cmServerResponse cmServerProtocol1::ProcessSetGlobalSettings(
- const cmServerRequest& request)
-{
- const std::vector<std::string> boolValues = {
- kDEBUG_OUTPUT_KEY, kTRACE_KEY, kTRACE_EXPAND_KEY,
- kWARN_UNINITIALIZED_KEY, kWARN_UNUSED_KEY, kWARN_UNUSED_CLI_KEY,
- kCHECK_SYSTEM_VARS_KEY
- };
- for (std::string const& i : boolValues) {
- if (!request.Data[i].isNull() && !request.Data[i].isBool()) {
- return request.ReportError("\"" + i +
- "\" must be unset or a bool value.");
- }
- }
-
- cmake* cm = this->CMakeInstance();
-
- setBool(request, kDEBUG_OUTPUT_KEY,
- [cm](bool e) { cm->SetDebugOutputOn(e); });
- setBool(request, kTRACE_KEY, [cm](bool e) { cm->SetTrace(e); });
- setBool(request, kTRACE_EXPAND_KEY, [cm](bool e) { cm->SetTraceExpand(e); });
- setBool(request, kWARN_UNINITIALIZED_KEY,
- [cm](bool e) { cm->SetWarnUninitialized(e); });
- setBool(request, kWARN_UNUSED_KEY, [this](bool e) { m_WarnUnused = e; });
- setBool(request, kWARN_UNUSED_CLI_KEY,
- [cm](bool e) { cm->SetWarnUnusedCli(e); });
- setBool(request, kCHECK_SYSTEM_VARS_KEY,
- [cm](bool e) { cm->SetCheckSystemVars(e); });
-
- return request.Reply(Json::Value());
-}
-
-cmServerResponse cmServerProtocol1::ProcessFileSystemWatchers(
- const cmServerRequest& request)
-{
- const cmFileMonitor* const fm = FileMonitor();
- Json::Value result = Json::objectValue;
- Json::Value files = Json::arrayValue;
- for (auto const& f : fm->WatchedFiles()) {
- files.append(f);
- }
- Json::Value directories = Json::arrayValue;
- for (auto const& d : fm->WatchedDirectories()) {
- directories.append(d);
- }
- result[kWATCHED_FILES_KEY] = files;
- result[kWATCHED_DIRECTORIES_KEY] = directories;
-
- return request.Reply(result);
-}
-
-cmServerResponse cmServerProtocol1::ProcessCTests(
- const cmServerRequest& request)
-{
- if (this->m_State < STATE_COMPUTED) {
- return request.ReportError("This instance was not yet computed.");
- }
-
- return request.Reply(cmDumpCTestInfo(this->CMakeInstance()));
-}
-
-cmServerProtocol1::GeneratorInformation::GeneratorInformation(
- std::string generatorName, std::string extraGeneratorName,
- std::string toolset, std::string platform, std::string sourceDirectory,
- std::string buildDirectory)
- : GeneratorName(std::move(generatorName))
- , ExtraGeneratorName(std::move(extraGeneratorName))
- , Toolset(std::move(toolset))
- , Platform(std::move(platform))
- , SourceDirectory(std::move(sourceDirectory))
- , BuildDirectory(std::move(buildDirectory))
-{
-}
-
-void cmServerProtocol1::GeneratorInformation::SetupGenerator(
- cmake* cm, std::string* errorMessage)
-{
- const std::string fullGeneratorName =
- cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
- GeneratorName, ExtraGeneratorName);
-
- cm->SetHomeDirectory(SourceDirectory);
- cm->SetHomeOutputDirectory(BuildDirectory);
-
- auto gg = cm->CreateGlobalGenerator(fullGeneratorName);
- if (!gg) {
- setErrorMessage(
- errorMessage,
- std::string("Could not set up the requested combination of \"") +
- kGENERATOR_KEY + "\" and \"" + kEXTRA_GENERATOR_KEY + "\"");
- return;
- }
-
- cm->SetGlobalGenerator(std::move(gg));
-
- cm->SetGeneratorToolset(Toolset);
- cm->SetGeneratorPlatform(Platform);
-}
diff --git a/Source/cmServerProtocol.h b/Source/cmServerProtocol.h
deleted file mode 100644
index 6009e23..0000000
--- a/Source/cmServerProtocol.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#pragma once
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include <cm3p/json/value.h>
-
-#include "cmake.h"
-
-class cmConnection;
-class cmFileMonitor;
-class cmServer;
-class cmServerRequest;
-
-class cmServerResponse
-{
-public:
- explicit cmServerResponse(const cmServerRequest& request);
-
- void SetData(const Json::Value& data);
- void SetError(const std::string& message);
-
- bool IsComplete() const;
- bool IsError() const;
- std::string ErrorMessage() const;
- Json::Value Data() const;
-
- const std::string Type;
- const std::string Cookie;
-
-private:
- enum PayLoad
- {
- PAYLOAD_UNKNOWN,
- PAYLOAD_ERROR,
- PAYLOAD_DATA
- };
- PayLoad m_Payload = PAYLOAD_UNKNOWN;
- std::string m_ErrorMessage;
- Json::Value m_Data;
-};
-
-class cmServerRequest
-{
-public:
- cmServerResponse Reply(const Json::Value& data) const;
- cmServerResponse ReportError(const std::string& message) const;
-
- const std::string Type;
- const std::string Cookie;
- const Json::Value Data;
- cmConnection* Connection;
-
-private:
- cmServerRequest(cmServer* server, cmConnection* connection, std::string t,
- std::string c, Json::Value d);
-
- void ReportProgress(int min, int current, int max,
- const std::string& message) const;
- void ReportMessage(const std::string& message,
- const std::string& title) const;
-
- cmServer* m_Server;
-
- friend class cmServer;
-};
-
-class cmServerProtocol
-{
-public:
- cmServerProtocol() = default;
- virtual ~cmServerProtocol() = default;
-
- cmServerProtocol(cmServerProtocol const&) = delete;
- cmServerProtocol& operator=(cmServerProtocol const&) = delete;
-
- virtual std::pair<int, int> ProtocolVersion() const = 0;
- virtual bool IsExperimental() const = 0;
- virtual cmServerResponse Process(const cmServerRequest& request) = 0;
-
- bool Activate(cmServer* server, const cmServerRequest& request,
- std::string* errorMessage);
-
- cmFileMonitor* FileMonitor() const;
- void SendSignal(const std::string& name, const Json::Value& data) const;
-
-protected:
- cmake* CMakeInstance() const;
- // Implement protocol specific activation tasks here. Called from Activate().
- virtual bool DoActivate(const cmServerRequest& request,
- std::string* errorMessage);
- bool m_WarnUnused = false; // storage for legacy option
-
-private:
- std::unique_ptr<cmake> m_CMakeInstance;
- cmServer* m_Server = nullptr; // not owned!
-
- friend class cmServer;
-};
-
-class cmServerProtocol1 : public cmServerProtocol
-{
-public:
- std::pair<int, int> ProtocolVersion() const override;
- bool IsExperimental() const override;
- cmServerResponse Process(const cmServerRequest& request) override;
-
-private:
- bool DoActivate(const cmServerRequest& request,
- std::string* errorMessage) override;
-
- void HandleCMakeFileChanges(const std::string& path, int event, int status);
-
- // Handle requests:
- cmServerResponse ProcessCache(const cmServerRequest& request);
- cmServerResponse ProcessCMakeInputs(const cmServerRequest& request);
- cmServerResponse ProcessCodeModel(const cmServerRequest& request);
- cmServerResponse ProcessCompute(const cmServerRequest& request);
- cmServerResponse ProcessConfigure(const cmServerRequest& request);
- cmServerResponse ProcessGlobalSettings(const cmServerRequest& request);
- cmServerResponse ProcessSetGlobalSettings(const cmServerRequest& request);
- cmServerResponse ProcessFileSystemWatchers(const cmServerRequest& request);
- cmServerResponse ProcessCTests(const cmServerRequest& request);
-
- enum State
- {
- STATE_INACTIVE,
- STATE_ACTIVE,
- STATE_CONFIGURED,
- STATE_COMPUTED
- };
- State m_State = STATE_INACTIVE;
-
- bool m_isDirty = false;
-
- struct GeneratorInformation
- {
- public:
- GeneratorInformation() = default;
- GeneratorInformation(std::string generatorName,
- std::string extraGeneratorName, std::string toolset,
- std::string platform, std::string sourceDirectory,
- std::string buildDirectory);
-
- void SetupGenerator(cmake* cm, std::string* errorMessage);
-
- std::string GeneratorName;
- std::string ExtraGeneratorName;
- std::string Toolset;
- std::string Platform;
-
- std::string SourceDirectory;
- std::string BuildDirectory;
- };
-
- GeneratorInformation GeneratorInfo;
-};
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 2a14b03..720a567 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -263,7 +263,7 @@ Json::Value cmake::ReportCapabilitiesJson() const
}
obj["generators"] = generators;
obj["fileApi"] = cmFileAPI::ReportCapabilities();
- obj["serverMode"] = true;
+ obj["serverMode"] = false;
return obj;
}
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 0bdc6fa..61ff470 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -28,8 +28,6 @@
#if !defined(CMAKE_BOOTSTRAP)
# include "cmDependsFortran.h" // For -E cmake_copy_f90_mod callback.
# include "cmFileTime.h"
-# include "cmServer.h"
-# include "cmServerConnection.h"
# include "bindexplib.h"
#endif
@@ -59,8 +57,6 @@
#include "cmsys/Process.h"
#include "cmsys/Terminal.h"
-class cmConnection;
-
int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
std::vector<std::string>::const_iterator argEnd);
int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
@@ -119,7 +115,6 @@ void CMakeCommandUsage(const char* program)
"(on one volume)\n"
<< " rm [-rRf] <file/dir>... - remove files or directories, use -f to "
"force it, r or R to remove directories and their contents recursively\n"
- << " server - start cmake in server mode\n"
<< " sleep <number>... - sleep for given number of seconds\n"
<< " tar [cxt][vf][zjJ] file.tar [file/dir1 file/dir2 ...]\n"
<< " - create or extract a tar or zip archive\n"
@@ -1351,47 +1346,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
}
if (args[1] == "server") {
- const std::string pipePrefix = "--pipe=";
- bool supportExperimental = false;
- bool isDebug = false;
- std::string pipe;
-
- for (auto const& arg : cmMakeRange(args).advance(2)) {
- if (arg == "--experimental") {
- supportExperimental = true;
- } else if (arg == "--debug") {
- pipe.clear();
- isDebug = true;
- } else if (cmHasPrefix(arg, pipePrefix)) {
- isDebug = false;
- pipe = arg.substr(pipePrefix.size());
- if (pipe.empty()) {
- cmSystemTools::Error("No pipe given after --pipe=");
- return 2;
- }
- } else {
- cmSystemTools::Error("Unknown argument for server mode");
- return 1;
- }
- }
-#if !defined(CMAKE_BOOTSTRAP)
- cmConnection* conn;
- if (isDebug) {
- conn = new cmServerStdIoConnection;
- } else {
- conn = new cmServerPipeConnection(pipe);
- }
- cmServer server(conn, supportExperimental);
- std::string errorMessage;
- if (server.Serve(&errorMessage)) {
- return 0;
- }
- cmSystemTools::Error(errorMessage);
-#else
- static_cast<void>(supportExperimental);
- static_cast<void>(isDebug);
- cmSystemTools::Error("CMake was not built with server mode enabled");
-#endif
+ cmSystemTools::Error(
+ "CMake server mode has been removed in favor of the file-api.");
return 1;
}