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