Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 107 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ list(APPEND MINIO_CPP_LIBS
if (WIN32)
list(APPEND MINIO_CPP_LIBS wsock32)
list(APPEND MINIO_CPP_LIBS ws2_32)
# miniocpp.pc.in has no visibility into target_link_libraries() - without this,
# pkg-config consumers (non-CMake) are missing wsock32/ws2_32 at link time
# (getaddrinfo, select, ...).
set(MINIO_CPP_PC_EXTRA_LIBS " -lwsock32 -lws2_32")
endif()

# Minio C++ Library
Expand Down Expand Up @@ -137,6 +141,7 @@ set(MINIO_CPP_HEADERS
include/miniocpp/providers.h
include/miniocpp/request.h
include/miniocpp/response.h
include/miniocpp/result.h
include/miniocpp/select.h
include/miniocpp/signer.h
include/miniocpp/sse.h
Expand Down Expand Up @@ -174,6 +179,78 @@ target_include_directories(miniocpp PUBLIC
$<BUILD_INTERFACE:${MINIO_CPP_INCLUDES}>
)
target_link_libraries(miniocpp PUBLIC ${MINIO_CPP_LIBS})

# Optional C++20 module interface for the public API (modules/miniocpp.cc).
# FILE_SET CXX_MODULES (CMake 3.28+) attaches it as a real part of the miniocpp
# target's build - the compiler gets whatever flags it needs for a module
# interface unit (e.g. /interface for MSVC) based on this declaration, not on
# the file's extension, so any CMake/MSBuild/Meson (via cmake.subproject())
# consumer of this target picks up `import miniocpp;` automatically. Requires
# C++20 (MINIO_CPP_STD=20); silently skipped otherwise for older setups.
#
# CMake's module dependency scanning is only implemented for the Ninja,
# Ninja Multi-Config, and Visual Studio (17.4+) generators - with any other
# generator (e.g. the Linux/macOS default "Unix Makefiles") CMake hard-errors
# at the Generate step as soon as it sees FILE_SET CXX_MODULES sources, even
# if MINIO_CPP_STD=20 was requested intentionally. Generator *name* alone is
# not enough either: CMake 3.28 requires Ninja 1.11+ for the dyndep-based
# scanning, and each compiler has its own minimum version for module support
# (MSVC 14.34 / VS 17.4, reported as compiler version 19.34; Clang 16;
# GCC 14) - see https://cmake.org/cmake/help/v3.28/manual/cmake-cxxmodules.7.html.
# An older or unrecognized compiler can still match the generator check
# above and then break module dependency scanning instead of falling back
# cleanly, so reject anything not explicitly known-good rather than
# defaulting to allowed.
set(MINIO_CPP_HAS_CXX_MODULE OFF)
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.28" AND MINIO_CPP_STD STREQUAL "20")
set(MINIO_CPP_MODULE_TOOLCHAIN_OK OFF)
if (CMAKE_GENERATOR STREQUAL "Ninja" OR CMAKE_GENERATOR STREQUAL "Ninja Multi-Config")
execute_process(
COMMAND "${CMAKE_MAKE_PROGRAM}" --version
OUTPUT_VARIABLE MINIO_CPP_NINJA_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
if (MINIO_CPP_NINJA_VERSION VERSION_GREATER_EQUAL "1.11")
set(MINIO_CPP_MODULE_TOOLCHAIN_OK ON)
endif()
elseif (CMAKE_GENERATOR MATCHES "^Visual Studio ")
set(MINIO_CPP_MODULE_TOOLCHAIN_OK ON)
endif()

# Applies regardless of which of the generators above is in use - Ninja can
# also drive an MSVC/Clang/GCC toolchain, and each compiler's own module
# support is gated on its own version, not the generator. Reject any
# compiler not explicitly listed here, rather than silently allowing it.
if (MINIO_CPP_MODULE_TOOLCHAIN_OK)
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "19.34")
set(MINIO_CPP_MODULE_TOOLCHAIN_OK OFF)
endif()
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "16.0")
set(MINIO_CPP_MODULE_TOOLCHAIN_OK OFF)
endif()
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "14")
set(MINIO_CPP_MODULE_TOOLCHAIN_OK OFF)
endif()
else()
set(MINIO_CPP_MODULE_TOOLCHAIN_OK OFF)
endif()
endif()

if (MINIO_CPP_MODULE_TOOLCHAIN_OK)
set(MINIO_CPP_HAS_CXX_MODULE ON)
target_sources(miniocpp
PUBLIC
FILE_SET CXX_MODULES
BASE_DIRS modules
FILES modules/miniocpp.cc
)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
endif()
endif()

if (MINIO_CPP_ENABLE_RDMA)
target_compile_definitions(miniocpp PUBLIC MINIO_CPP_RDMA)
endif()
Expand Down Expand Up @@ -295,13 +372,33 @@ configure_package_config_file(
NO_CHECK_REQUIRED_COMPONENTS_MACRO
)

install(TARGETS miniocpp
EXPORT miniocpp-targets
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
if (MINIO_CPP_HAS_CXX_MODULE)
install(TARGETS miniocpp
EXPORT miniocpp-targets
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
FILE_SET CXX_MODULES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/miniocpp/modules")
else()
install(TARGETS miniocpp
EXPORT miniocpp-targets
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
endif()

# Known limitation: this export does not pass CXX_MODULES_DIRECTORY, so an
# installed package (via find_package(miniocpp) + CMake, as opposed to
# consuming subprojects/miniocpp source directly, or via pkg-config/vcpkg)
# is missing the generated module metadata CMake needs to let a downstream
# CMake consumer `import miniocpp;` - see
# https://cmake.org/cmake/help/latest/command/install.html#exporting-c-modules.
# Separately, installing module interfaces is not supported at all with
# the Visual Studio generator (independent of the MINIO_CPP_HAS_CXX_MODULE
# toolchain gate above, which only covers the build step). Neither gap is
# covered by an automated test yet.
install(EXPORT miniocpp-targets
NAMESPACE miniocpp::
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/miniocpp"
Expand All @@ -313,5 +410,9 @@ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/miniocpp-config.cmake"
install(FILES
${MINIO_CPP_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/miniocpp")

# error.h/credentials.h depend on the vendored tl::expected, which is otherwise
# never installed - without this, consumers (e.g. via vcpkg) fail to build.
install(DIRECTORY include/tl DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")

configure_file(miniocpp.pc.in ${CMAKE_CURRENT_BINARY_DIR}/miniocpp.pc @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/miniocpp.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
57 changes: 57 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
project('miniocpp', 'cpp', version : '0.4.0')
Comment thread
coderabbitai[bot] marked this conversation as resolved.

cxx = meson.get_compiler('cpp')

openssl_dep = dependency('openssl')
curlpp_dep = dependency('curlpp')
inih_dep = dependency('INIReader')
nlohmann_json_dep = dependency('nlohmann_json')
pugixml_dep = dependency('pugixml')
zlib_dep = dependency('zlib')

extra_libs = []
if host_machine.system() == 'windows'
extra_libs = [cxx.find_library('ws2_32'), cxx.find_library('wsock32')]
endif

all_deps = [openssl_dep, curlpp_dep, inih_dep, nlohmann_json_dep, pugixml_dep, zlib_dep] + extra_libs
miniocpp_include = include_directories('include')

miniocpp_sources = files(
'src/args.cc',
'src/baseclient.cc',
'src/client.cc',
'src/credentials.cc',
'src/error.cc',
'src/http.cc',
'src/providers.cc',
'src/request.cc',
'src/response.cc',
'src/select.cc',
'src/signer.cc',
'src/sse.cc',
'src/types.cc',
'src/utils.cc',
)

# The real library - all .cc files from this repo, not the official minio-cpp
# vcpkg package.
miniocpp_lib = static_library('miniocpp', miniocpp_sources,
include_directories : miniocpp_include,
dependencies : all_deps,
)

# Module as its own target - /interface only applies to this one file, not to
# every .cc source.
miniocpp_module_lib = static_library('miniocpp_module', 'modules/miniocpp.cc',
include_directories : miniocpp_include,
dependencies : all_deps,
cpp_args : cxx.get_id() == 'msvc' ? ['/interface'] : [],
override_options : ['cpp_std=c++20'],
)

miniocpp_dep = declare_dependency(
link_with : [miniocpp_lib, miniocpp_module_lib],
include_directories : miniocpp_include,
dependencies : all_deps,
)
4 changes: 2 additions & 2 deletions miniocpp.pc.in
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ Name: @PROJECT_NAME@
Description: @PROJECT_DESCRIPTION@
Version: @PROJECT_VERSION@

Requires:
Libs: -L${libdir} -lminiocpp
Requires: curlpp libcrypto libssl pugixml zlib
Libs: -L${libdir} -lminiocpp@MINIO_CPP_PC_EXTRA_LIBS@
Cflags: -I${includedir}
26 changes: 26 additions & 0 deletions modules/miniocpp.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module;

#include <miniocpp/client.h>

export module miniocpp;

// Re-exporting the public API through the module requires an EXPLICIT using-
// declaration per symbol (using ns::Symbol;) - not a using-directive (using
// namespace ns;), because declarations from the global module fragment (the
// #include above) only become "reachable", not automatic members of an export
// namespace. The list below covers what a typical consumer needs today -
// extend it by adding more using-declarations as needed.
export namespace minio::s3 {
using s3::BaseUrl;
using s3::BucketExistsArgs;
using s3::BucketExistsResponse;
using s3::Client;
} // namespace minio::s3

export namespace minio::creds {
using minio::creds::StaticProvider;
}

export namespace minio {
using minio::Result;
}