diff --git a/scripts/cmake/vcpkg_find_acquire_program(GN).cmake b/scripts/cmake/vcpkg_find_acquire_program(GN).cmake index eeb025a050cf62..bcf0f9df727eb6 100644 --- a/scripts/cmake/vcpkg_find_acquire_program(GN).cmake +++ b/scripts/cmake/vcpkg_find_acquire_program(GN).cmake @@ -4,7 +4,7 @@ if(EXISTS "${CURRENT_HOST_INSTALLED_DIR}/share/gn/version.txt") file(READ "${CURRENT_HOST_INSTALLED_DIR}/share/gn/version.txt" program_version) set(paths_to_search "${CURRENT_HOST_INSTALLED_DIR}/tools/gn") else() # Old behavior - message("Consider adding vcpkg-tool-gn as a host dependency of this port or create an issue at https://github.com/microsoft/vcpkg/issues") + message(STATUS "Consider adding vcpkg-tool-gn as a host dependency of this port or create an issue at https://github.com/microsoft/vcpkg/issues") set(cipd_download_gn "https://chrome-infra-packages.appspot.com/dl/gn/gn") if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") execute_process(COMMAND uname -m OUTPUT_VARIABLE HOST_ARCH OUTPUT_STRIP_TRAILING_WHITESPACE) diff --git a/scripts/cmake/vcpkg_find_acquire_program.cmake b/scripts/cmake/vcpkg_find_acquire_program.cmake index 4dc2c0e169f2ca..442814ee901230 100644 --- a/scripts/cmake/vcpkg_find_acquire_program.cmake +++ b/scripts/cmake/vcpkg_find_acquire_program.cmake @@ -49,6 +49,7 @@ function(z_vcpkg_find_acquire_program_find_external program) unset(SCRIPT_${arg_PROGRAM_NAME} CACHE) endif() + set(${program} "$CACHE{${program}}") if("${version_command}" STREQUAL "") set(version_is_good ON) # can't check for the version being good, so assume it is elseif(${program}) # only do a version check if ${program} has a value @@ -60,8 +61,10 @@ function(z_vcpkg_find_acquire_program_find_external program) ) endif() - if(NOT version_is_good) - unset("${program}" PARENT_SCOPE) + if(version_is_good) + set(${program} "$CACHE{${program}}" PARENT_SCOPE) + else() + set("${program}" "${program}-NOTFOUND" PARENT_SCOPE) unset("${program}" CACHE) endif() endfunction() @@ -92,6 +95,7 @@ function(z_vcpkg_find_acquire_program_find_internal program) endif() unset(SCRIPT_${program} CACHE) endif() + set(${program} "$CACHE{${program}}" PARENT_SCOPE) endfunction() function(vcpkg_find_acquire_program program) @@ -140,6 +144,15 @@ function(vcpkg_find_acquire_program program) set(search_names "${program_name}") endif() + # Force nested `find_program` to either use the cached variable or + # to actually search, regardless of a parent scope variable. + # Called functions must change the variable in this scope. + if("$CACHE{${program}}" STREQUAL "") + set(${program} "NOTFOUND") + else() + set(${program} "$CACHE{${program}}") + endif() + z_vcpkg_find_acquire_program_find_internal("${program}" INTERPRETER "${interpreter}" PATHS ${paths_to_search} diff --git a/scripts/test_ports/vcpkg-find-acquire-program/portfile.cmake b/scripts/test_ports/vcpkg-find-acquire-program/portfile.cmake index d31679c9c49a86..a66d3b0eb721b6 100644 --- a/scripts/test_ports/vcpkg-find-acquire-program/portfile.cmake +++ b/scripts/test_ports/vcpkg-find-acquire-program/portfile.cmake @@ -70,3 +70,87 @@ if(missing) list(JOIN missing "\n " missing) message(FATAL_ERROR "The following programs do not exist:\n ${missing}") endif() + +# The postcondition of `vcpkg_find_acquire_program` is that there is a regular +# variable of the requested name with a non-false value in the calling scope. +# +# Normally, it searches for the requested program and sets a regular variable +# in the calling scope. However, it does nothing if a variable with that name +# is already set to a value which CMake regards as true. +# In contrast, `find_program` sets a cache variable when the search is run. +# It does nothing if a variable with the given name is defined with a value +# of "NOTFOUND" or ending with "-NOTFOUND". +# The small behavioral differences needs extra attention. + +include("${CURRENT_HOST_INSTALLED_DIR}/share/unit-test-cmake/test-macros.cmake") + +set(expected_gn "$CACHE{GN}") + +# Cache variable is set to trueish value: Early return of vfap with current value. +unset(GN) +set(GN "THIS IS CACHED GN" CACHE INTERNAL "") +unit_test_check_variable_equal([[_vcpkg_find_acquire_program(GN)]] GN "THIS IS CACHED GN") + +# Cache variable is NOTFOUNDish or empty value: These values evaluate to false, +# so a search via vfap should run and yield the expected path. +unset(GN) +set(GN "NOTFOUND" CACHE INTERNAL "") +unit_test_check_variable_equal([[_vcpkg_find_acquire_program(GN)]] GN "${expected_gn}") + +unset(GN) +set(GN "GN-NOTFOUND" CACHE INTERNAL "") +unit_test_check_variable_equal([[_vcpkg_find_acquire_program(GN)]] GN "${expected_gn}") + +unset(GN) +set(GN "" CACHE INTERNAL "") +unit_test_check_variable_equal([[_vcpkg_find_acquire_program(GN)]] GN "${expected_gn}") + + +# Regular variable is set to trueish value: Early return of vfap with current value. +unset(GN CACHE) +set(GN "THIS IS REGULAR GN") +unit_test_check_variable_equal([[_vcpkg_find_acquire_program(GN)]] GN "THIS IS REGULAR GN") + +# Regular variable is NOTFOUNDish or empty value: These values evaluate to false, +# so a search via vfap should run and yield the expected path. +unset(GN CACHE) +set(GN "NOTFOUND") +unit_test_check_variable_equal([[_vcpkg_find_acquire_program(GN)]] GN "${expected_gn}") + +unset(GN CACHE) +set(GN "GN-NOTFOUND") +unit_test_check_variable_equal([[_vcpkg_find_acquire_program(GN)]] GN "${expected_gn}") + +unset(GN CACHE) +set(GN "") +unit_test_check_variable_equal([[_vcpkg_find_acquire_program(GN)]] GN "${expected_gn}") + +# Regular variable is NOTFOUNDish or empty value, and it hides a cache variable: +# The cache variable takes effect. +set(GN "THIS IS CACHED GN" CACHE INTERNAL "") +set(GN "NOTFOUND") +unit_test_check_variable_equal([[_vcpkg_find_acquire_program(GN)]] GN "THIS IS CACHED GN") + +set(GN "THIS IS CACHED GN" CACHE INTERNAL "") +set(GN "GN-NOTFOUND") +unit_test_check_variable_equal([[_vcpkg_find_acquire_program(GN)]] GN "THIS IS CACHED GN") + +set(GN "THIS IS CACHED GN" CACHE INTERNAL "") +set(GN "") +unit_test_check_variable_equal([[_vcpkg_find_acquire_program(GN)]] GN "THIS IS CACHED GN") + +set(GN "NOTFOUND" CACHE INTERNAL "") +set(GN "NOTFOUND") +unit_test_check_variable_equal([[_vcpkg_find_acquire_program(GN)]] GN "${expected_gn}") + +set(GN "CACHED-NOTFOUND" CACHE INTERNAL "") +set(GN "NOTFOUND") +unit_test_check_variable_equal([[_vcpkg_find_acquire_program(GN)]] GN "${expected_gn}") + +set(GN "" CACHE INTERNAL "") +set(GN "NOTFOUND") +unit_test_check_variable_equal([[_vcpkg_find_acquire_program(GN)]] GN "${expected_gn}") + +# If vfap cannot find or acquire the requested program, it raises a fatal error. +unit_test_ensure_fatal_error([[_vcpkg_find_acquire_program(REALLY_NO_SUCH_PROGAM)]]) + diff --git a/scripts/test_ports/vcpkg-find-acquire-program/vcpkg.json b/scripts/test_ports/vcpkg-find-acquire-program/vcpkg.json index 0b622ebbbf5470..600b305bee90c9 100644 --- a/scripts/test_ports/vcpkg-find-acquire-program/vcpkg.json +++ b/scripts/test_ports/vcpkg-find-acquire-program/vcpkg.json @@ -1,7 +1,9 @@ { "name": "vcpkg-find-acquire-program", - "version-string": "0", - "port-version": 2, + "version-string": "ci", "description": "Test port to exercise vcpkg_find_acquire_program", - "supports": "native" + "supports": "native", + "dependencies": [ + "unit-test-cmake" + ] }