Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[vcpkg-ci] Add test port for cmake user projects #19034

Merged
merged 17 commits into from
Nov 22, 2021
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions scripts/ci.baseline.txt
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ clblast:x64-linux=fail
clblast:x64-windows-static=fail
clblast:x64-windows-static-md=fail
clockutils:x64-linux=fail
# CMake 3.4 needs libidn.so.11 (Ubuntu: libidn11)
cmake-user:x64-linux=skip
cmcstl2:arm64-windows = skip
cmcstl2:arm-uwp = skip
cmcstl2:x64-linux = skip
Expand Down
171 changes: 171 additions & 0 deletions scripts/test_ports/cmake-user/portfile.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
set(VCPKG_POLICY_EMPTY_PACKAGE enabled)

set(cmake_version OFF)
if("cmake-3-4" IN_LIST FEATURES)
set(cmake_version 3.4.3)
string(REGEX REPLACE "([^.]*[.][^.]*).*" "\\1" cmake_major_minor "${cmake_version}")
if(HOST_TRIPLET MATCHES "^x.*-(windows|mingw)")
set(name "cmake-${cmake_version}-win32-x86")
vcpkg_download_distfile(legacy_cmake_archive
FILENAME "${name}.zip"
URLS "https://github.com/Kitware/CMake/releases/download/v${cmake_version}/${name}.zip"
"https://cmake.org/files/v${cmake_major_minor}/${name}.zip"
SHA512 c74a8f85ce04a2c0f68fd315a9a7e2fee5cc98af9e8117cca6b35a4f0942cae2d101672e5936a8bfc20289c8c82da582531495308657348a1121e3f568588bd3
)
set(cmake_bin_dir "/bin")
elseif(HOST_TRIPLET MATCHES "^x.*-osx")
set(name "cmake-${cmake_version}-Darwin-x86_64")
vcpkg_download_distfile(legacy_cmake_archive
FILENAME "${name}.tar.gz"
URLS "https://github.com/Kitware/CMake/releases/download/v3.4.3/${name}.tar.gz"
"https://cmake.org/files/v${cmake_major_minor}/${name}.tar.gz"
SHA512 c3da566a19e95b8f91bf601518b9c49304b9bb8500f5a086eb2c867514176278e51dd893952b8ab54a2839ed02c898036c7985fe0bb761db9ccb988343463ea2
)
set(cmake_bin_dir "/CMake.app/Contents/bin")
elseif(HOST_TRIPLET MATCHES "^x.*-linux")
set(name "cmake-${cmake_version}-Linux-x86_64")
vcpkg_download_distfile(legacy_cmake_archive
FILENAME "${name}.tar.gz"
URLS "https://github.com/Kitware/CMake/releases/download/v3.4.3/${name}.tar.gz"
"https://cmake.org/files/v${cmake_major_minor}/${name}.tar.gz"
SHA512 455b8f940ccda0ba1169d3620db67c0bf89284126386408cd28b76b66c59c4c2ea5ad8def0095166e7524f6cf5202f117a2fa49e1525f93ed711657a5d2ae988
)
set(cmake_bin_dir "/bin")
else()
message(FATAL_ERROR "Unable to test feature 'cmake-3-4' for '${HOST_TRIPLET}' host.")
endif()

vcpkg_extract_source_archive_ex(
OUT_SOURCE_PATH legacy_cmake
ARCHIVE "${legacy_cmake_archive}"
REF "${cmake_version}"
WORKING_DIRECTORY "${CURRENT_BUILDTREES_DIR}/${name}"
)
set(CMAKE_COMMAND "${legacy_cmake}${cmake_bin_dir}/cmake")
endif()

set(packages "")
if("find-package" IN_LIST FEATURES)
file(READ "${CMAKE_CURRENT_LIST_DIR}/vcpkg.json" vcpkg_json)
string(JSON packages_json GET "${vcpkg_json}" "features" "find-package" "dependencies")
string(JSON packages_count LENGTH "${packages_json}")
if(packages_count GREATER 0)
math(EXPR last "${packages_count} - 1")
foreach(i RANGE 0 ${last})
string(JSON package GET "${packages_json}" ${i} "$package")
list(APPEND packages "${package}")
endforeach()
endif()
if(VCPKG_TARGET_IS_WINDOWS AND NOT VCPKG_TARGET_IS_MINGW)
list(REMOVE_ITEM packages "Curses")
endif()
endif()

if(DEFINED ENV{VCPKG_FORCE_SYSTEM_BINARIES})
set(NINJA "ninja")
else()
vcpkg_find_acquire_program(NINJA)
endif()

function(test_cmake_project)
cmake_parse_arguments(PARSE_ARGV 0 "arg" "" "NAME" "OPTIONS")
if(NOT arg_NAME)
message(FATAL_ERROR "The NAME argument is mandatory.")
endif()

set(build_dir "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-${arg_NAME}")
set(base_options
-G "Ninja"
"-DCMAKE_MAKE_PROGRAM=${NINJA}"
"-DCMAKE_TOOLCHAIN_FILE=${SCRIPTS}/buildsystems/vcpkg.cmake"
"-DVCPKG_INSTALLED_DIR=${_VCPKG_INSTALLED_DIR}"
"-DCMAKE_INSTALL_PREFIX=${build_dir}/install"
"-DVCPKG_TARGET_TRIPLET=${TARGET_TRIPLET}"
"-DVCPKG_MANIFEST_MODE=OFF"
)

if(DEFINED VCPKG_CMAKE_SYSTEM_NAME AND VCPKG_CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
list(APPEND base_options "-DCMAKE_SYSTEM_NAME=${VCPKG_CMAKE_SYSTEM_NAME}")
if(DEFINED VCPKG_CMAKE_SYSTEM_VERSION)
list(APPEND base_options "-DCMAKE_SYSTEM_VERSION=${VCPKG_CMAKE_SYSTEM_VERSION}")
endif()
if(DEFINED VCPKG_PLATFORM_TOOLSET)
list(APPEND base_options "-DVCPKG_PLATFORM_TOOLSET=${VCPKG_PLATFORM_TOOLSET}")
endif()
endif()

if(VCPKG_LIBRARY_LINKAGE STREQUAL "dynamic")
list(APPEND base_options -DBUILD_SHARED_LIBS=ON)
else()
list(APPEND base_options -DBUILD_SHARED_LIBS=OFF)
endif()

message(STATUS "Running tests for '${arg_NAME}'")
file(REMOVE_RECURSE "${build_dir}")
file(MAKE_DIRECTORY "${build_dir}")
vcpkg_execute_required_process(
COMMAND
"${CMAKE_COMMAND}" "${CMAKE_CURRENT_LIST_DIR}/project"
${base_options}
${arg_OPTIONS}
WORKING_DIRECTORY "${build_dir}"
LOGNAME "${TARGET_TRIPLET}-${arg_NAME}-config"
)
vcpkg_execute_required_process(
COMMAND
"${CMAKE_COMMAND}" --build . --target install
WORKING_DIRECTORY "${build_dir}"
LOGNAME "${TARGET_TRIPLET}-${arg_NAME}-build"
)
# To produce better error messages for failing wrappers,
# we run execute_process directly here, for each wrapper.
string(REPLACE " OFF:" ":" message
" CMake ${cmake_version}: `find_package(@package@)` failed.\n"
" See logs for more information:\n"
" @log_out@\n"
" @log_err@\n"
)
if(DEFINED ENV{BUILD_REASON}) # On Azure Pipelines, add extra markup.
string(REPLACE " CMake" "##vso[task.logissue type=error]CMake" message "${message}")
endif()
foreach(package IN LISTS packages)
string(MAKE_C_IDENTIFIER "${package}" package_string)
set(find_package_build_dir "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-find-package-${package_string}-${arg_NAME}")
set(log_out "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-find-package-${package_string}-${arg_NAME}-out.log")
set(log_err "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-find-package-${package_string}-${arg_NAME}-err.log")

message(STATUS " find_package(${package})")
file(REMOVE_RECURSE "${find_package_build_dir}")
file(MAKE_DIRECTORY "${find_package_build_dir}")
execute_process(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should delete and recreate build_dir each time to ensure the different find_package calls are not accidentally aiding and abetting each other.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.
Originally I tried to avoid this in order to not spend time for a full toolchain configuration. The find-package test are not in parallel. CI build time is now 35 s instead of 11 s (x64-windows).
As a milder decoupling, we might keep the same build dir, but pass -U*_LIBRAR* -U*_INCLUDE_DIR* -U*_DIR -U*_FOUND in order to unset the typical variables.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That might be sufficient for a future improvement.

COMMAND
"${CMAKE_COMMAND}" "${CMAKE_CURRENT_LIST_DIR}/project"
${base_options}
${arg_OPTIONS}
"-DFIND_PACKAGES=${package}"
OUTPUT_FILE "${log_out}"
ERROR_FILE "${log_err}"
RESULT_VARIABLE package_result
WORKING_DIRECTORY "${find_package_build_dir}"
)
if(package_result)
string(CONFIGURE "${message}" package_message @ONLY)
message(SEND_ERROR "${package_message}")
endif()
endforeach()
endfunction()

test_cmake_project(NAME "release"
OPTIONS
"-DCMAKE_BUILD_TYPE=Release"
"-DCMAKE_PREFIX_PATH=SYSTEM_LIBS" # for testing VCPKG_PREFER_SYSTEM_LIBS
"-DVCPKG_PREFER_SYSTEM_LIBS=OFF"
"-DCHECK_CMAKE_VERSION=${cmake_version}"
)
test_cmake_project(NAME "debug"
OPTIONS
"-DCMAKE_BUILD_TYPE=Debug"
"-DCMAKE_PREFIX_PATH=SYSTEM_LIBS" # for testing VCPKG_PREFER_SYSTEM_LIBS
"-DVCPKG_PREFER_SYSTEM_LIBS=ON"
"-DCHECK_CMAKE_VERSION=${cmake_version}"
)
66 changes: 66 additions & 0 deletions scripts/test_ports/cmake-user/project/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
cmake_minimum_required(VERSION 3.4)
project(cmake-user LANGUAGES C)

message(STATUS "CMAKE_COMMAND: ${CMAKE_COMMAND}")
set(CHECK_CMAKE_VERSION "NOTFOUND" CACHE STRING "Version of CMake expected to be found")
if(NOT CHECK_CMAKE_VERSION)
message(WARNING "CMake version check: skipped (actual: ${CMAKE_VERSION})")
elseif(NOT CHECK_CMAKE_VERSION VERSION_EQUAL CMAKE_VERSION)
message(SEND_ERROR "CMake version check: failed (actual: ${CMAKE_VERSION} expected: ${CHECK_CMAKE_VERSION})")
else()
message(STATUS "CMake version check: success (actual: ${CMAKE_VERSION})")
endif()

message(STATUS "CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH}")
list(FIND CMAKE_PREFIX_PATH "SYSTEM_LIBS" system_libs)
list(FIND CMAKE_PREFIX_PATH "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}" vcpkg)
if(system_libs LESS 0)
message(SEND_ERROR "VCPKG_PREFER_SYSTEM_LIBS check: failed (Cannot find SYSTEM_LIBS in CMAKE_PREFIX_PATH.)")
elseif(vcpkg LESS 0)
message(SEND_ERROR "VCPKG_PREFER_SYSTEM_LIBS check: failed (Cannot find vcpkg path in CMAKE_PREFIX_PATH.")
elseif(VCPKG_PREFER_SYSTEM_LIBS AND system_libs GREATER vcpkg)
message(SEND_ERROR "VCPKG_PREFER_SYSTEM_LIBS check: failed (actual: ${VCPKG_PREFER_SYSTEM_LIBS}, but vcpkg paths are before system paths in CMAKE_PREFIX_PATH.)")
elseif(NOT VCPKG_PREFER_SYSTEM_LIBS AND system_libs LESS vcpkg)
message(SEND_ERROR "VCPKG_PREFER_SYSTEM_LIBS check: failed (actual: ${VCPKG_PREFER_SYSTEM_LIBS}, but vcpkg paths are after system paths in CMAKE_PREFIX_PATH.)")
else()
message(STATUS "VCPKG_PREFER_SYSTEM_LIBS check: success (actual: ${VCPKG_PREFER_SYSTEM_LIBS})")
endif()

# add_library overload
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib.c" "int lib_unused() { return 1; }")
add_library(lib "${CMAKE_CURRENT_BINARY_DIR}/lib.c")

# add_executable overload
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/exe.c" "int main() { return 0; }")
add_executable(exe "${CMAKE_CURRENT_BINARY_DIR}/exe.c")

# install overload
set(X_VCPKG_APPLOCAL_DEPS_INSTALL 1)
install(TARGETS exe lib
RUNTIME DESTINATION bin
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
)

# find_package overload and wrapper
set(FIND_PACKAGES "" CACHE STRING "List of packages to be found and used")
foreach(package ${FIND_PACKAGES})
string(TOUPPER "${package}" package_upper)
set(CMAKE_FIND_DEBUG_MODE ON)
find_package("${package}" QUIET)
set(CMAKE_FIND_DEBUG_MODE OFF)
if(NOT ${package}_FOUND AND NOT ${package_upper}_FOUND)
message(SEND_ERROR "find_package(${package}) check: failed")
elseif(DEFINED ${package_upper}_LIBRARIES)
message(STATUS "${package_upper}_LIBRARIES: ${${package_upper}_LIBRARIES}")
message(STATUS "find_package(${package}) check: success")
target_link_libraries(exe PRIVATE ${${package_upper}_LIBRARIES})
elseif(DEFINED ${package}_LIBRARIES)
message(STATUS "${package}_LIBRARIES: ${${package}_LIBRARIES}")
message(STATUS "find_package(${package}) check: success")
target_link_libraries(exe PRIVATE ${${package}_LIBRARIES})
else()
message(STATUS "${package}_LIBRARIES: undefined")
message(STATUS "find_package(${package}) check: success")
endif()
endforeach()
71 changes: 71 additions & 0 deletions scripts/test_ports/cmake-user/vcpkg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"name": "cmake-user",
"version-date": "2021-07-24",
"description": "Test port to verify the vcpkg toolchain in cmake user projects",
"default-features": [
"ci"
],
"features": {
"ci": {
"description": "The CI set of features to test",
"dependencies": [
{
"name": "cmake-user",
"default-features": false,
"features": [
"find-package"
]
},
{
"name": "cmake-user",
"default-features": false,
"features": [
"cmake-3-4"
],
"platform": "x64 & (windows | linux | osx) & !uwp"
}
]
},
"cmake-3-4": {
"description": "Use CMake 3.4 to build the test project"
},
"find-package": {
"description": "Ports to be tested via find_package($package)",
"dependencies": [
{
"$package": "BZip2",
"name": "bzip2"
},
{
"$package": "EXPAT",
"name": "expat"
},
{
"$package": "Freetype",
"name": "freetype"
},
{
"$package": "Intl",
"name": "gettext"
},
{
"$package": "GIF",
"name": "giflib"
},
{
"$package": "LibLZMA",
"name": "liblzma"
},
{
"$package": "Curses",
"name": "ncurses",
"platform": "!windows & !uwp"
},
{
"$package": "ZLIB",
"name": "zlib"
}
]
}
}
}