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