Screenplay: Function Wrapping add_library()#
Streamline Build-Spaghetti: How Want It?#
Screenplay: Public And Private Include Directories was a massacre
toolcase/base/CMakeLists.txthas become rather cluttered (baseist 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?
SHAREDandSTATICpassed?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.txtRemove existing
include()frombase/CMakeLists.txtRANT: when including via
${CMAKE_MODULE_PATH}, omit the.cmakeextension or the file will not be found
⟶ directory scope (see Variables)
Restructure
data-loggerandboiling-potWhile we are at it, move compiler settings into
/cmake/compiler.cmake