Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
thejohnfreeman committed Nov 6, 2024
2 parents 0e208e1 + bac33bb commit fb867a0
Show file tree
Hide file tree
Showing 12 changed files with 301 additions and 197 deletions.
66 changes: 27 additions & 39 deletions cmake/cupcake_add_executables.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -7,49 +7,37 @@ include(cupcake_json)
function(cupcake_add_executables)
cupcake_assert_special()

# executables = metadata.get('executables', []):
# executables :: [{ name :: string, links? :: array }]
cupcake_json_get(executables ARRAY "[]" "${PROJECT_JSON}" executables)
# for executable in executables:
string(JSON count LENGTH "${executables}")
if(count GREATER 0)
math(EXPR stop "${count} - 1")
foreach(i RANGE ${stop})
# executable :: { name :: string, private? :: boolean, links :: array }
string(JSON executable GET "${executables}" ${i})
# executables = metadata.get('executables', [])
cupcake_json_get_list(executables "${PROJECT_JSON}" executables)
foreach(executable IN LISTS executables)
# executable :: { name :: string, private? :: boolean, links :: array }

# If ${name} is a JSON string, it is unquoted here.
string(JSON name GET "${executable}" name)
cupcake_json_get(private BOOLEAN "false" "${executable}" private)
if(private)
set(private PRIVATE)
else()
set(private)
endif()
cupcake_add_executable(${name} ${private} "${ARGN}")
# If ${name} is a JSON string, it is unquoted here.
string(JSON name GET "${executable}" name)
cupcake_json_get(private BOOLEAN "false" "${executable}" private)
if(private)
set(private PRIVATE)
else()
set(private)
endif()
cupcake_add_executable(${name} ${private} "${ARGN}")

cupcake_json_get(links ARRAY "[]" "${executable}" links)
# links :: [
cupcake_json_get_list(links "${executable}" links)
foreach(link IN LISTS links)
# link ::
# | string
# | { target :: string, scope? :: PUBLIC | PRIVATE | INTERFACE }
# ]
string(JSON count LENGTH "${links}")
if(count GREATER 0)
math(EXPR stop "${count} - 1")
foreach(j RANGE ${stop})
string(JSON link GET "${links}" ${j})
string(JSON type TYPE "${links}" ${j})
if(type STREQUAL STRING)
set(target "${link}")
set(scope "PRIVATE")
else()
string(JSON target GET "${link}" target)
cupcake_json_get(scope STRING "PRIVATE" "${link}" scope)
endif()
cmake_language(EVAL CODE "set(target ${target})")
target_link_libraries(${this} ${scope} ${target})
endforeach()
string(JSON type TYPE "${link}")
if(type STREQUAL STRING)
# A JSON string is already quoted.
set(target ${link})
set(scope "PRIVATE")
else()
string(JSON target GET "${link}" target)
cupcake_json_get(scope STRING "PRIVATE" "${link}" scope)
endif()
cmake_language(EVAL CODE "set(target ${target})")
target_link_libraries(${this} ${scope} ${target})
endforeach()
endif()
endforeach()
endfunction()
66 changes: 27 additions & 39 deletions cmake/cupcake_add_libraries.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -7,49 +7,37 @@ include(cupcake_json)
function(cupcake_add_libraries)
cupcake_assert_special()

# libraries = metadata.get('libraries', []):
# libraries :: [{ name :: string, links? :: array }]
cupcake_json_get(libraries ARRAY "[]" "${PROJECT_JSON}" libraries)
# for library in libraries:
string(JSON count LENGTH "${libraries}")
if(count GREATER 0)
math(EXPR stop "${count} - 1")
foreach(i RANGE ${stop})
# library :: { name :: string, private? :: boolean, links :: array }
string(JSON library GET "${libraries}" ${i})
# libraries = metadata.get('libraries', [])
cupcake_json_get_list(libraries "${PROJECT_JSON}" libraries)
foreach(library IN LISTS libraries)
# library :: { name :: string, private? :: boolean, links :: array }

# If ${name} is a JSON string, it is unquoted here.
string(JSON name GET "${library}" name)
cupcake_json_get(private BOOLEAN "false" "${library}" private)
if(private)
set(private PRIVATE)
else()
set(private)
endif()
cupcake_add_library(${name} ${private} "${ARGN}")
# If ${name} is a JSON string, it is unquoted here.
string(JSON name GET "${library}" name)
cupcake_json_get(private BOOLEAN "false" "${library}" private)
if(private)
set(private PRIVATE)
else()
set(private)
endif()
cupcake_add_library(${name} ${private} "${ARGN}")

cupcake_json_get(links ARRAY "[]" "${library}" links)
# links :: [
cupcake_json_get_list(links "${library}" links)
foreach(link IN LISTS links)
# link ::
# | string
# | { target :: string, scope? :: PUBLIC | PRIVATE | INTERFACE }
# ]
string(JSON count LENGTH "${links}")
if(count GREATER 0)
math(EXPR stop "${count} - 1")
foreach(j RANGE ${stop})
string(JSON link GET "${links}" ${j})
string(JSON type TYPE "${links}" ${j})
if(type STREQUAL STRING)
set(target "${link}")
set(scope "PUBLIC")
else()
string(JSON target GET "${link}" target)
cupcake_json_get(scope STRING "PUBLIC" "${link}" scope)
endif()
cmake_language(EVAL CODE "set(target ${target})")
target_link_libraries(${this} ${scope} ${target})
endforeach()
string(JSON type TYPE "${link}")
if(type STREQUAL STRING)
# A JSON string is already quoted.
set(target ${link})
set(scope "PUBLIC")
else()
string(JSON target GET "${link}" target)
cupcake_json_get(scope STRING "PUBLIC" "${link}" scope)
endif()
cmake_language(EVAL CODE "set(target ${target})")
target_link_libraries(${this} ${scope} ${target})
endforeach()
endif()
endforeach()
endfunction()
4 changes: 1 addition & 3 deletions cmake/cupcake_add_library.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ function(cupcake_add_library name)
if(name STREQUAL PROJECT_NAME)
add_library(${PROJECT_NAME}.library ALIAS ${target})
endif()
set_target_properties(${target} PROPERTIES
EXPORT_NAME libraries::${name}
)

target_link_libraries(${PROJECT_NAME}.libraries INTERFACE ${target})

Expand Down Expand Up @@ -112,6 +109,7 @@ function(cupcake_add_library name)
endif()

if(NOT arg_PRIVATE)
set_target_properties(${target} PROPERTIES EXPORT_NAME libraries::${name})
set(alias ${PROJECT_NAME}::libraries::${name})
add_library(${alias} ALIAS ${target})
add_library(${PROJECT_NAME}::l::${name} ALIAS ${target})
Expand Down
50 changes: 20 additions & 30 deletions cmake/cupcake_add_tests.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,30 @@ include(cupcake_json)

function(cupcake_add_tests)
cupcake_assert_special()
cupcake_json_get(tests ARRAY "[]" "${PROJECT_JSON}" tests)
# tests :: [{ name :: string, links? :: array }]
string(JSON count LENGTH "${tests}")
if(count GREATER 0)
math(EXPR stop "${count} - 1")
foreach(i RANGE ${stop})
string(JSON test GET "${tests}" ${i})
cupcake_json_get_list(tests "${PROJECT_JSON}" tests)
foreach(test IN LISTS tests)
# test :: { name :: string, links? :: array }

string(JSON name GET "${test}" name)
# If ${name} is a JSON string, it is unquoted here.
cupcake_add_test(${name} "${ARGN}")
string(JSON name GET "${test}" name)
# If ${name} is a JSON string, it is unquoted here.
cupcake_add_test(${name} "${ARGN}")

cupcake_json_get(links ARRAY "[]" "${test}" links)
# links :: [
cupcake_json_get_list(links "${test}" links)
foreach(link IN LISTS links)
# link ::
# | string
# | { target :: string, scope? :: PUBLIC | PRIVATE | INTERFACE }
# ]
string(JSON count LENGTH "${links}")
if(count GREATER 0)
math(EXPR stop "${count} - 1")
foreach(j RANGE ${stop})
string(JSON link GET "${links}" ${j})
string(JSON type TYPE "${links}" ${j})
if(type STREQUAL STRING)
set(target "${link}")
set(scope "PRIVATE")
else()
string(JSON target GET "${link}" target)
cupcake_json_get(scope STRING "PRIVATE" "${link}" scope)
endif()
cmake_language(EVAL CODE "set(target ${target})")
target_link_libraries(${this} ${scope} ${target})
endforeach()
string(JSON type TYPE "${link}")
if(type STREQUAL STRING)
# A JSON string is already quoted.
set(target ${link})
set(scope "PRIVATE")
else()
string(JSON target GET "${link}" target)
cupcake_json_get(scope STRING "PRIVATE" "${link}" scope)
endif()
cmake_language(EVAL CODE "set(target ${target})")
target_link_libraries(${this} ${scope} ${target})
endforeach()
endif()
endforeach()
endfunction()
39 changes: 17 additions & 22 deletions cmake/cupcake_find_packages.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,21 @@ include(cupcake_json)
# TODO: Default `group` to `main`.
function(cupcake_find_packages group)
cupcake_assert_special()
cupcake_json_get(imports ARRAY "[]" "${PROJECT_JSON}" imports)
# imports :: [{ file :: string?, targets :: [string], groups :: [string] }]
string(JSON count LENGTH "${imports}")
if(count GREATER 0)
math(EXPR stop "${count} - 1")
foreach(i RANGE ${stop})
string(JSON import GET "${imports}" ${i})
# Select only imports whose `groups` (default: `["main"]`)
# contain `group`.
cupcake_json_get(groups ARRAY "[\"main\"]" "${import}" groups)
cupcake_json_to_list(groups "${groups}")
list(FIND groups "${group}" j)
if(j LESS 0)
continue()
endif()
string(JSON file GET "${import}" file)
if(NOT file)
string(JSON file GET "${import}" name)
endif()
cupcake_find_package("${file}" "${ARGN}")
endforeach()
endif()
cupcake_json_get_list(imports "${PROJECT_JSON}" imports)
foreach(import IN LISTS imports)
# import :: { file :: string?, targets :: [string], groups :: [string] }
# Select only imports whose `groups` (default: `["main"]`) contain `group`.
cupcake_json_get(groups ARRAY "[\"main\"]" "${import}" groups)
cupcake_json_to_list(groups "${groups}")
# Group names are quoted JSON strings in the list.
list(FIND groups "\"${group}\"" i)
if(i LESS 0)
continue()
endif()
string(JSON file GET "${import}" file)
if(NOT file)
string(JSON file GET "${import}" name)
endif()
cupcake_find_package("${file}" "${ARGN}")
endforeach()
endfunction()
4 changes: 4 additions & 0 deletions cmake/cupcake_install_cpp_info.cmake
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
include_guard(GLOBAL)

include(cupcake_module_dir)
include(cupcake_project_properties)

file(READ "${CUPCAKE_MODULE_DIR}/data/install_cpp_info.cmake"
CUPCAKE_INSTALL_CPP_INFO
Expand All @@ -18,8 +19,11 @@ file(READ "${CUPCAKE_MODULE_DIR}/data/install_cpp_info.cmake"
# package with `find_package` and then generates and installs a `cpp_info.py`
# under `CMAKE_INSTALL_PREFIX`.
function(cupcake_install_cpp_info)
cupcake_get_project_property(EXTERNAL_CONAN_COMPONENTS)
string(REPLACE "\"" "\\\"" EXTERNAL_CONAN_COMPONENTS "${EXTERNAL_CONAN_COMPONENTS}")
install(
CODE "
set(EXTERNAL_CONAN_COMPONENTS \"${EXTERNAL_CONAN_COMPONENTS}\")
set(CMAKE_BINARY_DIR \"${CMAKE_BINARY_DIR}\")
set(PACKAGE_NAME ${PROJECT_NAME})
string(TOUPPER $<CONFIG> CONFIG)
Expand Down
31 changes: 27 additions & 4 deletions cmake/cupcake_json.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,38 @@ function(cupcake_json_get variable type default json)
set(${variable} "${value}" PARENT_SCOPE)
endfunction()

function(cupcake_json_to_list list array)
set(tmp "")
function(cupcake_json_to_list variable array)
unset(list)
string(JSON count LENGTH "${array}")
if(count GREATER 0)
math(EXPR stop "${count} - 1")
foreach(i RANGE ${stop})
string(JSON item GET "${array}" ${i})
list(APPEND tmp "${item}")
string(JSON type TYPE "${array}" ${i})
if(type STREQUAL STRING)
# CMake automatically unquotes JSON strings. Re-quote them here.
set(item "\"${item}\"")
endif()
list(APPEND list "${item}")
endforeach()
endif()
set(${list} "${tmp}" PARENT_SCOPE)
set(${variable} "${list}" PARENT_SCOPE)
endfunction()

function(cupcake_json_get_list variable json)
cupcake_json_get(list ARRAY "[]" "${json}" ${ARGN})
cupcake_json_to_list(list "${list}")
set(${variable} "${list}" PARENT_SCOPE)
endfunction()

# Unquote all strings in a list.
# unquote(variable [string...])
function(cupcake_unquote variable)
foreach(string ${ARGN})
if(string MATCHES "^\"(.*)\"$")
set(string "${CMAKE_MATCH_1}")
endif()
string(APPEND list "${string}")
endforeach()
set(${variable} "${list}" PARENT_SCOPE)
endfunction()
38 changes: 17 additions & 21 deletions cmake/cupcake_link_libraries.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,21 @@ include(cupcake_json)
# TODO: Default `group` to `main`.
function(cupcake_link_libraries target scope group)
cupcake_assert_special()
cupcake_json_get(imports ARRAY "[]" "${PROJECT_JSON}" imports)
# imports :: [{ file :: string, targets :: [string] }]
string(JSON count LENGTH "${imports}")
if(count GREATER 0)
math(EXPR stop "${count} - 1")
foreach(i RANGE ${stop})
string(JSON import GET "${imports}" ${i})
# Select only imports whose `groups` (default: `["main"]`)
# contain `group`.
cupcake_json_get(groups ARRAY "[\"main\"]" "${import}" groups)
cupcake_json_to_list(groups "${groups}")
list(FIND groups "${group}" j)
if(j LESS 0)
continue()
endif()
string(JSON name GET "${import}" name)
cupcake_json_get(targets ARRAY "[\"${name}::${name}\"]" "${import}" targets)
cupcake_json_to_list(targets "${targets}")
target_link_libraries(${target} ${scope} ${targets})
endforeach()
endif()
cupcake_json_get_list(imports "${PROJECT_JSON}" imports)
foreach(import IN LISTS imports)
# import :: { file :: string, targets :: [string] }
# Select only imports whose `groups` (default: `["main"]`) contain `group`.
cupcake_json_get(groups ARRAY "[\"main\"]" "${import}" groups)
cupcake_json_to_list(groups "${groups}")
# Group names are quoted JSON strings in the list.
list(FIND groups "\"${group}\"" i)
if(i LESS 0)
continue()
endif()
string(JSON name GET "${import}" name)
cupcake_json_get(targets ARRAY "[\"${name}::${name}\"]" "${import}" targets)
cupcake_json_to_list(targets "${targets}")
cupcake_unquote(targets "${targets}")
target_link_libraries(${target} ${scope} ${targets})
endforeach()
endfunction()
Loading

0 comments on commit fb867a0

Please sign in to comment.