Skip to content

Commit dba11d9

Browse files
committed
cmake: rework add_cxx_example
1 parent fdf0f7b commit dba11d9

File tree

2 files changed

+91
-37
lines changed

2 files changed

+91
-37
lines changed

cmake/cpp.cmake

Lines changed: 80 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,86 @@ function(add_cxx_library)
210210
message(STATUS "Configuring library ${LIBRARY_NAME} ...DONE")
211211
endfunction()
212212

213+
###################
214+
## C++ Example ##
215+
###################
216+
# add_cxx_example()
217+
# CMake function to generate and build C++ library.
218+
# Parameters:
219+
# NAME: CMake target name
220+
# [HEADERS]: List of headers files
221+
# SOURCES: List of source files
222+
# [COMPILE_DEFINITIONS]: List of private compile definitions
223+
# [COMPILE_OPTIONS]: List of private compile options
224+
# [LINK_LIBRARIES]: List of **public** libraries to use when linking
225+
# note: ortools::ortools is always linked to the target
226+
# [LINK_OPTIONS]: List of private link options
227+
# e.g.:
228+
# add_cxx_example(
229+
# NAME
230+
# foo
231+
# HEADERS
232+
# foo.h
233+
# SOURCES
234+
# foo.cc
235+
# ${PROJECT_SOURCE_DIR}/Foo/foo.cc
236+
# LINK_LIBRARIES
237+
# GTest::gmock
238+
# GTest::gtest_main
239+
# )
240+
function(add_cxx_example)
241+
set(options "")
242+
set(oneValueArgs "NAME;INSTALL_DIR")
243+
set(multiValueArgs
244+
"HEADERS;SOURCES;COMPILE_DEFINITIONS;COMPILE_OPTIONS;LINK_LIBRARIES;LINK_OPTIONS")
245+
cmake_parse_arguments(EXAMPLE
246+
"${options}"
247+
"${oneValueArgs}"
248+
"${multiValueArgs}"
249+
${ARGN}
250+
)
251+
if(NOT BUILD_EXAMPLES)
252+
return()
253+
endif()
254+
255+
if(NOT EXAMPLE_NAME)
256+
message(FATAL_ERROR "no NAME provided")
257+
endif()
258+
if(NOT EXAMPLE_SOURCES)
259+
message(FATAL_ERROR "no SOURCES provided")
260+
endif()
261+
message(STATUS "Configuring library ${EXAMPLE_NAME} ...")
262+
263+
add_executable(${EXAMPLE_NAME} "")
264+
target_sources(${EXAMPLE_NAME} PRIVATE ${EXAMPLE_SOURCES})
265+
target_include_directories(${EXAMPLE_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
266+
target_compile_definitions(${EXAMPLE_NAME} PRIVATE ${EXAMPLE_COMPILE_DEFINITIONS})
267+
target_compile_features(${EXAMPLE_NAME} PRIVATE cxx_std_20)
268+
target_compile_options(${EXAMPLE_NAME} PRIVATE ${EXAMPLE_COMPILE_OPTIONS})
269+
target_link_libraries(${EXAMPLE_NAME} PRIVATE ${EXAMPLE_LINK_LIBRARIES})
270+
target_link_options(${EXAMPLE_NAME} PRIVATE ${EXAMPLE_LINK_OPTIONS})
271+
272+
include(GNUInstallDirs)
273+
if(APPLE)
274+
set_target_properties(${EXAMPLE_NAME} PROPERTIES
275+
INSTALL_RPATH "@loader_path/../${CMAKE_INSTALL_LIBDIR};@loader_path")
276+
elseif(UNIX)
277+
cmake_path(RELATIVE_PATH CMAKE_INSTALL_FULL_LIBDIR
278+
BASE_DIRECTORY ${CMAKE_INSTALL_FULL_BINDIR}
279+
OUTPUT_VARIABLE libdir_relative_path)
280+
set_target_properties(${EXAMPLE_NAME} PROPERTIES
281+
INSTALL_RPATH "$ORIGIN/${libdir_relative_path}:$ORIGIN")
282+
endif()
283+
284+
install(TARGETS ${EXAMPLE_NAME})
285+
add_test(
286+
NAME cxx_${EXAMPLE_NAME}
287+
COMMAND ${EXAMPLE_NAME}
288+
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
289+
)
290+
message(STATUS "Configuring example ${EXAMPLE_NAME}: ...DONE")
291+
endfunction()
292+
213293
###################
214294
## CMake Install ##
215295
###################
@@ -238,39 +318,3 @@ install(
238318
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
239319
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
240320
COMPONENT Devel)
241-
242-
# add_cpp_example()
243-
# CMake function to generate and build C++ example.
244-
# Parameters:
245-
# the C++ filename
246-
# e.g.:
247-
# add_cpp_example(foo.cpp)
248-
function(add_cpp_example FILE_NAME)
249-
message(STATUS "Configuring example ${FILE_NAME}: ...")
250-
get_filename_component(EXAMPLE_NAME ${FILE_NAME} NAME_WE)
251-
get_filename_component(COMPONENT_DIR ${FILE_NAME} DIRECTORY)
252-
get_filename_component(COMPONENT_NAME ${COMPONENT_DIR} NAME)
253-
254-
if(APPLE)
255-
set(CMAKE_INSTALL_RPATH
256-
"@loader_path/../${CMAKE_INSTALL_LIBDIR};@loader_path")
257-
elseif(UNIX)
258-
set(CMAKE_INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}:$ORIGIN")
259-
endif()
260-
261-
add_executable(${EXAMPLE_NAME} ${FILE_NAME})
262-
target_include_directories(${EXAMPLE_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
263-
target_compile_features(${EXAMPLE_NAME} PRIVATE cxx_std_17)
264-
target_link_libraries(${EXAMPLE_NAME} PRIVATE
265-
${PROJECT_NAMESPACE}::Foo
266-
${PROJECT_NAMESPACE}::Bar
267-
${PROJECT_NAMESPACE}::FooBar)
268-
269-
include(GNUInstallDirs)
270-
install(TARGETS ${EXAMPLE_NAME})
271-
272-
if(BUILD_TESTING)
273-
add_test(NAME cpp_${COMPONENT_NAME}_${EXAMPLE_NAME} COMMAND ${EXAMPLE_NAME})
274-
endif()
275-
message(STATUS "Configuring example ${FILE_NAME}: ...DONE")
276-
endfunction()

examples/CMakeLists.txt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,17 @@ endif()
44

55
file(GLOB CPP_SRCS "*.cpp")
66
foreach(FILE_NAME IN LISTS CPP_SRCS)
7-
add_cpp_example(${FILE_NAME})
7+
get_filename_component(NAME ${FILE_NAME} NAME_WE)
8+
add_cxx_example(
9+
NAME
10+
${NAME}
11+
SOURCES
12+
${FILE_NAME}
13+
LINK_LIBRARIES
14+
${PROJECT_NAMESPACE}::Foo
15+
${PROJECT_NAMESPACE}::Bar
16+
${PROJECT_NAMESPACE}::FooBar
17+
)
818
endforeach()
919

1020
file(GLOB PYTHON_SRCS "*.py")

0 commit comments

Comments
 (0)