1# Picotool Property Defines
2# All INHERITED, so can be defined globally, or per target
3#
4# The picotool functions all set the specified target properties,
5# and therefore if the property should be set for multiple targets
6# then it can be set manually with `set_property` or other CMake
7# functions to set properties for a given scope.
8define_property(TARGET
9    PROPERTY PICOTOOL_OTP_FILE
10    INHERITED
11    BRIEF_DOCS "OTP File to write"
12    FULL_DOCS "OTP File to write"
13)
14define_property(TARGET
15    PROPERTY PICOTOOL_SIGN_OUTPUT
16    INHERITED
17    BRIEF_DOCS "Sign output"
18    FULL_DOCS "Sign output"
19)
20define_property(TARGET
21    PROPERTY PICOTOOL_SIGFILE
22    INHERITED
23    BRIEF_DOCS "Private key for signing"
24    FULL_DOCS "Private key for signing"
25)
26define_property(TARGET
27    PROPERTY PICOTOOL_HASH_OUTPUT
28    INHERITED
29    BRIEF_DOCS "Hash output"
30    FULL_DOCS "Hash output"
31)
32define_property(TARGET
33    PROPERTY PICOTOOL_EMBED_PT
34    INHERITED
35    BRIEF_DOCS "Partition table to embed in output"
36    FULL_DOCS "Partition table to embed in output"
37)
38define_property(TARGET
39    PROPERTY PICOTOOL_AESFILE
40    INHERITED
41    BRIEF_DOCS "AES key for encrypting"
42    FULL_DOCS "AES key for encrypting"
43)
44define_property(TARGET
45    PROPERTY PICOTOOL_ENC_SIGFILE
46    INHERITED
47    BRIEF_DOCS "Private key for signing encrypted binaries"
48    FULL_DOCS "Private key for signing encrypted binaries"
49)
50define_property(TARGET
51    PROPERTY PICOTOOL_UF2_PACKAGE_ADDR
52    INHERITED
53    BRIEF_DOCS "Address to package UF2 at"
54    FULL_DOCS "Address to package UF2 at"
55)
56define_property(TARGET
57    PROPERTY PICOTOOL_UF2_FAMILY
58    INHERITED
59    BRIEF_DOCS "UF2 family to use"
60    FULL_DOCS "UF2 family to use"
61)
62define_property(TARGET
63    PROPERTY PICOTOOL_EXTRA_PROCESS_ARGS
64    INHERITED
65    BRIEF_DOCS "Extra arguments to pass to processing"
66    FULL_DOCS "Extra arguments to pass to processing"
67)
68define_property(TARGET
69    PROPERTY PICOTOOL_EXTRA_UF2_ARGS
70    INHERITED
71    BRIEF_DOCS "Extra arguments to pass to uf2 conversion"
72    FULL_DOCS "Extra arguments to pass to uf2 conversion"
73)
74
75# Check pioasm is installed, or build it if not installed
76function(pico_init_pioasm)
77    # Assemble the version string from components instead of using PICO_SDK_VERSION_STRING, because the version string
78    # potentially has a PRE_RELEASE_ID suffix, which will trip up the find_package call.
79    set(pioasm_VERSION_REQUIRED "${PICO_SDK_VERSION_MAJOR}.${PICO_SDK_VERSION_MINOR}.${PICO_SDK_VERSION_REVISION}")
80    if (NOT TARGET pioasm AND NOT DEFINED pioasm_FOUND)
81        set(pioasm_INSTALL_DIR ${CMAKE_BINARY_DIR}/pioasm-install)
82        if (NOT pioasm_DIR AND EXISTS ${pioasm_INSTALL_DIR}/pioasm)
83            set(pioasm_DIR ${pioasm_INSTALL_DIR}/pioasm)
84        endif()
85        # Find package - will find installed pioasm, either at pioasm_DIR or system
86        find_package(pioasm ${pioasm_VERSION_REQUIRED} QUIET CONFIG NO_CMAKE_FIND_ROOT_PATH)
87
88        if (NOT pioasm_FOUND)
89            set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PICO_SDK_PATH}/tools)
90            # todo CMAKE_CURRENT_FUNCTION_LIST_DIR ... what version?
91            find_package(pioasm MODULE REQUIRED)
92        endif()
93    endif()
94
95    if (TARGET pioasm)
96        set(pioasm_FOUND 1 PARENT_SCOPE)
97    else()
98        message("No pioasm found")
99    endif()
100endfunction()
101
102# Check picotool is installed, or download and build it if not installed
103function(pico_init_picotool)
104    set(picotool_VERSION_REQUIRED 2.1.0)
105    if (NOT TARGET picotool AND NOT DEFINED picotool_FOUND)
106        # Build path of local install dir
107        if (DEFINED ENV{PICOTOOL_FETCH_FROM_GIT_PATH} AND (NOT PICOTOOL_FETCH_FROM_GIT_PATH))
108            set(PICOTOOL_FETCH_FROM_GIT_PATH $ENV{PICOTOOL_FETCH_FROM_GIT_PATH})
109            message("Using PICOTOOL_FETCH_FROM_GIT_PATH from environment ('${PICOTOOL_FETCH_FROM_GIT_PATH}')")
110        endif ()
111        include(FetchContent)
112        if (PICOTOOL_FETCH_FROM_GIT_PATH)
113            get_filename_component(picotool_INSTALL_DIR "${PICOTOOL_FETCH_FROM_GIT_PATH}" ABSOLUTE)
114        else()
115            set(picotool_INSTALL_DIR ${FETCHCONTENT_BASE_DIR})
116        endif ()
117
118        if (NOT PICOTOOL_FORCE_FETCH_FROM_GIT AND NOT ENV{PICOTOOL_FORCE_FETCH_FROM_GIT})
119            if (NOT picotool_DIR AND EXISTS ${picotool_INSTALL_DIR}/picotool)
120                set(picotool_DIR ${picotool_INSTALL_DIR}/picotool)
121            endif()
122            # Find package - will find installed picotool, either at picotool_DIR or system
123            find_package(picotool ${picotool_VERSION_REQUIRED} QUIET CONFIG NO_CMAKE_FIND_ROOT_PATH)
124            if (NOT picotool_FOUND AND picotool_CONSIDERED_VERSIONS)
125                message(FATAL_ERROR
126                    "Incompatible picotool installation found: "
127                    "Requires version ${picotool_VERSION_REQUIRED}, "
128                    "you have version ${picotool_CONSIDERED_VERSIONS}\n"
129                    "Update your installation, or set PICOTOOL_FORCE_FETCH_FROM_GIT "
130                    "to download and build the correct version"
131                )
132            endif()
133        else()
134            message("Forcing fetch of picotool from git")
135        endif()
136        if (NOT picotool_FOUND)
137            set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PICO_SDK_PATH}/tools)
138            find_package(picotool MODULE)
139        endif()
140    endif()
141
142    if (TARGET picotool)
143        set(picotool_FOUND 1 PARENT_SCOPE)
144    else()
145        message("No picotool found")
146    endif()
147endfunction()
148
149function(picotool_check_configurable TARGET)
150    get_target_property(configured ${TARGET} PICOTOOL_PROCESSING_CONFIGURED)
151    if (configured)
152        message(FATAL_ERROR "All picotool post-processing functions for \"${TARGET}\" must come before pico_add_extra_outputs(${TARGET})")
153    endif()
154endfunction()
155
156# Generate pio header and include it in the build
157# PICO_CMAKE_CONFIG: PICO_DEFAULT_PIOASM_OUTPUT_FORMAT, Default output format used by pioasm when using pico_generate_pio_header, type=string, default=c-sdk, group=build
158function(pico_generate_pio_header TARGET PIO)
159    pico_init_pioasm()
160    cmake_parse_arguments(pico_generate_pio_header "" "OUTPUT_FORMAT;OUTPUT_DIR" "" ${ARGN} )
161
162    if (pico_generate_pio_header_OUTPUT_FORMAT)
163        set(OUTPUT_FORMAT "${pico_generate_pio_header_OUTPUT_FORMAT}")
164    elseif(DEFINED PICO_DEFAULT_PIOASM_OUTPUT_FORMAT)
165        set(OUTPUT_FORMAT "${PICO_DEFAULT_PIOASM_OUTPUT_FORMAT}")
166    else()
167        set(OUTPUT_FORMAT "c-sdk")
168    endif()
169
170    if (pico_generate_pio_header_OUTPUT_DIR)
171        file(MAKE_DIRECTORY ${pico_generate_pio_header_OUTPUT_DIR})
172        get_filename_component(HEADER_DIR ${pico_generate_pio_header_OUTPUT_DIR} ABSOLUTE)
173    else()
174        set(HEADER_DIR "${CMAKE_CURRENT_BINARY_DIR}")
175    endif()
176    get_filename_component(PIO_NAME ${PIO} NAME)
177    set(HEADER "${HEADER_DIR}/${PIO_NAME}.h")
178    #message("Will generate ${HEADER}")
179    get_filename_component(HEADER_GEN_TARGET ${PIO} NAME_WE)
180    set(HEADER_GEN_TARGET "${TARGET}_${HEADER_GEN_TARGET}_pio_h")
181
182    add_custom_target(${HEADER_GEN_TARGET} DEPENDS ${HEADER})
183
184    if (PICO_PIO_VERSION)
185        set(VERSION_STRING "${PICO_PIO_VERSION}")
186    else()
187        set(VERSION_STRING "0")
188    endif()
189    add_custom_command(OUTPUT ${HEADER}
190            DEPENDS ${PIO}
191            COMMAND pioasm -o ${OUTPUT_FORMAT} -v ${VERSION_STRING} ${PIO} ${HEADER}
192            VERBATIM)
193    add_dependencies(${TARGET} ${HEADER_GEN_TARGET})
194    get_target_property(target_type ${TARGET} TYPE)
195    if ("INTERFACE_LIBRARY" STREQUAL "${target_type}")
196        target_include_directories(${TARGET} INTERFACE ${HEADER_DIR})
197    else()
198        target_include_directories(${TARGET} PUBLIC ${HEADER_DIR})
199    endif()
200endfunction()
201
202# pico_package_uf2_output(TARGET PACKADDR)
203# Package a UF2 output to be written to the PACKADDR address. This can be
204# used with a no_flash binary to write the UF2 to flash when dragging &
205# dropping, and it will be copied to SRAM by the bootrom before execution.
206# This sets PICOTOOL_UF2_PACKAGE_ADDR to PACKADDR.
207function(pico_package_uf2_output TARGET PACKADDR)
208    picotool_check_configurable(${TARGET})
209    set_target_properties(${TARGET} PROPERTIES
210        PICOTOOL_UF2_PACKAGE_ADDR ${PACKADDR}
211    )
212endfunction()
213
214# pico_set_otp_key_output_file(TARGET OTPFILE)
215# Output the public key hash and other necessary rows to an otp JSON file.
216# This sets PICOTOOL_OTP_FILE to OTPFILE.
217function(pico_set_otp_key_output_file TARGET OTPFILE)
218    picotool_check_configurable(${TARGET})
219    set_target_properties(${TARGET} PROPERTIES
220        PICOTOOL_OTP_FILE ${OTPFILE}
221    )
222endfunction()
223
224# pico_load_map_clear_sram(TARGET)
225# Adds an entry to the load map to instruct the bootrom to clear all of SRAM
226# before loading the binary. This appends the `--clear` argument
227# to PICOTOOL_EXTRA_PROCESS_ARGS.
228function(pico_load_map_clear_sram TARGET)
229    picotool_check_configurable(${TARGET})
230    # get and set, to inherit list
231    get_target_property(extra_args ${TARGET} PICOTOOL_EXTRA_PROCESS_ARGS)
232    if (extra_args)
233        set_target_properties(${TARGET} PROPERTIES PICOTOOL_EXTRA_PROCESS_ARGS ${extra_args})
234    endif()
235    # append --clear to list
236    set_property(TARGET ${TARGET} APPEND PROPERTY
237        PICOTOOL_EXTRA_PROCESS_ARGS "--clear"
238    )
239endfunction()
240
241# pico_set_binary_version(<TARGET> [MAJOR <version>] [MINOR <version>] [ROLLBACK <version>] [ROLLBACK_ROWS <rows...>])
242# Adds a version item to the metadata block, with the given major, minor and
243# rollback version, along with the rollback rows. These are appended as arguments
244# to PICOTOOL_EXTRA_PROCESS_ARGS if setting the rollback version, or set as compile
245# definitions if only setting the major/minor versions.
246function(pico_set_binary_version TARGET)
247    picotool_check_configurable(${TARGET})
248    set(oneValueArgs MAJOR MINOR ROLLBACK)
249    set(multiValueArgs ROWS)
250    cmake_parse_arguments(PARSE_ARGV 1 SV "" "${oneValueArgs}" "${multiValueArgs}")
251    # get and set, to inherit list
252    get_target_property(extra_args ${TARGET} PICOTOOL_EXTRA_PROCESS_ARGS)
253    if (extra_args)
254        set_target_properties(${TARGET} PROPERTIES PICOTOOL_EXTRA_PROCESS_ARGS ${extra_args})
255    endif()
256    if (SV_ROLLBACK)
257        if (SV_MAJOR)
258            # append major version
259            set_property(TARGET ${TARGET} APPEND PROPERTY
260                PICOTOOL_EXTRA_PROCESS_ARGS "--major" "${SV_MAJOR}"
261            )
262        endif()
263        if (SV_MINOR)
264            # append minor version
265            set_property(TARGET ${TARGET} APPEND PROPERTY
266                PICOTOOL_EXTRA_PROCESS_ARGS "--minor" "${SV_MINOR}"
267            )
268        endif()
269        # append rollback version
270        set_property(TARGET ${TARGET} APPEND PROPERTY
271            PICOTOOL_EXTRA_PROCESS_ARGS "--rollback" "${SV_ROLLBACK}"
272        )
273        if (SV_ROWS)
274            # append rollback rows
275            foreach(row IN LISTS SV_ROWS)
276                set_property(TARGET ${TARGET} APPEND PROPERTY
277                    PICOTOOL_EXTRA_PROCESS_ARGS "${row}"
278                )
279            endforeach()
280        endif()
281    else()
282        if (SV_MAJOR)
283            # set major version
284            target_compile_definitions(${TARGET} PRIVATE PICO_CRT0_VERSION_MAJOR=${SV_MAJOR})
285        endif()
286        if (SV_MINOR)
287            # append minor version
288            target_compile_definitions(${TARGET} PRIVATE PICO_CRT0_VERSION_MINOR=${SV_MINOR})
289        endif()
290    endif()
291endfunction()
292
293# pico_set_uf2_family(TARGET FAMILY)
294# Set the UF2 family to use when creating the UF2.
295# This sets PICOTOOL_UF2_FAMILY to FAMILY.
296function(pico_set_uf2_family TARGET FAMILY)
297    picotool_check_configurable(${TARGET})
298    set_target_properties(${TARGET} PROPERTIES
299        PICOTOOL_UF2_FAMILY ${FAMILY}
300    )
301endfunction()
302
303# pico_sign_binary(TARGET [SIGFILE])
304# Sign the target binary with the given PEM signature. This sets
305# PICOTOOL_SIGN_OUTPUT to true, PICOTOOL_SIGFILE to SIGFILE (if specified),
306# and PICOTOOL_OTP_FILE to ${TARGET}.otp.json (if not already set). To
307# specify a common SIGFILE for multiple targets, the SIGFILE property can be
308# set for a given scope, and then the SIGFILE argument is optional.
309function(pico_sign_binary TARGET)
310    picotool_check_configurable(${TARGET})
311    # Enforce signing through target properties
312    set_target_properties(${TARGET} PROPERTIES
313        PICOTOOL_SIGN_OUTPUT true
314    )
315    if (ARGC EQUAL 2)
316        set_target_properties(${TARGET} PROPERTIES
317            PICOTOOL_SIGFILE ${ARGV1}
318        )
319    else()
320        get_target_property(sig_file ${TARGET} PICOTOOL_SIGFILE)
321        if (NOT sig_file)
322            message(FATAL_ERROR "Signature file not set for ${TARGET}")
323        endif()
324    endif()
325    get_target_property(otp_file ${TARGET} PICOTOOL_OTP_FILE)
326    if (NOT otp_file)
327        set_target_properties(${TARGET} PROPERTIES
328            PICOTOOL_OTP_FILE "${TARGET}.otp.json"
329        )
330    endif()
331endfunction()
332
333# pico_hash_binary(TARGET)
334# Hash the target binary. This sets PICOTOOL_HASH_OUTPUT to true.
335function(pico_hash_binary TARGET)
336    picotool_check_configurable(${TARGET})
337    # Enforce hashing through target properties
338    set_target_properties(${TARGET} PROPERTIES
339        PICOTOOL_HASH_OUTPUT true
340    )
341endfunction()
342
343# pico_embed_pt_in_binary(TARGET PTFILE)
344# Create the specified partition table from JSON, and embed it in the
345# block loop. This sets PICOTOOL_EMBED_PT to PTFILE.
346function(pico_embed_pt_in_binary TARGET PTFILE)
347    picotool_check_configurable(${TARGET})
348    set_target_properties(${TARGET} PROPERTIES
349        PICOTOOL_EMBED_PT ${PTFILE}
350    )
351endfunction()
352
353# pico_encrypt_binary(TARGET AESFILE [SIGFILE])
354# Encrypt the target binary with the given AES key (should be a binary
355# file containing 32 bytes of a random key), and sign the encrypted binary.
356# This sets PICOTOOL_AESFILE to AESFILE, and PICOTOOL_ENC_SIGFILE to SIGFILE
357# if present, else PICOTOOL_SIGFILE.
358function(pico_encrypt_binary TARGET AESFILE)
359    picotool_check_configurable(${TARGET})
360    set_target_properties(${TARGET} PROPERTIES
361        PICOTOOL_AESFILE ${AESFILE}
362    )
363    if (ARGC EQUAL 3)
364        set_target_properties(${TARGET} PROPERTIES
365            PICOTOOL_ENC_SIGFILE ${ARGV2}
366        )
367    else()
368        get_target_property(enc_sig_file ${TARGET} PICOTOOL_ENC_SIGFILE)
369        if (NOT enc_sig_file)
370            get_target_property(sig_file ${TARGET} PICOTOOL_SIGFILE)
371            if (NOT sig_file)
372                message(FATAL_ERROR "Signature file not set for ${TARGET}")
373            else()
374                set_target_properties(${TARGET} PROPERTIES
375                    PICOTOOL_ENC_SIGFILE ${sig_file}
376                )
377            endif()
378        endif()
379    endif()
380endfunction()
381
382# pico_add_uf2_output(TARGET)
383# Add a UF2 output using picotool - must be called after
384# all required properties have been set
385function(pico_add_uf2_output TARGET)
386    pico_init_picotool()
387    get_target_property(${TARGET}_archive_directory ${TARGET} ARCHIVE_OUTPUT_DIRECTORY)
388    if (${TARGET}_archive_directory)
389        get_filename_component(output_path "${${TARGET}_archive_directory}"
390                REALPATH BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}")
391        file(MAKE_DIRECTORY "${output_path}")
392        set(output_path "${output_path}/")
393    else()
394        set(output_path "")
395    endif()
396
397    get_target_property(${TARGET}_uf2_package_addr ${TARGET} PICOTOOL_UF2_PACKAGE_ADDR)
398    if (${TARGET}_uf2_package_addr)
399        set(uf2_package_args "-o;${${TARGET}_uf2_package_addr}")
400    endif()
401
402    get_target_property(extra_uf2_args ${TARGET} PICOTOOL_EXTRA_UF2_ARGS)
403    if (PICO_RP2350_A2_SUPPORTED)
404        if (NOT extra_uf2_args)
405            set(extra_uf2_args "--abs-block")
406        elseif(NOT "--abs-block" IN_LIST extra_uf2_args)
407            list(APPEND extra_uf2_args "--abs-block")
408        endif()
409    else()
410        if (NOT extra_uf2_args)
411            set(extra_uf2_args "")
412        endif()
413    endif()
414
415    if (picotool_FOUND)
416        get_target_property(picotool_family ${TARGET} PICOTOOL_UF2_FAMILY)
417        if (NOT picotool_family)
418            if (PICOTOOL_DEFAULT_FAMILY)
419                set(picotool_family ${PICOTOOL_DEFAULT_FAMILY})
420            else()
421                set(picotool_family ${PICO_PLATFORM})
422            endif()
423        endif()
424        add_custom_command(TARGET ${TARGET} POST_BUILD
425            COMMAND picotool
426            ARGS uf2 convert
427                --quiet
428                ${uf2_package_args}
429                $<TARGET_FILE:${TARGET}>
430                ${output_path}$<IF:$<BOOL:$<TARGET_PROPERTY:${TARGET},OUTPUT_NAME>>,$<TARGET_PROPERTY:${TARGET},OUTPUT_NAME>,$<TARGET_PROPERTY:${TARGET},NAME>>.uf2
431                --family ${picotool_family}
432                ${extra_uf2_args}
433            COMMAND_EXPAND_LISTS
434            VERBATIM)
435    endif()
436endfunction()
437
438# Run picotool post-processing on the binary - must be called after
439# all required properties have been set
440function(picotool_postprocess_binary TARGET)
441    set_target_properties(${TARGET} PROPERTIES
442        PICOTOOL_PROCESSING_CONFIGURED true
443    )
444    # Read target properties
445    get_target_property(picotool_sign_output ${TARGET} PICOTOOL_SIGN_OUTPUT)
446    if (picotool_sign_output)
447        list(APPEND picotool_args "--sign")
448        get_target_property(picotool_sigfile ${TARGET} PICOTOOL_SIGFILE)
449        pico_add_link_depend(${TARGET} ${picotool_sigfile})
450    endif()
451
452    get_target_property(picotool_hash_output ${TARGET} PICOTOOL_HASH_OUTPUT)
453    if (picotool_hash_output)
454        list(APPEND picotool_args "--hash")
455    endif()
456
457    get_target_property(otp_file ${TARGET} PICOTOOL_OTP_FILE)
458    if (NOT otp_file)
459        set(otp_file "")
460    endif()
461    get_target_property(uf2_package_addr ${TARGET} PICOTOOL_UF2_PACKAGE_ADDR)
462
463    # Embed PT properties
464    get_target_property(picotool_embed_pt ${TARGET} PICOTOOL_EMBED_PT)
465    if (picotool_embed_pt)
466        pico_add_link_depend(${TARGET} ${picotool_embed_pt})
467    endif()
468
469    # Encryption properties
470    get_target_property(picotool_aesfile ${TARGET} PICOTOOL_AESFILE)
471    if (picotool_aesfile)
472        pico_add_link_depend(${TARGET} ${picotool_aesfile})
473    endif()
474    get_target_property(picotool_enc_sigfile ${TARGET} PICOTOOL_ENC_SIGFILE)
475    if (picotool_enc_sigfile)
476        pico_add_link_depend(${TARGET} ${picotool_enc_sigfile})
477    endif()
478
479    # Extra args
480    get_target_property(extra_process_args ${TARGET} PICOTOOL_EXTRA_PROCESS_ARGS)
481    if (extra_process_args)
482        list(APPEND picotool_args ${extra_process_args})
483    endif()
484
485    pico_init_picotool()
486    if (picotool_FOUND)
487        # Embed PT
488        if (picotool_embed_pt)
489            add_custom_command(TARGET ${TARGET} POST_BUILD
490                DEPENDS ${picotool_embed_pt}
491                COMMAND picotool partition create --quiet ${picotool_embed_pt} $<TARGET_FILE:${TARGET}> $<TARGET_FILE:${TARGET}>
492                VERBATIM)
493        endif()
494        # Signing/hashing/load maps for packaging
495        if (
496            picotool_sign_output OR
497            picotool_hash_output OR
498            uf2_package_addr OR
499            extra_process_args
500        )
501        add_custom_command(TARGET ${TARGET} POST_BUILD
502            DEPENDS ${picotool_sigfile}
503            COMMAND picotool
504            ARGS seal
505                --quiet
506                $<TARGET_FILE:${TARGET}> $<TARGET_FILE:${TARGET}>
507                ${picotool_sigfile} ${otp_file}
508                ${picotool_args}
509            COMMAND_EXPAND_LISTS
510            VERBATIM)
511        endif()
512        # Encryption
513        if (picotool_aesfile)
514            add_custom_command(TARGET ${TARGET} POST_BUILD
515                DEPENDS ${picotool_enc_sigfile} ${picotool_aesfile}
516                COMMAND picotool encrypt --quiet --hash --sign $<TARGET_FILE:${TARGET}> $<TARGET_FILE:${TARGET}> ${picotool_aesfile} ${picotool_enc_sigfile}
517                VERBATIM)
518            if (ARGC EQUAL 2)
519                set(${ARGV1} TRUE PARENT_SCOPE)
520            endif()
521        endif()
522    endif()
523endfunction()
524