Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
9 changes: 9 additions & 0 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ jobs:
skip: "*musllinux*"
arch: "x86_64"

# cibuildwheel's "auto" on Windows means AMD64 *and* x86, but dcmqi publishes no
# 32-bit binaries. The win32 wheel it produced could therefore only ever contain
# the 64-bit ones, so the architecture is pinned rather than probed.
- os: windows-latest
arch: "AMD64"

- os: macos-14
arch: "arm64"

Expand All @@ -102,6 +108,9 @@ jobs:
- os: ubuntu-latest
arch: "auto"

- os: windows-latest
arch: "auto"

steps:
- uses: actions/checkout@v7
with:
Expand Down
47 changes: 8 additions & 39 deletions .github/workflows/update-dcmqi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,16 @@ jobs:
esac
done

# Generate dcmqiUrls.cmake
# Generate dcmqiUrls.cmake. This file carries data only -- the version, and one
# filename/checksum pair per published asset. Choosing between those assets is done
# by dcmqiArchive.cmake, which is hand-written and must not be emitted here: it was
# previously generated below, so any fix to the selection logic was silently
# reverted by the next run of this workflow.
{
echo '# Checksums computed from assets associated with the dcmqi GitHub release'
echo '#'
echo '# Generated by .github/workflows/update-dcmqi.yml -- do not edit by hand.'
echo '# Which of these assets a build uses is decided in dcmqiArchive.cmake.'
echo ''
echo "set(version \"$latest_version\")"
echo ''
Expand Down Expand Up @@ -117,44 +124,6 @@ jobs:
win_file="dcmqi-${latest_version}-win64.zip"
echo "set(win64_filename \"$win_file\")"
echo "set(win64_sha256 \"${checksums[$win_file]}\")"
echo ''
echo ''

# Platform detection
echo 'cmake_host_system_information(RESULT is_64bit QUERY IS_64BIT)'
echo ''
echo 'set(archive "linux")'
echo ''
echo 'if(APPLE)'
if [ "$has_mac_split" = true ]; then
echo ' if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")'
echo ' set(archive "macos_arm64")'
echo ' else()'
echo ' set(archive "macos_x86_64")'
echo ' endif()'
else
echo ' set(archive "macos")'
fi
echo 'endif()'
echo ''
echo 'if(WIN32)'
echo ' if(is_64bit AND NOT (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "ARM64"))'
echo ' set(archive "win64")'
echo ' endif()'
echo 'endif()'
echo ''
echo 'if(NOT DEFINED "${archive}_filename")'
echo ' message(FATAL_ERROR "Failed to determine which archive to download: '"'"'${archive}_filename'"'"' variable is not defined")'
echo 'endif()'
echo ''
echo 'if(NOT DEFINED "${archive}_sha256")'
echo ' message(FATAL_ERROR "Could you make sure variable '"'"'${archive}_sha256'"'"' is defined ?")'
echo 'endif()'
echo ''
echo 'set(dcmqi_archive_filename "${${archive}_filename}")'
echo 'set(dcmqi_archive_sha256 "${${archive}_sha256}")'
echo ''
echo 'set(dcmqi_archive_url "https://github.com/QIICR/dcmqi/releases/download/v${version}/${dcmqi_archive_filename}")'
} > dcmqiUrls.cmake

# Update binaries.txt with discovered binary list
Expand Down
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
cmake_minimum_required(VERSION 3.15...3.26)
project(${SKBUILD_PROJECT_NAME} LANGUAGES NONE)

# Set in the current scope the following variables:
# dcmqiUrls.cmake is generated: it lists every published asset and its checksum.
# dcmqiArchive.cmake then picks the one matching this build and sets in the current scope:
# - dcmqi_archive_url
# - dcmqi_archive_sha256
include(${CMAKE_CURRENT_SOURCE_DIR}/dcmqiUrls.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/dcmqiArchive.cmake)

#
# Download & extract archive
Expand Down
99 changes: 99 additions & 0 deletions dcmqiArchive.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Selects the dcmqi release asset matching the platform and architecture being built for.
#
# The available assets and their checksums come from dcmqiUrls.cmake, which the update-dcmqi
# workflow regenerates; this file holds the logic and is written by hand.
#
# Picking the wrong asset is silent: a mismatched archive still extracts and installs, and the
# wheel only fails later, when a user runs a binary that cannot execute on their machine. So
# anything short of an exact platform/architecture match is a hard error here.

if(NOT DEFINED version)
message(FATAL_ERROR "dcmqiUrls.cmake must be included before dcmqiArchive.cmake")
endif()

# The architecture this build *targets*, which is not always the host's:
#
# * Visual Studio generators carry the target in CMAKE_GENERATOR_PLATFORM, and
# scikit-build-core sets it from the interpreter the wheel is being built for. A 32-bit
# Python on a 64-bit runner therefore reports "Win32" here while the host still looks
# 64-bit -- precisely the case that used to be mistaken for win64.
# * macOS cross builds set CMAKE_OSX_ARCHITECTURES (scikit-build-core derives it from
# ARCHFLAGS, which cibuildwheel sets).
#
# CMAKE_SYSTEM_PROCESSOR reports the host whenever we are not cross-compiling, so it only
# serves as the fallback.
set(_dcmqi_arch "${CMAKE_SYSTEM_PROCESSOR}")
if(APPLE AND CMAKE_OSX_ARCHITECTURES)
list(LENGTH CMAKE_OSX_ARCHITECTURES _dcmqi_arch_count)
if(_dcmqi_arch_count GREATER 1)
message(FATAL_ERROR
"CMAKE_OSX_ARCHITECTURES asks for a universal build (${CMAKE_OSX_ARCHITECTURES}), but "
"dcmqi publishes one archive per architecture. Build a separate wheel for each.")
endif()
set(_dcmqi_arch "${CMAKE_OSX_ARCHITECTURES}")
elseif(CMAKE_GENERATOR_PLATFORM)
set(_dcmqi_arch "${CMAKE_GENERATOR_PLATFORM}")
endif()

string(TOLOWER "${_dcmqi_arch}" _dcmqi_arch)
if(_dcmqi_arch MATCHES "^(x86_64|x64|amd64)$")
set(_dcmqi_arch "x86_64")
elseif(_dcmqi_arch MATCHES "^(arm64|aarch64)$")
set(_dcmqi_arch "arm64")
elseif(_dcmqi_arch MATCHES "^(win32|x86|i[3-6]86)$")
set(_dcmqi_arch "x86")
endif()

if(APPLE)
set(_dcmqi_platform "macos")
elseif(WIN32)
set(_dcmqi_platform "win")
elseif(UNIX)
set(_dcmqi_platform "linux")
else()
message(FATAL_ERROR
"dcmqi publishes no binary package for this operating system "
"(CMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME})")
endif()

# Asset variables are named <platform>_<arch>. The two assets whose upstream names predate
# architecture qualification get an alias: "linux" and "win64" both mean x86_64. See
# CPACK_SYSTEM_NAME in QIICR/dcmqi.
set(_dcmqi_candidates "${_dcmqi_platform}_${_dcmqi_arch}")
if(_dcmqi_platform STREQUAL "linux" AND _dcmqi_arch STREQUAL "x86_64")
list(APPEND _dcmqi_candidates "linux")
elseif(_dcmqi_platform STREQUAL "win" AND _dcmqi_arch STREQUAL "x86_64")
list(APPEND _dcmqi_candidates "win64")
elseif(_dcmqi_platform STREQUAL "macos")
# Older releases shipped a single, unqualified macOS archive; the generator still emits
# that name if upstream ever stops splitting by architecture.
list(APPEND _dcmqi_candidates "macos")
endif()

set(archive "")
foreach(_dcmqi_candidate IN LISTS _dcmqi_candidates)
if(DEFINED ${_dcmqi_candidate}_filename AND DEFINED ${_dcmqi_candidate}_sha256)
set(archive "${_dcmqi_candidate}")
break()
endif()
endforeach()

if(NOT archive)
set(_dcmqi_tried "")
foreach(_dcmqi_candidate IN LISTS _dcmqi_candidates)
list(APPEND _dcmqi_tried "${_dcmqi_candidate}_filename")
endforeach()
string(REPLACE ";" ", " _dcmqi_tried "${_dcmqi_tried}")
message(FATAL_ERROR
"dcmqi v${version} publishes no binary package for ${_dcmqi_platform}/${_dcmqi_arch}, so no "
"wheel can be built for it. Looked in dcmqiUrls.cmake for ${_dcmqi_tried} (and a matching "
"_sha256). Published assets: https://github.com/QIICR/dcmqi/releases/tag/v${version}")
endif()

set(dcmqi_archive_filename "${${archive}_filename}")
set(dcmqi_archive_sha256 "${${archive}_sha256}")
set(dcmqi_archive_url
"https://github.com/QIICR/dcmqi/releases/download/v${version}/${dcmqi_archive_filename}")

message(STATUS
"dcmqi archive for ${_dcmqi_platform}/${_dcmqi_arch}: ${dcmqi_archive_filename}")
35 changes: 3 additions & 32 deletions dcmqiUrls.cmake
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# Checksums computed from assets associated with the dcmqi GitHub release
#
# Generated by .github/workflows/update-dcmqi.yml -- do not edit by hand.
# Which of these assets a build uses is decided in dcmqiArchive.cmake.

set(version "1.5.6")

Expand All @@ -13,35 +16,3 @@ set(macos_x86_64_sha256 "6678f2a60547c3a14a9f0376932217c3faee28158b6805c3b89d3

set(win64_filename "dcmqi-1.5.6-win64.zip")
set(win64_sha256 "72f4bf6bc6b265e5843c42436267fb59a8079ca765095f218300d019f9e15e3d")


cmake_host_system_information(RESULT is_64bit QUERY IS_64BIT)

set(archive "linux")

if(APPLE)
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
set(archive "macos_arm64")
else()
set(archive "macos_x86_64")
endif()
endif()

if(WIN32)
if(is_64bit AND NOT (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "ARM64"))
set(archive "win64")
endif()
endif()

if(NOT DEFINED "${archive}_filename")
message(FATAL_ERROR "Failed to determine which archive to download: '${archive}_filename' variable is not defined")
endif()

if(NOT DEFINED "${archive}_sha256")
message(FATAL_ERROR "Could you make sure variable '${archive}_sha256' is defined ?")
endif()

set(dcmqi_archive_filename "${${archive}_filename}")
set(dcmqi_archive_sha256 "${${archive}_sha256}")

set(dcmqi_archive_url "https://github.com/QIICR/dcmqi/releases/download/v${version}/${dcmqi_archive_filename}")
Loading