Screenplay: Function Wrapping add_library()
¶
Streamline Build-Spaghetti: How Want It?¶
Screenplay: Public And Private Include Directories was a massacre
toolcase/base/CMakeLists.txt
has become rather cluttered (base
ist the worst, the others are ugly too)Wanted: simple call to
my_add_library()
, beautifully reflecting the situationImplicitly dictating the directory structure
. ├── include │ ├── private │ └── public └── src
my_add_library(
NAME base
DEBUG
PUBLIC_HEADERS
sensor.h
sensor-const.h
sensor-random.h
sensor-avg.h
sensor-w1.h
switch.h
sysfs-switch.h
hysteresis.h
PRIVATE_HEADERS
file-util.h
SOURCES
sensor-const.cpp
sensor-random.cpp
sensor-avg.cpp
sensor-w1.cpp
sysfs-switch.cpp
hysteresis.cpp
file-util.cpp
)
Function my_add_library()
: cmake_parse_arguments()
¶
In same
CMakeLists.txt
, define function⟶
cmake_parse_arguments()
function(my_add_library) cmake_parse_arguments(MY_ADD_LIBRARY "SHARED;STATIC" "NAME" "PRIVATE_HEADERS;PUBLIC_HEADERS;SOURCES" ${ARGN}) message("MY_ADD_LIBRARY_SHARED: >${MY_ADD_LIBRARY_SHARED}<") message("MY_ADD_LIBRARY_STATIC: >${MY_ADD_LIBRARY_STATIC}<") message("MY_ADD_LIBRARY_NAME: >${MY_ADD_LIBRARY_NAME}<") message("MY_ADD_LIBRARY_PRIVATE_HEADERS: >${MY_ADD_LIBRARY_PRIVATE_HEADERS}<") message("MY_ADD_LIBRARY_PUBLIC_HEADERS: >${MY_ADD_LIBRARY_PUBLIC_HEADERS}<") message("MY_ADD_LIBRARY_SOURCES: >${MY_ADD_LIBRARY_SOURCES}<") endfunction()
Hmm … how about error checking?
SHARED
andSTATIC
passed?Externalize into
my_add_library.cmake
, and develop there (in script mode, mostly)⟶ we will use it in other modules too
Function my_add_library()
: Final Version¶
function(my_add_library)
cmake_parse_arguments(MY_ADD_LIBRARY "SHARED;STATIC;DEBUG" "NAME" "PRIVATE_HEADERS;PUBLIC_HEADERS;SOURCES" ${ARGN})
if (MY_ADD_LIBRARY_DEBUG)
message("MY_ADD_LIBRARY_SHARED: >${MY_ADD_LIBRARY_SHARED}<")
message("MY_ADD_LIBRARY_STATIC: >${MY_ADD_LIBRARY_STATIC}<")
message("MY_ADD_LIBRARY_NAME: >${MY_ADD_LIBRARY_NAME}<")
message("MY_ADD_LIBRARY_PRIVATE_HEADERS: >${MY_ADD_LIBRARY_PRIVATE_HEADERS}<")
message("MY_ADD_LIBRARY_PUBLIC_HEADERS: >${MY_ADD_LIBRARY_PUBLIC_HEADERS}<")
message("MY_ADD_LIBRARY_SOURCES: >${MY_ADD_LIBRARY_SOURCES}<")
message("ARGC: ${ARGC}")
message("ARGV: ${ARGV}")
message("ARGN: >${ARGN}<")
endif()
if (MY_ADD_LIBRARY_SHARED AND MY_ADD_LIBRARY_STATIC)
message(FATAL_ERROR "STATIC *and* SHARED is not possible")
endif()
foreach (f ${MY_ADD_LIBRARY_PUBLIC_HEADERS})
list(APPEND public_headers "include/public/${f}")
endforeach()
foreach (f ${MY_ADD_LIBRARY_PRIVATE_HEADERS})
list(APPEND public_headers "include/private/${f}")
endforeach()
foreach (f ${MY_ADD_LIBRARY_SOURCES})
list(APPEND sources "src/${f}")
endforeach()
if (MY_ADD_LIBRARY_SHARED)
set(how "SHARED")
elseif (MY_ADD_LIBRARY_STATIC)
set(how "STATIC")
endif()
add_library(
${MY_ADD_LIBRARY_NAME}
${how}
${public_headers}
${private_headers}
${sources}
)
target_include_directories(${MY_ADD_LIBRARY_NAME} PUBLIC ./include/public)
target_include_directories(${MY_ADD_LIBRARY_NAME} PRIVATE ./include/private)
install(TARGETS ${MY_ADD_LIBRARY_NAME} DESTINATION lib)
install(FILES ${MY_ADD_LIBRARY_PUBLIC_HEADERS} DESTINATION include)
endfunction()
Make my_add_library()
A Matter For The Architect¶
Put in toplevel
cmake/
directory (for all files of similar purpose)⟶ add to
${CMAKE_MODULE_PATH}
include()
in toplevelCMakeLists.txt
Remove existing
include()
frombase/CMakeLists.txt
RANT: when including via
${CMAKE_MODULE_PATH}
, omit the.cmake
extension or the file will not be found
⟶ directory scope (see Variables)
Restructure
data-logger
andboiling-pot
While we are at it, move compiler settings into
/cmake/compiler.cmake