xref: /aosp_15_r20/external/pigweed/pw_build/pigweed.cmake (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker# Copyright 2020 The Pigweed Authors
2*61c4878aSAndroid Build Coastguard Worker#
3*61c4878aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4*61c4878aSAndroid Build Coastguard Worker# use this file except in compliance with the License. You may obtain a copy of
5*61c4878aSAndroid Build Coastguard Worker# the License at
6*61c4878aSAndroid Build Coastguard Worker#
7*61c4878aSAndroid Build Coastguard Worker#     https://www.apache.org/licenses/LICENSE-2.0
8*61c4878aSAndroid Build Coastguard Worker#
9*61c4878aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*61c4878aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11*61c4878aSAndroid Build Coastguard Worker# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12*61c4878aSAndroid Build Coastguard Worker# License for the specific language governing permissions and limitations under
13*61c4878aSAndroid Build Coastguard Worker# the License.
14*61c4878aSAndroid Build Coastguard Workerinclude_guard(GLOBAL)
15*61c4878aSAndroid Build Coastguard Worker
16*61c4878aSAndroid Build Coastguard Workercmake_minimum_required(VERSION 3.19)
17*61c4878aSAndroid Build Coastguard Worker
18*61c4878aSAndroid Build Coastguard Worker# The PW_ROOT environment variable should be set in bootstrap. If it is not set,
19*61c4878aSAndroid Build Coastguard Worker# set it to the root of the Pigweed repository.
20*61c4878aSAndroid Build Coastguard Workerif("$ENV{PW_ROOT}" STREQUAL "")
21*61c4878aSAndroid Build Coastguard Worker  get_filename_component(pw_root "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE)
22*61c4878aSAndroid Build Coastguard Worker  message("The PW_ROOT environment variable is not set; "
23*61c4878aSAndroid Build Coastguard Worker          "using ${pw_root} within CMake")
24*61c4878aSAndroid Build Coastguard Worker  set(ENV{PW_ROOT} "${pw_root}")
25*61c4878aSAndroid Build Coastguard Workerendif()
26*61c4878aSAndroid Build Coastguard Worker
27*61c4878aSAndroid Build Coastguard Worker# TOOD(ewout, hepler): Remove this legacy include once all users pull in
28*61c4878aSAndroid Build Coastguard Worker# pw_unit_test/test.cmake for test functions and variables instead of relying
29*61c4878aSAndroid Build Coastguard Worker# on them to be provided by pw_build/pigweed.cmake.
30*61c4878aSAndroid Build Coastguard Workerinclude("$ENV{PW_ROOT}/pw_unit_test/test.cmake")
31*61c4878aSAndroid Build Coastguard Worker
32*61c4878aSAndroid Build Coastguard Worker# Wrapper around cmake_parse_arguments that fails with an error if any arguments
33*61c4878aSAndroid Build Coastguard Worker# remained unparsed or a required argument was not provided.
34*61c4878aSAndroid Build Coastguard Worker#
35*61c4878aSAndroid Build Coastguard Worker# All parsed arguments are prefixed with "arg_". This helper can only be used
36*61c4878aSAndroid Build Coastguard Worker# by functions, not macros.
37*61c4878aSAndroid Build Coastguard Worker#
38*61c4878aSAndroid Build Coastguard Worker# Required Arguments:
39*61c4878aSAndroid Build Coastguard Worker#
40*61c4878aSAndroid Build Coastguard Worker#   NUM_POSITIONAL_ARGS - PARSE_ARGV <N> arguments for
41*61c4878aSAndroid Build Coastguard Worker#                              cmake_parse_arguments
42*61c4878aSAndroid Build Coastguard Worker#
43*61c4878aSAndroid Build Coastguard Worker# Optional Args:
44*61c4878aSAndroid Build Coastguard Worker#
45*61c4878aSAndroid Build Coastguard Worker#   OPTION_ARGS - <option> arguments for cmake_parse_arguments
46*61c4878aSAndroid Build Coastguard Worker#   ONE_VALUE_ARGS - <one_value_keywords> arguments for cmake_parse_arguments
47*61c4878aSAndroid Build Coastguard Worker#   MULTI_VALUE_ARGS - <multi_value_keywords> arguments for
48*61c4878aSAndroid Build Coastguard Worker#                           cmake_parse_arguments
49*61c4878aSAndroid Build Coastguard Worker#   REQUIRED_ARGS - required arguments which must be set, these may any
50*61c4878aSAndroid Build Coastguard Worker#                        argument type (<option>, <one_value_keywords>, and/or
51*61c4878aSAndroid Build Coastguard Worker#                        <multi_value_keywords>)
52*61c4878aSAndroid Build Coastguard Worker#
53*61c4878aSAndroid Build Coastguard Workermacro(pw_parse_arguments)
54*61c4878aSAndroid Build Coastguard Worker  # First parse the arguments to this macro.
55*61c4878aSAndroid Build Coastguard Worker  cmake_parse_arguments(
56*61c4878aSAndroid Build Coastguard Worker    pw_parse_arg "" "NUM_POSITIONAL_ARGS"
57*61c4878aSAndroid Build Coastguard Worker    "OPTION_ARGS;ONE_VALUE_ARGS;MULTI_VALUE_ARGS;REQUIRED_ARGS"
58*61c4878aSAndroid Build Coastguard Worker    ${ARGN}
59*61c4878aSAndroid Build Coastguard Worker  )
60*61c4878aSAndroid Build Coastguard Worker  pw_require_args("pw_parse_arguments" "pw_parse_arg_" NUM_POSITIONAL_ARGS)
61*61c4878aSAndroid Build Coastguard Worker  if(NOT "${pw_parse_arg_UNPARSED_ARGUMENTS}" STREQUAL "")
62*61c4878aSAndroid Build Coastguard Worker    message(FATAL_ERROR "Unexpected arguments to pw_parse_arguments: "
63*61c4878aSAndroid Build Coastguard Worker            "${pw_parse_arg_UNPARSED_ARGUMENTS}")
64*61c4878aSAndroid Build Coastguard Worker  endif()
65*61c4878aSAndroid Build Coastguard Worker
66*61c4878aSAndroid Build Coastguard Worker  # Now that we have the macro's arguments, process the caller's arguments.
67*61c4878aSAndroid Build Coastguard Worker  pw_parse_arguments_strict("${CMAKE_CURRENT_FUNCTION}"
68*61c4878aSAndroid Build Coastguard Worker    "${pw_parse_arg_NUM_POSITIONAL_ARGS}"
69*61c4878aSAndroid Build Coastguard Worker    "${pw_parse_arg_OPTION_ARGS}"
70*61c4878aSAndroid Build Coastguard Worker    "${pw_parse_arg_ONE_VALUE_ARGS}"
71*61c4878aSAndroid Build Coastguard Worker    "${pw_parse_arg_MULTI_VALUE_ARGS}"
72*61c4878aSAndroid Build Coastguard Worker  )
73*61c4878aSAndroid Build Coastguard Worker  pw_require_args("${CMAKE_CURRENT_FUNCTION}" "arg_"
74*61c4878aSAndroid Build Coastguard Worker                  ${pw_parse_arg_REQUIRED_ARGS})
75*61c4878aSAndroid Build Coastguard Workerendmacro()
76*61c4878aSAndroid Build Coastguard Worker
77*61c4878aSAndroid Build Coastguard Worker# TODO(ewout, hepler): Deprecate this function in favor of pw_parse_arguments.
78*61c4878aSAndroid Build Coastguard Worker# Wrapper around cmake_parse_arguments that fails with an error if any arguments
79*61c4878aSAndroid Build Coastguard Worker# remained unparsed.
80*61c4878aSAndroid Build Coastguard Workermacro(pw_parse_arguments_strict function start_arg options one multi)
81*61c4878aSAndroid Build Coastguard Worker  cmake_parse_arguments(PARSE_ARGV
82*61c4878aSAndroid Build Coastguard Worker      "${start_arg}" arg "${options}" "${one}" "${multi}"
83*61c4878aSAndroid Build Coastguard Worker  )
84*61c4878aSAndroid Build Coastguard Worker  if(NOT "${arg_UNPARSED_ARGUMENTS}" STREQUAL "")
85*61c4878aSAndroid Build Coastguard Worker    set(_all_args ${options} ${one} ${multi})
86*61c4878aSAndroid Build Coastguard Worker    message(FATAL_ERROR
87*61c4878aSAndroid Build Coastguard Worker        "Unexpected arguments to ${function}: ${arg_UNPARSED_ARGUMENTS}\n"
88*61c4878aSAndroid Build Coastguard Worker        "Valid arguments: ${_all_args}"
89*61c4878aSAndroid Build Coastguard Worker    )
90*61c4878aSAndroid Build Coastguard Worker  endif()
91*61c4878aSAndroid Build Coastguard Workerendmacro()
92*61c4878aSAndroid Build Coastguard Worker
93*61c4878aSAndroid Build Coastguard Worker# Checks that one or more variables are set. This is used to check that
94*61c4878aSAndroid Build Coastguard Worker# arguments were provided to a function. Fails with FATAL_ERROR if
95*61c4878aSAndroid Build Coastguard Worker# ${ARG_PREFIX}${name} is empty. The FUNCTION_NAME is used in the error message.
96*61c4878aSAndroid Build Coastguard Worker# If FUNCTION_NAME is "", it is set to CMAKE_CURRENT_FUNCTION.
97*61c4878aSAndroid Build Coastguard Worker#
98*61c4878aSAndroid Build Coastguard Worker# Usage:
99*61c4878aSAndroid Build Coastguard Worker#
100*61c4878aSAndroid Build Coastguard Worker#   pw_require_args(FUNCTION_NAME ARG_PREFIX ARG_NAME [ARG_NAME ...])
101*61c4878aSAndroid Build Coastguard Worker#
102*61c4878aSAndroid Build Coastguard Worker# Examples:
103*61c4878aSAndroid Build Coastguard Worker#
104*61c4878aSAndroid Build Coastguard Worker#   # Checks that arg_FOO is non-empty, using the current function name.
105*61c4878aSAndroid Build Coastguard Worker#   pw_require_args("" arg_ FOO)
106*61c4878aSAndroid Build Coastguard Worker#
107*61c4878aSAndroid Build Coastguard Worker#   # Checks that FOO and BAR are non-empty, using function name "do_the_thing".
108*61c4878aSAndroid Build Coastguard Worker#   pw_require_args(do_the_thing "" FOO BAR)
109*61c4878aSAndroid Build Coastguard Worker#
110*61c4878aSAndroid Build Coastguard Workermacro(pw_require_args FUNCTION_NAME ARG_PREFIX)
111*61c4878aSAndroid Build Coastguard Worker  if("${FUNCTION_NAME}" STREQUAL "")
112*61c4878aSAndroid Build Coastguard Worker    set(_pw_require_args_FUNCTION_NAME "${CMAKE_CURRENT_FUNCTION}")
113*61c4878aSAndroid Build Coastguard Worker  else()
114*61c4878aSAndroid Build Coastguard Worker    set(_pw_require_args_FUNCTION_NAME "${FUNCTION_NAME}")
115*61c4878aSAndroid Build Coastguard Worker  endif()
116*61c4878aSAndroid Build Coastguard Worker
117*61c4878aSAndroid Build Coastguard Worker  foreach(name IN ITEMS ${ARGN})
118*61c4878aSAndroid Build Coastguard Worker    if("${${ARG_PREFIX}${name}}" STREQUAL "")
119*61c4878aSAndroid Build Coastguard Worker      message(FATAL_ERROR "A value must be provided for ${name} in "
120*61c4878aSAndroid Build Coastguard Worker          "${_pw_require_args_FUNCTION_NAME}.")
121*61c4878aSAndroid Build Coastguard Worker    endif()
122*61c4878aSAndroid Build Coastguard Worker  endforeach()
123*61c4878aSAndroid Build Coastguard Workerendmacro()
124*61c4878aSAndroid Build Coastguard Worker
125*61c4878aSAndroid Build Coastguard Worker# pw_target_link_targets: CMake target only form of target_link_libraries.
126*61c4878aSAndroid Build Coastguard Worker#
127*61c4878aSAndroid Build Coastguard Worker# Helper wrapper around target_link_libraries which only supports CMake targets
128*61c4878aSAndroid Build Coastguard Worker# and detects when the target does not exist.
129*61c4878aSAndroid Build Coastguard Worker#
130*61c4878aSAndroid Build Coastguard Worker# NOTE: Generator expressions are not supported.
131*61c4878aSAndroid Build Coastguard Worker#
132*61c4878aSAndroid Build Coastguard Worker# Due to the processing order of list files, the list of targets has to be
133*61c4878aSAndroid Build Coastguard Worker# checked at the end of the root CMake list file. Instead of requiring all
134*61c4878aSAndroid Build Coastguard Worker# list files to be modified, a DEFER CALL is used.
135*61c4878aSAndroid Build Coastguard Worker#
136*61c4878aSAndroid Build Coastguard Worker# Required Args:
137*61c4878aSAndroid Build Coastguard Worker#
138*61c4878aSAndroid Build Coastguard Worker#   <name> - The library target to add the TARGET link dependencies to.
139*61c4878aSAndroid Build Coastguard Worker#
140*61c4878aSAndroid Build Coastguard Worker# Optional Args:
141*61c4878aSAndroid Build Coastguard Worker#
142*61c4878aSAndroid Build Coastguard Worker#   INTERFACE - interface target_link_libraries arguments which are all TARGETs.
143*61c4878aSAndroid Build Coastguard Worker#   PUBLIC - public target_link_libraries arguments which are all TARGETs.
144*61c4878aSAndroid Build Coastguard Worker#   PRIVATE - private target_link_libraries arguments which are all TARGETs.
145*61c4878aSAndroid Build Coastguard Workerfunction(pw_target_link_targets NAME)
146*61c4878aSAndroid Build Coastguard Worker  set(types INTERFACE PUBLIC PRIVATE )
147*61c4878aSAndroid Build Coastguard Worker  pw_parse_arguments(
148*61c4878aSAndroid Build Coastguard Worker    NUM_POSITIONAL_ARGS
149*61c4878aSAndroid Build Coastguard Worker      1
150*61c4878aSAndroid Build Coastguard Worker    MULTI_VALUE_ARGS
151*61c4878aSAndroid Build Coastguard Worker      ${types}
152*61c4878aSAndroid Build Coastguard Worker  )
153*61c4878aSAndroid Build Coastguard Worker
154*61c4878aSAndroid Build Coastguard Worker  if(NOT TARGET "${NAME}")
155*61c4878aSAndroid Build Coastguard Worker    message(FATAL_ERROR "\"${NAME}\" must be a TARGET library")
156*61c4878aSAndroid Build Coastguard Worker  endif()
157*61c4878aSAndroid Build Coastguard Worker
158*61c4878aSAndroid Build Coastguard Worker  foreach(type IN LISTS types)
159*61c4878aSAndroid Build Coastguard Worker    foreach(library IN LISTS arg_${type})
160*61c4878aSAndroid Build Coastguard Worker      target_link_libraries(${NAME} ${type} ${library})
161*61c4878aSAndroid Build Coastguard Worker      if(NOT TARGET ${library})
162*61c4878aSAndroid Build Coastguard Worker        # It's possible the target has not yet been defined due to the ordering
163*61c4878aSAndroid Build Coastguard Worker        # of add_subdirectory. Ergo defer the call until the end of the
164*61c4878aSAndroid Build Coastguard Worker        # configuration phase.
165*61c4878aSAndroid Build Coastguard Worker
166*61c4878aSAndroid Build Coastguard Worker        # cmake_language(DEFER ...) evaluates arguments at the time the deferred
167*61c4878aSAndroid Build Coastguard Worker        # call is executed, ergo wrap it in a cmake_language(EVAL CODE ...) to
168*61c4878aSAndroid Build Coastguard Worker        # evaluate the arguments now. The arguments are wrapped in brackets to
169*61c4878aSAndroid Build Coastguard Worker        # avoid re-evaluation at the deferred call.
170*61c4878aSAndroid Build Coastguard Worker        cmake_language(EVAL CODE
171*61c4878aSAndroid Build Coastguard Worker          "cmake_language(DEFER DIRECTORY ${CMAKE_SOURCE_DIR} CALL
172*61c4878aSAndroid Build Coastguard Worker                          _pw_target_link_targets_deferred_check
173*61c4878aSAndroid Build Coastguard Worker                          [[${NAME}]] [[${type}]] ${library})"
174*61c4878aSAndroid Build Coastguard Worker        )
175*61c4878aSAndroid Build Coastguard Worker      endif()
176*61c4878aSAndroid Build Coastguard Worker    endforeach()
177*61c4878aSAndroid Build Coastguard Worker  endforeach()
178*61c4878aSAndroid Build Coastguard Workerendfunction()
179*61c4878aSAndroid Build Coastguard Worker
180*61c4878aSAndroid Build Coastguard Worker# Runs any deferred library checks for pw_target_link_targets.
181*61c4878aSAndroid Build Coastguard Worker#
182*61c4878aSAndroid Build Coastguard Worker# Required Args:
183*61c4878aSAndroid Build Coastguard Worker#
184*61c4878aSAndroid Build Coastguard Worker#   <name> - The name of the library target to add the link dependencies to.
185*61c4878aSAndroid Build Coastguard Worker#   <type> - The type of the library (INTERFACE, PUBLIC, PRIVATE).
186*61c4878aSAndroid Build Coastguard Worker#   <library> - The library to check to assert it's a TARGET.
187*61c4878aSAndroid Build Coastguard Workerfunction(_pw_target_link_targets_deferred_check NAME TYPE LIBRARY)
188*61c4878aSAndroid Build Coastguard Worker  if(NOT TARGET ${LIBRARY})
189*61c4878aSAndroid Build Coastguard Worker      message(FATAL_ERROR
190*61c4878aSAndroid Build Coastguard Worker        "${NAME}'s ${TYPE} dep \"${LIBRARY}\" is not a target.")
191*61c4878aSAndroid Build Coastguard Worker  endif()
192*61c4878aSAndroid Build Coastguard Workerendfunction()
193*61c4878aSAndroid Build Coastguard Worker
194*61c4878aSAndroid Build Coastguard Worker# Sets the provided variable to the multi_value_keywords from pw_add_library.
195*61c4878aSAndroid Build Coastguard Workermacro(_pw_add_library_multi_value_args variable)
196*61c4878aSAndroid Build Coastguard Worker  set("${variable}" SOURCES HEADERS
197*61c4878aSAndroid Build Coastguard Worker                    PUBLIC_DEPS PRIVATE_DEPS
198*61c4878aSAndroid Build Coastguard Worker                    PUBLIC_INCLUDES PRIVATE_INCLUDES
199*61c4878aSAndroid Build Coastguard Worker                    PUBLIC_DEFINES PRIVATE_DEFINES
200*61c4878aSAndroid Build Coastguard Worker                    PUBLIC_COMPILE_OPTIONS PRIVATE_COMPILE_OPTIONS
201*61c4878aSAndroid Build Coastguard Worker                    PUBLIC_LINK_OPTIONS PRIVATE_LINK_OPTIONS "${ARGN}")
202*61c4878aSAndroid Build Coastguard Workerendmacro()
203*61c4878aSAndroid Build Coastguard Worker
204*61c4878aSAndroid Build Coastguard Worker# pw_add_library_generic: Creates a CMake library target.
205*61c4878aSAndroid Build Coastguard Worker#
206*61c4878aSAndroid Build Coastguard Worker# Required Args:
207*61c4878aSAndroid Build Coastguard Worker#
208*61c4878aSAndroid Build Coastguard Worker#   <name> - The name of the library target to be created.
209*61c4878aSAndroid Build Coastguard Worker#   <type> - The library type which must be INTERFACE, OBJECT, STATIC, or
210*61c4878aSAndroid Build Coastguard Worker#            SHARED.
211*61c4878aSAndroid Build Coastguard Worker#
212*61c4878aSAndroid Build Coastguard Worker# Optional Args:
213*61c4878aSAndroid Build Coastguard Worker#
214*61c4878aSAndroid Build Coastguard Worker#   SOURCES - source files for this library
215*61c4878aSAndroid Build Coastguard Worker#   HEADERS - header files for this library
216*61c4878aSAndroid Build Coastguard Worker#   PUBLIC_DEPS - public pw_target_link_targets arguments
217*61c4878aSAndroid Build Coastguard Worker#   PRIVATE_DEPS - private pw_target_link_targets arguments
218*61c4878aSAndroid Build Coastguard Worker#   PUBLIC_INCLUDES - public target_include_directories argument
219*61c4878aSAndroid Build Coastguard Worker#   PRIVATE_INCLUDES - public target_include_directories argument
220*61c4878aSAndroid Build Coastguard Worker#   PUBLIC_DEFINES - public target_compile_definitions arguments
221*61c4878aSAndroid Build Coastguard Worker#   PRIVATE_DEFINES - private target_compile_definitions arguments
222*61c4878aSAndroid Build Coastguard Worker#   PUBLIC_COMPILE_OPTIONS - public target_compile_options arguments
223*61c4878aSAndroid Build Coastguard Worker#   PRIVATE_COMPILE_OPTIONS - private target_compile_options arguments
224*61c4878aSAndroid Build Coastguard Worker#   PRIVATE_COMPILE_OPTIONS_DEPS_BEFORE - private target_compile_options BEFORE
225*61c4878aSAndroid Build Coastguard Worker#     arguments from the specified deps's INTERFACE_COMPILE_OPTIONS. Note that
226*61c4878aSAndroid Build Coastguard Worker#     these deps are not pulled in as target_link_libraries. This should not be
227*61c4878aSAndroid Build Coastguard Worker#     exposed by the non-generic API.
228*61c4878aSAndroid Build Coastguard Worker#   PUBLIC_LINK_OPTIONS - public target_link_options arguments
229*61c4878aSAndroid Build Coastguard Worker#   PRIVATE_LINK_OPTIONS - private target_link_options arguments
230*61c4878aSAndroid Build Coastguard Workerfunction(pw_add_library_generic NAME TYPE)
231*61c4878aSAndroid Build Coastguard Worker  set(supported_library_types INTERFACE OBJECT STATIC SHARED)
232*61c4878aSAndroid Build Coastguard Worker  if(NOT "${TYPE}" IN_LIST supported_library_types)
233*61c4878aSAndroid Build Coastguard Worker    message(FATAL_ERROR "\"${TYPE}\" is not a valid library type for ${NAME}. "
234*61c4878aSAndroid Build Coastguard Worker          "Must be INTERFACE, OBJECT, STATIC, or SHARED.")
235*61c4878aSAndroid Build Coastguard Worker  endif()
236*61c4878aSAndroid Build Coastguard Worker
237*61c4878aSAndroid Build Coastguard Worker  _pw_add_library_multi_value_args(multi_value_args)
238*61c4878aSAndroid Build Coastguard Worker  pw_parse_arguments(
239*61c4878aSAndroid Build Coastguard Worker    NUM_POSITIONAL_ARGS
240*61c4878aSAndroid Build Coastguard Worker      2
241*61c4878aSAndroid Build Coastguard Worker    MULTI_VALUE_ARGS
242*61c4878aSAndroid Build Coastguard Worker      ${multi_value_args}
243*61c4878aSAndroid Build Coastguard Worker      PRIVATE_COMPILE_OPTIONS_DEPS_BEFORE
244*61c4878aSAndroid Build Coastguard Worker  )
245*61c4878aSAndroid Build Coastguard Worker
246*61c4878aSAndroid Build Coastguard Worker  # CMake 3.22 does not have a notion of target_headers yet, so in the mean
247*61c4878aSAndroid Build Coastguard Worker  # time we ask for headers to be specified for consistency with GN & Bazel and
248*61c4878aSAndroid Build Coastguard Worker  # to improve the IDE experience. However, we do want to ensure all the headers
249*61c4878aSAndroid Build Coastguard Worker  # which are otherwise ignored by CMake are present.
250*61c4878aSAndroid Build Coastguard Worker  #
251*61c4878aSAndroid Build Coastguard Worker  # See https://gitlab.kitware.com/cmake/cmake/-/issues/22468 for adding support
252*61c4878aSAndroid Build Coastguard Worker  # to CMake to associate headers with targets properly for CMake 3.23.
253*61c4878aSAndroid Build Coastguard Worker  foreach(header IN ITEMS ${arg_HEADERS})
254*61c4878aSAndroid Build Coastguard Worker    get_filename_component(header "${header}" ABSOLUTE)
255*61c4878aSAndroid Build Coastguard Worker    if(NOT EXISTS ${header})
256*61c4878aSAndroid Build Coastguard Worker      message(FATAL_ERROR "Header not found: \"${header}\"")
257*61c4878aSAndroid Build Coastguard Worker    endif()
258*61c4878aSAndroid Build Coastguard Worker  endforeach()
259*61c4878aSAndroid Build Coastguard Worker
260*61c4878aSAndroid Build Coastguard Worker  # In order to more easily create the various types of libraries, two hidden
261*61c4878aSAndroid Build Coastguard Worker  # targets are created: NAME._config and NAME._public_config which loosely
262*61c4878aSAndroid Build Coastguard Worker  # mirror the GN configs although we also carry target link dependencies
263*61c4878aSAndroid Build Coastguard Worker  # through these.
264*61c4878aSAndroid Build Coastguard Worker
265*61c4878aSAndroid Build Coastguard Worker  # Add the NAME._config target_link_libraries dependency with the
266*61c4878aSAndroid Build Coastguard Worker  # PRIVATE_INCLUDES, PRIVATE_DEFINES, PRIVATE_COMPILE_OPTIONS,
267*61c4878aSAndroid Build Coastguard Worker  # PRIVATE_LINK_OPTIONS, and PRIVATE_DEPS.
268*61c4878aSAndroid Build Coastguard Worker  add_library("${NAME}._config" INTERFACE EXCLUDE_FROM_ALL)
269*61c4878aSAndroid Build Coastguard Worker  target_include_directories("${NAME}._config"
270*61c4878aSAndroid Build Coastguard Worker    INTERFACE
271*61c4878aSAndroid Build Coastguard Worker      ${arg_PRIVATE_INCLUDES}
272*61c4878aSAndroid Build Coastguard Worker  )
273*61c4878aSAndroid Build Coastguard Worker  target_compile_definitions("${NAME}._config"
274*61c4878aSAndroid Build Coastguard Worker    INTERFACE
275*61c4878aSAndroid Build Coastguard Worker      ${arg_PRIVATE_DEFINES}
276*61c4878aSAndroid Build Coastguard Worker  )
277*61c4878aSAndroid Build Coastguard Worker  target_compile_options("${NAME}._config"
278*61c4878aSAndroid Build Coastguard Worker    INTERFACE
279*61c4878aSAndroid Build Coastguard Worker      ${arg_PRIVATE_COMPILE_OPTIONS}
280*61c4878aSAndroid Build Coastguard Worker  )
281*61c4878aSAndroid Build Coastguard Worker  target_link_options("${NAME}._config"
282*61c4878aSAndroid Build Coastguard Worker    INTERFACE
283*61c4878aSAndroid Build Coastguard Worker      ${arg_PRIVATE_LINK_OPTIONS}
284*61c4878aSAndroid Build Coastguard Worker  )
285*61c4878aSAndroid Build Coastguard Worker  pw_target_link_targets("${NAME}._config"
286*61c4878aSAndroid Build Coastguard Worker    INTERFACE
287*61c4878aSAndroid Build Coastguard Worker      ${arg_PRIVATE_DEPS}
288*61c4878aSAndroid Build Coastguard Worker  )
289*61c4878aSAndroid Build Coastguard Worker
290*61c4878aSAndroid Build Coastguard Worker  # Add the NAME._public_config target_link_libraries dependency with the
291*61c4878aSAndroid Build Coastguard Worker  # PUBLIC_INCLUDES, PUBLIC_DEFINES, PUBLIC_COMPILE_OPTIONS,
292*61c4878aSAndroid Build Coastguard Worker  # PUBLIC_LINK_OPTIONS, and PUBLIC_DEPS.
293*61c4878aSAndroid Build Coastguard Worker  add_library("${NAME}._public_config" INTERFACE EXCLUDE_FROM_ALL)
294*61c4878aSAndroid Build Coastguard Worker  target_include_directories("${NAME}._public_config"
295*61c4878aSAndroid Build Coastguard Worker    INTERFACE
296*61c4878aSAndroid Build Coastguard Worker      ${arg_PUBLIC_INCLUDES}
297*61c4878aSAndroid Build Coastguard Worker  )
298*61c4878aSAndroid Build Coastguard Worker  target_compile_definitions("${NAME}._public_config"
299*61c4878aSAndroid Build Coastguard Worker    INTERFACE
300*61c4878aSAndroid Build Coastguard Worker      ${arg_PUBLIC_DEFINES}
301*61c4878aSAndroid Build Coastguard Worker  )
302*61c4878aSAndroid Build Coastguard Worker  target_compile_options("${NAME}._public_config"
303*61c4878aSAndroid Build Coastguard Worker    INTERFACE
304*61c4878aSAndroid Build Coastguard Worker      ${arg_PUBLIC_COMPILE_OPTIONS}
305*61c4878aSAndroid Build Coastguard Worker  )
306*61c4878aSAndroid Build Coastguard Worker  target_link_options("${NAME}._public_config"
307*61c4878aSAndroid Build Coastguard Worker    INTERFACE
308*61c4878aSAndroid Build Coastguard Worker      ${arg_PUBLIC_LINK_OPTIONS}
309*61c4878aSAndroid Build Coastguard Worker  )
310*61c4878aSAndroid Build Coastguard Worker  pw_target_link_targets("${NAME}._public_config"
311*61c4878aSAndroid Build Coastguard Worker    INTERFACE
312*61c4878aSAndroid Build Coastguard Worker      ${arg_PUBLIC_DEPS}
313*61c4878aSAndroid Build Coastguard Worker  )
314*61c4878aSAndroid Build Coastguard Worker
315*61c4878aSAndroid Build Coastguard Worker  # Instantiate the library depending on the type using the NAME._config and
316*61c4878aSAndroid Build Coastguard Worker  # NAME._public_config libraries we just created.
317*61c4878aSAndroid Build Coastguard Worker  if("${TYPE}" STREQUAL "INTERFACE")
318*61c4878aSAndroid Build Coastguard Worker    if(NOT "${arg_SOURCES}" STREQUAL "")
319*61c4878aSAndroid Build Coastguard Worker      message(
320*61c4878aSAndroid Build Coastguard Worker        SEND_ERROR "${NAME} cannot have sources as it's an INTERFACE library")
321*61c4878aSAndroid Build Coastguard Worker    endif(NOT "${arg_SOURCES}" STREQUAL "")
322*61c4878aSAndroid Build Coastguard Worker
323*61c4878aSAndroid Build Coastguard Worker    add_library("${NAME}" INTERFACE EXCLUDE_FROM_ALL)
324*61c4878aSAndroid Build Coastguard Worker    target_sources("${NAME}" PRIVATE ${arg_HEADERS})
325*61c4878aSAndroid Build Coastguard Worker    pw_target_link_targets("${NAME}"
326*61c4878aSAndroid Build Coastguard Worker      INTERFACE
327*61c4878aSAndroid Build Coastguard Worker        "${NAME}._public_config"
328*61c4878aSAndroid Build Coastguard Worker    )
329*61c4878aSAndroid Build Coastguard Worker  elseif(("${TYPE}" STREQUAL "STATIC") OR ("${TYPE}" STREQUAL "SHARED"))
330*61c4878aSAndroid Build Coastguard Worker    if("${arg_SOURCES}" STREQUAL "")
331*61c4878aSAndroid Build Coastguard Worker      message(
332*61c4878aSAndroid Build Coastguard Worker        SEND_ERROR "${NAME} must have SOURCES as it's not an INTERFACE library")
333*61c4878aSAndroid Build Coastguard Worker    endif("${arg_SOURCES}" STREQUAL "")
334*61c4878aSAndroid Build Coastguard Worker
335*61c4878aSAndroid Build Coastguard Worker    add_library("${NAME}" "${TYPE}" EXCLUDE_FROM_ALL)
336*61c4878aSAndroid Build Coastguard Worker    target_sources("${NAME}" PRIVATE ${arg_HEADERS} ${arg_SOURCES})
337*61c4878aSAndroid Build Coastguard Worker    pw_target_link_targets("${NAME}"
338*61c4878aSAndroid Build Coastguard Worker      PUBLIC
339*61c4878aSAndroid Build Coastguard Worker        "${NAME}._public_config"
340*61c4878aSAndroid Build Coastguard Worker      PRIVATE
341*61c4878aSAndroid Build Coastguard Worker        "${NAME}._config"
342*61c4878aSAndroid Build Coastguard Worker    )
343*61c4878aSAndroid Build Coastguard Worker    foreach(compile_option_dep IN LISTS arg_PRIVATE_COMPILE_OPTIONS_DEPS_BEFORE)
344*61c4878aSAndroid Build Coastguard Worker      # This will fail at build time if the target does not exist.
345*61c4878aSAndroid Build Coastguard Worker      target_compile_options("${NAME}" BEFORE PRIVATE
346*61c4878aSAndroid Build Coastguard Worker          $<TARGET_PROPERTY:${compile_option_dep},INTERFACE_COMPILE_OPTIONS>
347*61c4878aSAndroid Build Coastguard Worker      )
348*61c4878aSAndroid Build Coastguard Worker    endforeach()
349*61c4878aSAndroid Build Coastguard Worker  elseif("${TYPE}" STREQUAL "OBJECT")
350*61c4878aSAndroid Build Coastguard Worker    if("${arg_SOURCES}" STREQUAL "")
351*61c4878aSAndroid Build Coastguard Worker      message(
352*61c4878aSAndroid Build Coastguard Worker        SEND_ERROR "${NAME} must have SOURCES as it's not an INTERFACE library")
353*61c4878aSAndroid Build Coastguard Worker    endif("${arg_SOURCES}" STREQUAL "")
354*61c4878aSAndroid Build Coastguard Worker
355*61c4878aSAndroid Build Coastguard Worker    # In order to support OBJECT libraries while maintaining transitive
356*61c4878aSAndroid Build Coastguard Worker    # linking dependencies, the library has to be split up into two where the
357*61c4878aSAndroid Build Coastguard Worker    # outer interface library forwards not only the internal object library
358*61c4878aSAndroid Build Coastguard Worker    # but also its TARGET_OBJECTS.
359*61c4878aSAndroid Build Coastguard Worker    add_library("${NAME}._object" OBJECT EXCLUDE_FROM_ALL)
360*61c4878aSAndroid Build Coastguard Worker    target_sources("${NAME}._object" PRIVATE ${arg_SOURCES})
361*61c4878aSAndroid Build Coastguard Worker    pw_target_link_targets("${NAME}._object"
362*61c4878aSAndroid Build Coastguard Worker      PRIVATE
363*61c4878aSAndroid Build Coastguard Worker        "${NAME}._public_config"
364*61c4878aSAndroid Build Coastguard Worker        "${NAME}._config"
365*61c4878aSAndroid Build Coastguard Worker    )
366*61c4878aSAndroid Build Coastguard Worker    foreach(compile_option_dep IN LISTS arg_PRIVATE_COMPILE_OPTIONS_DEPS_BEFORE)
367*61c4878aSAndroid Build Coastguard Worker      # This will fail at build time if the target does not exist.
368*61c4878aSAndroid Build Coastguard Worker      target_compile_options("${NAME}._object" BEFORE PRIVATE
369*61c4878aSAndroid Build Coastguard Worker          $<TARGET_PROPERTY:${compile_option_dep},INTERFACE_COMPILE_OPTIONS>
370*61c4878aSAndroid Build Coastguard Worker      )
371*61c4878aSAndroid Build Coastguard Worker    endforeach()
372*61c4878aSAndroid Build Coastguard Worker
373*61c4878aSAndroid Build Coastguard Worker    add_library("${NAME}" INTERFACE EXCLUDE_FROM_ALL)
374*61c4878aSAndroid Build Coastguard Worker    target_sources("${NAME}" PRIVATE ${arg_HEADERS})
375*61c4878aSAndroid Build Coastguard Worker    pw_target_link_targets("${NAME}"
376*61c4878aSAndroid Build Coastguard Worker      INTERFACE
377*61c4878aSAndroid Build Coastguard Worker        "${NAME}._public_config"
378*61c4878aSAndroid Build Coastguard Worker        "${NAME}._object"
379*61c4878aSAndroid Build Coastguard Worker    )
380*61c4878aSAndroid Build Coastguard Worker    target_link_libraries("${NAME}"
381*61c4878aSAndroid Build Coastguard Worker      INTERFACE
382*61c4878aSAndroid Build Coastguard Worker        $<TARGET_OBJECTS:${NAME}._object>
383*61c4878aSAndroid Build Coastguard Worker    )
384*61c4878aSAndroid Build Coastguard Worker  else()
385*61c4878aSAndroid Build Coastguard Worker    message(FATAL_ERROR "Unsupported libary type: ${TYPE}")
386*61c4878aSAndroid Build Coastguard Worker  endif()
387*61c4878aSAndroid Build Coastguard Workerendfunction(pw_add_library_generic)
388*61c4878aSAndroid Build Coastguard Worker
389*61c4878aSAndroid Build Coastguard Worker# Checks that the library's name is prefixed by the relative path with dot
390*61c4878aSAndroid Build Coastguard Worker# separators instead of forward slashes. Ignores paths not under the root
391*61c4878aSAndroid Build Coastguard Worker# directory.
392*61c4878aSAndroid Build Coastguard Worker#
393*61c4878aSAndroid Build Coastguard Worker# Optional Args:
394*61c4878aSAndroid Build Coastguard Worker#
395*61c4878aSAndroid Build Coastguard Worker#   REMAP_PREFIXES - support remapping a prefix for checks
396*61c4878aSAndroid Build Coastguard Worker#
397*61c4878aSAndroid Build Coastguard Workerfunction(_pw_check_name_is_relative_to_root NAME ROOT)
398*61c4878aSAndroid Build Coastguard Worker  pw_parse_arguments(
399*61c4878aSAndroid Build Coastguard Worker    NUM_POSITIONAL_ARGS
400*61c4878aSAndroid Build Coastguard Worker      2
401*61c4878aSAndroid Build Coastguard Worker    MULTI_VALUE_ARGS
402*61c4878aSAndroid Build Coastguard Worker      REMAP_PREFIXES
403*61c4878aSAndroid Build Coastguard Worker  )
404*61c4878aSAndroid Build Coastguard Worker
405*61c4878aSAndroid Build Coastguard Worker  file(RELATIVE_PATH rel_path "${ROOT}" "${CMAKE_CURRENT_SOURCE_DIR}")
406*61c4878aSAndroid Build Coastguard Worker  if("${rel_path}" MATCHES "^\\.\\.")
407*61c4878aSAndroid Build Coastguard Worker    return()  # Ignore paths not under ROOT
408*61c4878aSAndroid Build Coastguard Worker  endif()
409*61c4878aSAndroid Build Coastguard Worker
410*61c4878aSAndroid Build Coastguard Worker  list(LENGTH arg_REMAP_PREFIXES remap_arg_count)
411*61c4878aSAndroid Build Coastguard Worker  if("${remap_arg_count}" EQUAL 2)
412*61c4878aSAndroid Build Coastguard Worker    list(GET arg_REMAP_PREFIXES 0 from_prefix)
413*61c4878aSAndroid Build Coastguard Worker    list(GET arg_REMAP_PREFIXES 1 to_prefix)
414*61c4878aSAndroid Build Coastguard Worker    string(REGEX REPLACE "^${from_prefix}" "${to_prefix}" rel_path "${rel_path}")
415*61c4878aSAndroid Build Coastguard Worker  elseif(NOT "${remap_arg_count}" EQUAL 0)
416*61c4878aSAndroid Build Coastguard Worker    message(FATAL_ERROR
417*61c4878aSAndroid Build Coastguard Worker        "If REMAP_PREFIXES is specified, exactly two arguments must be given.")
418*61c4878aSAndroid Build Coastguard Worker  endif()
419*61c4878aSAndroid Build Coastguard Worker
420*61c4878aSAndroid Build Coastguard Worker  if(NOT "${rel_path}" MATCHES "^\\.\\..*")
421*61c4878aSAndroid Build Coastguard Worker    string(REPLACE "/" "." dot_rel_path "${rel_path}")
422*61c4878aSAndroid Build Coastguard Worker    if(NOT "${NAME}" MATCHES "^${dot_rel_path}(\\.[^\\.]+)?(\\.facade)?$")
423*61c4878aSAndroid Build Coastguard Worker      message(FATAL_ERROR
424*61c4878aSAndroid Build Coastguard Worker          "Module libraries under ${ROOT} must match the module name or be in "
425*61c4878aSAndroid Build Coastguard Worker          "the form 'PATH_TO.THE_TARGET.NAME'. The library '${NAME}' does not "
426*61c4878aSAndroid Build Coastguard Worker          "match. Expected ${dot_rel_path}.LIBRARY_NAME"
427*61c4878aSAndroid Build Coastguard Worker      )
428*61c4878aSAndroid Build Coastguard Worker    endif()
429*61c4878aSAndroid Build Coastguard Worker  endif()
430*61c4878aSAndroid Build Coastguard Workerendfunction(_pw_check_name_is_relative_to_root)
431*61c4878aSAndroid Build Coastguard Worker
432*61c4878aSAndroid Build Coastguard Worker# Creates a pw module library.
433*61c4878aSAndroid Build Coastguard Worker#
434*61c4878aSAndroid Build Coastguard Worker# Required Args:
435*61c4878aSAndroid Build Coastguard Worker#
436*61c4878aSAndroid Build Coastguard Worker#   <name> - The name of the library target to be created.
437*61c4878aSAndroid Build Coastguard Worker#   <type> - The library type which must be INTERFACE, OBJECT, STATIC or SHARED.
438*61c4878aSAndroid Build Coastguard Worker#
439*61c4878aSAndroid Build Coastguard Worker# Optional Args:
440*61c4878aSAndroid Build Coastguard Worker#
441*61c4878aSAndroid Build Coastguard Worker#   SOURCES - source files for this library
442*61c4878aSAndroid Build Coastguard Worker#   HEADERS - header files for this library
443*61c4878aSAndroid Build Coastguard Worker#   PUBLIC_DEPS - public pw_target_link_targets arguments
444*61c4878aSAndroid Build Coastguard Worker#   PRIVATE_DEPS - private pw_target_link_targets arguments
445*61c4878aSAndroid Build Coastguard Worker#   PUBLIC_INCLUDES - public target_include_directories argument
446*61c4878aSAndroid Build Coastguard Worker#   PRIVATE_INCLUDES - public target_include_directories argument
447*61c4878aSAndroid Build Coastguard Worker#   PUBLIC_DEFINES - public target_compile_definitions arguments
448*61c4878aSAndroid Build Coastguard Worker#   PRIVATE_DEFINES - private target_compile_definitions arguments
449*61c4878aSAndroid Build Coastguard Worker#   PUBLIC_COMPILE_OPTIONS - public target_compile_options arguments
450*61c4878aSAndroid Build Coastguard Worker#   PRIVATE_COMPILE_OPTIONS - private target_compile_options arguments
451*61c4878aSAndroid Build Coastguard Worker#   PUBLIC_LINK_OPTIONS - public target_link_options arguments
452*61c4878aSAndroid Build Coastguard Worker#   PRIVATE_LINK_OPTIONS - private target_link_options arguments
453*61c4878aSAndroid Build Coastguard Worker#
454*61c4878aSAndroid Build Coastguard Workerfunction(pw_add_library NAME TYPE)
455*61c4878aSAndroid Build Coastguard Worker  _pw_add_library_multi_value_args(pw_add_library_generic_multi_value_args)
456*61c4878aSAndroid Build Coastguard Worker  pw_parse_arguments(
457*61c4878aSAndroid Build Coastguard Worker    NUM_POSITIONAL_ARGS
458*61c4878aSAndroid Build Coastguard Worker      2
459*61c4878aSAndroid Build Coastguard Worker    MULTI_VALUE_ARGS
460*61c4878aSAndroid Build Coastguard Worker      ${pw_add_library_generic_multi_value_args}
461*61c4878aSAndroid Build Coastguard Worker  )
462*61c4878aSAndroid Build Coastguard Worker
463*61c4878aSAndroid Build Coastguard Worker  _pw_check_name_is_relative_to_root("${NAME}" "$ENV{PW_ROOT}"
464*61c4878aSAndroid Build Coastguard Worker    REMAP_PREFIXES
465*61c4878aSAndroid Build Coastguard Worker      third_party pw_third_party
466*61c4878aSAndroid Build Coastguard Worker  )
467*61c4878aSAndroid Build Coastguard Worker
468*61c4878aSAndroid Build Coastguard Worker  pw_add_library_generic(${NAME} ${TYPE}
469*61c4878aSAndroid Build Coastguard Worker    SOURCES
470*61c4878aSAndroid Build Coastguard Worker      ${arg_SOURCES}
471*61c4878aSAndroid Build Coastguard Worker    HEADERS
472*61c4878aSAndroid Build Coastguard Worker      ${arg_HEADERS}
473*61c4878aSAndroid Build Coastguard Worker    PUBLIC_DEPS
474*61c4878aSAndroid Build Coastguard Worker      # TODO: b/232141950 - Apply compilation options that affect ABI
475*61c4878aSAndroid Build Coastguard Worker      # globally in the CMake build instead of injecting them into libraries.
476*61c4878aSAndroid Build Coastguard Worker      pw_build
477*61c4878aSAndroid Build Coastguard Worker      ${arg_PUBLIC_DEPS}
478*61c4878aSAndroid Build Coastguard Worker    PRIVATE_DEPS
479*61c4878aSAndroid Build Coastguard Worker      ${arg_PRIVATE_DEPS}
480*61c4878aSAndroid Build Coastguard Worker    PUBLIC_INCLUDES
481*61c4878aSAndroid Build Coastguard Worker      ${arg_PUBLIC_INCLUDES}
482*61c4878aSAndroid Build Coastguard Worker    PRIVATE_INCLUDES
483*61c4878aSAndroid Build Coastguard Worker      ${arg_PRIVATE_INCLUDES}
484*61c4878aSAndroid Build Coastguard Worker    PUBLIC_DEFINES
485*61c4878aSAndroid Build Coastguard Worker      ${arg_PUBLIC_DEFINES}
486*61c4878aSAndroid Build Coastguard Worker    PRIVATE_DEFINES
487*61c4878aSAndroid Build Coastguard Worker      ${arg_PRIVATE_DEFINES}
488*61c4878aSAndroid Build Coastguard Worker    PUBLIC_COMPILE_OPTIONS
489*61c4878aSAndroid Build Coastguard Worker      ${arg_PUBLIC_COMPILE_OPTIONS}
490*61c4878aSAndroid Build Coastguard Worker    PRIVATE_COMPILE_OPTIONS_DEPS_BEFORE
491*61c4878aSAndroid Build Coastguard Worker      pw_build.warnings
492*61c4878aSAndroid Build Coastguard Worker    PRIVATE_COMPILE_OPTIONS
493*61c4878aSAndroid Build Coastguard Worker      ${arg_PRIVATE_COMPILE_OPTIONS}
494*61c4878aSAndroid Build Coastguard Worker    PUBLIC_LINK_OPTIONS
495*61c4878aSAndroid Build Coastguard Worker      ${arg_PUBLIC_LINK_OPTIONS}
496*61c4878aSAndroid Build Coastguard Worker    PRIVATE_LINK_OPTIONS
497*61c4878aSAndroid Build Coastguard Worker      ${arg_PRIVATE_LINK_OPTIONS}
498*61c4878aSAndroid Build Coastguard Worker  )
499*61c4878aSAndroid Build Coastguard Workerendfunction(pw_add_library)
500*61c4878aSAndroid Build Coastguard Worker
501*61c4878aSAndroid Build Coastguard Worker# Declares a module as a facade.
502*61c4878aSAndroid Build Coastguard Worker#
503*61c4878aSAndroid Build Coastguard Worker# Facades are declared as two libraries to avoid circular dependencies.
504*61c4878aSAndroid Build Coastguard Worker# Libraries that use the facade depend on a library named for the module. The
505*61c4878aSAndroid Build Coastguard Worker# module that implements the facade depends on a library named
506*61c4878aSAndroid Build Coastguard Worker# MODULE_NAME.facade.
507*61c4878aSAndroid Build Coastguard Worker#
508*61c4878aSAndroid Build Coastguard Worker# pw_add_facade accepts the same arguments as pw_add_library.
509*61c4878aSAndroid Build Coastguard Worker# It also accepts the following argument:
510*61c4878aSAndroid Build Coastguard Worker#
511*61c4878aSAndroid Build Coastguard Worker#  BACKEND - The name of the facade's backend variable.
512*61c4878aSAndroid Build Coastguard Workerfunction(pw_add_facade NAME TYPE)
513*61c4878aSAndroid Build Coastguard Worker  _pw_add_library_multi_value_args(multi_value_args)
514*61c4878aSAndroid Build Coastguard Worker  pw_parse_arguments(
515*61c4878aSAndroid Build Coastguard Worker    NUM_POSITIONAL_ARGS
516*61c4878aSAndroid Build Coastguard Worker      2
517*61c4878aSAndroid Build Coastguard Worker    ONE_VALUE_ARGS
518*61c4878aSAndroid Build Coastguard Worker      BACKEND
519*61c4878aSAndroid Build Coastguard Worker    MULTI_VALUE_ARGS
520*61c4878aSAndroid Build Coastguard Worker      ${multi_value_args}
521*61c4878aSAndroid Build Coastguard Worker  )
522*61c4878aSAndroid Build Coastguard Worker
523*61c4878aSAndroid Build Coastguard Worker  _pw_check_name_is_relative_to_root("${NAME}" "$ENV{PW_ROOT}"
524*61c4878aSAndroid Build Coastguard Worker    REMAP_PREFIXES
525*61c4878aSAndroid Build Coastguard Worker      third_party pw_third_party
526*61c4878aSAndroid Build Coastguard Worker  )
527*61c4878aSAndroid Build Coastguard Worker
528*61c4878aSAndroid Build Coastguard Worker  pw_add_facade_generic("${NAME}" "${TYPE}"
529*61c4878aSAndroid Build Coastguard Worker    BACKEND
530*61c4878aSAndroid Build Coastguard Worker      ${arg_BACKEND}
531*61c4878aSAndroid Build Coastguard Worker    SOURCES
532*61c4878aSAndroid Build Coastguard Worker      ${arg_SOURCES}
533*61c4878aSAndroid Build Coastguard Worker    HEADERS
534*61c4878aSAndroid Build Coastguard Worker      ${arg_HEADERS}
535*61c4878aSAndroid Build Coastguard Worker    PUBLIC_DEPS
536*61c4878aSAndroid Build Coastguard Worker      # TODO: b/232141950 - Apply compilation options that affect ABI
537*61c4878aSAndroid Build Coastguard Worker      # globally in the CMake build instead of injecting them into libraries.
538*61c4878aSAndroid Build Coastguard Worker      pw_build
539*61c4878aSAndroid Build Coastguard Worker      ${arg_PUBLIC_DEPS}
540*61c4878aSAndroid Build Coastguard Worker    PRIVATE_DEPS
541*61c4878aSAndroid Build Coastguard Worker      ${arg_PRIVATE_DEPS}
542*61c4878aSAndroid Build Coastguard Worker    PUBLIC_INCLUDES
543*61c4878aSAndroid Build Coastguard Worker      ${arg_PUBLIC_INCLUDES}
544*61c4878aSAndroid Build Coastguard Worker    PRIVATE_INCLUDES
545*61c4878aSAndroid Build Coastguard Worker      ${arg_PRIVATE_INCLUDES}
546*61c4878aSAndroid Build Coastguard Worker    PUBLIC_DEFINES
547*61c4878aSAndroid Build Coastguard Worker      ${arg_PUBLIC_DEFINES}
548*61c4878aSAndroid Build Coastguard Worker    PRIVATE_DEFINES
549*61c4878aSAndroid Build Coastguard Worker      ${arg_PRIVATE_DEFINES}
550*61c4878aSAndroid Build Coastguard Worker    PUBLIC_COMPILE_OPTIONS
551*61c4878aSAndroid Build Coastguard Worker      ${arg_PUBLIC_COMPILE_OPTIONS}
552*61c4878aSAndroid Build Coastguard Worker    PRIVATE_COMPILE_OPTIONS_DEPS_BEFORE
553*61c4878aSAndroid Build Coastguard Worker      pw_build.warnings
554*61c4878aSAndroid Build Coastguard Worker    PRIVATE_COMPILE_OPTIONS
555*61c4878aSAndroid Build Coastguard Worker      ${arg_PRIVATE_COMPILE_OPTIONS}
556*61c4878aSAndroid Build Coastguard Worker    PUBLIC_LINK_OPTIONS
557*61c4878aSAndroid Build Coastguard Worker      ${arg_PUBLIC_LINK_OPTIONS}
558*61c4878aSAndroid Build Coastguard Worker    PRIVATE_LINK_OPTIONS
559*61c4878aSAndroid Build Coastguard Worker      ${arg_PRIVATE_LINK_OPTIONS}
560*61c4878aSAndroid Build Coastguard Worker  )
561*61c4878aSAndroid Build Coastguard Workerendfunction(pw_add_facade)
562*61c4878aSAndroid Build Coastguard Worker
563*61c4878aSAndroid Build Coastguard Worker# pw_add_facade_generic: Creates a CMake facade library target.
564*61c4878aSAndroid Build Coastguard Worker#
565*61c4878aSAndroid Build Coastguard Worker# Facades are declared as two libraries to avoid circular dependencies.
566*61c4878aSAndroid Build Coastguard Worker# Libraries that use the facade depend on the <name> of this target. The
567*61c4878aSAndroid Build Coastguard Worker# libraries that implement this facade have to depend on an internal library
568*61c4878aSAndroid Build Coastguard Worker# named <name>.facade.
569*61c4878aSAndroid Build Coastguard Worker#
570*61c4878aSAndroid Build Coastguard Worker# Required Args:
571*61c4878aSAndroid Build Coastguard Worker#
572*61c4878aSAndroid Build Coastguard Worker#   <name> - The name for the public facade target (<name>) for all users and
573*61c4878aSAndroid Build Coastguard Worker#            the suffixed facade target for backend implementers (<name.facade).
574*61c4878aSAndroid Build Coastguard Worker#   <type> - The library type which must be INTERFACE, OBJECT, STATIC, or
575*61c4878aSAndroid Build Coastguard Worker#            SHARED.
576*61c4878aSAndroid Build Coastguard Worker#   BACKEND - The name of the facade's backend variable.
577*61c4878aSAndroid Build Coastguard Worker#
578*61c4878aSAndroid Build Coastguard Worker# Optional Args:
579*61c4878aSAndroid Build Coastguard Worker#
580*61c4878aSAndroid Build Coastguard Worker#   SOURCES - source files for this library
581*61c4878aSAndroid Build Coastguard Worker#   HEADERS - header files for this library
582*61c4878aSAndroid Build Coastguard Worker#   PUBLIC_DEPS - public pw_target_link_targets arguments
583*61c4878aSAndroid Build Coastguard Worker#   PRIVATE_DEPS - private pw_target_link_targets arguments
584*61c4878aSAndroid Build Coastguard Worker#   PUBLIC_INCLUDES - public target_include_directories argument
585*61c4878aSAndroid Build Coastguard Worker#   PRIVATE_INCLUDES - public target_include_directories argument
586*61c4878aSAndroid Build Coastguard Worker#   PUBLIC_DEFINES - public target_compile_definitions arguments
587*61c4878aSAndroid Build Coastguard Worker#   PRIVATE_DEFINES - private target_compile_definitions arguments
588*61c4878aSAndroid Build Coastguard Worker#   PUBLIC_COMPILE_OPTIONS - public target_compile_options arguments
589*61c4878aSAndroid Build Coastguard Worker#   PRIVATE_COMPILE_OPTIONS_DEPS_BEFORE - private target_compile_options BEFORE
590*61c4878aSAndroid Build Coastguard Worker#     arguments from the specified deps's INTERFACE_COMPILE_OPTIONS. Note that
591*61c4878aSAndroid Build Coastguard Worker#     these deps are not pulled in as target_link_libraries. This should not be
592*61c4878aSAndroid Build Coastguard Worker#     exposed by the non-generic API.
593*61c4878aSAndroid Build Coastguard Worker#   PRIVATE_COMPILE_OPTIONS - private target_compile_options arguments
594*61c4878aSAndroid Build Coastguard Worker#   PUBLIC_LINK_OPTIONS - public target_link_options arguments
595*61c4878aSAndroid Build Coastguard Worker#   PRIVATE_LINK_OPTIONS - private target_link_options arguments
596*61c4878aSAndroid Build Coastguard Workerfunction(pw_add_facade_generic NAME TYPE)
597*61c4878aSAndroid Build Coastguard Worker  set(supported_library_types INTERFACE OBJECT STATIC SHARED)
598*61c4878aSAndroid Build Coastguard Worker  if(NOT "${TYPE}" IN_LIST supported_library_types)
599*61c4878aSAndroid Build Coastguard Worker    message(FATAL_ERROR "\"${TYPE}\" is not a valid library type for ${NAME}. "
600*61c4878aSAndroid Build Coastguard Worker          "Must be INTERFACE, OBJECT, STATIC, or SHARED.")
601*61c4878aSAndroid Build Coastguard Worker  endif()
602*61c4878aSAndroid Build Coastguard Worker
603*61c4878aSAndroid Build Coastguard Worker  _pw_add_library_multi_value_args(multi_value_args)
604*61c4878aSAndroid Build Coastguard Worker  pw_parse_arguments(
605*61c4878aSAndroid Build Coastguard Worker    NUM_POSITIONAL_ARGS
606*61c4878aSAndroid Build Coastguard Worker      2
607*61c4878aSAndroid Build Coastguard Worker    ONE_VALUE_ARGS
608*61c4878aSAndroid Build Coastguard Worker      BACKEND
609*61c4878aSAndroid Build Coastguard Worker    MULTI_VALUE_ARGS
610*61c4878aSAndroid Build Coastguard Worker      ${multi_value_args}
611*61c4878aSAndroid Build Coastguard Worker      PRIVATE_COMPILE_OPTIONS_DEPS_BEFORE
612*61c4878aSAndroid Build Coastguard Worker    REQUIRED_ARGS
613*61c4878aSAndroid Build Coastguard Worker      BACKEND
614*61c4878aSAndroid Build Coastguard Worker  )
615*61c4878aSAndroid Build Coastguard Worker
616*61c4878aSAndroid Build Coastguard Worker  if(NOT DEFINED "${arg_BACKEND}")
617*61c4878aSAndroid Build Coastguard Worker    message(FATAL_ERROR "${NAME}'s backend variable ${arg_BACKEND} has not "
618*61c4878aSAndroid Build Coastguard Worker            "been defined, you may be missing a pw_add_backend_variable or "
619*61c4878aSAndroid Build Coastguard Worker            "the *.cmake import to that file.")
620*61c4878aSAndroid Build Coastguard Worker  endif()
621*61c4878aSAndroid Build Coastguard Worker  string(REGEX MATCH ".+_BACKEND" backend_ends_in_backend "${arg_BACKEND}")
622*61c4878aSAndroid Build Coastguard Worker  if(NOT backend_ends_in_backend)
623*61c4878aSAndroid Build Coastguard Worker    message(FATAL_ERROR "The ${NAME} pw_add_generic_facade's BACKEND argument "
624*61c4878aSAndroid Build Coastguard Worker            "(${arg_BACKEND}) must end in _BACKEND (${name_ends_in_backend})")
625*61c4878aSAndroid Build Coastguard Worker  endif()
626*61c4878aSAndroid Build Coastguard Worker
627*61c4878aSAndroid Build Coastguard Worker  set(backend_target "${${arg_BACKEND}}")
628*61c4878aSAndroid Build Coastguard Worker  if ("${backend_target}" STREQUAL "")
629*61c4878aSAndroid Build Coastguard Worker    # If no backend is set, a script that displays an error message is used
630*61c4878aSAndroid Build Coastguard Worker    # instead. If the facade is used in the build, it fails with this error.
631*61c4878aSAndroid Build Coastguard Worker    pw_add_error_target("${NAME}.NO_BACKEND_SET"
632*61c4878aSAndroid Build Coastguard Worker      MESSAGE
633*61c4878aSAndroid Build Coastguard Worker        "Attempted to build the ${NAME} facade with no backend set. "
634*61c4878aSAndroid Build Coastguard Worker        "Configure the ${NAME} backend using pw_set_backend or remove all "
635*61c4878aSAndroid Build Coastguard Worker        "dependencies on it. See https://pigweed.dev/pw_build."
636*61c4878aSAndroid Build Coastguard Worker    )
637*61c4878aSAndroid Build Coastguard Worker
638*61c4878aSAndroid Build Coastguard Worker    set(backend_target "${NAME}.NO_BACKEND_SET")
639*61c4878aSAndroid Build Coastguard Worker  endif()
640*61c4878aSAndroid Build Coastguard Worker
641*61c4878aSAndroid Build Coastguard Worker  # Define the facade library, which is used by the backend to avoid circular
642*61c4878aSAndroid Build Coastguard Worker  # dependencies.
643*61c4878aSAndroid Build Coastguard Worker  pw_add_library_generic("${NAME}.facade" INTERFACE
644*61c4878aSAndroid Build Coastguard Worker    HEADERS
645*61c4878aSAndroid Build Coastguard Worker      ${arg_HEADERS}
646*61c4878aSAndroid Build Coastguard Worker    PUBLIC_INCLUDES
647*61c4878aSAndroid Build Coastguard Worker      ${arg_PUBLIC_INCLUDES}
648*61c4878aSAndroid Build Coastguard Worker    PUBLIC_DEPS
649*61c4878aSAndroid Build Coastguard Worker      ${arg_PUBLIC_DEPS}
650*61c4878aSAndroid Build Coastguard Worker    PUBLIC_DEFINES
651*61c4878aSAndroid Build Coastguard Worker      ${arg_PUBLIC_DEFINES}
652*61c4878aSAndroid Build Coastguard Worker    PUBLIC_COMPILE_OPTIONS
653*61c4878aSAndroid Build Coastguard Worker      ${arg_PUBLIC_COMPILE_OPTIONS}
654*61c4878aSAndroid Build Coastguard Worker    PUBLIC_LINK_OPTIONS
655*61c4878aSAndroid Build Coastguard Worker      ${arg_PUBLIC_LINK_OPTIONS}
656*61c4878aSAndroid Build Coastguard Worker  )
657*61c4878aSAndroid Build Coastguard Worker
658*61c4878aSAndroid Build Coastguard Worker  # Define the public-facing library for this facade, which depends on the
659*61c4878aSAndroid Build Coastguard Worker  # header files and public interface aspects from the .facade target and
660*61c4878aSAndroid Build Coastguard Worker  # exposes the dependency on the backend along with the private library
661*61c4878aSAndroid Build Coastguard Worker  # target components.
662*61c4878aSAndroid Build Coastguard Worker  pw_add_library_generic("${NAME}" "${TYPE}"
663*61c4878aSAndroid Build Coastguard Worker    PUBLIC_DEPS
664*61c4878aSAndroid Build Coastguard Worker      "${NAME}.facade"
665*61c4878aSAndroid Build Coastguard Worker      "${backend_target}"
666*61c4878aSAndroid Build Coastguard Worker    SOURCES
667*61c4878aSAndroid Build Coastguard Worker      ${arg_SOURCES}
668*61c4878aSAndroid Build Coastguard Worker    PRIVATE_INCLUDES
669*61c4878aSAndroid Build Coastguard Worker      ${arg_PRIVATE_INCLUDES}
670*61c4878aSAndroid Build Coastguard Worker    PRIVATE_DEPS
671*61c4878aSAndroid Build Coastguard Worker      ${arg_PRIVATE_DEPS}
672*61c4878aSAndroid Build Coastguard Worker    PRIVATE_DEFINES
673*61c4878aSAndroid Build Coastguard Worker      ${arg_PRIVATE_DEFINES}
674*61c4878aSAndroid Build Coastguard Worker    PRIVATE_COMPILE_OPTIONS_DEPS_BEFORE
675*61c4878aSAndroid Build Coastguard Worker      ${arg_PRIVATE_COMPILE_OPTIONS_DEPS_BEFORE}
676*61c4878aSAndroid Build Coastguard Worker    PRIVATE_COMPILE_OPTIONS
677*61c4878aSAndroid Build Coastguard Worker      ${arg_PRIVATE_COMPILE_OPTIONS}
678*61c4878aSAndroid Build Coastguard Worker    PRIVATE_LINK_OPTIONS
679*61c4878aSAndroid Build Coastguard Worker      ${arg_PRIVATE_LINK_OPTIONS}
680*61c4878aSAndroid Build Coastguard Worker  )
681*61c4878aSAndroid Build Coastguard Workerendfunction(pw_add_facade_generic)
682*61c4878aSAndroid Build Coastguard Worker
683*61c4878aSAndroid Build Coastguard Worker# Declare a facade's backend variables which can be overriden later by using
684*61c4878aSAndroid Build Coastguard Worker# pw_set_backend.
685*61c4878aSAndroid Build Coastguard Worker#
686*61c4878aSAndroid Build Coastguard Worker# Required Arguments:
687*61c4878aSAndroid Build Coastguard Worker#   NAME - Name of the facade's backend variable.
688*61c4878aSAndroid Build Coastguard Worker#
689*61c4878aSAndroid Build Coastguard Worker# Optional Arguments:
690*61c4878aSAndroid Build Coastguard Worker#   DEFAULT_BACKEND - Optional default backend selection for the facade.
691*61c4878aSAndroid Build Coastguard Worker#
692*61c4878aSAndroid Build Coastguard Workerfunction(pw_add_backend_variable NAME)
693*61c4878aSAndroid Build Coastguard Worker  pw_parse_arguments(
694*61c4878aSAndroid Build Coastguard Worker    NUM_POSITIONAL_ARGS
695*61c4878aSAndroid Build Coastguard Worker      1
696*61c4878aSAndroid Build Coastguard Worker    ONE_VALUE_ARGS
697*61c4878aSAndroid Build Coastguard Worker      DEFAULT_BACKEND
698*61c4878aSAndroid Build Coastguard Worker  )
699*61c4878aSAndroid Build Coastguard Worker
700*61c4878aSAndroid Build Coastguard Worker  string(REGEX MATCH ".+_BACKEND" name_ends_in_backend "${NAME}")
701*61c4878aSAndroid Build Coastguard Worker  if(NOT name_ends_in_backend)
702*61c4878aSAndroid Build Coastguard Worker    message(FATAL_ERROR "The ${NAME} pw_add_backend_variable's NAME argument "
703*61c4878aSAndroid Build Coastguard Worker            "must end in _BACKEND")
704*61c4878aSAndroid Build Coastguard Worker  endif()
705*61c4878aSAndroid Build Coastguard Worker
706*61c4878aSAndroid Build Coastguard Worker  set("${NAME}" "${arg_DEFAULT_BACKEND}" CACHE STRING
707*61c4878aSAndroid Build Coastguard Worker      "${NAME} backend variable for a facade")
708*61c4878aSAndroid Build Coastguard Workerendfunction()
709*61c4878aSAndroid Build Coastguard Worker
710*61c4878aSAndroid Build Coastguard Worker# Sets which backend to use for the given facade's backend variable.
711*61c4878aSAndroid Build Coastguard Workerfunction(pw_set_backend NAME BACKEND)
712*61c4878aSAndroid Build Coastguard Worker  # TODO(ewout, hepler): Deprecate this temporarily support which permits the
713*61c4878aSAndroid Build Coastguard Worker  # direct facade name directly, instead of the facade's backend variable name.
714*61c4878aSAndroid Build Coastguard Worker  # Also update this to later assert the variable is DEFINED to catch typos.
715*61c4878aSAndroid Build Coastguard Worker  string(REGEX MATCH ".+_BACKEND" name_ends_in_backend "${NAME}")
716*61c4878aSAndroid Build Coastguard Worker  if(NOT name_ends_in_backend)
717*61c4878aSAndroid Build Coastguard Worker    set(NAME "${NAME}_BACKEND")
718*61c4878aSAndroid Build Coastguard Worker  endif()
719*61c4878aSAndroid Build Coastguard Worker  if(NOT DEFINED "${NAME}")
720*61c4878aSAndroid Build Coastguard Worker    message(WARNING "${NAME} was not defined when pw_set_backend was invoked, "
721*61c4878aSAndroid Build Coastguard Worker            "you may be missing a pw_add_backend_variable or the *.cmake "
722*61c4878aSAndroid Build Coastguard Worker            "import to that file.")
723*61c4878aSAndroid Build Coastguard Worker  endif()
724*61c4878aSAndroid Build Coastguard Worker
725*61c4878aSAndroid Build Coastguard Worker  set("${NAME}" "${BACKEND}" CACHE STRING "backend variable for a facade" FORCE)
726*61c4878aSAndroid Build Coastguard Workerendfunction(pw_set_backend)
727*61c4878aSAndroid Build Coastguard Worker
728*61c4878aSAndroid Build Coastguard Worker# Zephyr specific wrapper for pw_set_backend.
729*61c4878aSAndroid Build Coastguard Workerfunction(pw_set_zephyr_backend_ifdef COND FACADE BACKEND BACKEND_DECL)
730*61c4878aSAndroid Build Coastguard Worker  if(${${COND}})
731*61c4878aSAndroid Build Coastguard Worker    if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/${BACKEND_DECL}")
732*61c4878aSAndroid Build Coastguard Worker      message(FATAL_ERROR
733*61c4878aSAndroid Build Coastguard Worker          "Can't find backend declaration file '${CMAKE_CURRENT_LIST_DIR}/${BACKEND_DECL}'")
734*61c4878aSAndroid Build Coastguard Worker    endif()
735*61c4878aSAndroid Build Coastguard Worker    include("${CMAKE_CURRENT_LIST_DIR}/${BACKEND_DECL}")
736*61c4878aSAndroid Build Coastguard Worker    pw_set_backend("${FACADE}" "${BACKEND}")
737*61c4878aSAndroid Build Coastguard Worker  endif()
738*61c4878aSAndroid Build Coastguard Workerendfunction()
739*61c4878aSAndroid Build Coastguard Worker
740*61c4878aSAndroid Build Coastguard Worker# Zephyr specific wrapper to convert a pw library to a Zephyr library
741*61c4878aSAndroid Build Coastguard Workerfunction(pw_zephyrize_libraries_ifdef COND)
742*61c4878aSAndroid Build Coastguard Worker  if(DEFINED Zephyr_FOUND)
743*61c4878aSAndroid Build Coastguard Worker    if(${${COND}})
744*61c4878aSAndroid Build Coastguard Worker      zephyr_link_libraries(${ARGN})
745*61c4878aSAndroid Build Coastguard Worker      foreach(lib ${ARGN})
746*61c4878aSAndroid Build Coastguard Worker        target_link_libraries(${lib} INTERFACE zephyr_interface)
747*61c4878aSAndroid Build Coastguard Worker      endforeach()
748*61c4878aSAndroid Build Coastguard Worker    endif()
749*61c4878aSAndroid Build Coastguard Worker  endif()
750*61c4878aSAndroid Build Coastguard Workerendfunction()
751*61c4878aSAndroid Build Coastguard Worker
752*61c4878aSAndroid Build Coastguard Worker# Zephyr function allowing conversion of Kconfig values to Pigweed configs
753*61c4878aSAndroid Build Coastguard Workerfunction(pw_set_config_from_zephyr ZEPHYR_CONFIG PW_CONFIG)
754*61c4878aSAndroid Build Coastguard Worker  if(${ZEPHYR_CONFIG})
755*61c4878aSAndroid Build Coastguard Worker    add_compile_definitions(${PW_CONFIG}=${${ZEPHYR_CONFIG}})
756*61c4878aSAndroid Build Coastguard Worker  endif()
757*61c4878aSAndroid Build Coastguard Workerendfunction()
758*61c4878aSAndroid Build Coastguard Worker
759*61c4878aSAndroid Build Coastguard Worker# Set up the default pw_build_DEFAULT_MODULE_CONFIG.
760*61c4878aSAndroid Build Coastguard Workerset("pw_build_DEFAULT_MODULE_CONFIG" pw_build.empty CACHE STRING
761*61c4878aSAndroid Build Coastguard Worker    "Default implementation for all Pigweed module configurations.")
762*61c4878aSAndroid Build Coastguard Worker
763*61c4878aSAndroid Build Coastguard Worker# Declares a module configuration variable for module libraries to depend on.
764*61c4878aSAndroid Build Coastguard Worker# Configs should be set to libraries which can be used to provide defines
765*61c4878aSAndroid Build Coastguard Worker# directly or though included header files.
766*61c4878aSAndroid Build Coastguard Worker#
767*61c4878aSAndroid Build Coastguard Worker# The configs can be selected either through the pw_set_module_config function
768*61c4878aSAndroid Build Coastguard Worker# to set the pw_build_DEFAULT_MODULE_CONFIG used by default for all Pigweed
769*61c4878aSAndroid Build Coastguard Worker# modules or by selecting a specific one for the given NAME'd configuration.
770*61c4878aSAndroid Build Coastguard Worker#
771*61c4878aSAndroid Build Coastguard Worker# Args:
772*61c4878aSAndroid Build Coastguard Worker#
773*61c4878aSAndroid Build Coastguard Worker#   NAME: name to use for the target which can be depended on for the config.
774*61c4878aSAndroid Build Coastguard Workerfunction(pw_add_module_config NAME)
775*61c4878aSAndroid Build Coastguard Worker  pw_parse_arguments(NUM_POSITIONAL_ARGS 1)
776*61c4878aSAndroid Build Coastguard Worker
777*61c4878aSAndroid Build Coastguard Worker  # Declare the module configuration variable for this module.
778*61c4878aSAndroid Build Coastguard Worker  set("${NAME}" "${pw_build_DEFAULT_MODULE_CONFIG}"
779*61c4878aSAndroid Build Coastguard Worker      CACHE STRING "Module configuration for ${NAME}")
780*61c4878aSAndroid Build Coastguard Workerendfunction(pw_add_module_config)
781*61c4878aSAndroid Build Coastguard Worker
782*61c4878aSAndroid Build Coastguard Worker# Sets which config library to use for the given module.
783*61c4878aSAndroid Build Coastguard Worker#
784*61c4878aSAndroid Build Coastguard Worker# This can be used to set a specific module configuration or the default
785*61c4878aSAndroid Build Coastguard Worker# module configuration used for all Pigweed modules:
786*61c4878aSAndroid Build Coastguard Worker#
787*61c4878aSAndroid Build Coastguard Worker#   pw_set_module_config(pw_build_DEFAULT_MODULE_CONFIG my_config)
788*61c4878aSAndroid Build Coastguard Worker#   pw_set_module_config(pw_foo_CONFIG my_foo_config)
789*61c4878aSAndroid Build Coastguard Workerfunction(pw_set_module_config NAME LIBRARY)
790*61c4878aSAndroid Build Coastguard Worker  pw_parse_arguments(NUM_POSITIONAL_ARGS 2)
791*61c4878aSAndroid Build Coastguard Worker
792*61c4878aSAndroid Build Coastguard Worker  # Update the module configuration variable.
793*61c4878aSAndroid Build Coastguard Worker  set("${NAME}" "${LIBRARY}" CACHE STRING "Config for ${NAME}" FORCE)
794*61c4878aSAndroid Build Coastguard Workerendfunction(pw_set_module_config)
795*61c4878aSAndroid Build Coastguard Worker
796*61c4878aSAndroid Build Coastguard Worker# Adds compiler options to all targets built by CMake. Flags may be added any
797*61c4878aSAndroid Build Coastguard Worker# time after this function is defined. The effect is global; all targets added
798*61c4878aSAndroid Build Coastguard Worker# before or after a pw_add_global_compile_options call will be built with the
799*61c4878aSAndroid Build Coastguard Worker# flags, regardless of where the files are located.
800*61c4878aSAndroid Build Coastguard Worker#
801*61c4878aSAndroid Build Coastguard Worker# pw_add_global_compile_options takes one optional named argument:
802*61c4878aSAndroid Build Coastguard Worker#
803*61c4878aSAndroid Build Coastguard Worker#   LANGUAGES: Which languages (ASM, C, CXX) to apply the options to. Flags
804*61c4878aSAndroid Build Coastguard Worker#       apply to all languages by default.
805*61c4878aSAndroid Build Coastguard Worker#
806*61c4878aSAndroid Build Coastguard Worker# All other arguments are interpreted as compiler options.
807*61c4878aSAndroid Build Coastguard Workerfunction(pw_add_global_compile_options)
808*61c4878aSAndroid Build Coastguard Worker  cmake_parse_arguments(PARSE_ARGV 0 args "" "" "LANGUAGES")
809*61c4878aSAndroid Build Coastguard Worker
810*61c4878aSAndroid Build Coastguard Worker  set(supported_build_languages ASM C CXX)
811*61c4878aSAndroid Build Coastguard Worker
812*61c4878aSAndroid Build Coastguard Worker  if(NOT args_LANGUAGES)
813*61c4878aSAndroid Build Coastguard Worker    set(args_LANGUAGES ${supported_build_languages})
814*61c4878aSAndroid Build Coastguard Worker  endif()
815*61c4878aSAndroid Build Coastguard Worker
816*61c4878aSAndroid Build Coastguard Worker  # Check the selected language.
817*61c4878aSAndroid Build Coastguard Worker  foreach(lang IN LISTS args_LANGUAGES)
818*61c4878aSAndroid Build Coastguard Worker    if(NOT "${lang}" IN_LIST supported_build_languages)
819*61c4878aSAndroid Build Coastguard Worker      message(FATAL_ERROR "'${lang}' is not a supported language. "
820*61c4878aSAndroid Build Coastguard Worker              "Supported languages: ${supported_build_languages}")
821*61c4878aSAndroid Build Coastguard Worker    endif()
822*61c4878aSAndroid Build Coastguard Worker  endforeach()
823*61c4878aSAndroid Build Coastguard Worker
824*61c4878aSAndroid Build Coastguard Worker  # Enumerate which flags variables to set.
825*61c4878aSAndroid Build Coastguard Worker  foreach(lang IN LISTS args_LANGUAGES)
826*61c4878aSAndroid Build Coastguard Worker    list(APPEND cmake_flags_variables "CMAKE_${lang}_FLAGS")
827*61c4878aSAndroid Build Coastguard Worker  endforeach()
828*61c4878aSAndroid Build Coastguard Worker
829*61c4878aSAndroid Build Coastguard Worker  # Set each flag for each specified flags variable.
830*61c4878aSAndroid Build Coastguard Worker  foreach(variable IN LISTS cmake_flags_variables)
831*61c4878aSAndroid Build Coastguard Worker    foreach(flag IN LISTS args_UNPARSED_ARGUMENTS)
832*61c4878aSAndroid Build Coastguard Worker      set(${variable} "${${variable}} ${flag}" CACHE INTERNAL "" FORCE)
833*61c4878aSAndroid Build Coastguard Worker    endforeach()
834*61c4878aSAndroid Build Coastguard Worker  endforeach()
835*61c4878aSAndroid Build Coastguard Workerendfunction(pw_add_global_compile_options)
836*61c4878aSAndroid Build Coastguard Worker
837*61c4878aSAndroid Build Coastguard Worker# pw_add_error_target: Creates a CMake target which fails to build and prints a
838*61c4878aSAndroid Build Coastguard Worker#                      message
839*61c4878aSAndroid Build Coastguard Worker#
840*61c4878aSAndroid Build Coastguard Worker# This function prints a message and causes a build failure only if you attempt
841*61c4878aSAndroid Build Coastguard Worker# to build the target. This is useful when FATAL_ERROR messages cannot be used
842*61c4878aSAndroid Build Coastguard Worker# to catch problems during the CMake configuration phase.
843*61c4878aSAndroid Build Coastguard Worker#
844*61c4878aSAndroid Build Coastguard Worker# Args:
845*61c4878aSAndroid Build Coastguard Worker#
846*61c4878aSAndroid Build Coastguard Worker#   NAME: name to use for the target
847*61c4878aSAndroid Build Coastguard Worker#   MESSAGE: The message to print, prefixed with "ERROR: ". The message may be
848*61c4878aSAndroid Build Coastguard Worker#            composed of multiple pieces by passing multiple strings.
849*61c4878aSAndroid Build Coastguard Worker#
850*61c4878aSAndroid Build Coastguard Workerfunction(pw_add_error_target NAME)
851*61c4878aSAndroid Build Coastguard Worker  pw_parse_arguments(
852*61c4878aSAndroid Build Coastguard Worker    NUM_POSITIONAL_ARGS
853*61c4878aSAndroid Build Coastguard Worker      1
854*61c4878aSAndroid Build Coastguard Worker    MULTI_VALUE_ARGS
855*61c4878aSAndroid Build Coastguard Worker      MESSAGE
856*61c4878aSAndroid Build Coastguard Worker  )
857*61c4878aSAndroid Build Coastguard Worker
858*61c4878aSAndroid Build Coastguard Worker  # In case the message is comprised of multiple strings, stitch them together.
859*61c4878aSAndroid Build Coastguard Worker  set(message "ERROR: ")
860*61c4878aSAndroid Build Coastguard Worker  foreach(line IN LISTS arg_MESSAGE)
861*61c4878aSAndroid Build Coastguard Worker    string(APPEND message "${line}")
862*61c4878aSAndroid Build Coastguard Worker  endforeach()
863*61c4878aSAndroid Build Coastguard Worker
864*61c4878aSAndroid Build Coastguard Worker  add_custom_target("${NAME}._error_message"
865*61c4878aSAndroid Build Coastguard Worker    COMMAND
866*61c4878aSAndroid Build Coastguard Worker      "${CMAKE_COMMAND}" -E echo "${message}"
867*61c4878aSAndroid Build Coastguard Worker    COMMAND
868*61c4878aSAndroid Build Coastguard Worker      "${CMAKE_COMMAND}" -E false
869*61c4878aSAndroid Build Coastguard Worker  )
870*61c4878aSAndroid Build Coastguard Worker
871*61c4878aSAndroid Build Coastguard Worker  # A static library is provided, in case this rule nominally provides a
872*61c4878aSAndroid Build Coastguard Worker  # compiled output, e.g. to enable $<TARGET_FILE:"${NAME}">.
873*61c4878aSAndroid Build Coastguard Worker  pw_add_library_generic("${NAME}" STATIC
874*61c4878aSAndroid Build Coastguard Worker    SOURCES
875*61c4878aSAndroid Build Coastguard Worker      $<TARGET_PROPERTY:pw_build.empty,SOURCES>
876*61c4878aSAndroid Build Coastguard Worker  )
877*61c4878aSAndroid Build Coastguard Worker  add_dependencies("${NAME}" "${NAME}._error_message")
878*61c4878aSAndroid Build Coastguard Workerendfunction(pw_add_error_target)
879*61c4878aSAndroid Build Coastguard Worker
880*61c4878aSAndroid Build Coastguard Worker# Rebases a set of files to a new root path and optionally appends extensions
881*61c4878aSAndroid Build Coastguard Worker# to them. This is particularly useful for file generators.
882*61c4878aSAndroid Build Coastguard Worker#
883*61c4878aSAndroid Build Coastguard Worker# Required Arguments:
884*61c4878aSAndroid Build Coastguard Worker#
885*61c4878aSAndroid Build Coastguard Worker#   <var>        - Variable to store the rebased file list in.
886*61c4878aSAndroid Build Coastguard Worker#   <new_root>   - The new root to rebase file paths onto.
887*61c4878aSAndroid Build Coastguard Worker#   <root>       - The current root to rebase off of.
888*61c4878aSAndroid Build Coastguard Worker#   <files>      - The list of files to rebase.
889*61c4878aSAndroid Build Coastguard Worker#   <extensions> - List of extensions to replace the existing file extensions
890*61c4878aSAndroid Build Coastguard Worker#                  with.
891*61c4878aSAndroid Build Coastguard Worker#
892*61c4878aSAndroid Build Coastguard Worker# Examples:
893*61c4878aSAndroid Build Coastguard Worker#
894*61c4878aSAndroid Build Coastguard Worker# list(APPEND files "public/proj/foo.def" "public/proj/bar.def")
895*61c4878aSAndroid Build Coastguard Worker#
896*61c4878aSAndroid Build Coastguard Worker# pw_rebase_paths(out_files "/tmp" "${CMAKE_CURRENT_SOURCE_DIR}/public"
897*61c4878aSAndroid Build Coastguard Worker#   ${files} "")
898*61c4878aSAndroid Build Coastguard Worker# out_files => [ "/tmp/proj/foo.def", "/tmp/proj/bar.def" ]
899*61c4878aSAndroid Build Coastguard Worker#
900*61c4878aSAndroid Build Coastguard Worker# pw_rebase_paths(out_files "/tmp" "${CMAKE_CURRENT_SOURCE_DIR}/public"
901*61c4878aSAndroid Build Coastguard Worker#   ${files} ".h")
902*61c4878aSAndroid Build Coastguard Worker# out_files => [ "/tmp/proj/foo.h", "/tmp/proj/bar.h" ]
903*61c4878aSAndroid Build Coastguard Worker#
904*61c4878aSAndroid Build Coastguard Worker# list (APPEND exts ".h" ".cc")
905*61c4878aSAndroid Build Coastguard Worker# pw_rebase_paths(out_files "/tmp" "${CMAKE_CURRENT_SOURCE_DIR}/public"
906*61c4878aSAndroid Build Coastguard Worker#   ${files} ${exts})
907*61c4878aSAndroid Build Coastguard Worker# out_files => [ "/tmp/proj/foo.h", "/tmp/proj/bar.h",
908*61c4878aSAndroid Build Coastguard Worker#                "/tmp/proj/foo.cc", "/tmp/proj/bar.cc" ]
909*61c4878aSAndroid Build Coastguard Workerfunction(pw_rebase_paths VAR NEW_ROOT ROOT FILES EXTENSIONS)
910*61c4878aSAndroid Build Coastguard Worker  foreach(file IN LISTS FILES)
911*61c4878aSAndroid Build Coastguard Worker    get_filename_component(file "${file}" ABSOLUTE)
912*61c4878aSAndroid Build Coastguard Worker    file(RELATIVE_PATH file "${ROOT}" "${file}")
913*61c4878aSAndroid Build Coastguard Worker
914*61c4878aSAndroid Build Coastguard Worker    if("${EXTENSIONS}" STREQUAL "")
915*61c4878aSAndroid Build Coastguard Worker      list(APPEND mirrored_files "${NEW_ROOT}/${file}")
916*61c4878aSAndroid Build Coastguard Worker    else()
917*61c4878aSAndroid Build Coastguard Worker      foreach(ext IN LISTS EXTENSIONS)
918*61c4878aSAndroid Build Coastguard Worker        get_filename_component(dir "${file}" DIRECTORY)
919*61c4878aSAndroid Build Coastguard Worker        get_filename_component(name "${file}" NAME_WE)
920*61c4878aSAndroid Build Coastguard Worker        list(APPEND mirrored_files "${NEW_ROOT}/${dir}/${name}${ext}")
921*61c4878aSAndroid Build Coastguard Worker      endforeach()
922*61c4878aSAndroid Build Coastguard Worker    endif()
923*61c4878aSAndroid Build Coastguard Worker  endforeach()
924*61c4878aSAndroid Build Coastguard Worker
925*61c4878aSAndroid Build Coastguard Worker  set("${VAR}"
926*61c4878aSAndroid Build Coastguard Worker    "${mirrored_files}"
927*61c4878aSAndroid Build Coastguard Worker    PARENT_SCOPE)
928*61c4878aSAndroid Build Coastguard Workerendfunction(pw_rebase_paths)
929