diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 702f6a36a..353376682 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -33,6 +33,17 @@ jobs: - run: cmake --build . --target lib3mf_memcheck working-directory: ./build + install-linux-packagers-smoke: + runs-on: ubuntu-24.04 + needs: [set-lib3mf-version] + steps: + - run: sudo apt update + - run: sudo apt install -y ninja-build pkg-config uuid-dev zlib1g-dev libzip-dev libssl-dev + - uses: actions/checkout@v4 + with: + submodules: true + - run: bash CI/install_smoke_test.sh + build-linux-ubi8-gcc12: runs-on: ubuntu-24.04 needs: [set-lib3mf-version] @@ -1112,4 +1123,4 @@ jobs: uses: actions/upload-artifact@v4 with: name: integration-test-results - path: results.txt \ No newline at end of file + path: results.txt diff --git a/CI/install_smoke_test.sh b/CI/install_smoke_test.sh new file mode 100755 index 000000000..280e97652 --- /dev/null +++ b/CI/install_smoke_test.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +set -euo pipefail + +root_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +build_dir="${root_dir}/build/install-smoke" +install_dir="${root_dir}/build/install-root" +rm -rf "${build_dir}" "${install_dir}" + +generator="Unix Makefiles" +if command -v ninja >/dev/null 2>&1; then + generator="Ninja" +fi + +cmake -S "${root_dir}" -B "${build_dir}" -G "${generator}" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX="${install_dir}" \ + -DUSE_INCLUDED_ZLIB=OFF \ + -DUSE_INCLUDED_LIBZIP=OFF \ + -DUSE_INCLUDED_SSL=OFF \ + -DLIB3MF_TESTS=OFF + +cmake --build "${build_dir}" --target lib3mf +cmake --install "${build_dir}" + +if ! find "${install_dir}" -type f \( -name "lib3mf*.so" -o -name "lib3mf*.so.*" -o -name "lib3mf*.dylib" \) | grep -q .; then + echo "Missing installed shared library (lib3mf*.so|dylib)." >&2 + exit 1 +fi + +pc_file="" +for candidate in \ + "${install_dir}/lib/pkgconfig/lib3mf.pc" \ + "${install_dir}/lib64/pkgconfig/lib3mf.pc" +do + if [[ -f "${candidate}" ]]; then + pc_file="${candidate}" + break + fi +done + +if [[ -z "${pc_file}" ]]; then + echo "Missing installed lib3mf.pc." >&2 + exit 1 +fi + +if [[ -f "${install_dir}/include/lib3mf/Bindings/C/lib3mf.h" && -f "${install_dir}/include/lib3mf/Bindings/C/lib3mf_types.h" ]]; then + header_root="${install_dir}/include/lib3mf/Bindings/C" +elif [[ -f "${install_dir}/include/Bindings/C/lib3mf.h" && -f "${install_dir}/include/Bindings/C/lib3mf_types.h" ]]; then + header_root="${install_dir}/include/Bindings/C" +else + echo "Missing installed C headers (lib3mf.h, lib3mf_types.h)." >&2 + exit 1 +fi + +export PKG_CONFIG_PATH="${install_dir}/lib/pkgconfig:${install_dir}/lib64/pkgconfig:${PKG_CONFIG_PATH:-}" +pkg-config --cflags --libs lib3mf >/dev/null + +cat > "${build_dir}/test.c" <<'EOF' +#include + +int main(void) { + Lib3MF_uint32 major = 0; + Lib3MF_uint32 minor = 0; + Lib3MF_uint32 micro = 0; + return (int) lib3mf_getlibraryversion(&major, &minor, µ); +} +EOF + +cc "${build_dir}/test.c" -o "${build_dir}/test" $(pkg-config --cflags --libs lib3mf) + +echo "Install smoke test passed. Headers at: ${header_root}; pkg-config file: ${pc_file}" diff --git a/CMakeLists.txt b/CMakeLists.txt index 0bebb4063..1fe9bae28 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,8 +6,6 @@ cmake_policy(SET CMP0048 NEW) set_property(GLOBAL PROPERTY USE_FOLDERS ON) -include(GNUInstallDirs) - # Define Version set(LIB3MF_VERSION_MAJOR 2) # increase on every backward-compatibility breaking change of the API set(LIB3MF_VERSION_MINOR 4) # increase on every backward compatible change of the API @@ -18,6 +16,7 @@ project(lib3mf VERSION ${LIB3MF_VERSION_MAJOR}.${LIB3MF_VERSION_MINOR}.${LIB3MF_VERSION_MICRO} DESCRIPTION "An implementation of the 3D Manufacturing Format file standard" ) +include(GNUInstallDirs) # macOS: ensure zlib includes (affects ALL targets incl. Tests) if(APPLE) @@ -29,9 +28,16 @@ if(buildcache_program) set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${buildcache_program}") endif() -set(CMAKE_INSTALL_BINDIR bin CACHE PATH "directory for installing binary files") -set(CMAKE_INSTALL_LIBDIR lib CACHE PATH "directory for installing library files") -set(CMAKE_INSTALL_INCLUDEDIR include/lib3mf CACHE PATH "directory for installing header files") +# Use GNUInstallDirs defaults unless explicitly overridden by the caller. +if(CMAKE_INSTALL_BINDIR_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_BINDIR "bin" CACHE PATH "directory for installing binary files" FORCE) +endif() +if(CMAKE_INSTALL_LIBDIR_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_LIBDIR "lib" CACHE PATH "directory for installing library files" FORCE) +endif() +if(CMAKE_INSTALL_INCLUDEDIR STREQUAL "include") + set(CMAKE_INSTALL_INCLUDEDIR "include/lib3mf" CACHE PATH "directory for installing header files" FORCE) +endif() option(USE_INCLUDED_ZLIB "Use included zlib" ON) option(USE_INCLUDED_LIBZIP "Use included libzip" ON) @@ -132,6 +138,13 @@ add_library(${PROJECT_NAME} SHARED ${SRCS_COMMON} ${HDRS_COMMON} ${ACT_GENERATED_SOURCE} ${VERSION_FILES_OUTPUTLOCATION} ) +add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND + ${CMAKE_COMMAND} + -DTARGET_FILE=$ + -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/VerifyTargetFile.cmake" + VERBATIM +) if (${MSVC}) # using Visual Studio C++ @@ -279,6 +292,7 @@ install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") + install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR_AUTOGENERATED}/Bindings DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") ######################################################### diff --git a/CMakePresets.json b/CMakePresets.json index 3b93ba150..28f542d29 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -95,6 +95,19 @@ "cacheVariables": { "CMAKE_BUILD_TYPE": "Release" } + }, + { + "name": "linux-packagers", + "displayName": "Linux Packagers", + "description": "Release build on Linux with system dependencies and tests disabled.", + "inherits": "linux-base", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "LIB3MF_TESTS": "OFF", + "USE_INCLUDED_ZLIB": "OFF", + "USE_INCLUDED_LIBZIP": "OFF", + "USE_INCLUDED_SSL": "OFF" + } } ], "buildPresets": [ @@ -127,6 +140,11 @@ "name": "linux-release", "displayName": "Build (Linux Release)", "configurePreset": "linux-release" + }, + { + "name": "linux-packagers", + "displayName": "Build (Linux Packagers)", + "configurePreset": "linux-packagers" } ], "testPresets": [ @@ -179,4 +197,4 @@ } } ] -} \ No newline at end of file +} diff --git a/cmake/VerifyTargetFile.cmake b/cmake/VerifyTargetFile.cmake new file mode 100644 index 000000000..0df998206 --- /dev/null +++ b/cmake/VerifyTargetFile.cmake @@ -0,0 +1,7 @@ +if(NOT DEFINED TARGET_FILE OR TARGET_FILE STREQUAL "") + message(FATAL_ERROR "VerifyTargetFile.cmake: TARGET_FILE is not set.") +endif() + +if(NOT EXISTS "${TARGET_FILE}") + message(FATAL_ERROR "VerifyTargetFile.cmake: built target file not found: ${TARGET_FILE}") +endif() diff --git a/lib3mf.pc.in b/lib3mf.pc.in index bb8030abf..b67375c02 100644 --- a/lib3mf.pc.in +++ b/lib3mf.pc.in @@ -8,5 +8,6 @@ Description: @PROJECT_DESCRIPTION@ Version: @PROJECT_VERSION@ Requires: -Libs: -L${libdir} -l3mf -lzip -lz -Cflags: -I${includedir} +Libs: -L${libdir} -l3mf +Libs.private: -lzip -lz +Cflags: -I${includedir}/Bindings/C