diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 5fcb448..52976c4 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -78,28 +78,25 @@ jobs: # Turn repeated input strings (such as the build output directory) into step outputs. These step outputs can be used throughout the workflow file. id: strings shell: bash - run: echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT" + run: | + echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT" + if [ "${{ matrix.os }}" == "windows-latest" ]; then + echo "preset-name=conan-default" >> "$GITHUB_OUTPUT" + else + echo "preset-name=conan-release" >> "$GITHUB_OUTPUT" + fi - name: 🐸 Create default Conan profile run: conan profile detect - name: ☁️ Get dependencies - run: conan install ${{ github.workspace }} --build=missing --output-folder=build --settings compiler.cppstd=20 + run: conan install ${{ github.workspace }} --build=missing -s compiler.cppstd=20 -o testing=True - name: 🛠️ Configure CMake - run: > - cmake -B ${{ steps.strings.outputs.build-output-dir }} - -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} - -DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }} - -DCMAKE_C_COMPILER=${{ matrix.c_compiler }} - -DBUILD_TESTING=ON - -DCODE_COVERAGE=OFF - --toolchain=conan_toolchain.cmake - -S ${{ github.workspace }} + run: cmake --preset ${{ steps.strings.outputs.preset-name }} - name: 🔨 Build project - run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }} --parallel + run: cmake --build --preset conan-release --parallel - name: 🏃 Run test suite - working-directory: build - run: ctest --build-config ${{ matrix.build_type }} + run: ctest --preset conan-release diff --git a/.github/workflows/coverage.yaml b/.github/workflows/coverage.yaml index 135984f..4841c68 100644 --- a/.github/workflows/coverage.yaml +++ b/.github/workflows/coverage.yaml @@ -38,28 +38,21 @@ jobs: run: conan profile detect - name: ☁️ Get dependencies - run: conan install ${{ github.workspace }} --build=missing --output-folder=build --settings compiler.cppstd=20 + run: conan install ${{ github.workspace }} --build=missing -s compiler.cppstd=20 -o testing=True -o coverage=True - name: 🛠️ Configure CMake - run: > - cmake -B build - -DCMAKE_BUILD_TYPE=Release - -DBUILD_TESTING=ON - -DCODE_COVERAGE=ON - --toolchain=conan_toolchain.cmake - -S ${{ github.workspace }} + run: cmake --preset conan-release - name: 🔨 Build project - run: cmake --build build --config Release --parallel + run: cmake --build --preset conan-release --parallel - name: 🏃 Run test suite - working-directory: build - run: ctest --build-config Release + run: ctest --preset conan-release - name: 📊 Generate coverage reports with lcov run: | lcov --directory . --capture --output-file coverage.info --gcov-tool gcov-13 - lcov --remove coverage.info '/usr/*' --remove coverage.info '**/.conan*' --remove coverage.info '**/test*' --output-file coverage.info + lcov --remove coverage.info '/usr/*' --remove coverage.info '**/.conan*' --remove coverage.info '**/test*' --remove coverage.info '**/test_package*' --output-file coverage.info lcov --list coverage.info - name: ☂️ Upload coverage reports to Codecov diff --git a/.gitignore b/.gitignore index d785328..6b22081 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,6 @@ /*build* /doc /include/cppIni/cppini_export.h +test_package/build +python CMakeUserPresets.json diff --git a/CMakeLists.txt b/CMakeLists.txt index f1da020..487bef4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ project(cppIni LANGUAGES CXX VERSION 0.1.0) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) -option(BUILD_TESTING "Build test files" ON) +option(BUILD_TESTING "Build test files" OFF) option(BUILD_SHARED_LIBS "Build shared library files" ON) option(CODE_COVERAGE "Enable coverage reporting" OFF) diff --git a/cmake/CodeCoverage.cmake b/cmake/CodeCoverage.cmake index 6b3a811..65545ed 100644 --- a/cmake/CodeCoverage.cmake +++ b/cmake/CodeCoverage.cmake @@ -11,3 +11,4 @@ if(CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU") ) target_link_options(coverage_config INTERFACE --coverage) endif() +install(TARGETS coverage_config EXPORT ${PROJECT_NAME}-targets) diff --git a/conanfile.py b/conanfile.py new file mode 100644 index 0000000..e36f11b --- /dev/null +++ b/conanfile.py @@ -0,0 +1,92 @@ +# cppIni - A C++20 library for reading and writing INI files +# Copyright (C) 2023 Nils Hofmann +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from conan import ConanFile +from conan.tools.build import check_min_cppstd +from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout, CMakeDeps + + +class cppiniRecipe(ConanFile): + name = "cppini" + version = "0.1.0" + package_type = "library" + + # Optional metadata + license = "GPL-3.0-or-later" + author = "Nils Hofmann " + url = "https://github.com/Master92/cppIni" + description = "A C++20 library for reading and writing INI files" + topics = ("c++20", "configuration", "ini") + + # Binary configuration + settings = "os", "compiler", "build_type", "arch" + options = { + "shared": [True, False], + "fPIC": [True, False], + "testing": [True, False], + "coverage": [True, False] + } + default_options = { + "shared": False, + "fPIC": True, + "testing": True, + "coverage": False + } + + # Sources are located in the same place as this recipe, copy them to the recipe + exports_sources = "CMakeLists.txt", "src/*", "include/*", "cmake/*", "tests/*" + + def build_requirements(self): + self.build_requires("cmake/[>=3.24]") + if self.options.testing: + self.test_requires("doctest/[>=2.4]") + + def config_options(self): + if self.settings.os == "Windows": + self.options.rm_safe("fPIC") + + def configure(self): + if self.options.shared: + self.options.rm_safe("fPIC") + + def layout(self): + cmake_layout(self) + + def validate(self): + if self.settings.compiler.cppstd: + check_min_cppstd(self, "20") + + def generate(self): + deps = CMakeDeps(self) + deps.generate() + tc = CMakeToolchain(self) + tc.variables["BUILD_SHARED_LIBS"] = self.options.shared + tc.variables["BUILD_TESTING"] = self.options.testing + tc.variables["CODE_COVERAGE"] = self.options.coverage + tc.generate() + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + cmake.test() + + def package(self): + cmake = CMake(self) + cmake.install() + + def package_info(self): + self.cpp_info.libs = ["cppini"] diff --git a/conanfile.txt b/conanfile.txt deleted file mode 100644 index cb01832..0000000 --- a/conanfile.txt +++ /dev/null @@ -1,6 +0,0 @@ -[requires] -doctest/[>=2.4] - -[generators] -CMakeDeps -CMakeToolchain \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1cd90d7..a6c813e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -36,3 +36,24 @@ target_include_directories(${PROJECT_NAME} PRIVATE $ ) + +## Install targets +include(GNUInstallDirs) +set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}) + +install(EXPORT ${PROJECT_NAME}-targets + FILE ${PROJECT_NAME}Targets.cmake + NAMESPACE ${PROJECT_NAME}:: + DESTINATION ${INSTALL_CONFIGDIR} +) + +install(FILES ${API_HEADERS} ${PROJECT_SOURCE_DIR}/include/${PROJECT_NAME}/${PROJECT_NAME_LOWER}_export.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} +) + +install(TARGETS ${PROJECT_NAME} + EXPORT ${PROJECT_NAME}-targets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/test_package/CMakeLists.txt b/test_package/CMakeLists.txt new file mode 100644 index 0000000..b981585 --- /dev/null +++ b/test_package/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.15) +project(PackageTest CXX) + +find_package(cppIni CONFIG REQUIRED) + +add_executable(example src/example.cpp) +target_link_libraries(example cppini::cppini) diff --git a/test_package/conanfile.py b/test_package/conanfile.py new file mode 100644 index 0000000..e3cea02 --- /dev/null +++ b/test_package/conanfile.py @@ -0,0 +1,26 @@ +import os + +from conan import ConanFile +from conan.tools.cmake import CMake, cmake_layout +from conan.tools.build import can_run + + +class cppiniTestConan(ConanFile): + settings = "os", "compiler", "build_type", "arch" + generators = "CMakeDeps", "CMakeToolchain" + + def requirements(self): + self.requires(self.tested_reference_str) + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def layout(self): + cmake_layout(self) + + def test(self): + if can_run(self): + cmd = os.path.join(self.cpp.build.bindir, "example") + self.run(cmd, env="conanrun") diff --git a/test_package/src/example.cpp b/test_package/src/example.cpp new file mode 100644 index 0000000..6ebd2d7 --- /dev/null +++ b/test_package/src/example.cpp @@ -0,0 +1,26 @@ +/* + * cppIni - A C++20 library for reading and writing INI files + * Copyright (C) 2023 Nils Hofmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +int main() +{ + Section s{"Section1"}; + + return EXIT_SUCCESS; +}