diff --git a/.github/workflows/ci_tests.yml b/.github/workflows/ci_tests.yml index 4ae60bf0..a6c0352f 100644 --- a/.github/workflows/ci_tests.yml +++ b/.github/workflows/ci_tests.yml @@ -43,7 +43,7 @@ jobs: { "stdlibs": ["libstdc++"], "tests": [ "Debug.Default", "Release.Default", "Release.TSan", - "Release.MaxSan", "Debug.Werror", "Debug.Dynamic", + "Release.MaxSan", "Debug.Werror", "Debug.Coverage" ] } @@ -78,7 +78,7 @@ jobs: { "stdlibs": ["libstdc++", "libc++"], "tests": [ "Debug.Default", "Release.Default", "Release.TSan", - "Release.MaxSan", "Debug.Werror", "Debug.Dynamic" + "Release.MaxSan", "Debug.Werror" ] } ] diff --git a/CMakeLists.txt b/CMakeLists.txt index c098765d..4fd233ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,9 +24,24 @@ option( ${PROJECT_IS_TOP_LEVEL} ) -include(CTest) +add_library(beman.exemplar INTERFACE) +add_library(beman::exemplar ALIAS beman.exemplar) + +target_sources( + beman.exemplar + PUBLIC + FILE_SET HEADERS + BASE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/include" + FILES + "${CMAKE_CURRENT_SOURCE_DIR}/include/beman/exemplar/identity.hpp" +) + +set_target_properties(beman.exemplar PROPERTIES VERIFY_INTERFACE_HEADER_SETS ON) -add_subdirectory(src/beman/exemplar) +find_package(beman-install-library REQUIRED) +beman_install_library(beman.exemplar) + +include(CTest) if(BEMAN_EXEMPLAR_BUILD_TESTS) add_subdirectory(tests/beman/exemplar) diff --git a/README.md b/README.md index 85a1cb22..e6b0e715 100644 --- a/README.md +++ b/README.md @@ -312,7 +312,6 @@ cmake -B build -S . -DCMAKE_CXX_STANDARD=20 -DBEMAN_EXEMPLAR_BUILD_TESTS=OFF Enable building examples. Default: ON. Values: { ON, OFF }. - #### `BEMAN_EXEMPLAR_INSTALL_CONFIG_FILE_PACKAGE` Enable installing the CMake config file package. Default: ON. @@ -358,10 +357,9 @@ any libraries or executables that include `beman.exemplar` headers. target_link_libraries(yourlib PUBLIC beman::exemplar) ``` -### Produce beman.exemplar static library +### Produce beman.exemplar interface library -You can include exemplar's headers locally -by producing a static `libbeman.exemplar.a` library. +You can produce exemplar's interface library locally by: ```bash cmake --workflow --preset gcc-release @@ -377,11 +375,9 @@ This will generate the following directory structure at `/opt/beman`. │ └── exemplar │ └── identity.hpp └── lib - ├── cmake - │   └── beman.exemplar - │   ├── beman.exemplar-config-version.cmake - │   ├── beman.exemplar-config.cmake - │   ├── beman.exemplar-targets-debug.cmake - │   └── beman.exemplar-targets.cmake - └── libbeman.exemplar.a + └── cmake + └── beman.exemplar + ├── beman.exemplar-config-version.cmake + ├── beman.exemplar-config.cmake + └── beman.exemplar-targets.cmake ``` diff --git a/src/beman/exemplar/beman.exemplar-config.cmake.in b/beman.exemplar-config.cmake.in similarity index 100% rename from src/beman/exemplar/beman.exemplar-config.cmake.in rename to beman.exemplar-config.cmake.in diff --git a/cookiecutter/check_cookiecutter.sh b/cookiecutter/check_cookiecutter.sh index fb5cb04c..7d3ae0cc 100755 --- a/cookiecutter/check_cookiecutter.sh +++ b/cookiecutter/check_cookiecutter.sh @@ -18,7 +18,8 @@ function check_consistency() { paper="P0898R3" \ owner="bemanproject" \ description="A Beman Library Exemplar" \ - godbolt_link="https://godbolt.org/z/4qEPK87va" + godbolt_link="https://godbolt.org/z/4qEPK87va" \ + library_type="interface" cp "$script_dir"/../.github/workflows/cookiecutter_test.yml "$out_dir_path"/exemplar/.github/workflows local diff_path diff_path=$(mktemp) diff --git a/cookiecutter/cookiecutter.json b/cookiecutter/cookiecutter.json index a33b87b4..0793d6a6 100644 --- a/cookiecutter/cookiecutter.json +++ b/cookiecutter/cookiecutter.json @@ -5,8 +5,9 @@ "owner": "github-user-name", "description": "Short project description.", "godbolt_link": "https://www.example.com", + "library_type": ["interface", "static"], "_copy_without_render": [ - "infra", - ".github/workflows" - ] + "infra" + ], + "_jinja2_env_vars": {"trim_blocks": true} } diff --git a/cookiecutter/hooks/post_gen_project.py b/cookiecutter/hooks/post_gen_project.py new file mode 100755 index 00000000..98e26321 --- /dev/null +++ b/cookiecutter/hooks/post_gen_project.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +"""Post-generation hook to clean up template files based on library_type.""" + +import shutil +from pathlib import Path + +# Get the library type from cookiecutter context +library_type = "{{ cookiecutter.library_type }}" + +# If interface library, remove the src/ directory (not needed for header-only) +if library_type == "interface": + src_dir = Path("src") + if src_dir.exists(): + shutil.rmtree(src_dir) + print("✓ Removed src/ directory (not needed for interface library)") + +print("✓ Template generation complete") diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/ci_tests.yml b/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/ci_tests.yml index 4ae60bf0..447e03f3 100644 --- a/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/ci_tests.yml +++ b/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/ci_tests.yml @@ -43,8 +43,9 @@ jobs: { "stdlibs": ["libstdc++"], "tests": [ "Debug.Default", "Release.Default", "Release.TSan", - "Release.MaxSan", "Debug.Werror", "Debug.Dynamic", - "Debug.Coverage" + "Release.MaxSan", "Debug.Werror", + "Debug.Coverage"{% if cookiecutter.library_type == "static" %}, "Debug.Dynamic"{% endif %} + ] } ] @@ -78,7 +79,8 @@ jobs: { "stdlibs": ["libstdc++", "libc++"], "tests": [ "Debug.Default", "Release.Default", "Release.TSan", - "Release.MaxSan", "Debug.Werror", "Debug.Dynamic" + "Release.MaxSan", "Debug.Werror"{% if cookiecutter.library_type == "static" %}, "Debug.Dynamic"{% endif %} + ] } ] diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-update.yml b/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-update.yml index ec7ac74c..ac5b0483 100644 --- a/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-update.yml +++ b/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-update.yml @@ -7,9 +7,12 @@ on: schedule: - cron: "0 16 * * 0" +{% raw -%} jobs: auto-update-pre-commit: uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-update-pre-commit.yml@1.1.0 secrets: APP_ID: ${{ secrets.AUTO_PR_BOT_APP_ID }} PRIVATE_KEY: ${{ secrets.AUTO_PR_BOT_PRIVATE_KEY }} +{%- endraw %} + diff --git a/cookiecutter/{{cookiecutter.project_name}}/CMakeLists.txt b/cookiecutter/{{cookiecutter.project_name}}/CMakeLists.txt index dcad0c2c..1cd78244 100644 --- a/cookiecutter/{{cookiecutter.project_name}}/CMakeLists.txt +++ b/cookiecutter/{{cookiecutter.project_name}}/CMakeLists.txt @@ -24,9 +24,28 @@ option( ${PROJECT_IS_TOP_LEVEL} ) -include(CTest) +{% if cookiecutter.library_type == "interface" %} +add_library(beman.{{cookiecutter.project_name}} INTERFACE) +add_library(beman::{{cookiecutter.project_name}} ALIAS beman.{{cookiecutter.project_name}}) + +target_sources( + beman.{{cookiecutter.project_name}} + PUBLIC + FILE_SET HEADERS + BASE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/include" + FILES + "${CMAKE_CURRENT_SOURCE_DIR}/include/beman/{{cookiecutter.project_name}}/identity.hpp" +) + +set_target_properties(beman.{{cookiecutter.project_name}} PROPERTIES VERIFY_INTERFACE_HEADER_SETS ON) +find_package(beman-install-library REQUIRED) +beman_install_library(beman.{{cookiecutter.project_name}}) +{% else %} add_subdirectory(src/beman/{{cookiecutter.project_name}}) +{% endif %} + +include(CTest) if(BEMAN_{{cookiecutter.project_name.upper()}}_BUILD_TESTS) add_subdirectory(tests/beman/{{cookiecutter.project_name}}) diff --git a/cookiecutter/{{cookiecutter.project_name}}/README.md b/cookiecutter/{{cookiecutter.project_name}}/README.md index 874ca814..513a44e4 100644 --- a/cookiecutter/{{cookiecutter.project_name}}/README.md +++ b/cookiecutter/{{cookiecutter.project_name}}/README.md @@ -312,7 +312,6 @@ cmake -B build -S . -DCMAKE_CXX_STANDARD=20 -DBEMAN_{{cookiecutter.project_name. Enable building examples. Default: ON. Values: { ON, OFF }. - #### `BEMAN_{{cookiecutter.project_name.upper()}}_INSTALL_CONFIG_FILE_PACKAGE` Enable installing the CMake config file package. Default: ON. @@ -358,10 +357,13 @@ any libraries or executables that include `beman.{{cookiecutter.project_name}}` target_link_libraries(yourlib PUBLIC beman::{{cookiecutter.project_name}}) ``` -### Produce beman.{{cookiecutter.project_name}} static library +### Produce beman.{{cookiecutter.project_name}} {{ cookiecutter.library_type }} library -You can include {{cookiecutter.project_name}}'s headers locally -by producing a static `libbeman.{{cookiecutter.project_name}}.a` library. +{% if cookiecutter.library_type == "interface" %} +You can produce {{cookiecutter.project_name}}'s interface library locally by: +{% else %} +You can produce {{cookiecutter.project_name}}'s static library `libbeman.{{cookiecutter.project_name}}.a` by: +{% endif %} ```bash cmake --workflow --preset gcc-release @@ -370,6 +372,22 @@ cmake --install build/gcc-release --prefix /opt/beman This will generate the following directory structure at `/opt/beman`. +{% if cookiecutter.library_type == "interface" %} +```txt +/opt/beman +├── include +│ └── beman +│ └── {{cookiecutter.project_name}} +│ └── identity.hpp +└── lib + └── cmake + └── beman.{{cookiecutter.project_name}} + ├── beman.{{cookiecutter.project_name}}-config-version.cmake + ├── beman.{{cookiecutter.project_name}}-config.cmake + └── beman.{{cookiecutter.project_name}}-targets.cmake + +``` +{% else %} ```txt /opt/beman ├── include @@ -378,10 +396,11 @@ This will generate the following directory structure at `/opt/beman`. │ └── identity.hpp └── lib ├── cmake - │   └── beman.{{cookiecutter.project_name}} - │   ├── beman.{{cookiecutter.project_name}}-config-version.cmake - │   ├── beman.{{cookiecutter.project_name}}-config.cmake - │   ├── beman.{{cookiecutter.project_name}}-targets-debug.cmake - │   └── beman.{{cookiecutter.project_name}}-targets.cmake + │ └── beman.{{cookiecutter.project_name}} + │ ├── beman.{{cookiecutter.project_name}}-config-version.cmake + │ ├── beman.{{cookiecutter.project_name}}-config.cmake + │ ├── beman.{{cookiecutter.project_name}}-targets-debug.cmake + │ └── beman.{{cookiecutter.project_name}}-targets.cmake └── libbeman.{{cookiecutter.project_name}}.a ``` +{% endif %} diff --git a/cookiecutter/{{cookiecutter.project_name}}/src/beman/{{cookiecutter.project_name}}/CMakeLists.txt b/cookiecutter/{{cookiecutter.project_name}}/src/beman/{{cookiecutter.project_name}}/CMakeLists.txt index ba64430a..14e85036 100644 --- a/cookiecutter/{{cookiecutter.project_name}}/src/beman/{{cookiecutter.project_name}}/CMakeLists.txt +++ b/cookiecutter/{{cookiecutter.project_name}}/src/beman/{{cookiecutter.project_name}}/CMakeLists.txt @@ -3,8 +3,6 @@ add_library(beman.{{cookiecutter.project_name}}) add_library(beman::{{cookiecutter.project_name}} ALIAS beman.{{cookiecutter.project_name}}) -target_sources(beman.{{cookiecutter.project_name}} PRIVATE identity.cpp) - target_sources( beman.{{cookiecutter.project_name}} PUBLIC @@ -12,6 +10,8 @@ target_sources( BASE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/../../../include" FILES "${CMAKE_CURRENT_SOURCE_DIR}/../../../include/beman/{{cookiecutter.project_name}}/identity.hpp" + PRIVATE + identity.cpp ) set_target_properties(beman.{{cookiecutter.project_name}} PROPERTIES VERIFY_INTERFACE_HEADER_SETS ON) diff --git a/cookiecutter/{{cookiecutter.project_name}}/src/beman/{{cookiecutter.project_name}}/identity.cpp b/cookiecutter/{{cookiecutter.project_name}}/src/beman/{{cookiecutter.project_name}}/identity.cpp index 1d076c7a..c1729968 100644 --- a/cookiecutter/{{cookiecutter.project_name}}/src/beman/{{cookiecutter.project_name}}/identity.cpp +++ b/cookiecutter/{{cookiecutter.project_name}}/src/beman/{{cookiecutter.project_name}}/identity.cpp @@ -1,3 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include + +// Implementation file for static library build. +// For a simple identity function, there's nothing to implement here, +// but this file exists to demonstrate the static library structure. diff --git a/src/beman/exemplar/CMakeLists.txt b/src/beman/exemplar/CMakeLists.txt deleted file mode 100644 index 14d9f70e..00000000 --- a/src/beman/exemplar/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -add_library(beman.exemplar) -add_library(beman::exemplar ALIAS beman.exemplar) - -target_sources(beman.exemplar PRIVATE identity.cpp) - -target_sources( - beman.exemplar - PUBLIC - FILE_SET HEADERS - BASE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/../../../include" - FILES - "${CMAKE_CURRENT_SOURCE_DIR}/../../../include/beman/exemplar/identity.hpp" -) - -set_target_properties(beman.exemplar PROPERTIES VERIFY_INTERFACE_HEADER_SETS ON) - -find_package(beman-install-library REQUIRED) -beman_install_library(beman.exemplar) diff --git a/src/beman/exemplar/identity.cpp b/src/beman/exemplar/identity.cpp deleted file mode 100644 index 21ef59d5..00000000 --- a/src/beman/exemplar/identity.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#include