# prevent older policies from interfering with this script cmake_policy(PUSH) cmake_policy(VERSION ${CMAKE_VERSION}) message(STATUS "=============================================================================") message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)") message(STATUS "") if(NOT CPackComponentsForAll_BINARY_DIR) message(FATAL_ERROR "CPackComponentsForAll_BINARY_DIR not set") endif() if(NOT CPackGen) message(FATAL_ERROR "CPackGen not set") endif() message("CMAKE_CPACK_COMMAND = ${CMAKE_CPACK_COMMAND}") if(NOT CMAKE_CPACK_COMMAND) message(FATAL_ERROR "CMAKE_CPACK_COMMAND not set") endif() if(NOT CPackComponentWay) message(FATAL_ERROR "CPackComponentWay not set") endif() set(expected_file_mask "") # The usual default behavior is to expect a single file # Then some specific generators (Archive, RPM, ...) # May produce several numbers of files depending on # CPACK_COMPONENT_xxx values set(expected_count 1) set(config_type $ENV{CMAKE_CONFIG_TYPE}) set(config_args ) if(config_type) set(config_args -C ${config_type}) endif() set(config_verbose ) if(CPackGen MATCHES "ZIP") set(expected_file_mask "${CPackComponentsForAll_BINARY_DIR}/MyLib-*.zip") if(${CPackComponentWay} STREQUAL "default") set(expected_count 1) elseif(${CPackComponentWay} STREQUAL "OnePackPerGroup") set(expected_count 3) elseif(${CPackComponentWay} STREQUAL "IgnoreGroup") set(expected_count 4) elseif(${CPackComponentWay} STREQUAL "AllInOne") set(expected_count 1) endif() elseif(CPackGen MATCHES "RPM") set(config_verbose -D "CPACK_RPM_PACKAGE_DEBUG=1") set(expected_file_mask "${CPackComponentsForAll_BINARY_DIR}/MyLib-*.rpm") if(${CPackComponentWay} STREQUAL "default") set(expected_count 1) elseif(${CPackComponentWay} STREQUAL "OnePackPerGroup") set(expected_count 3) elseif(${CPackComponentWay} STREQUAL "IgnoreGroup") set(expected_count 4) elseif(${CPackComponentWay} STREQUAL "AllInOne") set(expected_count 1) endif() elseif(CPackGen MATCHES "DEB") set(expected_file_mask "${CPackComponentsForAll_BINARY_DIR}/mylib*_1.0.2_*.deb") if(${CPackComponentWay} STREQUAL "default") set(expected_count 1) elseif(${CPackComponentWay} STREQUAL "OnePackPerGroup") set(expected_count 3) elseif(${CPackComponentWay} STREQUAL "IgnoreGroup") set(expected_count 4) elseif(${CPackComponentWay} STREQUAL "AllInOne") set(expected_count 1) endif() elseif(CPackGen MATCHES "NuGet") set(config_verbose -D "CPACK_NUGET_PACKAGE_DEBUG=1") set(expected_file_mask "${CPackComponentsForAll_BINARY_DIR}/MyLib*1.0.2.nupkg") if(${CPackComponentWay} STREQUAL "default") set(expected_count 1) elseif(${CPackComponentWay} STREQUAL "OnePackPerGroup") set(expected_count 3) elseif(${CPackComponentWay} STREQUAL "IgnoreGroup") set(expected_count 4) elseif(${CPackComponentWay} STREQUAL "AllInOne") set(expected_count 1) endif() endif() if(CPackGen MATCHES "DragNDrop") set(expected_file_mask "${CPackComponentsForAll_BINARY_DIR}/MyLib-*.dmg") if(${CPackComponentWay} STREQUAL "default") set(expected_count 1) set(expect_dmg_sla 1) elseif(${CPackComponentWay} STREQUAL "OnePackPerGroup") set(expected_count 3) elseif(${CPackComponentWay} STREQUAL "IgnoreGroup") set(expected_count 4) elseif(${CPackComponentWay} STREQUAL "AllInOne") set(expected_count 1) set(expect_dmg_sla 1) endif() endif() # clean-up previously CPack generated files if(expected_file_mask) file(GLOB expected_file "${expected_file_mask}") if(expected_file) file(REMOVE ${expected_file}) endif() endif() message("config_args = ${config_args}") message("config_verbose = ${config_verbose}") execute_process(COMMAND ${CMAKE_CPACK_COMMAND} ${config_verbose} -G ${CPackGen} ${config_args} RESULT_VARIABLE CPack_result OUTPUT_VARIABLE CPack_output ERROR_VARIABLE CPack_error WORKING_DIRECTORY ${CPackComponentsForAll_BINARY_DIR}) string(REPLACE "\n" "\n cpack-out> " cpack_out "\n${CPack_output}") string(REPLACE "\n" "\n cpack-err> " cpack_err "\n${CPack_error}") string(REPLACE "\n" "\n cpack-res> " cpack_res "\n${CPack_result}") string(CONCAT output_error_message "CPack output:${cpack_out}\n" "CPack error:${cpack_err}\n" "CPack result:${cpack_res}\n" ) if(CPack_result) message(FATAL_ERROR "error: CPack execution went wrong!,\n${output_error_message}") else () message(STATUS "CPack_output=${CPack_output}") endif() # Now verify if the number of expected file is OK # - using expected_file_mask and # - expected_count if(expected_file_mask) file(GLOB expected_file "${expected_file_mask}") message(STATUS "expected_count='${expected_count}'") message(STATUS "expected_file='${expected_file}'") message(STATUS "expected_file_mask='${expected_file_mask}'") if(NOT expected_file) message(FATAL_ERROR "error: expected_file does not exist: CPackComponentsForAll test fails.\n${output_error_message}") endif() list(LENGTH expected_file actual_count) message(STATUS "actual_count='${actual_count}'") if(NOT actual_count EQUAL expected_count) message(FATAL_ERROR "error: expected_count=${expected_count} does not match actual_count=${actual_count}: CPackComponents test fails.\n${output_error_message}") endif() if(expect_dmg_sla) execute_process(COMMAND hdiutil udifderez -xml "${expected_file}" OUTPUT_VARIABLE out ERROR_VARIABLE err RESULT_VARIABLE res) if(NOT res EQUAL 0) string(REPLACE "\n" "\n " err " ${err}") message(FATAL_ERROR "error: running 'hdiutil udifderez -xml' on\n ${expected_file}\nfailed with:\n${err}") endif() foreach(key "LPic" "STR#" "TEXT") if(NOT out MATCHES "${key}") string(REPLACE "\n" "\n " out " ${out}") message(FATAL_ERROR "error: running 'hdiutil udifderez -xml' on\n ${expected_file}\ndid not show '${key}' key:\n${out}") endif() endforeach() foreach(line # LPic first and last base64 lines "\tAAIAEQADAAEAAAAAAAIAAAAIAAMAAAABAAQAAAAEAAUAAAAOAAYA\n" "\tAA0AAABbAAQAAAAzAA8AAQAMABAAAAALAA4AAA==\n" # STR# first and last base64 lines "\tAAkHRW5nbGlzaAVBZ3JlZQhEaXNhZ3JlZQVQcmludAdTYXZlLi4u\n" "\tdGVkIGEgcHJpbnRlci4=\n" # TEXT first and last base64 lines "\tTElDRU5TRQ0tLS0tLS0tDVRoaXMgaXMgYW4gaW5zdGFsbGVyIGNy\n" "\tTm8gbGljZW5zZSBwcm92aWRlZC4NDQ==\n" ) if(NOT out MATCHES "${line}") string(REPLACE "\n" "\n " out " ${out}") message(FATAL_ERROR "error: running 'hdiutil udifderez -xml' on\n ${expected_file}\ndid not show '${line}':\n${out}") endif() endforeach() endif() endif() # Validate content if(CPackGen MATCHES "RPM") find_program(RPM_EXECUTABLE rpm) if(NOT RPM_EXECUTABLE) message(FATAL_ERROR "error: missing rpm executable required by the test") endif() set(CPACK_RPM_PACKAGE_SUMMARY "default summary") set(CPACK_RPM_HEADERS_PACKAGE_SUMMARY "headers summary") set(CPACK_RPM_HEADERS_PACKAGE_DESCRIPTION "headers description") set(CPACK_COMPONENT_APPLICATIONS_DESCRIPTION "An extremely useful application that makes use of MyLib") set(CPACK_COMPONENT_LIBRARIES_DESCRIPTION "Static libraries used to build programs with MyLib") set(LIB_SUFFIX "6?4?") # test package info if(${CPackComponentWay} STREQUAL "IgnoreGroup") # set gnu install prefixes to what they are set during rpm creation # CMAKE_SIZEOF_VOID_P is not set here but lib is prefix of lib64 so # relocation path test won't fail on OSes with lib64 library location include(GNUInstallDirs) set(CPACK_PACKAGING_INSTALL_PREFIX "/usr/foo/bar") foreach(check_file ${expected_file}) string(REGEX MATCH ".*libraries.*" check_file_libraries_match ${check_file}) string(REGEX MATCH ".*headers.*" check_file_headers_match ${check_file}) string(REGEX MATCH ".*applications.*" check_file_applications_match ${check_file}) string(REGEX MATCH ".*Unspecified.*" check_file_Unspecified_match ${check_file}) execute_process(COMMAND ${RPM_EXECUTABLE} -pqi ${check_file} OUTPUT_VARIABLE check_file_content ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process(COMMAND ${RPM_EXECUTABLE} -pqa ${check_file} RESULT_VARIABLE check_package_architecture_result OUTPUT_VARIABLE check_package_architecture ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process(COMMAND ${RPM_EXECUTABLE} -pql ${check_file} OUTPUT_VARIABLE check_package_content ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) set(whitespaces "[\\t\\n\\r ]*") if(check_file_libraries_match) set(check_file_match_expected_summary ".*${CPACK_RPM_PACKAGE_SUMMARY}.*") set(check_file_match_expected_description ".*${CPACK_COMPONENT_LIBRARIES_DESCRIPTION}.*") set(check_file_match_expected_relocation_path "Relocations${whitespaces}:${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}${LIB_SUFFIX}${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/other_relocatable${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}${LIB_SUFFIX}/inside_relocatable_two/depth_two/different_relocatable") set(check_file_match_expected_architecture "") # we don't explicitly set this value so it is different on each platform - ignore it set(spec_regex "*libraries*") set(check_content_list "^/usr/foo/bar/lib${LIB_SUFFIX} /usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one /usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two /usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/depth_three /usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/depth_three/symlink_parentdir_path /usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/symlink_outside_package /usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/symlink_outside_wdr /usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/symlink_relocatable_subpath /usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/symlink_samedir_path /usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/symlink_samedir_path_current_dir /usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/symlink_samedir_path_longer /usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/symlink_subdir_path /usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_two /usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_two/depth_two /usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_two/depth_two/different_relocatable /usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_two/depth_two/different_relocatable/bar /usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_two/depth_two/symlink_other_relocatable_path /usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_two/depth_two/symlink_to_non_relocatable_path /usr/foo/bar/lib${LIB_SUFFIX}/libmylib.a /usr/foo/bar/non_relocatable /usr/foo/bar/non_relocatable/depth_two /usr/foo/bar/non_relocatable/depth_two/symlink_from_non_relocatable_path /usr/foo/bar/other_relocatable /usr/foo/bar/other_relocatable/depth_two(\n.*\.build-id.*)*$") elseif(check_file_headers_match) set(check_file_match_expected_summary ".*${CPACK_RPM_HEADERS_PACKAGE_SUMMARY}.*") set(check_file_match_expected_description ".*${CPACK_RPM_HEADERS_PACKAGE_DESCRIPTION}.*") set(check_file_match_expected_relocation_path "Relocations${whitespaces}:${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}") set(check_file_match_expected_architecture "noarch") set(spec_regex "*headers*") set(check_content_list "^/usr/foo/bar\n/usr/foo/bar/include\n/usr/foo/bar/include/mylib.h(\n.*\.build-id.*)*$") elseif(check_file_applications_match) set(check_file_match_expected_summary ".*${CPACK_RPM_PACKAGE_SUMMARY}.*") set(check_file_match_expected_description ".*${CPACK_COMPONENT_APPLICATIONS_DESCRIPTION}.*") set(check_file_match_expected_relocation_path "Relocations${whitespaces}:${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}") set(check_file_match_expected_architecture "armv7hl") set(spec_regex "*applications*") set(check_content_list "^/usr/foo/bar /usr/foo/bar/bin /usr/foo/bar/bin/mylibapp(\n.*\.build-id.*)*$") elseif(check_file_Unspecified_match) set(check_file_match_expected_summary ".*${CPACK_RPM_PACKAGE_SUMMARY}.*") set(check_file_match_expected_description ".*DESCRIPTION.*") set(check_file_match_expected_relocation_path "Relocations${whitespaces}:${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}") set(check_file_match_expected_architecture "") # we don't explicitly set this value so it is different on each platform - ignore it set(spec_regex "*Unspecified*") set(check_content_list "^/usr/foo/bar /usr/foo/bar/bin /usr/foo/bar/bin/@in@_@path@@with /usr/foo/bar/bin/@in@_@path@@with/@and /usr/foo/bar/bin/@in@_@path@@with/@and/@ /usr/foo/bar/bin/@in@_@path@@with/@and/@/@in_path@ /usr/foo/bar/bin/@in@_@path@@with/@and/@/@in_path@/mylibapp2 /usr/foo/bar/share /usr/foo/bar/share/man /usr/foo/bar/share/man/mylib /usr/foo/bar/share/man/mylib/man3 /usr/foo/bar/share/man/mylib/man3/mylib.1 /usr/foo/bar/share/man/mylib/man3/mylib.1/mylib /usr/foo/bar/share/man/mylib/man3/mylib.1/mylib2(\n.*\.build-id.*)*$") else() message(FATAL_ERROR "error: unexpected rpm package '${check_file}'") endif() ####################### # test package info ####################### string(REGEX MATCH ${check_file_match_expected_summary} check_file_match_summary ${check_file_content}) if(NOT check_file_match_summary) message(FATAL_ERROR "error: '${check_file}' rpm package summary does not match expected value - regex '${check_file_match_expected_summary}'; RPM output: '${check_file_content}'") endif() string(REGEX MATCH ${check_file_match_expected_description} check_file_match_description ${check_file_content}) if(NOT check_file_match_description) message(FATAL_ERROR "error: '${check_file}' rpm package description does not match expected value - regex '${check_file_match_expected_description}'; RPM output: '${check_file_content}'") endif() string(REGEX MATCH ${check_file_match_expected_relocation_path} check_file_match_relocation_path ${check_file_content}) if(NOT check_file_match_relocation_path) file(GLOB_RECURSE spec_file "${CPackComponentsForAll_BINARY_DIR}/${spec_regex}.spec") if(spec_file) file(READ ${spec_file} spec_file_content) endif() message(FATAL_ERROR "error: '${check_file}' rpm package relocation path does not match expected value - regex '${check_file_match_expected_relocation_path}'; RPM output: '${check_file_content}'; generated spec file: '${spec_file_content}'") endif() ####################### # test package architecture ####################### string(REGEX MATCH "Architecture${whitespaces}:" check_info_contains_arch ${check_file_content}) if(check_info_contains_arch) # test for rpm versions that contain architecture in package info (e.g. 4.11.x) string(REGEX MATCH "Architecture${whitespaces}:${whitespaces}${check_file_match_expected_architecture}" check_file_match_architecture ${check_file_content}) if(NOT check_file_match_architecture) message(FATAL_ERROR "error: '${check_file}' Architecture does not match expected value - '${check_file_match_expected_architecture}'; RPM output: '${check_file_content}'; generated spec file: '${spec_file_content}'") endif() elseif(NOT check_package_architecture_result) # test result only on platforms that support -pqa rpm query # test for rpm versions that do not contain architecture in package info (e.g. 4.8.x) string(REGEX MATCH ".*${check_file_match_expected_architecture}" check_file_match_architecture "${check_package_architecture}") if(NOT check_file_match_architecture) message(FATAL_ERROR "error: '${check_file}' Architecture does not match expected value - '${check_file_match_expected_architecture}'; RPM output: '${check_package_architecture}'; generated spec file: '${spec_file_content}'") endif() # else rpm version too old (e.g. 4.4.x) - skip test endif() ####################### # test package content ####################### string(REGEX MATCH "${check_content_list}" expected_content_list "${check_package_content}") if(NOT expected_content_list) file(GLOB_RECURSE spec_file "${CPackComponentsForAll_BINARY_DIR}/${spec_regex}.spec") if(spec_file) file(READ ${spec_file} spec_file_content) endif() message(FATAL_ERROR "error: '${check_file}' rpm package content does not match expected value - regex '${check_content_list}'; RPM output: '${check_package_content}'; generated spec file: '${spec_file_content}'") endif() # validate permissions user and group execute_process(COMMAND ${RPM_EXECUTABLE} -pqlv ${check_file} OUTPUT_VARIABLE check_file_content ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) if(check_file_libraries_match) set(check_file_match_expected_permissions ".*-rwx------.*user.*defgrp.*") elseif(check_file_headers_match) set(check_file_match_expected_permissions ".*-rwxr--r--.*defusr.*defgrp.*") elseif(check_file_applications_match) set(check_file_match_expected_permissions ".*-rwxr--r--.*defusr.*group.*") elseif(check_file_Unspecified_match) set(check_file_match_expected_permissions ".*-rwxr--r--.*defusr.*defgrp.*") else() message(FATAL_ERROR "error: unexpected rpm package '${check_file}'") endif() string(REGEX MATCH "${check_file_match_expected_permissions}" check_file_match_permissions "${check_file_content}") if(NOT check_file_match_permissions) message(FATAL_ERROR "error: '${check_file}' rpm package permissions do not match expected value - regex '${check_file_match_expected_permissions}'") endif() endforeach() ####################### # verify generated symbolic links ####################### file(GLOB_RECURSE symlink_files RELATIVE "${CPackComponentsForAll_BINARY_DIR}" "${CPackComponentsForAll_BINARY_DIR}/*/symlink_*") foreach(check_symlink IN LISTS symlink_files) get_filename_component(symlink_name "${check_symlink}" NAME) execute_process(COMMAND ls -la "${check_symlink}" WORKING_DIRECTORY "${CPackComponentsForAll_BINARY_DIR}" OUTPUT_VARIABLE SYMLINK_POINT_ OUTPUT_STRIP_TRAILING_WHITESPACE) if("${symlink_name}" STREQUAL "symlink_samedir_path" OR "${symlink_name}" STREQUAL "symlink_samedir_path_current_dir" OR "${symlink_name}" STREQUAL "symlink_samedir_path_longer") string(REGEX MATCH "^.*${whitespaces}->${whitespaces}depth_three$" check_symlink "${SYMLINK_POINT_}") elseif("${symlink_name}" STREQUAL "symlink_subdir_path") string(REGEX MATCH "^.*${whitespaces}->${whitespaces}depth_two/depth_three$" check_symlink "${SYMLINK_POINT_}") elseif("${symlink_name}" STREQUAL "symlink_parentdir_path") string(REGEX MATCH "^.*${whitespaces}->${whitespaces}../$" check_symlink "${SYMLINK_POINT_}") elseif("${symlink_name}" STREQUAL "symlink_to_non_relocatable_path") string(REGEX MATCH "^.*${whitespaces}->${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/non_relocatable/depth_two$" check_symlink "${SYMLINK_POINT_}") elseif("${symlink_name}" STREQUAL "symlink_outside_package") string(REGEX MATCH "^.*${whitespaces}->${whitespaces}outside_package$" check_symlink "${SYMLINK_POINT_}") elseif("${symlink_name}" STREQUAL "symlink_outside_wdr") string(REGEX MATCH "^.*${whitespaces}->${whitespaces}/outside_package_wdr$" check_symlink "${SYMLINK_POINT_}") elseif("${symlink_name}" STREQUAL "symlink_other_relocatable_path" OR "${symlink_name}" STREQUAL "symlink_from_non_relocatable_path" OR "${symlink_name}" STREQUAL "symlink_relocatable_subpath") # these links were not changed - post install script only - ignore them else() message(FATAL_ERROR "error: unexpected rpm symbolic link '${check_symlink}'") endif() if(NOT check_symlink) message(FATAL_ERROR "symlink points to unexpected location '${SYMLINK_POINT_}'") endif() endforeach() # verify post install symlink relocation script file(GLOB_RECURSE spec_file "${CPackComponentsForAll_BINARY_DIR}/*libraries*.spec") file(READ ${spec_file} spec_file_content) file(READ "${CMAKE_CURRENT_LIST_DIR}/symlink_postinstall_expected.txt" symlink_postinstall_expected) # prepare regex string(STRIP "${symlink_postinstall_expected}" symlink_postinstall_expected) string(REPLACE "[" "\\[" symlink_postinstall_expected "${symlink_postinstall_expected}") string(REPLACE "$" "\\$" symlink_postinstall_expected "${symlink_postinstall_expected}") string(REPLACE "lib" "lib${LIB_SUFFIX}" symlink_postinstall_expected "${symlink_postinstall_expected}") # compare string(REGEX MATCH ".*${symlink_postinstall_expected}.*" symlink_postinstall_expected_matches "${spec_file_content}") if(NOT symlink_postinstall_expected_matches) message(FATAL_ERROR "error: unexpected rpm symbolic link postinstall script! generated spec file: '${spec_file_content}'") endif() endif() endif() cmake_policy(POP)