Tests: Add tests for install(PACKAGE_INFO)

Add several test cases to verify that install(PACKAGE_INFO) is working
as expected. These cover validating the output for several scenarios,
improper use of the command, effects of command arguments, and a handful
of improper uses.

Tests that should still be added include one covering DESTINATION (both
the default and user-specified) and the CPS location and link_location
attributes. These have been skipped for now because the former requires
actually installing a test project, and the latter involves validating
attributes whose values are platform-dependent. (In particular, I don't
think link_location will appear on not-Windows.) Additionally, there is
no coverage of (other) common install-command arguments such as
PERMISSIONS, COMPONENT, etc.; however, because the logic implementing
these is shared, the tests covering them for other sub-commands is
probably sufficient.

Note that, because the files are generated in a location that includes a
hash of the install destination, and because the default destination is
platform dependent, the tests need to specify a fixed DESTINATION so
that the location of generated files (which we need to inspect and
validate) is predictable.
This commit is contained in:
Matthew Woehlke
2024-08-01 14:59:47 -04:00
parent 3d52d70b84
commit 1a846c8849
57 changed files with 394 additions and 0 deletions

View File

@@ -1175,6 +1175,7 @@ add_RunCMake_test(AutoExportDll
)
add_RunCMake_test(AndroidMK)
add_RunCMake_test(PackageInfo)
if(CMake_TEST_ANDROID_NDK OR CMake_TEST_ANDROID_STANDALONE_TOOLCHAIN)
if(NOT "${CMAKE_GENERATOR}" MATCHES "Make|Ninja|Visual Studio 1[456]")

View File

@@ -0,0 +1,16 @@
include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
set(out_dir "${RunCMake_BINARY_DIR}/Appendix-build/CMakeFiles/Export/510c5684a4a8a792eadfb55bc9744983")
file(READ "${out_dir}/foo.cps" content)
expect_value("${content}" "foo" "name")
expect_value("${content}" "interface" "components" "mammal" "type")
expect_value("${content}" "1.0" "version")
file(READ "${out_dir}/foo-dog.cps" content)
expect_value("${content}" "foo" "name")
expect_value("${content}" "interface" "components" "canine" "type")
expect_missing("${content}" "version")
expect_array("${content}" 1 "components" "canine" "requires")
expect_value("${content}" ":mammal" "components" "canine" "requires" 0)

View File

@@ -0,0 +1,9 @@
add_library(mammal INTERFACE)
add_library(canine INTERFACE)
target_link_libraries(canine INTERFACE mammal)
install(TARGETS mammal EXPORT mammal DESTINATION .)
install(TARGETS canine EXPORT canine DESTINATION .)
install(PACKAGE_INFO foo DESTINATION cps EXPORT mammal VERSION 1.0)
install(PACKAGE_INFO foo DESTINATION cps EXPORT canine APPENDIX dog)

View File

@@ -0,0 +1,34 @@
macro(_expect entity op actual expected)
if(NOT "${actual}" ${op} "${expected}")
list(JOIN ARGN "." name)
set(RunCMake_TEST_FAILED
"Attribute '${name}' ${entity} '${actual}' does not match expected ${entity} '${expected}'" PARENT_SCOPE)
return()
endif()
endmacro()
function(expect_value content expected_value)
string(JSON actual_value GET "${content}" ${ARGN})
_expect("value" STREQUAL "${actual_value}" "${expected_value}" ${ARGN})
endfunction()
function(expect_array content expected_length)
string(JSON actual_type TYPE "${content}" ${ARGN})
_expect("type" STREQUAL "${actual_type}" "ARRAY" ${ARGN})
string(JSON actual_length LENGTH "${content}" ${ARGN})
_expect("length" EQUAL "${actual_length}" "${expected_length}" ${ARGN})
endfunction()
function(expect_null content)
string(JSON actual_type TYPE "${content}" ${ARGN})
_expect("type" STREQUAL "${actual_type}" "NULL" ${ARGN})
endfunction()
function(expect_missing content)
string(JSON value ERROR_VARIABLE error GET "${content}" ${ARGN})
if(NOT value MATCHES "^(.*-)?NOTFOUND$")
set(RunCMake_TEST_FAILED
"Attribute '${ARGN}' is unexpectedly present" PARENT_SCOPE)
endif()
endfunction()

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,2 @@
CMake Error at BadArgs1.cmake:3 \(install\):
install COMPAT_VERSION requires VERSION.

View File

@@ -0,0 +1,3 @@
add_library(foo INTERFACE)
install(TARGETS foo EXPORT foo DESTINATION .)
install(PACKAGE_INFO test EXPORT foo COMPAT_VERSION 1.0)

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,2 @@
CMake Error at BadArgs2.cmake:3 \(install\):
install VERSION_SCHEMA requires VERSION.

View File

@@ -0,0 +1,3 @@
add_library(foo INTERFACE)
install(TARGETS foo EXPORT foo DESTINATION .)
install(PACKAGE_INFO test EXPORT foo VERSION_SCHEMA simple)

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,2 @@
CMake Error at BadArgs3.cmake:3 \(install\):
install APPENDIX and VERSION are mutually exclusive.

View File

@@ -0,0 +1,3 @@
add_library(foo INTERFACE)
install(TARGETS foo EXPORT foo DESTINATION .)
install(PACKAGE_INFO test EXPORT foo APPENDIX test VERSION 1.0)

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,2 @@
CMake Error at BadArgs4.cmake:3 \(install\):
install APPENDIX and DEFAULT_TARGETS are mutually exclusive.

View File

@@ -0,0 +1,3 @@
add_library(foo INTERFACE)
install(TARGETS foo EXPORT foo DESTINATION .)
install(PACKAGE_INFO test EXPORT foo APPENDIX test DEFAULT_TARGETS foo)

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,2 @@
CMake Error at BadArgs5.cmake:3 \(install\):
install APPENDIX and DEFAULT_CONFIGURATIONS are mutually exclusive.

View File

@@ -0,0 +1,3 @@
add_library(foo INTERFACE)
install(TARGETS foo EXPORT foo DESTINATION .)
install(PACKAGE_INFO test EXPORT foo APPENDIX test DEFAULT_CONFIGURATIONS test)

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,2 @@
CMake Error: Package "test" specifies DEFAULT_TARGETS "dog", which is not a target in the export set "foo".
CMake Error: Package "test" specifies DEFAULT_TARGETS "cat", which is not a target in the export set "foo".

View File

@@ -0,0 +1,5 @@
add_library(foo INTERFACE)
add_library(dog INTERFACE)
install(TARGETS foo EXPORT foo DESTINATION .)
install(TARGETS dog EXPORT dog DESTINATION .)
install(PACKAGE_INFO test EXPORT foo DEFAULT_TARGETS dog cat)

View File

@@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 3.30)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,2 @@
CMake Error at ExperimentalGate.cmake:5 \(install\):
install does not recognize sub-command PACKAGE_INFO

View File

@@ -0,0 +1,5 @@
unset(CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO)
add_library(foo INTERFACE)
install(TARGETS foo EXPORT foo DESTINATION .)
install(PACKAGE_INFO foo DESTINATION cps EXPORT foo)

View File

@@ -0,0 +1,7 @@
CMake Warning \(dev\) at ExperimentalWarning.cmake:8 \(install\):
CMake's support for exporting package information in the Common Package
Specification format. It is meant only for experimentation and feedback to
CMake developers.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.

View File

@@ -0,0 +1,8 @@
set(
CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO
"b80be207-778e-46ba-8080-b23bba22639e"
)
add_library(foo INTERFACE)
install(TARGETS foo EXPORT foo DESTINATION .)
install(PACKAGE_INFO foo DESTINATION cps EXPORT foo)

View File

@@ -0,0 +1,24 @@
include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
set(out_dir "${RunCMake_BINARY_DIR}/InterfaceProperties-build/CMakeFiles/Export/510c5684a4a8a792eadfb55bc9744983")
file(READ "${out_dir}/foo.cps" content)
expect_value("${content}" "foo" "name")
string(JSON component GET "${content}" "components" "foo")
expect_value("${component}" "interface" "type")
expect_array("${component}" 1 "includes")
expect_value("${component}" "@prefix@/include/foo" "includes" 0)
expect_array("${component}" 1 "compile_features")
expect_value("${component}" "c++23" "compile_features" 0)
expect_array("${component}" 1 "compile_flags")
expect_value("${component}" "-ffast-math" "compile_flags" 0)
expect_null("${component}" "compile_definitions" "*" "FOO")
expect_value("${component}" "BAR" "compile_definitions" "*" "BAR")
expect_array("${component}" 1 "link_directories")
expect_value("${component}" "/opt/foo/lib" "link_directories" 0)
expect_array("${component}" 1 "link_flags")
expect_value("${component}" "--needed" "link_flags" 0)
expect_array("${component}" 1 "link_libraries")
expect_value("${component}" "/usr/lib/libm.so" "link_libraries" 0)

View File

@@ -0,0 +1,15 @@
add_library(foo INTERFACE)
target_compile_features(foo INTERFACE cxx_std_23)
target_compile_options(foo INTERFACE -ffast-math)
target_compile_definitions(foo INTERFACE -DFOO -DBAR=BAR)
target_include_directories(
foo INTERFACE
$<INSTALL_INTERFACE:include/foo>
)
target_link_directories(foo INTERFACE /opt/foo/lib)
target_link_options(foo INTERFACE --needed)
target_link_libraries(foo INTERFACE /usr/lib/libm.so)
install(TARGETS foo EXPORT foo DESTINATION .)
install(PACKAGE_INFO foo DESTINATION cps EXPORT foo)

View File

@@ -0,0 +1,9 @@
include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
set(out_dir "${RunCMake_BINARY_DIR}/LowerCaseFile-build/CMakeFiles/Export/510c5684a4a8a792eadfb55bc9744983")
file(READ "${out_dir}/lowercase.cps" content)
expect_value("${content}" "LowerCase" "name")
file(READ "${out_dir}/PreserveCase.cps" content)
expect_value("${content}" "PreserveCase" "name")

View File

@@ -0,0 +1,4 @@
add_library(foo INTERFACE)
install(TARGETS foo EXPORT foo DESTINATION .)
install(PACKAGE_INFO LowerCase DESTINATION cps EXPORT foo LOWER_CASE_FILE)
install(PACKAGE_INFO PreserveCase DESTINATION cps EXPORT foo)

View File

@@ -0,0 +1,16 @@
include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
set(out_dir "${RunCMake_BINARY_DIR}/Metadata-build/CMakeFiles/Export/510c5684a4a8a792eadfb55bc9744983")
file(READ "${out_dir}/foo.cps" content)
expect_value("${content}" "foo" "name")
expect_value("${content}" "1.2.3" "version")
expect_value("${content}" "1.2.0" "compat_version")
expect_value("${content}" "simple" "version_schema")
expect_array("${content}" 1 "default_components")
expect_value("${content}" "foo" "default_components" 0)
expect_array("${content}" 2 "configurations")
expect_value("${content}" "release" "configurations" 0)
expect_value("${content}" "debug" "configurations" 1)

View File

@@ -0,0 +1,12 @@
add_library(foo INTERFACE)
install(TARGETS foo EXPORT foo DESTINATION .)
install(
PACKAGE_INFO foo
DESTINATION cps
EXPORT foo
VERSION 1.2.3
VERSION_SCHEMA simple
COMPAT_VERSION 1.2.0
DEFAULT_TARGETS foo
DEFAULT_CONFIGURATIONS release debug
)

View File

@@ -0,0 +1,18 @@
include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
set(out_dir "${RunCMake_BINARY_DIR}/Minimal-build/CMakeFiles/Export/510c5684a4a8a792eadfb55bc9744983")
file(READ "${out_dir}/foo.cps" content)
expect_value("${content}" "foo" "name")
expect_value("${content}" "interface" "components" "foo" "type")
expect_missing("${content}" "version")
expect_missing("${content}" "configurations")
expect_missing("${content}" "default_targets")
expect_missing("${content}" "components" "foo" "compile_definitions")
expect_missing("${content}" "components" "foo" "compile_features")
expect_missing("${content}" "components" "foo" "compile_flags")
expect_missing("${content}" "components" "foo" "link_directories")
expect_missing("${content}" "components" "foo" "link_features")
expect_missing("${content}" "components" "foo" "link_flags")
expect_missing("${content}" "components" "foo" "link_libraries")
expect_missing("${content}" "components" "foo" "requires")

View File

@@ -0,0 +1,3 @@
add_library(foo INTERFACE)
install(TARGETS foo EXPORT foo DESTINATION .)
install(PACKAGE_INFO foo DESTINATION cps EXPORT foo)

View File

@@ -0,0 +1 @@
CMake Error: install\(PACKAGE_INFO "dog" \.\.\.\) includes target "canine" which requires target "mammal" that is not in any export set.

View File

@@ -0,0 +1,6 @@
add_library(mammal INTERFACE)
add_library(canine INTERFACE)
target_link_libraries(canine INTERFACE mammal)
install(TARGETS canine EXPORT dog DESTINATION .)
install(PACKAGE_INFO dog EXPORT dog)

View File

@@ -0,0 +1,7 @@
CMake Error in CMakeLists.txt:
Target "test" references target "foo", which does not use the standard
namespace separator. This is not allowed.
.*
CMake Error in CMakeLists.txt:
Target "test" references target "bar_bar", which does not use the standard
namespace separator. This is not allowed.

View File

@@ -0,0 +1,14 @@
add_library(foo INTERFACE)
add_library(bar INTERFACE)
add_library(test INTERFACE)
target_link_libraries(test INTERFACE foo bar)
install(TARGETS foo EXPORT foo DESTINATION .)
install(TARGETS bar EXPORT bar DESTINATION .)
install(EXPORT foo DESTINATION .)
install(EXPORT bar DESTINATION . NAMESPACE bar_)
install(TARGETS test EXPORT test DESTINATION .)
install(PACKAGE_INFO test EXPORT test)

View File

@@ -0,0 +1,3 @@
CMake Error in CMakeLists.txt:
Target "foo" references imported target "bar" which does not come from any
known package.

View File

@@ -0,0 +1,7 @@
add_library(bar INTERFACE IMPORTED)
add_library(foo INTERFACE)
target_link_libraries(foo INTERFACE bar)
install(TARGETS foo EXPORT foo DESTINATION .)
install(PACKAGE_INFO foo EXPORT foo)

View File

@@ -0,0 +1,4 @@
CMake Error in CMakeLists.txt:
Target "foo" references target "wrong::lib", which comes from the "broken"
package, but does not belong to the package's canonical namespace. This is
not allowed.

View File

@@ -0,0 +1,11 @@
find_package(
broken REQUIRED CONFIG
NO_DEFAULT_PATH
PATHS ${CMAKE_CURRENT_LIST_DIR}
)
add_library(foo INTERFACE)
target_link_libraries(foo INTERFACE wrong::lib)
install(TARGETS foo EXPORT foo DESTINATION .)
install(PACKAGE_INFO foo EXPORT foo)

View File

@@ -0,0 +1,20 @@
include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
set(out_dir "${RunCMake_BINARY_DIR}/Requirements-build/CMakeFiles/Export/510c5684a4a8a792eadfb55bc9744983")
file(READ "${out_dir}/foo.cps" content)
expect_value("${content}" "foo" "name")
expect_value("${content}" "interface" "components" "libb" "type")
file(READ "${out_dir}/bar.cps" content)
expect_value("${content}" "bar" "name")
expect_null("${content}" "requires" "foo")
expect_null("${content}" "requires" "test")
expect_value("${content}" "interface" "components" "libc" "type")
expect_value("${content}" "interface" "components" "libd" "type")
string(JSON component GET "${content}" "components" "libd")
expect_array("${component}" 3 "requires")
expect_value("${component}" "test:liba" "requires" 0)
expect_value("${component}" "foo:libb" "requires" 1)
expect_value("${component}" ":libc" "requires" 2)

View File

@@ -0,0 +1,20 @@
find_package(
test REQUIRED CONFIG
NO_DEFAULT_PATH
PATHS ${CMAKE_CURRENT_LIST_DIR}
)
add_library(libb INTERFACE)
add_library(libc INTERFACE)
add_library(libd INTERFACE)
add_library(foo ALIAS libb)
add_library(bar ALIAS libc)
target_link_libraries(libd INTERFACE test::liba foo bar)
install(TARGETS libb EXPORT foo DESTINATION .)
install(PACKAGE_INFO foo DESTINATION cps EXPORT foo)
install(TARGETS libc libd EXPORT bar DESTINATION .)
install(PACKAGE_INFO bar DESTINATION cps EXPORT bar)

View File

@@ -0,0 +1,32 @@
include(RunCMake)
# Test experimental gate
run_cmake(ExperimentalGate)
run_cmake(ExperimentalWarning)
# Enable experimental feature and suppress warnings
set(RunCMake_TEST_OPTIONS
-Wno-dev
"-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO:STRING=b80be207-778e-46ba-8080-b23bba22639e"
)
# Test incorrect usage
run_cmake(BadArgs1)
run_cmake(BadArgs2)
run_cmake(BadArgs3)
run_cmake(BadArgs4)
run_cmake(BadArgs5)
run_cmake(BadDefaultTarget)
run_cmake(ReferencesNonExportedTarget)
run_cmake(ReferencesWronglyExportedTarget)
run_cmake(ReferencesWronglyImportedTarget)
run_cmake(ReferencesWronglyNamespacedTarget)
# Test functionality
run_cmake(Appendix)
run_cmake(InterfaceProperties)
run_cmake(Metadata)
run_cmake(Minimal)
run_cmake(LowerCaseFile)
run_cmake(Requirements)
run_cmake(TargetTypes)

View File

@@ -0,0 +1,11 @@
include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
set(out_dir "${RunCMake_BINARY_DIR}/TargetTypes-build/CMakeFiles/Export/510c5684a4a8a792eadfb55bc9744983")
file(READ "${out_dir}/foo.cps" content)
expect_value("${content}" "foo" "name")
expect_value("${content}" "archive" "components" "foo-static" "type")
expect_value("${content}" "dylib" "components" "foo-shared" "type")
expect_value("${content}" "module" "components" "foo-module" "type")
expect_value("${content}" "interface" "components" "bar" "type")
expect_value("${content}" "executable" "components" "test" "type")

View File

@@ -0,0 +1,20 @@
project(TargetTypes CXX)
add_library(foo-static STATIC foo.cxx)
add_library(foo-shared SHARED foo.cxx)
add_library(foo-module MODULE foo.cxx)
add_library(bar INTERFACE)
add_executable(test test.cxx)
install(
TARGETS
foo-static
foo-shared
foo-module
bar
test
EXPORT foo
DESTINATION .
)
install(PACKAGE_INFO foo DESTINATION cps EXPORT foo)

View File

@@ -0,0 +1 @@
add_library(wrong::lib INTERFACE IMPORTED)

View File

@@ -0,0 +1,3 @@
void foo()
{
}

View File

@@ -0,0 +1 @@
add_library(test::liba INTERFACE IMPORTED)

View File

@@ -0,0 +1,4 @@
int main()
{
return 0;
}