xref: /aosp_15_r20/external/pytorch/cmake/public/utils.cmake (revision da0073e96a02ea20f0ac840b70461e3646d07c45)
1*da0073e9SAndroid Build Coastguard Worker################################################################################################
2*da0073e9SAndroid Build Coastguard Worker# Exclude and prepend functionalities
3*da0073e9SAndroid Build Coastguard Workerfunction(exclude OUTPUT INPUT)
4*da0073e9SAndroid Build Coastguard Workerset(EXCLUDES ${ARGN})
5*da0073e9SAndroid Build Coastguard Workerforeach(EXCLUDE ${EXCLUDES})
6*da0073e9SAndroid Build Coastguard Worker        list(REMOVE_ITEM INPUT "${EXCLUDE}")
7*da0073e9SAndroid Build Coastguard Workerendforeach()
8*da0073e9SAndroid Build Coastguard Workerset(${OUTPUT} ${INPUT} PARENT_SCOPE)
9*da0073e9SAndroid Build Coastguard Workerendfunction(exclude)
10*da0073e9SAndroid Build Coastguard Worker
11*da0073e9SAndroid Build Coastguard Workerfunction(prepend OUTPUT PREPEND)
12*da0073e9SAndroid Build Coastguard Workerset(OUT "")
13*da0073e9SAndroid Build Coastguard Workerforeach(ITEM ${ARGN})
14*da0073e9SAndroid Build Coastguard Worker        list(APPEND OUT "${PREPEND}${ITEM}")
15*da0073e9SAndroid Build Coastguard Workerendforeach()
16*da0073e9SAndroid Build Coastguard Workerset(${OUTPUT} ${OUT} PARENT_SCOPE)
17*da0073e9SAndroid Build Coastguard Workerendfunction(prepend)
18*da0073e9SAndroid Build Coastguard Worker
19*da0073e9SAndroid Build Coastguard Worker################################################################################################
20*da0073e9SAndroid Build Coastguard Worker# Parses a version string that might have values beyond major, minor, and patch
21*da0073e9SAndroid Build Coastguard Worker# and set version variables for the library.
22*da0073e9SAndroid Build Coastguard Worker# Usage:
23*da0073e9SAndroid Build Coastguard Worker#   caffe2_parse_version_str(<library_name> <version_string>)
24*da0073e9SAndroid Build Coastguard Workerfunction(caffe2_parse_version_str LIBNAME VERSIONSTR)
25*da0073e9SAndroid Build Coastguard Worker  string(REGEX REPLACE "^([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_MAJOR "${VERSIONSTR}")
26*da0073e9SAndroid Build Coastguard Worker  string(REGEX REPLACE "^[0-9]+\\.([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_MINOR  "${VERSIONSTR}")
27*da0073e9SAndroid Build Coastguard Worker  string(REGEX REPLACE "[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_PATCH "${VERSIONSTR}")
28*da0073e9SAndroid Build Coastguard Worker  set(${LIBNAME}_VERSION_MAJOR ${${LIBNAME}_VERSION_MAJOR} ${ARGN} PARENT_SCOPE)
29*da0073e9SAndroid Build Coastguard Worker  set(${LIBNAME}_VERSION_MINOR ${${LIBNAME}_VERSION_MINOR} ${ARGN} PARENT_SCOPE)
30*da0073e9SAndroid Build Coastguard Worker  set(${LIBNAME}_VERSION_PATCH ${${LIBNAME}_VERSION_PATCH} ${ARGN} PARENT_SCOPE)
31*da0073e9SAndroid Build Coastguard Worker  set(${LIBNAME}_VERSION "${${LIBNAME}_VERSION_MAJOR}.${${LIBNAME}_VERSION_MINOR}.${${LIBNAME}_VERSION_PATCH}" PARENT_SCOPE)
32*da0073e9SAndroid Build Coastguard Workerendfunction()
33*da0073e9SAndroid Build Coastguard Worker
34*da0073e9SAndroid Build Coastguard Worker###
35*da0073e9SAndroid Build Coastguard Worker# Removes common indentation from a block of text to produce code suitable for
36*da0073e9SAndroid Build Coastguard Worker# setting to `python -c`, or using with pycmd. This allows multiline code to be
37*da0073e9SAndroid Build Coastguard Worker# nested nicely in the surrounding code structure.
38*da0073e9SAndroid Build Coastguard Worker#
39*da0073e9SAndroid Build Coastguard Worker# This function respsects Python_EXECUTABLE if it defined, otherwise it uses
40*da0073e9SAndroid Build Coastguard Worker# `python` and hopes for the best. An error will be thrown if it is not found.
41*da0073e9SAndroid Build Coastguard Worker#
42*da0073e9SAndroid Build Coastguard Worker# Args:
43*da0073e9SAndroid Build Coastguard Worker#     outvar : variable that will hold the stdout of the python command
44*da0073e9SAndroid Build Coastguard Worker#     text   : text to remove indentation from
45*da0073e9SAndroid Build Coastguard Worker#
46*da0073e9SAndroid Build Coastguard Workerfunction(dedent outvar text)
47*da0073e9SAndroid Build Coastguard Worker  # Use Python_EXECUTABLE if it is defined, otherwise default to python
48*da0073e9SAndroid Build Coastguard Worker  if("${Python_EXECUTABLE}" STREQUAL "")
49*da0073e9SAndroid Build Coastguard Worker    set(_python_exe "python3")
50*da0073e9SAndroid Build Coastguard Worker  else()
51*da0073e9SAndroid Build Coastguard Worker    set(_python_exe "${Python_EXECUTABLE}")
52*da0073e9SAndroid Build Coastguard Worker  endif()
53*da0073e9SAndroid Build Coastguard Worker  set(_fixup_cmd "import sys; from textwrap import dedent; print(dedent(sys.stdin.read()))")
54*da0073e9SAndroid Build Coastguard Worker  file(WRITE "${CMAKE_BINARY_DIR}/indented.txt" "${text}")
55*da0073e9SAndroid Build Coastguard Worker  execute_process(
56*da0073e9SAndroid Build Coastguard Worker    COMMAND "${_python_exe}" -c "${_fixup_cmd}"
57*da0073e9SAndroid Build Coastguard Worker    INPUT_FILE "${CMAKE_BINARY_DIR}/indented.txt"
58*da0073e9SAndroid Build Coastguard Worker    RESULT_VARIABLE _dedent_exitcode
59*da0073e9SAndroid Build Coastguard Worker    OUTPUT_VARIABLE _dedent_text)
60*da0073e9SAndroid Build Coastguard Worker  if(NOT _dedent_exitcode EQUAL 0)
61*da0073e9SAndroid Build Coastguard Worker    message(ERROR " Failed to remove indentation from: \n\"\"\"\n${text}\n\"\"\"
62*da0073e9SAndroid Build Coastguard Worker    Python dedent failed with error code: ${_dedent_exitcode}")
63*da0073e9SAndroid Build Coastguard Worker    message(FATAL_ERROR " Python dedent failed with error code: ${_dedent_exitcode}")
64*da0073e9SAndroid Build Coastguard Worker  endif()
65*da0073e9SAndroid Build Coastguard Worker  # Remove supurflous newlines (artifacts of print)
66*da0073e9SAndroid Build Coastguard Worker  string(STRIP "${_dedent_text}" _dedent_text)
67*da0073e9SAndroid Build Coastguard Worker  set(${outvar} "${_dedent_text}" PARENT_SCOPE)
68*da0073e9SAndroid Build Coastguard Workerendfunction()
69*da0073e9SAndroid Build Coastguard Worker
70*da0073e9SAndroid Build Coastguard Worker
71*da0073e9SAndroid Build Coastguard Workerfunction(pycmd_no_exit outvar exitcode cmd)
72*da0073e9SAndroid Build Coastguard Worker  # Use Python_EXECUTABLE if it is defined, otherwise default to python
73*da0073e9SAndroid Build Coastguard Worker  if("${Python_EXECUTABLE}" STREQUAL "")
74*da0073e9SAndroid Build Coastguard Worker    set(_python_exe "python")
75*da0073e9SAndroid Build Coastguard Worker  else()
76*da0073e9SAndroid Build Coastguard Worker    set(_python_exe "${Python_EXECUTABLE}")
77*da0073e9SAndroid Build Coastguard Worker  endif()
78*da0073e9SAndroid Build Coastguard Worker  # run the actual command
79*da0073e9SAndroid Build Coastguard Worker  execute_process(
80*da0073e9SAndroid Build Coastguard Worker    COMMAND "${_python_exe}" -c "${cmd}"
81*da0073e9SAndroid Build Coastguard Worker    RESULT_VARIABLE _exitcode
82*da0073e9SAndroid Build Coastguard Worker    OUTPUT_VARIABLE _output)
83*da0073e9SAndroid Build Coastguard Worker  # Remove supurflous newlines (artifacts of print)
84*da0073e9SAndroid Build Coastguard Worker  string(STRIP "${_output}" _output)
85*da0073e9SAndroid Build Coastguard Worker  set(${outvar} "${_output}" PARENT_SCOPE)
86*da0073e9SAndroid Build Coastguard Worker  set(${exitcode} "${_exitcode}" PARENT_SCOPE)
87*da0073e9SAndroid Build Coastguard Workerendfunction()
88*da0073e9SAndroid Build Coastguard Worker
89*da0073e9SAndroid Build Coastguard Worker
90*da0073e9SAndroid Build Coastguard Worker###
91*da0073e9SAndroid Build Coastguard Worker# Helper function to run `python -c "<cmd>"` and capture the results of stdout
92*da0073e9SAndroid Build Coastguard Worker#
93*da0073e9SAndroid Build Coastguard Worker# Runs a python command and populates an outvar with the result of stdout.
94*da0073e9SAndroid Build Coastguard Worker# Common indentation in the text of `cmd` is removed before the command is
95*da0073e9SAndroid Build Coastguard Worker# executed, so the caller does not need to worry about indentation issues.
96*da0073e9SAndroid Build Coastguard Worker#
97*da0073e9SAndroid Build Coastguard Worker# This function respsects Python_EXECUTABLE if it defined, otherwise it uses
98*da0073e9SAndroid Build Coastguard Worker# `python` and hopes for the best. An error will be thrown if it is not found.
99*da0073e9SAndroid Build Coastguard Worker#
100*da0073e9SAndroid Build Coastguard Worker# Args:
101*da0073e9SAndroid Build Coastguard Worker#     outvar : variable that will hold the stdout of the python command
102*da0073e9SAndroid Build Coastguard Worker#     cmd    : text representing a (possibly multiline) block of python code
103*da0073e9SAndroid Build Coastguard Worker#
104*da0073e9SAndroid Build Coastguard Workerfunction(pycmd outvar cmd)
105*da0073e9SAndroid Build Coastguard Worker  dedent(_dedent_cmd "${cmd}")
106*da0073e9SAndroid Build Coastguard Worker  pycmd_no_exit(_output _exitcode "${_dedent_cmd}")
107*da0073e9SAndroid Build Coastguard Worker
108*da0073e9SAndroid Build Coastguard Worker  if(NOT _exitcode EQUAL 0)
109*da0073e9SAndroid Build Coastguard Worker    message(ERROR " Failed when running python code: \"\"\"\n${_dedent_cmd}\n\"\"\"")
110*da0073e9SAndroid Build Coastguard Worker    message(FATAL_ERROR " Python command failed with error code: ${_exitcode}")
111*da0073e9SAndroid Build Coastguard Worker  endif()
112*da0073e9SAndroid Build Coastguard Worker  # Remove supurflous newlines (artifacts of print)
113*da0073e9SAndroid Build Coastguard Worker  string(STRIP "${_output}" _output)
114*da0073e9SAndroid Build Coastguard Worker  set(${outvar} "${_output}" PARENT_SCOPE)
115*da0073e9SAndroid Build Coastguard Workerendfunction()
116*da0073e9SAndroid Build Coastguard Worker
117*da0073e9SAndroid Build Coastguard Worker
118*da0073e9SAndroid Build Coastguard Worker##############################################################################
119*da0073e9SAndroid Build Coastguard Worker# Macro to update cached options.
120*da0073e9SAndroid Build Coastguard Workermacro(caffe2_update_option variable value)
121*da0073e9SAndroid Build Coastguard Worker  if(CAFFE2_CMAKE_BUILDING_WITH_MAIN_REPO)
122*da0073e9SAndroid Build Coastguard Worker    get_property(__help_string CACHE ${variable} PROPERTY HELPSTRING)
123*da0073e9SAndroid Build Coastguard Worker    set(${variable} ${value} CACHE BOOL ${__help_string} FORCE)
124*da0073e9SAndroid Build Coastguard Worker  else()
125*da0073e9SAndroid Build Coastguard Worker    set(${variable} ${value})
126*da0073e9SAndroid Build Coastguard Worker  endif()
127*da0073e9SAndroid Build Coastguard Workerendmacro()
128*da0073e9SAndroid Build Coastguard Worker
129*da0073e9SAndroid Build Coastguard Worker
130*da0073e9SAndroid Build Coastguard Worker##############################################################################
131*da0073e9SAndroid Build Coastguard Worker# Add an interface library definition that is dependent on the source.
132*da0073e9SAndroid Build Coastguard Worker#
133*da0073e9SAndroid Build Coastguard Worker# It's probably easiest to explain why this macro exists, by describing
134*da0073e9SAndroid Build Coastguard Worker# what things would look like if we didn't have this macro.
135*da0073e9SAndroid Build Coastguard Worker#
136*da0073e9SAndroid Build Coastguard Worker# Let's suppose we want to statically link against torch.  We've defined
137*da0073e9SAndroid Build Coastguard Worker# a library in cmake called torch, and we might think that we just
138*da0073e9SAndroid Build Coastguard Worker# target_link_libraries(my-app PUBLIC torch).  This will result in a
139*da0073e9SAndroid Build Coastguard Worker# linker argument 'libtorch.a' getting passed to the linker.
140*da0073e9SAndroid Build Coastguard Worker#
141*da0073e9SAndroid Build Coastguard Worker# Unfortunately, this link command is wrong!  We have static
142*da0073e9SAndroid Build Coastguard Worker# initializers in libtorch.a that would get improperly pruned by
143*da0073e9SAndroid Build Coastguard Worker# the default link settings.  What we actually need is for you
144*da0073e9SAndroid Build Coastguard Worker# to do -Wl,--whole-archive,libtorch.a -Wl,--no-whole-archive to ensure
145*da0073e9SAndroid Build Coastguard Worker# that we keep all symbols, even if they are (seemingly) not used.
146*da0073e9SAndroid Build Coastguard Worker#
147*da0073e9SAndroid Build Coastguard Worker# What caffe2_interface_library does is create an interface library
148*da0073e9SAndroid Build Coastguard Worker# that indirectly depends on the real library, but sets up the link
149*da0073e9SAndroid Build Coastguard Worker# arguments so that you get all of the extra link settings you need.
150*da0073e9SAndroid Build Coastguard Worker# The result is not a "real" library, and so we have to manually
151*da0073e9SAndroid Build Coastguard Worker# copy over necessary properties from the original target.
152*da0073e9SAndroid Build Coastguard Worker#
153*da0073e9SAndroid Build Coastguard Worker# (The discussion above is about static libraries, but a similar
154*da0073e9SAndroid Build Coastguard Worker# situation occurs for dynamic libraries: if no symbols are used from
155*da0073e9SAndroid Build Coastguard Worker# a dynamic library, it will be pruned unless you are --no-as-needed)
156*da0073e9SAndroid Build Coastguard Workermacro(caffe2_interface_library SRC DST)
157*da0073e9SAndroid Build Coastguard Worker  add_library(${DST} INTERFACE)
158*da0073e9SAndroid Build Coastguard Worker  add_dependencies(${DST} ${SRC})
159*da0073e9SAndroid Build Coastguard Worker  # Depending on the nature of the source library as well as the compiler,
160*da0073e9SAndroid Build Coastguard Worker  # determine the needed compilation flags.
161*da0073e9SAndroid Build Coastguard Worker  get_target_property(__src_target_type ${SRC} TYPE)
162*da0073e9SAndroid Build Coastguard Worker  # Depending on the type of the source library, we will set up the
163*da0073e9SAndroid Build Coastguard Worker  # link command for the specific SRC library.
164*da0073e9SAndroid Build Coastguard Worker  if(${__src_target_type} STREQUAL "STATIC_LIBRARY")
165*da0073e9SAndroid Build Coastguard Worker    # In the case of static library, we will need to add whole-static flags.
166*da0073e9SAndroid Build Coastguard Worker    if(APPLE)
167*da0073e9SAndroid Build Coastguard Worker      target_link_libraries(
168*da0073e9SAndroid Build Coastguard Worker          ${DST} INTERFACE -Wl,-force_load,\"$<TARGET_FILE:${SRC}>\")
169*da0073e9SAndroid Build Coastguard Worker    elseif(MSVC)
170*da0073e9SAndroid Build Coastguard Worker      # In MSVC, we will add whole archive in default.
171*da0073e9SAndroid Build Coastguard Worker      target_link_libraries(
172*da0073e9SAndroid Build Coastguard Worker         ${DST} INTERFACE "$<TARGET_FILE:${SRC}>")
173*da0073e9SAndroid Build Coastguard Worker      target_link_options(
174*da0073e9SAndroid Build Coastguard Worker         ${DST} INTERFACE "-WHOLEARCHIVE:$<TARGET_FILE:${SRC}>")
175*da0073e9SAndroid Build Coastguard Worker    else()
176*da0073e9SAndroid Build Coastguard Worker      # Assume everything else is like gcc
177*da0073e9SAndroid Build Coastguard Worker      target_link_libraries(${DST} INTERFACE
178*da0073e9SAndroid Build Coastguard Worker          "-Wl,--whole-archive,\"$<TARGET_FILE:${SRC}>\" -Wl,--no-whole-archive")
179*da0073e9SAndroid Build Coastguard Worker    endif()
180*da0073e9SAndroid Build Coastguard Worker    # Link all interface link libraries of the src target as well.
181*da0073e9SAndroid Build Coastguard Worker    # For static library, we need to explicitly depend on all the libraries
182*da0073e9SAndroid Build Coastguard Worker    # that are the dependent library of the source library. Note that we cannot
183*da0073e9SAndroid Build Coastguard Worker    # use the populated INTERFACE_LINK_LIBRARIES property, because if one of the
184*da0073e9SAndroid Build Coastguard Worker    # dependent library is not a target, cmake creates a $<LINK_ONLY:src> wrapper
185*da0073e9SAndroid Build Coastguard Worker    # and then one is not able to find target "src". For more discussions, check
186*da0073e9SAndroid Build Coastguard Worker    #   https://gitlab.kitware.com/cmake/cmake/issues/15415
187*da0073e9SAndroid Build Coastguard Worker    #   https://cmake.org/pipermail/cmake-developers/2013-May/019019.html
188*da0073e9SAndroid Build Coastguard Worker    # Specifically the following quote
189*da0073e9SAndroid Build Coastguard Worker    #
190*da0073e9SAndroid Build Coastguard Worker    # """
191*da0073e9SAndroid Build Coastguard Worker    # For STATIC libraries we can define that the PUBLIC/PRIVATE/INTERFACE keys
192*da0073e9SAndroid Build Coastguard Worker    # are ignored for linking and that it always populates both LINK_LIBRARIES
193*da0073e9SAndroid Build Coastguard Worker    # LINK_INTERFACE_LIBRARIES.  Note that for STATIC libraries the
194*da0073e9SAndroid Build Coastguard Worker    # LINK_LIBRARIES property will not be used for anything except build-order
195*da0073e9SAndroid Build Coastguard Worker    # dependencies.
196*da0073e9SAndroid Build Coastguard Worker    # """
197*da0073e9SAndroid Build Coastguard Worker    target_link_libraries(${DST} INTERFACE
198*da0073e9SAndroid Build Coastguard Worker        $<TARGET_PROPERTY:${SRC},LINK_LIBRARIES>)
199*da0073e9SAndroid Build Coastguard Worker  elseif(${__src_target_type} STREQUAL "SHARED_LIBRARY")
200*da0073e9SAndroid Build Coastguard Worker    if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
201*da0073e9SAndroid Build Coastguard Worker      target_link_libraries(${DST} INTERFACE
202*da0073e9SAndroid Build Coastguard Worker          "-Wl,--no-as-needed,\"$<TARGET_FILE:${SRC}>\" -Wl,--as-needed")
203*da0073e9SAndroid Build Coastguard Worker    else()
204*da0073e9SAndroid Build Coastguard Worker      target_link_libraries(${DST} INTERFACE ${SRC})
205*da0073e9SAndroid Build Coastguard Worker    endif()
206*da0073e9SAndroid Build Coastguard Worker    # Link all interface link libraries of the src target as well.
207*da0073e9SAndroid Build Coastguard Worker    # For shared libraries, we can simply depend on the INTERFACE_LINK_LIBRARIES
208*da0073e9SAndroid Build Coastguard Worker    # property of the target.
209*da0073e9SAndroid Build Coastguard Worker    target_link_libraries(${DST} INTERFACE
210*da0073e9SAndroid Build Coastguard Worker        $<TARGET_PROPERTY:${SRC},INTERFACE_LINK_LIBRARIES>)
211*da0073e9SAndroid Build Coastguard Worker  else()
212*da0073e9SAndroid Build Coastguard Worker    message(FATAL_ERROR
213*da0073e9SAndroid Build Coastguard Worker        "You made a CMake build file error: target " ${SRC}
214*da0073e9SAndroid Build Coastguard Worker        " must be of type either STATIC_LIBRARY or SHARED_LIBRARY. However, "
215*da0073e9SAndroid Build Coastguard Worker        "I got " ${__src_target_type} ".")
216*da0073e9SAndroid Build Coastguard Worker  endif()
217*da0073e9SAndroid Build Coastguard Worker  # For all other interface properties, manually inherit from the source target.
218*da0073e9SAndroid Build Coastguard Worker  set_target_properties(${DST} PROPERTIES
219*da0073e9SAndroid Build Coastguard Worker    INTERFACE_COMPILE_DEFINITIONS
220*da0073e9SAndroid Build Coastguard Worker    $<TARGET_PROPERTY:${SRC},INTERFACE_COMPILE_DEFINITIONS>
221*da0073e9SAndroid Build Coastguard Worker    INTERFACE_COMPILE_OPTIONS
222*da0073e9SAndroid Build Coastguard Worker    $<TARGET_PROPERTY:${SRC},INTERFACE_COMPILE_OPTIONS>
223*da0073e9SAndroid Build Coastguard Worker    INTERFACE_INCLUDE_DIRECTORIES
224*da0073e9SAndroid Build Coastguard Worker    $<TARGET_PROPERTY:${SRC},INTERFACE_INCLUDE_DIRECTORIES>
225*da0073e9SAndroid Build Coastguard Worker    INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
226*da0073e9SAndroid Build Coastguard Worker    $<TARGET_PROPERTY:${SRC},INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>)
227*da0073e9SAndroid Build Coastguard Workerendmacro()
228*da0073e9SAndroid Build Coastguard Worker
229*da0073e9SAndroid Build Coastguard Worker
230*da0073e9SAndroid Build Coastguard Worker##############################################################################
231*da0073e9SAndroid Build Coastguard Worker# Creating a Caffe2 binary target with sources specified with relative path.
232*da0073e9SAndroid Build Coastguard Worker# Usage:
233*da0073e9SAndroid Build Coastguard Worker#   caffe2_binary_target(target_name_or_src <src1> [<src2>] [<src3>] ...)
234*da0073e9SAndroid Build Coastguard Worker# If only target_name_or_src is specified, this target is build with one single
235*da0073e9SAndroid Build Coastguard Worker# source file and the target name is autogen from the filename. Otherwise, the
236*da0073e9SAndroid Build Coastguard Worker# target name is given by the first argument and the rest are the source files
237*da0073e9SAndroid Build Coastguard Worker# to build the target.
238*da0073e9SAndroid Build Coastguard Workerfunction(caffe2_binary_target target_name_or_src)
239*da0073e9SAndroid Build Coastguard Worker  # https://cmake.org/cmake/help/latest/command/function.html
240*da0073e9SAndroid Build Coastguard Worker  # Checking that ARGC is greater than # is the only way to ensure
241*da0073e9SAndroid Build Coastguard Worker  # that ARGV# was passed to the function as an extra argument.
242*da0073e9SAndroid Build Coastguard Worker  if(ARGC GREATER 1)
243*da0073e9SAndroid Build Coastguard Worker    set(__target ${target_name_or_src})
244*da0073e9SAndroid Build Coastguard Worker    prepend(__srcs "${CMAKE_CURRENT_SOURCE_DIR}/" "${ARGN}")
245*da0073e9SAndroid Build Coastguard Worker  else()
246*da0073e9SAndroid Build Coastguard Worker    get_filename_component(__target ${target_name_or_src} NAME_WE)
247*da0073e9SAndroid Build Coastguard Worker    prepend(__srcs "${CMAKE_CURRENT_SOURCE_DIR}/" "${target_name_or_src}")
248*da0073e9SAndroid Build Coastguard Worker  endif()
249*da0073e9SAndroid Build Coastguard Worker  add_executable(${__target} ${__srcs})
250*da0073e9SAndroid Build Coastguard Worker  target_link_libraries(${__target} torch_library)
251*da0073e9SAndroid Build Coastguard Worker  # If we have Caffe2_MODULES defined, we will also link with the modules.
252*da0073e9SAndroid Build Coastguard Worker  if(DEFINED Caffe2_MODULES)
253*da0073e9SAndroid Build Coastguard Worker    target_link_libraries(${__target} ${Caffe2_MODULES})
254*da0073e9SAndroid Build Coastguard Worker  endif()
255*da0073e9SAndroid Build Coastguard Worker  install(TARGETS ${__target} DESTINATION bin)
256*da0073e9SAndroid Build Coastguard Workerendfunction()
257*da0073e9SAndroid Build Coastguard Worker
258*da0073e9SAndroid Build Coastguard Workerfunction(caffe2_hip_binary_target target_name_or_src)
259*da0073e9SAndroid Build Coastguard Worker  if(ARGC GREATER 1)
260*da0073e9SAndroid Build Coastguard Worker    set(__target ${target_name_or_src})
261*da0073e9SAndroid Build Coastguard Worker    prepend(__srcs "${CMAKE_CURRENT_SOURCE_DIR}/" "${ARGN}")
262*da0073e9SAndroid Build Coastguard Worker  else()
263*da0073e9SAndroid Build Coastguard Worker    get_filename_component(__target ${target_name_or_src} NAME_WE)
264*da0073e9SAndroid Build Coastguard Worker    prepend(__srcs "${CMAKE_CURRENT_SOURCE_DIR}/" "${target_name_or_src}")
265*da0073e9SAndroid Build Coastguard Worker  endif()
266*da0073e9SAndroid Build Coastguard Worker
267*da0073e9SAndroid Build Coastguard Worker  caffe2_binary_target(${target_name_or_src})
268*da0073e9SAndroid Build Coastguard Worker
269*da0073e9SAndroid Build Coastguard Worker  target_compile_options(${__target} PRIVATE ${HIP_CXX_FLAGS})
270*da0073e9SAndroid Build Coastguard Worker  target_include_directories(${__target} PRIVATE ${Caffe2_HIP_INCLUDE})
271*da0073e9SAndroid Build Coastguard Workerendfunction()
272*da0073e9SAndroid Build Coastguard Worker
273*da0073e9SAndroid Build Coastguard Worker
274*da0073e9SAndroid Build Coastguard Worker##############################################################################
275*da0073e9SAndroid Build Coastguard Worker# Multiplex between adding libraries for CUDA versus HIP (AMD Software Stack).
276*da0073e9SAndroid Build Coastguard Worker# Usage:
277*da0073e9SAndroid Build Coastguard Worker#   torch_cuda_based_add_library(cuda_target)
278*da0073e9SAndroid Build Coastguard Worker#
279*da0073e9SAndroid Build Coastguard Workermacro(torch_cuda_based_add_library cuda_target)
280*da0073e9SAndroid Build Coastguard Worker  if(USE_ROCM)
281*da0073e9SAndroid Build Coastguard Worker    hip_add_library(${cuda_target} ${ARGN})
282*da0073e9SAndroid Build Coastguard Worker  elseif(USE_CUDA)
283*da0073e9SAndroid Build Coastguard Worker    add_library(${cuda_target} ${ARGN})
284*da0073e9SAndroid Build Coastguard Worker  else()
285*da0073e9SAndroid Build Coastguard Worker  endif()
286*da0073e9SAndroid Build Coastguard Workerendmacro()
287*da0073e9SAndroid Build Coastguard Worker
288*da0073e9SAndroid Build Coastguard Worker##############################################################################
289*da0073e9SAndroid Build Coastguard Worker# Get the HIP arch flags specified by PYTORCH_ROCM_ARCH.
290*da0073e9SAndroid Build Coastguard Worker# Usage:
291*da0073e9SAndroid Build Coastguard Worker#   torch_hip_get_arch_list(variable_to_store_flags)
292*da0073e9SAndroid Build Coastguard Worker#
293*da0073e9SAndroid Build Coastguard Workermacro(torch_hip_get_arch_list store_var)
294*da0073e9SAndroid Build Coastguard Worker  if(DEFINED ENV{PYTORCH_ROCM_ARCH})
295*da0073e9SAndroid Build Coastguard Worker    set(_TMP $ENV{PYTORCH_ROCM_ARCH})
296*da0073e9SAndroid Build Coastguard Worker  else()
297*da0073e9SAndroid Build Coastguard Worker    # Use arch of installed GPUs as default
298*da0073e9SAndroid Build Coastguard Worker    execute_process(COMMAND "rocm_agent_enumerator" COMMAND bash "-c" "grep -v gfx000 | sort -u | xargs | tr -d '\n'"
299*da0073e9SAndroid Build Coastguard Worker                    RESULT_VARIABLE ROCM_AGENT_ENUMERATOR_RESULT
300*da0073e9SAndroid Build Coastguard Worker                    OUTPUT_VARIABLE ROCM_ARCH_INSTALLED)
301*da0073e9SAndroid Build Coastguard Worker    if(NOT ROCM_AGENT_ENUMERATOR_RESULT EQUAL 0)
302*da0073e9SAndroid Build Coastguard Worker      message(FATAL_ERROR " Could not detect ROCm arch for GPUs on machine. Result: '${ROCM_AGENT_ENUMERATOR_RESULT}'")
303*da0073e9SAndroid Build Coastguard Worker    endif()
304*da0073e9SAndroid Build Coastguard Worker    set(_TMP ${ROCM_ARCH_INSTALLED})
305*da0073e9SAndroid Build Coastguard Worker  endif()
306*da0073e9SAndroid Build Coastguard Worker  string(REPLACE " " ";" ${store_var} "${_TMP}")
307*da0073e9SAndroid Build Coastguard Workerendmacro()
308*da0073e9SAndroid Build Coastguard Worker
309*da0073e9SAndroid Build Coastguard Worker##############################################################################
310*da0073e9SAndroid Build Coastguard Worker# Get the NVCC arch flags specified by TORCH_CUDA_ARCH_LIST and CUDA_ARCH_NAME.
311*da0073e9SAndroid Build Coastguard Worker# Usage:
312*da0073e9SAndroid Build Coastguard Worker#   torch_cuda_get_nvcc_gencode_flag(variable_to_store_flags)
313*da0073e9SAndroid Build Coastguard Worker#
314*da0073e9SAndroid Build Coastguard Workermacro(torch_cuda_get_nvcc_gencode_flag store_var)
315*da0073e9SAndroid Build Coastguard Worker  # setting nvcc arch flags
316*da0073e9SAndroid Build Coastguard Worker  if((NOT DEFINED TORCH_CUDA_ARCH_LIST) AND (DEFINED ENV{TORCH_CUDA_ARCH_LIST}))
317*da0073e9SAndroid Build Coastguard Worker    message(WARNING
318*da0073e9SAndroid Build Coastguard Worker        "In the future we will require one to explicitly pass "
319*da0073e9SAndroid Build Coastguard Worker        "TORCH_CUDA_ARCH_LIST to cmake instead of implicitly setting it as an "
320*da0073e9SAndroid Build Coastguard Worker        "env variable. This will become a FATAL_ERROR in future version of "
321*da0073e9SAndroid Build Coastguard Worker        "pytorch.")
322*da0073e9SAndroid Build Coastguard Worker    set(TORCH_CUDA_ARCH_LIST $ENV{TORCH_CUDA_ARCH_LIST})
323*da0073e9SAndroid Build Coastguard Worker  endif()
324*da0073e9SAndroid Build Coastguard Worker  if(DEFINED CUDA_ARCH_NAME)
325*da0073e9SAndroid Build Coastguard Worker    message(WARNING
326*da0073e9SAndroid Build Coastguard Worker        "CUDA_ARCH_NAME is no longer used. Use TORCH_CUDA_ARCH_LIST instead. "
327*da0073e9SAndroid Build Coastguard Worker        "Right now, CUDA_ARCH_NAME is ${CUDA_ARCH_NAME} and "
328*da0073e9SAndroid Build Coastguard Worker        "TORCH_CUDA_ARCH_LIST is ${TORCH_CUDA_ARCH_LIST}.")
329*da0073e9SAndroid Build Coastguard Worker    set(TORCH_CUDA_ARCH_LIST TORCH_CUDA_ARCH_LIST ${CUDA_ARCH_NAME})
330*da0073e9SAndroid Build Coastguard Worker  endif()
331*da0073e9SAndroid Build Coastguard Worker
332*da0073e9SAndroid Build Coastguard Worker  # Invoke cuda_select_nvcc_arch_flags from proper cmake FindCUDA.
333*da0073e9SAndroid Build Coastguard Worker  cuda_select_nvcc_arch_flags(${store_var} ${TORCH_CUDA_ARCH_LIST})
334*da0073e9SAndroid Build Coastguard Workerendmacro()
335*da0073e9SAndroid Build Coastguard Worker
336*da0073e9SAndroid Build Coastguard Worker
337*da0073e9SAndroid Build Coastguard Worker##############################################################################
338*da0073e9SAndroid Build Coastguard Worker# Add standard compile options.
339*da0073e9SAndroid Build Coastguard Worker# Usage:
340*da0073e9SAndroid Build Coastguard Worker#   torch_compile_options(lib_name)
341*da0073e9SAndroid Build Coastguard Workerfunction(torch_compile_options libname)
342*da0073e9SAndroid Build Coastguard Worker  set_property(TARGET ${libname} PROPERTY CXX_STANDARD 17)
343*da0073e9SAndroid Build Coastguard Worker
344*da0073e9SAndroid Build Coastguard Worker  # until they can be unified, keep these lists synced with setup.py
345*da0073e9SAndroid Build Coastguard Worker  if(MSVC)
346*da0073e9SAndroid Build Coastguard Worker
347*da0073e9SAndroid Build Coastguard Worker    if(MSVC_Z7_OVERRIDE)
348*da0073e9SAndroid Build Coastguard Worker      set(MSVC_DEBINFO_OPTION "/Z7")
349*da0073e9SAndroid Build Coastguard Worker    else()
350*da0073e9SAndroid Build Coastguard Worker      set(MSVC_DEBINFO_OPTION "/Zi")
351*da0073e9SAndroid Build Coastguard Worker    endif()
352*da0073e9SAndroid Build Coastguard Worker
353*da0073e9SAndroid Build Coastguard Worker    target_compile_options(${libname} PUBLIC
354*da0073e9SAndroid Build Coastguard Worker      $<$<COMPILE_LANGUAGE:CXX>:
355*da0073e9SAndroid Build Coastguard Worker        ${MSVC_RUNTIME_LIBRARY_OPTION}
356*da0073e9SAndroid Build Coastguard Worker        $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:${MSVC_DEBINFO_OPTION}>
357*da0073e9SAndroid Build Coastguard Worker        /EHsc
358*da0073e9SAndroid Build Coastguard Worker        /bigobj>
359*da0073e9SAndroid Build Coastguard Worker      )
360*da0073e9SAndroid Build Coastguard Worker  else()
361*da0073e9SAndroid Build Coastguard Worker    set(private_compile_options
362*da0073e9SAndroid Build Coastguard Worker      -Wall
363*da0073e9SAndroid Build Coastguard Worker      -Wextra
364*da0073e9SAndroid Build Coastguard Worker      -Wdeprecated
365*da0073e9SAndroid Build Coastguard Worker      -Wno-unused-parameter
366*da0073e9SAndroid Build Coastguard Worker      -Wno-missing-field-initializers
367*da0073e9SAndroid Build Coastguard Worker      -Wno-type-limits
368*da0073e9SAndroid Build Coastguard Worker      -Wno-array-bounds
369*da0073e9SAndroid Build Coastguard Worker      -Wno-unknown-pragmas
370*da0073e9SAndroid Build Coastguard Worker      -Wno-strict-overflow
371*da0073e9SAndroid Build Coastguard Worker      -Wno-strict-aliasing
372*da0073e9SAndroid Build Coastguard Worker      )
373*da0073e9SAndroid Build Coastguard Worker    list(APPEND private_compile_options -Wunused-function)
374*da0073e9SAndroid Build Coastguard Worker    list(APPEND private_compile_options -Wunused-variable)
375*da0073e9SAndroid Build Coastguard Worker    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
376*da0073e9SAndroid Build Coastguard Worker      list(APPEND private_compile_options -Wunused-but-set-variable)
377*da0073e9SAndroid Build Coastguard Worker    endif()
378*da0073e9SAndroid Build Coastguard Worker    if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
379*da0073e9SAndroid Build Coastguard Worker      list(APPEND private_compile_options -Wunused-private-field)
380*da0073e9SAndroid Build Coastguard Worker    endif()
381*da0073e9SAndroid Build Coastguard Worker    if(NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
382*da0073e9SAndroid Build Coastguard Worker      list(APPEND private_compile_options
383*da0073e9SAndroid Build Coastguard Worker        # Considered to be flaky.  See the discussion at
384*da0073e9SAndroid Build Coastguard Worker        # https://github.com/pytorch/pytorch/pull/9608
385*da0073e9SAndroid Build Coastguard Worker        -Wno-maybe-uninitialized)
386*da0073e9SAndroid Build Coastguard Worker    endif()
387*da0073e9SAndroid Build Coastguard Worker
388*da0073e9SAndroid Build Coastguard Worker    if(WERROR)
389*da0073e9SAndroid Build Coastguard Worker      list(APPEND private_compile_options
390*da0073e9SAndroid Build Coastguard Worker        -Werror
391*da0073e9SAndroid Build Coastguard Worker        -Werror=inconsistent-missing-override
392*da0073e9SAndroid Build Coastguard Worker        -Werror=inconsistent-missing-destructor-override
393*da0073e9SAndroid Build Coastguard Worker        -Werror=unused-function
394*da0073e9SAndroid Build Coastguard Worker        -Werror=unused-variable
395*da0073e9SAndroid Build Coastguard Worker        -Werror=pedantic
396*da0073e9SAndroid Build Coastguard Worker      )
397*da0073e9SAndroid Build Coastguard Worker      if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
398*da0073e9SAndroid Build Coastguard Worker        list(APPEND private_compile_options -Werror=unused-but-set-variable)
399*da0073e9SAndroid Build Coastguard Worker      endif()
400*da0073e9SAndroid Build Coastguard Worker    endif()
401*da0073e9SAndroid Build Coastguard Worker  endif()
402*da0073e9SAndroid Build Coastguard Worker
403*da0073e9SAndroid Build Coastguard Worker
404*da0073e9SAndroid Build Coastguard Worker  target_compile_options(${libname} PRIVATE
405*da0073e9SAndroid Build Coastguard Worker      $<$<COMPILE_LANGUAGE:CXX>:${private_compile_options}>)
406*da0073e9SAndroid Build Coastguard Worker  if(USE_CUDA)
407*da0073e9SAndroid Build Coastguard Worker    foreach(option IN LISTS private_compile_options)
408*da0073e9SAndroid Build Coastguard Worker      target_compile_options(${libname} PRIVATE $<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler ${option}>)
409*da0073e9SAndroid Build Coastguard Worker    endforeach()
410*da0073e9SAndroid Build Coastguard Worker  endif()
411*da0073e9SAndroid Build Coastguard Worker
412*da0073e9SAndroid Build Coastguard Worker  if(NOT WIN32 AND NOT USE_ASAN)
413*da0073e9SAndroid Build Coastguard Worker    # Enable hidden visibility by default to make it easier to debug issues with
414*da0073e9SAndroid Build Coastguard Worker    # TORCH_API annotations. Hidden visibility with selective default visibility
415*da0073e9SAndroid Build Coastguard Worker    # behaves close enough to Windows' dllimport/dllexport.
416*da0073e9SAndroid Build Coastguard Worker    #
417*da0073e9SAndroid Build Coastguard Worker    # Unfortunately, hidden visibility messes up some ubsan warnings because
418*da0073e9SAndroid Build Coastguard Worker    # templated classes crossing library boundary get duplicated (but identical)
419*da0073e9SAndroid Build Coastguard Worker    # definitions. It's easier to just disable it.
420*da0073e9SAndroid Build Coastguard Worker    target_compile_options(${libname} PRIVATE
421*da0073e9SAndroid Build Coastguard Worker        $<$<COMPILE_LANGUAGE:CXX>: -fvisibility=hidden>)
422*da0073e9SAndroid Build Coastguard Worker  endif()
423*da0073e9SAndroid Build Coastguard Worker
424*da0073e9SAndroid Build Coastguard Worker  # Use -O2 for release builds (-O3 doesn't improve perf, and -Os results in perf regression)
425*da0073e9SAndroid Build Coastguard Worker  target_compile_options(${libname} PRIVATE
426*da0073e9SAndroid Build Coastguard Worker      $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<OR:$<CONFIG:Release>,$<CONFIG:RelWithDebInfo>>>:-O2>)
427*da0073e9SAndroid Build Coastguard Worker
428*da0073e9SAndroid Build Coastguard Workerendfunction()
429*da0073e9SAndroid Build Coastguard Worker
430*da0073e9SAndroid Build Coastguard Worker##############################################################################
431*da0073e9SAndroid Build Coastguard Worker# Set old-style FindCuda.cmake compile flags from modern CMake cuda flags.
432*da0073e9SAndroid Build Coastguard Worker# Usage:
433*da0073e9SAndroid Build Coastguard Worker#   torch_update_find_cuda_flags()
434*da0073e9SAndroid Build Coastguard Workerfunction(torch_update_find_cuda_flags)
435*da0073e9SAndroid Build Coastguard Worker  # Convert -O2 -Xcompiler="-O2 -Wall" to "-O2;-Xcompiler=-O2,-Wall"
436*da0073e9SAndroid Build Coastguard Worker  if(USE_CUDA)
437*da0073e9SAndroid Build Coastguard Worker    separate_arguments(FLAGS UNIX_COMMAND "${CMAKE_CUDA_FLAGS}")
438*da0073e9SAndroid Build Coastguard Worker    string(REPLACE " " "," FLAGS "${FLAGS}")
439*da0073e9SAndroid Build Coastguard Worker    set(CUDA_NVCC_FLAGS ${FLAGS} PARENT_SCOPE)
440*da0073e9SAndroid Build Coastguard Worker
441*da0073e9SAndroid Build Coastguard Worker    separate_arguments(FLAGS_DEBUG UNIX_COMMAND "${CMAKE_CUDA_FLAGS_DEBUG}")
442*da0073e9SAndroid Build Coastguard Worker    string(REPLACE " " "," FLAGS_DEBUG "${FLAGS_DEBUG}")
443*da0073e9SAndroid Build Coastguard Worker    set(CUDA_NVCC_FLAGS_DEBUG "${FLAGS_DEBUG}" PARENT_SCOPE)
444*da0073e9SAndroid Build Coastguard Worker
445*da0073e9SAndroid Build Coastguard Worker    separate_arguments(FLAGS_RELEASE UNIX_COMMAND "${CMAKE_CUDA_FLAGS_RELEASE}")
446*da0073e9SAndroid Build Coastguard Worker    string(REPLACE " " "," FLAGS_RELEASE "${FLAGS_RELEASE}")
447*da0073e9SAndroid Build Coastguard Worker    set(CUDA_NVCC_FLAGS_RELEASE "${FLAGS_RELEASE}" PARENT_SCOPE)
448*da0073e9SAndroid Build Coastguard Worker
449*da0073e9SAndroid Build Coastguard Worker    separate_arguments(FLAGS_MINSIZEREL UNIX_COMMAND "${CMAKE_CUDA_FLAGS_MINSIZEREL}")
450*da0073e9SAndroid Build Coastguard Worker    string(REPLACE " " "," FLAGS_MINSIZEREL "${FLAGS_MINSIZEREL}")
451*da0073e9SAndroid Build Coastguard Worker    set(CUDA_NVCC_FLAGS_MINSIZEREL "${FLAGS_MINSIZEREL}" PARENT_SCOPE)
452*da0073e9SAndroid Build Coastguard Worker
453*da0073e9SAndroid Build Coastguard Worker    separate_arguments(FLAGS_RELWITHDEBINFO UNIX_COMMAND "${CMAKE_CUDA_FLAGS_RELWITHDEBINFO}")
454*da0073e9SAndroid Build Coastguard Worker    string(REPLACE " " "," FLAGS_RELWITHDEBINFO "${FLAGS_RELWITHDEBINFO}")
455*da0073e9SAndroid Build Coastguard Worker    set(CUDA_NVCC_FLAGS_RELWITHDEBINFO "${FLAGS_RELWITHDEBINFO}" PARENT_SCOPE)
456*da0073e9SAndroid Build Coastguard Worker
457*da0073e9SAndroid Build Coastguard Worker    message(STATUS "Converting CMAKE_CUDA_FLAGS to CUDA_NVCC_FLAGS:\n"
458*da0073e9SAndroid Build Coastguard Worker                    "    CUDA_NVCC_FLAGS                = ${FLAGS}\n"
459*da0073e9SAndroid Build Coastguard Worker                    "    CUDA_NVCC_FLAGS_DEBUG          = ${FLAGS_DEBUG}\n"
460*da0073e9SAndroid Build Coastguard Worker                    "    CUDA_NVCC_FLAGS_RELEASE        = ${FLAGS_RELEASE}\n"
461*da0073e9SAndroid Build Coastguard Worker                    "    CUDA_NVCC_FLAGS_RELWITHDEBINFO = ${FLAGS_RELWITHDEBINFO}\n"
462*da0073e9SAndroid Build Coastguard Worker                    "    CUDA_NVCC_FLAGS_MINSIZEREL     = ${FLAGS_MINSIZEREL}")
463*da0073e9SAndroid Build Coastguard Worker  endif()
464*da0073e9SAndroid Build Coastguard Workerendfunction()
465*da0073e9SAndroid Build Coastguard Worker
466*da0073e9SAndroid Build Coastguard Workerinclude(CheckCXXCompilerFlag)
467*da0073e9SAndroid Build Coastguard Worker
468*da0073e9SAndroid Build Coastguard Worker##############################################################################
469*da0073e9SAndroid Build Coastguard Worker# CHeck if given flag is supported and append it to provided outputvar
470*da0073e9SAndroid Build Coastguard Worker# Also define HAS_UPPER_CASE_FLAG_NAME variable
471*da0073e9SAndroid Build Coastguard Worker# Usage:
472*da0073e9SAndroid Build Coastguard Worker#   append_cxx_flag_if_supported("-Werror" CMAKE_CXX_FLAGS)
473*da0073e9SAndroid Build Coastguard Workerfunction(append_cxx_flag_if_supported flag outputvar)
474*da0073e9SAndroid Build Coastguard Worker    string(TOUPPER "HAS${flag}" _FLAG_NAME)
475*da0073e9SAndroid Build Coastguard Worker    string(REGEX REPLACE "[=-]" "_" _FLAG_NAME "${_FLAG_NAME}")
476*da0073e9SAndroid Build Coastguard Worker    # GCC silents unknown -Wno-XXX flags, so we detect the corresponding -WXXX.
477*da0073e9SAndroid Build Coastguard Worker    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
478*da0073e9SAndroid Build Coastguard Worker      string(REGEX REPLACE "Wno-" "W" new_flag "${flag}")
479*da0073e9SAndroid Build Coastguard Worker    else()
480*da0073e9SAndroid Build Coastguard Worker      set(new_flag ${flag})
481*da0073e9SAndroid Build Coastguard Worker    endif()
482*da0073e9SAndroid Build Coastguard Worker    check_cxx_compiler_flag("${new_flag}" ${_FLAG_NAME})
483*da0073e9SAndroid Build Coastguard Worker    if(${_FLAG_NAME})
484*da0073e9SAndroid Build Coastguard Worker        string(APPEND ${outputvar} " ${flag}")
485*da0073e9SAndroid Build Coastguard Worker        set(${outputvar} "${${outputvar}}" PARENT_SCOPE)
486*da0073e9SAndroid Build Coastguard Worker    endif()
487*da0073e9SAndroid Build Coastguard Workerendfunction()
488*da0073e9SAndroid Build Coastguard Worker
489*da0073e9SAndroid Build Coastguard Workerfunction(target_compile_options_if_supported target flag)
490*da0073e9SAndroid Build Coastguard Worker  set(_compile_options "")
491*da0073e9SAndroid Build Coastguard Worker  append_cxx_flag_if_supported("${flag}" _compile_options)
492*da0073e9SAndroid Build Coastguard Worker  if(NOT "${_compile_options}" STREQUAL "")
493*da0073e9SAndroid Build Coastguard Worker    target_compile_options(${target} PRIVATE ${flag})
494*da0073e9SAndroid Build Coastguard Worker  endif()
495*da0073e9SAndroid Build Coastguard Workerendfunction()
496