Skip to content

Commit 266d23c

Browse files
authored
Add permanent header-only and compiled library targets with CMake export support (#62)
* updating version numbers * no need for meson options now that we are building both compiled and header only together and providing them as options * no need for header only ci tasks, each ci task now builds and tests two different targets, regular pystring and pystring_header_only * no need for header only ci tasks, each ci task now builds and tests two different targets, regular pystring and pystring_header_only * updated meson and cmake build systems to have two available targets for the user to pick from compiled and header only * adding cmake configuration file * removing empty ci target * adding bit in pystringConfig to prevent double definition error * adding newline in file end for consistency
1 parent 381829c commit 266d23c

7 files changed

Lines changed: 149 additions & 178 deletions

File tree

.github/workflows/ci.yml

Lines changed: 2 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
runs-on: ubuntu-latest
2222
strategy:
2323
matrix:
24-
build: [1, 2, 3, 4, 5, 6]
24+
build: [1, 2, 3, 4]
2525
include:
2626
# -------------------------------------------------------------------
2727
# CLANG, Release
@@ -75,36 +75,6 @@ jobs:
7575
compiler-desc: gcc
7676
os: ubuntu-latest
7777

78-
79-
# -------------------------------------------------------------------
80-
# CLANG, Release header only
81-
# -------------------------------------------------------------------
82-
- build: 5
83-
build-type: Release
84-
build-shared: 'ON'
85-
header-only: 'ON'
86-
cxx-standard: 17
87-
cxx-compiler: clang++
88-
cxx-flags: ''
89-
cc-compiler: clang
90-
compiler-desc: clang
91-
os: ubuntu-latest
92-
93-
# -------------------------------------------------------------------
94-
# gcc, Release header only
95-
# -------------------------------------------------------------------
96-
- build: 6
97-
build-type: Release
98-
build-shared: 'ON'
99-
header-only: 'ON'
100-
cxx-standard: 17
101-
cxx-compiler: g++
102-
cxx-flags: ''
103-
cc-compiler: gcc
104-
compiler-desc: gcc
105-
os: ubuntu-latest
106-
107-
10878
env:
10979
CXX: ${{ matrix.cxx-compiler }}
11080
CC: ${{ matrix.cc-compiler }}
@@ -124,7 +94,6 @@ jobs:
12494
-DCMAKE_CXX_FLAGS=${{ matrix.cxx-flags }} \
12595
-DCMAKE_VERBOSE_MAKEFILE:BOOL='OFF' \
12696
-DBUILD_SHARED_LIBS=${{ matrix.build-shared }} \
127-
-DPYSTRING_HEADER_ONLY=${{ matrix.header-only }}
12897
working-directory: _build
12998
- name: Build
13099
run: |
@@ -145,7 +114,7 @@ jobs:
145114
runs-on: macos-latest
146115
strategy:
147116
matrix:
148-
build: [1, 2, 3]
117+
build: [1, 2]
149118
include:
150119

151120
# Release
@@ -165,16 +134,6 @@ jobs:
165134
cxx-flags: ''
166135
os: macos-latest
167136

168-
169-
# Release header only
170-
- build: 3
171-
build-type: Release
172-
build-shared: 'ON'
173-
header-only: 'ON'
174-
cxx-standard: 17
175-
cxx-flags: ''
176-
os: macos-latest
177-
178137
steps:
179138
- name: Checkout
180139
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -192,7 +151,6 @@ jobs:
192151
-DCMAKE_CXX_FLAGS=${{ matrix.cxx-flags }} \
193152
-DCMAKE_VERBOSE_MAKEFILE:BOOL='OFF' \
194153
-DBUILD_SHARED_LIBS=${{ matrix.build-shared }} \
195-
-DPYSTRING_HEADER_ONLY=${{ matrix.header-only }}
196154
working-directory: _build
197155
- name: Build
198156
run: |
@@ -232,15 +190,6 @@ jobs:
232190
cxx-flags: ''
233191
os: windows-latest
234192

235-
# Release header only
236-
- build: 3
237-
build-type: Release
238-
build-shared: 'ON'
239-
header-only: 'ON'
240-
cxx-standard: 17
241-
cxx-flags: ''
242-
os: windows-latest
243-
244193

245194
steps:
246195
- name: Checkout
@@ -261,7 +210,6 @@ jobs:
261210
-DCMAKE_CXX_FLAGS=${{ matrix.cxx-flags }} \
262211
-DCMAKE_VERBOSE_MAKEFILE:BOOL='OFF' \
263212
-DBUILD_SHARED_LIBS=${{ matrix.build-shared }} \
264-
-DPYSTRING_HEADER_ONLY=${{ matrix.header-only }}
265213
shell: bash
266214
working-directory: _build
267215
- name: Build

.github/workflows/meson.yml

Lines changed: 7 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,13 @@ on:
77
jobs:
88
meson-build-and-tests:
99
runs-on: ${{ matrix.platform }}
10-
name: ${{ matrix.platform }}, ${{ matrix.mode.name }} ${{ matrix.flavor }} ${{ matrix.library_mode }}
10+
name: ${{ matrix.platform }}, ${{ matrix.mode.name }} ${{ matrix.flavor }}
1111
strategy:
1212
fail-fast: false
1313
matrix:
1414
flavor:
1515
- debug
1616
- release
17-
library_mode:
18-
- compiled
19-
- header-only
2017
mode:
2118
- name: default
2219
extra_envs: {}
@@ -64,29 +61,6 @@ jobs:
6461
- macos-latest
6562

6663
exclude:
67-
# Only test header-only with a subset of configurations to reduce CI time
68-
# Test header-only only with default compiler in release mode
69-
- library_mode: header-only
70-
flavor: debug
71-
- library_mode: header-only
72-
mode:
73-
name: gcc
74-
- library_mode: header-only
75-
mode:
76-
name: clang
77-
- library_mode: header-only
78-
mode:
79-
name: sanitize
80-
- library_mode: header-only
81-
mode:
82-
name: sanitize+asanonly
83-
- library_mode: header-only
84-
mode:
85-
name: clang+sanitize
86-
- library_mode: header-only
87-
mode:
88-
name: clang-cl+sanitize
89-
9064
# clang-cl only makes sense on windows.
9165
- platform: ubuntu-22.04
9266
mode:
@@ -151,21 +125,21 @@ jobs:
151125
if: ${{ matrix.platform == 'windows-2022' }}
152126
env: ${{ matrix.mode.extra_envs }}
153127
run: |
154-
meson setup build-${{ matrix.flavor }}-${{ matrix.library_mode }} --buildtype=${{ matrix.flavor }} -Ddefault_library=static -Dheader_only=${{ matrix.library_mode == 'header-only' && 'true' || 'false' }} ${{ matrix.mode.args }} --vsenv
128+
meson setup build-${{ matrix.flavor }} --buildtype=${{ matrix.flavor }} -Ddefault_library=static ${{ matrix.mode.args }} --vsenv
155129
- name: Configuring
156130
if: ${{ matrix.platform != 'windows-2022' }}
157131
env: ${{ matrix.mode.extra_envs }}
158132
run: |
159-
meson setup build-${{ matrix.flavor }}-${{ matrix.library_mode }} --buildtype=${{ matrix.flavor }} -Dheader_only=${{ matrix.library_mode == 'header-only' && 'true' || 'false' }} ${{ matrix.mode.args }}
133+
meson setup build-${{ matrix.flavor }} --buildtype=${{ matrix.flavor }} ${{ matrix.mode.args }}
160134
- name: Building
161135
run: |
162-
meson compile -C build-${{ matrix.flavor }}-${{ matrix.library_mode }}
136+
meson compile -C build-${{ matrix.flavor }}
163137
- name: Running tests
164138
env: ${{ matrix.mode.extra_envs }}
165139
run: |
166-
meson test -C build-${{ matrix.flavor }}-${{ matrix.library_mode }} --timeout-multiplier 0
140+
meson test -C build-${{ matrix.flavor }} --timeout-multiplier 0
167141
- uses: actions/upload-artifact@v4
168142
if: failure()
169143
with:
170-
name: ${{ matrix.platform }}-${{ matrix.mode.name }}-${{ matrix.flavor }}-${{ matrix.library_mode }}-logs
171-
path: build-${{ matrix.flavor }}-${{ matrix.library_mode }}/meson-logs
144+
name: ${{ matrix.platform }}-${{ matrix.mode.name }}-${{ matrix.flavor }}-logs
145+
path: build-${{ matrix.flavor }}/meson-logs

CMakeLists.txt

Lines changed: 81 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
cmake_minimum_required(VERSION 3.10)
2-
project(pystring LANGUAGES CXX VERSION 1.1.4)
2+
project(pystring LANGUAGES CXX VERSION 1.2.0)
33

44
set(CMAKE_CXX_STANDARD 11)
55
set(CMAKE_CXX_STANDARD_REQUIRED ON)
66
set(CMAKE_CXX_EXTENSIONS OFF)
77

88
option (BUILD_SHARED_LIBS "Build shared libraries (set to OFF to build static libs)" ON)
9-
option(PYSTRING_HEADER_ONLY "Build as header-only library" OFF)
109

1110
# If the user hasn't configured cmake with an explicit
1211
# -DCMAKE_INSTALL_PREFIX=..., then set it to safely install into ./dist, to
@@ -19,52 +18,86 @@ endif()
1918
message (STATUS "Installation path will be ${CMAKE_INSTALL_PREFIX}")
2019
include(GNUInstallDirs)
2120

22-
if(PYSTRING_HEADER_ONLY)
23-
message(STATUS "Building pystring as header-only library")
24-
add_library(pystring INTERFACE)
25-
26-
target_compile_definitions(pystring INTERFACE PYSTRING_HEADER_ONLY)
27-
28-
target_include_directories(pystring INTERFACE
29-
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
30-
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
31-
)
32-
33-
# Install both headers for header-only mode
34-
install(FILES pystring.h pystring_impl.h
35-
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}
36-
)
37-
else()
38-
message(STATUS "Building pystring as compiled library")
39-
40-
add_library(pystring
41-
pystring.cpp
42-
pystring.h
43-
)
44-
45-
set_target_properties(pystring PROPERTIES
46-
VERSION ${PROJECT_VERSION}
47-
SOVERSION ${PROJECT_VERSION_MAJOR}
48-
)
49-
50-
install(TARGETS pystring
51-
LIBRARY DESTINATION lib
52-
RUNTIME DESTINATION bin
53-
ARCHIVE DESTINATION lib
54-
)
55-
56-
install (FILES pystring.h
57-
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}
58-
COMPONENT developer
59-
)
60-
61-
endif()
62-
63-
# Test executable
64-
65-
add_executable (pystring_test test.cpp)
66-
TARGET_LINK_LIBRARIES (pystring_test pystring)
21+
# --- Compiled library target: pystring::pystring ---
22+
add_library(pystring
23+
pystring.cpp
24+
pystring.h
25+
)
26+
27+
set_target_properties(pystring PROPERTIES
28+
VERSION ${PROJECT_VERSION}
29+
SOVERSION ${PROJECT_VERSION_MAJOR}
30+
)
31+
32+
target_include_directories(pystring PUBLIC
33+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
34+
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
35+
)
36+
37+
install(TARGETS pystring
38+
EXPORT pystringTargets
39+
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
40+
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
41+
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
42+
)
43+
44+
45+
# --- Header-only target: pystring::pystring_header_only ---
46+
add_library(pystring_header_only INTERFACE)
47+
48+
target_compile_definitions(pystring_header_only INTERFACE PYSTRING_HEADER_ONLY)
49+
50+
target_include_directories(pystring_header_only INTERFACE
51+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
52+
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
53+
)
54+
55+
install(TARGETS pystring_header_only
56+
EXPORT pystringTargets
57+
)
58+
59+
install(FILES pystring.h pystring_impl.h
60+
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}
61+
)
62+
63+
# --- Export & package config ---
64+
install(EXPORT pystringTargets
65+
FILE pystringTargets.cmake
66+
NAMESPACE pystring::
67+
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/pystring
68+
)
69+
70+
include(CMakePackageConfigHelpers)
71+
72+
configure_package_config_file(
73+
cmake/pystringConfig.cmake.in
74+
pystringConfig.cmake
75+
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/pystring
76+
)
77+
78+
write_basic_package_version_file(
79+
pystringConfigVersion.cmake
80+
VERSION ${PROJECT_VERSION}
81+
COMPATIBILITY SameMajorVersion
82+
)
83+
84+
install(FILES
85+
${CMAKE_CURRENT_BINARY_DIR}/pystringConfig.cmake
86+
${CMAKE_CURRENT_BINARY_DIR}/pystringConfigVersion.cmake
87+
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/pystring
88+
)
89+
90+
# --- Tests ---
91+
add_executable(pystring_test test.cpp)
92+
target_link_libraries(pystring_test pystring)
93+
94+
add_executable(pystring_test_header_only test.cpp)
95+
target_link_libraries(pystring_test_header_only pystring_header_only)
96+
97+
# Compile-time check that PYSTRING_HEADER_ONLY propagates correctly
98+
add_executable(pystring_test_header_only_define test_header_only_define.cpp)
99+
target_link_libraries(pystring_test_header_only_define pystring_header_only)
67100

68101
enable_testing()
69102
add_test(NAME PyStringTest COMMAND pystring_test)
70-
103+
add_test(NAME PyStringTestHeaderOnly COMMAND pystring_test_header_only)

cmake/pystringConfig.cmake.in

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@PACKAGE_INIT@
2+
3+
# Prevent double-definition errors
4+
if(NOT TARGET pystring::pystring AND NOT TARGET pystring::pystring_header_only)
5+
include("${CMAKE_CURRENT_LIST_DIR}/pystringTargets.cmake")
6+
endif()
7+
8+
check_required_components(pystring)

0 commit comments

Comments
 (0)