1cmake_policy(SET CMP0079 NEW) # allow inserting of dependencies into our INTERFACE libraries 2set(PICO_PLATFORM_CMAKE_FILE "${PICO_PLATFORM_CMAKE_FILE}" CACHE INTERNAL "") 3set(PICO_DOXYGEN_PATHS "" CACHE INTERNAL "") # generated each time 4set(PICO_DOXYGEN_EXCLUDE_PATHS "" CACHE INTERNAL "") # generated each time 5set(PICO_DOXYGEN_PRE_DEFINES "" CACHE INTERNAL "") # generated each time 6set(PICO_DOXYGEN_ENABLED_SECTIONS "" CACHE INTERNAL "") # generated each time 7 8if (NOT PICO_PLATFORM_CMAKE_DIR) 9 set(PICO_PLATFORM_CMAKE_DIR ${CMAKE_CURRENT_LIST_DIR}) 10endif() 11if (NOT PICO_PLATFORM_CMAKE_FILE) 12 set(PICO_PLATFORM_CMAKE_FILE ${PICO_PLATFORM_CMAKE_DIR}/${PICO_PLATFORM}.cmake CACHE INTERNAL "") 13endif () 14 15if (NOT EXISTS "${PICO_PLATFORM_CMAKE_FILE}") 16 message(FATAL_ERROR "${PICO_PLATFORM_CMAKE_FILE} does not exist. \ 17 Either specify a valid PICO_PLATFORM (or PICO_PLATFORM_CMAKE_FILE).") 18endif () 19 20# call add_subdirectory(subdir) unless SKIP_SUBDIR evaluates to true 21# second argument is optional path 22function(pico_add_subdirectory subdir) 23 # todo add option to disable skip flag 24 string(TOUPPER ${subdir} subdir_upper) 25 # we do not include any path part of the subdir 26 get_filename_component(subdir_upper ${subdir_upper} NAME) 27 set(replace_flag SKIP_${subdir_upper}) 28 if (NOT ${replace_flag}) 29 string(TOUPPER ${subdir} subdir_upper) 30 set(replace_flag SKIP_${subdir_upper}) 31 if (${ARGC} GREATER 1) 32 # argv1 is the root where the subdir is relative to 33 add_subdirectory(${ARGV1}/${subdir} ${subdir}) 34 # todo make this optional? 35 pico_add_doxygen(${ARGV1}/${subdir}) 36 else() 37 add_subdirectory(${subdir}) 38 # todo make this optional? 39 pico_add_doxygen(${subdir}) 40 endif() 41 else() 42 message("Not including ${subdir} because ${replace_flag} defined.") 43 endif () 44 pico_promote_common_scope_vars() 45endfunction() 46 47# takes dependencies after the target 48function(pico_mirrored_target_link_libraries TARGET SCOPE) 49 if (${ARGC} LESS 3) 50 message(FATAL_ERROR "expected a target, scope and at least one dependency") 51 endif() 52 if (NOT TARGET ${TARGET}_headers) 53 message(FATAL_ERROR "${TARGET} does not have headers") 54 endif() 55 # library should depend on its own header 56 target_link_libraries(${TARGET} ${SCOPE} ${TARGET}_headers) 57 foreach(DEPENDENCY IN LISTS ARGN) 58 if (DEPENDENCY MATCHES ".*_headers") 59 message(FATAL_ERROR "should not use headers with pico_mirrored_target_link_libraries") 60 endif() 61 # note, it would be nice to only add the dependency if it exists, but we do 62 # not necessarily add libraries in reverse dependency order, so we do this 63 # unconditionally, so this function should only be passed dependencies that 64 # have headers, or link will fail with a missing library -lfoo_headers 65 target_link_libraries(${TARGET}_headers ${SCOPE} ${DEPENDENCY}_headers) 66 target_link_libraries(${TARGET} ${SCOPE} ${DEPENDENCY}) 67 endforeach() 68endfunction() 69 70# add a link option to wrap the given function name; i.e. -Wl:wrap=FUNCNAME for gcc 71function(pico_wrap_function TARGET FUNCNAME) 72 target_link_options(${TARGET} INTERFACE "LINKER:--wrap=${FUNCNAME}") 73endfunction() 74 75# add map file generation for the given target 76function(pico_add_map_output TARGET) 77 pico_get_runtime_output_directory(${TARGET} output_path) 78 get_target_property(target_type ${TARGET} TYPE) 79 if ("EXECUTABLE" STREQUAL "${target_type}") 80 target_link_options(${TARGET} PRIVATE "LINKER:-Map=${output_path}$<IF:$<BOOL:$<TARGET_PROPERTY:OUTPUT_NAME>>,$<TARGET_PROPERTY:OUTPUT_NAME>,$<TARGET_PROPERTY:NAME>>${CMAKE_EXECUTABLE_SUFFIX}.map") 81 else () 82 target_link_options(${TARGET} INTERFACE "LINKER:-Map=${output_path}$<IF:$<BOOL:$<TARGET_PROPERTY:OUTPUT_NAME>>,$<TARGET_PROPERTY:OUTPUT_NAME>,$<TARGET_PROPERTY:NAME>>${CMAKE_EXECUTABLE_SUFFIX}.map") 83 endif () 84endfunction() 85 86# create a hardware_NAME_headers target (see pico_simple_hardware_headers_target) 87# create a hardware_NAME target (see pico_simple_hardware_target) 88macro(pico_simple_hardware_target NAME) 89 pico_simple_hardware_headers_target(${NAME}) 90 pico_simple_hardware_impl_target(${NAME}) 91endmacro() 92 93# create an INTERFACE library named target, and define LIB_TARGET=1 (upper case) as a compile option 94# and make it dependent on a pre-existing corresponding _headers library 95# optional arg NOFLAG will skip the LIB_TARGET definition 96function(pico_add_impl_library target) 97 add_library(${target} INTERFACE) 98 string(TOUPPER ${target} TARGET_UPPER) 99 if (${ARGC} GREATER 1) 100 if (NOT "${ARGV1}" STREQUAL "NOFLAG") 101 message(FATAL_ERROR "Unknown parameter ${ARGV1}") 102 endif() 103 else() 104 target_compile_definitions(${target} INTERFACE LIB_${TARGET_UPPER}=1) 105 endif() 106 target_link_libraries(${target} INTERFACE ${target}_headers) 107endfunction() 108 109# create an INTERFACE library named target along with associated header, and define LIB_TARGET=1 (upper case) as a compile option 110# optional arg NOFLAG will skip the LIB_TARGET definition 111function(pico_add_library target) 112 add_library(${target}_headers INTERFACE) 113 pico_add_impl_library(${target} ${ARGN}) 114endfunction() 115 116# create an INTERFACE library named hardware_NAME_headers INTERFACE library if it doesn't already exist, 117# and add include/ relative to the calling directory to the includes. 118# and hardware_structs and hardware_claim as dependencies of the library 119macro(pico_simple_hardware_headers_target NAME) 120 if (NOT TARGET hardware_${NAME}_headers) 121 add_library(hardware_${NAME}_headers INTERFACE) 122 123 target_include_directories(hardware_${NAME}_headers SYSTEM INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include) 124 target_link_libraries(hardware_${NAME}_headers INTERFACE pico_base_headers) 125 if (NOT PICO_NO_HARDWARE) 126 target_link_libraries(hardware_${NAME}_headers INTERFACE hardware_structs hardware_claim_headers) 127 endif() 128 endif() 129endmacro() 130 131# create an INTERFACE library named hardware_NAME if it doesn't exist, along with a hardware_NAME_headers 132# INTERFACE library that it depends on. The hardware_NAME_headers library add include/ relative to 133# and pico_base_headers, and harddware_structs as a dependency of the library 134macro(pico_simple_hardware_headers_only_target NAME) 135 if (NOT TARGET hardware_${NAME}) 136 # Choosing not to add LIB_HARDWARE_ defines to avoid command line bloat pending a need (they aren't 137 # super interesting except to determine functionality as they are mostly passive accessors, however 138 # they could be useful to determine if the header is available. 139 # pico_add_sdk_impl_library(hardware_${NAME}) 140 add_library(hardware_${NAME}_headers INTERFACE) 141 142 # a headers only target should still have an explicit _headers library for consistency 143 target_include_directories(hardware_${NAME}_headers SYSTEM INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include) 144 target_link_libraries(hardware_${NAME}_headers INTERFACE pico_base_headers) 145 if (NOT PICO_NO_HARDWARE) 146 target_link_libraries(hardware_${NAME}_headers INTERFACE hardware_structs) 147 endif() 148 149 add_library(hardware_${NAME} INTERFACE) 150 target_link_libraries(hardware_${NAME} INTERFACE hardware_${NAME}_headers) 151 endif() 152endmacro() 153 154# create an INTERFACE library named hardware_NAME if it doesn't exist, dependent on a pre-existing hardware_NAME_headers 155# INTERFACE library and pico_platform. The file NAME.c relative to the caller is added to the C sources for the hardware_NAME 156macro(pico_simple_hardware_impl_target NAME) 157 if (NOT TARGET hardware_${NAME}) 158 # Choosing not to add LIB_HARDWARE_ defines to avoid command line bloat pending a need (they aren't 159 # super interesting except to determine functionality as they are mostly passive accessors, however 160 # they could be useful to determine if the header is available. 161 # pico_add_sdk_impl_library(hardware_${NAME}) 162 add_library(hardware_${NAME} INTERFACE) 163 164 target_sources(hardware_${NAME} INTERFACE 165 ${CMAKE_CURRENT_LIST_DIR}/${NAME}.c 166 ) 167 168 pico_mirrored_target_link_libraries(hardware_${NAME} INTERFACE pico_platform) 169 if (NOT PICO_NO_HARDWARE) 170 target_link_libraries(hardware_${NAME} INTERFACE hardware_claim) 171 endif() 172 endif() 173endmacro() 174 175function(pico_add_doxygen_pre_define PRE_DEFINE) 176 list(APPEND PICO_DOXYGEN_PRE_DEFINES "${PRE_DEFINE}") 177 set(PICO_DOXYGEN_PRE_DEFINES "${PICO_DOXYGEN_PRE_DEFINES}" CACHE INTERNAL "") 178endfunction() 179 180function(pico_add_doxygen_enabled_section ENABLED_SECTION) 181 list(APPEND PICO_DOXYGEN_ENABLED_SECTIONS "${ENABLED_SECTION}") 182 set(PICO_DOXYGEN_ENABLED_SECTIONS "${PICO_DOXYGEN_ENABLED_SECTIONS}" CACHE INTERNAL "") 183endfunction() 184 185function(pico_add_doxygen SOURCE_DIR) 186 if (NOT IS_ABSOLUTE "${SOURCE_DIR}") 187 get_filename_component(SOURCE_DIR "${SOURCE_DIR}" ABSOLUTE BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) 188 endif() 189 list(APPEND PICO_DOXYGEN_PATHS "${SOURCE_DIR}") 190 set(PICO_DOXYGEN_PATHS "${PICO_DOXYGEN_PATHS}" CACHE INTERNAL "") 191endfunction() 192 193function(pico_add_doxygen_exclude SOURCE_DIR) 194 if (NOT IS_ABSOLUTE "${SOURCE_DIR}") 195 get_filename_component(SOURCE_DIR "${SOURCE_DIR}" ABSOLUTE BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) 196 endif() 197 list(APPEND PICO_DOXYGEN_EXCLUDE_PATHS "${SOURCE_DIR}") 198 set(PICO_DOXYGEN_EXCLUDE_PATHS "${PICO_DOXYGEN_EXCLUDE_PATHS}" CACHE INTERNAL "") 199endfunction() 200 201include(${PICO_PLATFORM_CMAKE_FILE}) 202 203pico_promote_common_scope_vars()