From 9b28feb8ca0ee1e4c2a16f9a75480b7b15488baa Mon Sep 17 00:00:00 2001 From: forbes Date: Fri, 27 Feb 2026 13:36:48 -0600 Subject: [PATCH] feat(sdk): scaffold KCSDK library + kcsdk pybind11 module (#350) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the KCSDK C++ shared library and kcsdk pybind11 module, establishing the build infrastructure for the C++-backed addon SDK. New files: - src/Gui/SDK/KCSDKGlobal.h — DLL export macros - src/Gui/SDK/SDKRegistry.h/.cpp — empty singleton with API_VERSION_MAJOR=1 - src/Gui/SDK/CMakeLists.txt — builds KCSDK shared library - src/Gui/SDK/bindings/kcsdk_py.cpp — pybind11 module exposing version + available() - src/Gui/SDK/bindings/CMakeLists.txt — builds kcsdk pybind11 module Modified: - src/Gui/CMakeLists.txt — add_subdirectory(SDK) Verified: import kcsdk; kcsdk.API_VERSION_MAJOR == 1; kcsdk.available() == [] --- src/Gui/CMakeLists.txt | 1 + src/Gui/SDK/CMakeLists.txt | 31 +++++++++++++ src/Gui/SDK/KCSDKGlobal.h | 37 +++++++++++++++ src/Gui/SDK/SDKRegistry.cpp | 51 +++++++++++++++++++++ src/Gui/SDK/SDKRegistry.h | 71 +++++++++++++++++++++++++++++ src/Gui/SDK/bindings/CMakeLists.txt | 30 ++++++++++++ src/Gui/SDK/bindings/kcsdk_py.cpp | 40 ++++++++++++++++ 7 files changed, 261 insertions(+) create mode 100644 src/Gui/SDK/CMakeLists.txt create mode 100644 src/Gui/SDK/KCSDKGlobal.h create mode 100644 src/Gui/SDK/SDKRegistry.cpp create mode 100644 src/Gui/SDK/SDKRegistry.h create mode 100644 src/Gui/SDK/bindings/CMakeLists.txt create mode 100644 src/Gui/SDK/bindings/kcsdk_py.cpp diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index 1949574784..68c35c6be2 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -14,6 +14,7 @@ endif() add_subdirectory(Stylesheets) add_subdirectory(PreferencePacks) add_subdirectory(PreferencePackTemplates) +add_subdirectory(SDK) if(BUILD_WITH_CONDA) add_definitions(-DFC_CONDA) diff --git a/src/Gui/SDK/CMakeLists.txt b/src/Gui/SDK/CMakeLists.txt new file mode 100644 index 0000000000..24e37f5e2c --- /dev/null +++ b/src/Gui/SDK/CMakeLists.txt @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +set(KCSDK_SRCS + KCSDKGlobal.h + SDKRegistry.h + SDKRegistry.cpp +) + +add_library(KCSDK SHARED ${KCSDK_SRCS}) + +target_include_directories(KCSDK + PUBLIC + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_BINARY_DIR}/src +) + +target_link_libraries(KCSDK + PRIVATE + FreeCADBase +) + +if(FREECAD_WARN_ERROR) + target_compile_warn_error(KCSDK) +endif() + +SET_BIN_DIR(KCSDK KCSDK /Mod/Create) +INSTALL(TARGETS KCSDK DESTINATION ${CMAKE_INSTALL_LIBDIR}) + +if(FREECAD_USE_PYBIND11) + add_subdirectory(bindings) +endif() diff --git a/src/Gui/SDK/KCSDKGlobal.h b/src/Gui/SDK/KCSDKGlobal.h new file mode 100644 index 0000000000..724239c257 --- /dev/null +++ b/src/Gui/SDK/KCSDKGlobal.h @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/**************************************************************************** + * * + * Copyright (c) 2025 Kindred Systems * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + ***************************************************************************/ + +#include + +#ifndef KCSDK_GLOBAL_H +#define KCSDK_GLOBAL_H + +#ifndef KCSDKExport +# ifdef KCSDK_EXPORTS +# define KCSDKExport FREECAD_DECL_EXPORT +# else +# define KCSDKExport FREECAD_DECL_IMPORT +# endif +#endif + +#endif // KCSDK_GLOBAL_H diff --git a/src/Gui/SDK/SDKRegistry.cpp b/src/Gui/SDK/SDKRegistry.cpp new file mode 100644 index 0000000000..d625a9758a --- /dev/null +++ b/src/Gui/SDK/SDKRegistry.cpp @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/**************************************************************************** + * * + * Copyright (c) 2025 Kindred Systems * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + ***************************************************************************/ + +#include "SDKRegistry.h" + +#include + +namespace KCSDK +{ + +SDKRegistry& SDKRegistry::instance() +{ + static SDKRegistry reg; + return reg; +} + +SDKRegistry::SDKRegistry() +{ + Base::Console().log("KCSDK: registry initialized (API v%d)\n", API_VERSION_MAJOR); +} + +SDKRegistry::~SDKRegistry() = default; + +std::vector SDKRegistry::available() const +{ + std::lock_guard lock(mutex_); + // No providers registered yet — will be populated in subsequent phases. + return {}; +} + +} // namespace KCSDK diff --git a/src/Gui/SDK/SDKRegistry.h b/src/Gui/SDK/SDKRegistry.h new file mode 100644 index 0000000000..050f2760a9 --- /dev/null +++ b/src/Gui/SDK/SDKRegistry.h @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/**************************************************************************** + * * + * Copyright (c) 2025 Kindred Systems * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + ***************************************************************************/ + +#ifndef KCSDK_SDKREGISTRY_H +#define KCSDK_SDKREGISTRY_H + +#include +#include +#include + +#include "KCSDKGlobal.h" + +namespace KCSDK +{ + +/// Current KCSDK API major version. Addons should check this at load time. +constexpr int API_VERSION_MAJOR = 1; + +/// Singleton registry for SDK-managed UI providers. +/// +/// This is the central coordination point for the Kindred addon SDK. +/// Provider interfaces (IPanelProvider, IToolbarProvider, etc.) will be +/// added in subsequent phases. For now this establishes the singleton +/// pattern, thread safety, and API versioning. +/// +/// Thread safety: all public methods are internally synchronized. +class KCSDKExport SDKRegistry +{ +public: + /// Access the singleton instance. + static SDKRegistry& instance(); + + ~SDKRegistry(); + + /// Return names of all registered providers (across all provider types). + std::vector available() const; + +private: + SDKRegistry(); + + SDKRegistry(const SDKRegistry&) = delete; + SDKRegistry& operator=(const SDKRegistry&) = delete; + SDKRegistry(SDKRegistry&&) = delete; + SDKRegistry& operator=(SDKRegistry&&) = delete; + + mutable std::mutex mutex_; +}; + +} // namespace KCSDK + +#endif // KCSDK_SDKREGISTRY_H diff --git a/src/Gui/SDK/bindings/CMakeLists.txt b/src/Gui/SDK/bindings/CMakeLists.txt new file mode 100644 index 0000000000..1b2ae723e0 --- /dev/null +++ b/src/Gui/SDK/bindings/CMakeLists.txt @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +set(KCSDKPy_SRCS + kcsdk_py.cpp +) + +add_library(kcsdk_py SHARED ${KCSDKPy_SRCS}) + +target_include_directories(kcsdk_py + PRIVATE + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_BINARY_DIR}/src + ${pybind11_INCLUDE_DIR} +) + +target_link_libraries(kcsdk_py + PRIVATE + pybind11::module + Python3::Python + KCSDK +) + +if(FREECAD_WARN_ERROR) + target_compile_warn_error(kcsdk_py) +endif() + +SET_BIN_DIR(kcsdk_py kcsdk /Mod/Create) +SET_PYTHON_PREFIX_SUFFIX(kcsdk_py) + +INSTALL(TARGETS kcsdk_py DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/src/Gui/SDK/bindings/kcsdk_py.cpp b/src/Gui/SDK/bindings/kcsdk_py.cpp new file mode 100644 index 0000000000..fc30cb4515 --- /dev/null +++ b/src/Gui/SDK/bindings/kcsdk_py.cpp @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/**************************************************************************** + * * + * Copyright (c) 2025 Kindred Systems * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + ***************************************************************************/ + +#include +#include + +#include + +namespace py = pybind11; +using namespace KCSDK; + +PYBIND11_MODULE(kcsdk, m) +{ + m.doc() = "KCSDK — Kindred Create addon SDK C++ API"; + m.attr("API_VERSION_MAJOR") = API_VERSION_MAJOR; + + m.def("available", []() { + return SDKRegistry::instance().available(); + }, "Return names of all registered providers."); +} -- 2.49.1