diff --git a/lib/Dialect/ESI/runtime/CMakeLists.txt b/lib/Dialect/ESI/runtime/CMakeLists.txt index 1bf82fa04c98..fdda1847c2da 100644 --- a/lib/Dialect/ESI/runtime/CMakeLists.txt +++ b/lib/Dialect/ESI/runtime/CMakeLists.txt @@ -27,6 +27,11 @@ cmake_minimum_required(VERSION 3.20) project(ESIRuntime LANGUAGES CXX) include(FetchContent) +set(ESI_STATIC_RUNTIME OFF CACHE BOOL "Build the ESI runtime as a static library.") +if(ESI_STATIC_RUNTIME) + message("-- Building ESI runtime as a static library.") +endif() + set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED YES) set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib") @@ -44,6 +49,10 @@ if (NOT TARGET nlohmann_json) FetchContent_MakeAvailable(json) endif() +if(ESI_STATIC_RUNTIME) + set(ZLIB_USE_STATIC_LIBS ON) +endif() + # We need zlib to uncompress the manifest. find_package(ZLIB) if(ZLIB_FOUND) @@ -57,7 +66,11 @@ else() ) FetchContent_MakeAvailable(ZLIB) set(ZLIB_INCLUDE_DIR ${zlib_SOURCE_DIR} ${zlib_BINARY_DIR}) - set(ZLIB_LIBRARY zlib) + if(ESI_STATIC_RUNTIME) + set(ZLIB_LIBRARY zlibstatic) + else() + set(ZLIB_LIBRARY zlib) + endif() endif() # In a Python wheel build, we need to install libraries to different places. @@ -118,10 +131,17 @@ IF(MSVC) set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS 1) ENDIF(MSVC) -# The core API. For now, compile the backends into it directly. -add_library(ESICppRuntime SHARED - ${ESICppRuntimeSources} -) +if(ESI_STATIC_RUNTIME) + add_library(ESICppRuntime STATIC + ${ESICppRuntimeSources} + ) +else() + add_library(ESICppRuntime SHARED + ${ESICppRuntimeSources} + ) +endif() +add_library(esiaccel::ESICppRuntime ALIAS ESICppRuntime) + target_include_directories(ESICppRuntime PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/cpp/include ) @@ -165,10 +185,12 @@ install(TARGETS ESICppRuntime COMPONENT ESIRuntime ) -install(IMPORTED_RUNTIME_ARTIFACTS ESICppRuntime - RUNTIME_DEPENDENCY_SET ESICppRuntime_RUNTIME_DEPS - COMPONENT ESIRuntime -) +if(NOT ESI_STATIC_RUNTIME) + install(IMPORTED_RUNTIME_ARTIFACTS ESICppRuntime + RUNTIME_DEPENDENCY_SET ESICppRuntime_RUNTIME_DEPS + COMPONENT ESIRuntime + ) +endif() install(RUNTIME_DEPENDENCY_SET ESICppRuntime_RUNTIME_DEPS DESTINATION ${LIB_DIR} PRE_EXCLUDE_REGEXES .* diff --git a/lib/Dialect/ESI/runtime/cpp/include/esi/Accelerator.h b/lib/Dialect/ESI/runtime/cpp/include/esi/Accelerator.h index 34567c466f88..c3a1cd9da9e6 100644 --- a/lib/Dialect/ESI/runtime/cpp/include/esi/Accelerator.h +++ b/lib/Dialect/ESI/runtime/cpp/include/esi/Accelerator.h @@ -134,15 +134,16 @@ namespace registry { // Connect to an ESI accelerator given a backend name and connection specifier. // Alternatively, instantiate the backend directly (if you're using C++). -std::unique_ptr -connect(Context &ctxt, std::string backend, std::string connection); +std::unique_ptr connect(Context &ctxt, + const std::string &backend, + const std::string &connection); namespace internal { /// Backends can register themselves to be connected via a connection string. using BackendCreate = std::function( Context &, std::string)>; -void registerBackend(std::string name, BackendCreate create); +void registerBackend(const std::string &name, BackendCreate create); // Helper struct to template diff --git a/lib/Dialect/ESI/runtime/cpp/lib/Accelerator.cpp b/lib/Dialect/ESI/runtime/cpp/lib/Accelerator.cpp index 019d734b0023..0aae47341b6e 100644 --- a/lib/Dialect/ESI/runtime/cpp/lib/Accelerator.cpp +++ b/lib/Dialect/ESI/runtime/cpp/lib/Accelerator.cpp @@ -175,22 +175,35 @@ static void loadBackend(std::string backend) { namespace registry { namespace internal { -static std::map backendRegistry; -void registerBackend(std::string name, BackendCreate create) { - if (backendRegistry.count(name)) +class BackendRegistry { +public: + static std::map &get() { + static BackendRegistry instance; + return instance.backendRegistry; + } + +private: + std::map backendRegistry; +}; + +void registerBackend(const std::string &name, BackendCreate create) { + auto ®istry = BackendRegistry::get(); + if (registry.count(name)) throw std::runtime_error("Backend already exists in registry"); - backendRegistry[name] = create; + registry[name] = create; } } // namespace internal -std::unique_ptr -connect(Context &ctxt, std::string backend, std::string connection) { - auto f = internal::backendRegistry.find(backend); - if (f == internal::backendRegistry.end()) { +std::unique_ptr connect(Context &ctxt, + const std::string &backend, + const std::string &connection) { + auto ®istry = internal::BackendRegistry::get(); + auto f = registry.find(backend); + if (f == registry.end()) { // If it's not already found in the registry, try to load it dynamically. loadBackend(backend); - f = internal::backendRegistry.find(backend); - if (f == internal::backendRegistry.end()) + f = registry.find(backend); + if (f == registry.end()) throw std::runtime_error("Backend '" + backend + "' not found"); } return f->second(ctxt, connection);