CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
186 lines
9.1 KiB
CMake
186 lines
9.1 KiB
CMake
# Copyright Advanced Micro Devices, Inc.
|
|
# SPDX-License-Identifier: MIT
|
|
|
|
# find_package dependency provider
|
|
# This is injected into sub-projects that contain dependencies. It runs in a
|
|
# context with the following variables defined at the top level:
|
|
# THEROCK_PROVIDED_PACKAGES: Package names that are to be provided from the
|
|
# super-project
|
|
# THEROCK_PACKAGE_DIR_${package_name}: Directory in the super-project to
|
|
# resolve the dependency.
|
|
# THEROCK_IGNORE_PACKAGES: Packages to ignore, even if they are in
|
|
# THEROCK_PROVIDED_PACKAGES, falling back to the system resolver.
|
|
# THEROCK_PKG_CONFIG_DIRS: Directories to search for .pc files.
|
|
# THEROCK_STRICT_PROVIDED_PACKAGES: All packages that the super-project knows
|
|
# about. If a sub-project attempts to resolve one of these without a
|
|
# proper declared dependency, it will error.
|
|
# See: _therock_cmake_subproject_setup_deps which assembles these variables
|
|
|
|
block(PROPAGATE CMAKE_PREFIX_PATH)
|
|
set(prefix_extensions)
|
|
if(THEROCK_PKG_CONFIG_DIRS)
|
|
foreach(_dir ${THEROCK_PKG_CONFIG_DIRS})
|
|
# There is a mismatch between THEROCK_PKG_CONFIG_DIRS, which specifies
|
|
# a full path to the .pc file (i.e. /some/path/lib/pkgconfig) versus
|
|
# how CMAKE_PREFIX_PATH is parsed for the same. The latter expects each
|
|
# path to be to the prefix and it will probe sub-directory 'lib/pkgconfig'
|
|
# (actually from an allow list of suitable prefix extensions) to determine
|
|
# if the path will be extended and propagated to pkg-config. Therefore,
|
|
# we need to back up to the actual prefix path. For super-project
|
|
# pkg-config dirs (which is what we are dealing with here), this will
|
|
# always be two levels up (i.e. lib/pkgdata). We could add more validation
|
|
# of this, but it is actually somewhat open ended to determine *which*
|
|
# two levels it is (i.e. lib32 vs lib, share vs lib, etc). But is is
|
|
# always two.
|
|
cmake_path(GET _dir PARENT_PATH _dir)
|
|
cmake_path(GET _dir PARENT_PATH _dir)
|
|
list(APPEND prefix_extensions "${_dir}")
|
|
endforeach()
|
|
message(STATUS "Sub-project pkg-config prefixes: ${prefix_extensions}")
|
|
list(APPEND CMAKE_PREFIX_PATH ${prefix_extensions})
|
|
endif()
|
|
endblock()
|
|
|
|
macro(therock_dependency_provider method package_name)
|
|
cmake_policy(PUSH)
|
|
cmake_policy(SET CMP0057 NEW)
|
|
if("${package_name}" IN_LIST THEROCK_PROVIDED_PACKAGES AND NOT
|
|
"${package_name}" IN_LIST THEROCK_IGNORE_PACKAGES)
|
|
cmake_policy(POP)
|
|
# It is quite hard to completely neuter find_package so that for an
|
|
# arbitrary signature it will only attempt to find from one specified path.
|
|
# This is important because it "latches" and if any find_package manages
|
|
# to escape to the system, it will likely find a library from outside the
|
|
# super-project, which can cause all kinds of hard to diagnose issues.
|
|
# For background, read carefully:
|
|
# https://cmake.org/cmake/help/latest/command/find_package.html#config-mode-search-procedure
|
|
# We opt-to rewrite the signature, removing any options that connote an
|
|
# implicit search behavior and then rewrite the signature to be explicit.
|
|
# We further do this in a function to avoid macro namespace pollution, since
|
|
# the find_package itself must be evaluated in the caller-scope.
|
|
therock_reparse_super_project_find_package(
|
|
"${THEROCK_PACKAGE_DIR_${package_name}}" "${package_name}" ${ARGN})
|
|
find_package(${_therock_rewritten_superproject_find_package_sig})
|
|
else()
|
|
if("${package_name}" IN_LIST THEROCK_STRICT_PROVIDED_PACKAGES AND NOT
|
|
"${package_name}" IN_LIST THEROCK_IGNORE_PACKAGES)
|
|
cmake_policy(POP)
|
|
message(FATAL_ERROR "Project contains find_package(${package_name}) for a package availabe in the super-project but not declared: Add a BUILD_DEPS or RUNTIME_DEPS appropriately")
|
|
endif()
|
|
cmake_policy(POP)
|
|
message(STATUS "Resolving system find_package(${package_name}) (not found in super-project ${THEROCK_PROVIDED_PACKAGES})")
|
|
set(_therock_has_preserved_module_path FALSE)
|
|
find_package(${package_name} ${ARGN} BYPASS_PROVIDER)
|
|
if(_therock_has_preserved_module_path)
|
|
set(CMAKE_MODULE_PATH "${_therock_preserved_module_path}")
|
|
endif()
|
|
endif()
|
|
endmacro()
|
|
|
|
if(THEROCK_USE_SAFE_DEPENDENCY_PROVIDER AND THEROCK_PROVIDED_PACKAGES)
|
|
message(STATUS "Resolving packages from super-project: ${THEROCK_PROVIDED_PACKAGES}")
|
|
cmake_language(
|
|
SET_DEPENDENCY_PROVIDER therock_dependency_provider
|
|
SUPPORTED_METHODS FIND_PACKAGE
|
|
)
|
|
endif()
|
|
|
|
function(therock_reparse_super_project_find_package superproject_path package_name)
|
|
# We parse the arguments we want dropped from the find_package and then use
|
|
# what was unparsed.
|
|
cmake_parse_arguments(PARSE_ARGV 1 UNUSED
|
|
"BYPASS_PROVIDER;CONFIG;MODULE;NO_DEFAULT_PATH;NO_CMAKE_PATH;NO_CMAKE_ENVIRONMENT_PATH;NO_SYSTEM_ENVIRONMENT_PATH;NO_CMAKE_PACKAGE_REGISTRY"
|
|
""
|
|
"HINTS;PATHS"
|
|
)
|
|
if(NOT superproject_path)
|
|
message(FATAL_ERROR "Super-project package path not found for ${package_name}")
|
|
endif()
|
|
|
|
# The signature of MODULE vs DEFAULT mode is different, so switch.
|
|
set(_rewritten ${UNUSED_UNPARSED_ARGUMENTS})
|
|
# Some very old code uses explicit MODULE mode, which forces the basic
|
|
# signature (*cough* old FindHIP based junk). In this mode, there is no way
|
|
# to explicitly indicate a search path in the signature (and other options
|
|
# are illegal), so we fork on this and hard code the CMAKE_MODULE_PATH
|
|
# in the parent scope, also stashing the original and setting an indicator
|
|
# to restore it. This is not *the best* thing to be doing, but since this
|
|
# is a controlled ecosystem and used for very old things, we tolerate the
|
|
# pitfalls.
|
|
if(UNUSED_MODULE)
|
|
# Explicit find module.
|
|
list(APPEND _rewritten MODULE BYPASS_PROVIDER)
|
|
set(_therock_has_preserved_module_path TRUE PARENT_SCOPE)
|
|
set(_therock_preserved_module_path "${CMAKE_MODULE_PATH}" PARENT_SCOPE)
|
|
set(CMAKE_MODULE_PATH "${superproject_path}" PARENT_SCOPE)
|
|
else()
|
|
# By default, assume a FULL signature.
|
|
if(UNUSED_CONFIG)
|
|
list(APPEND _rewritten "CONFIG")
|
|
endif()
|
|
list(APPEND _rewritten BYPASS_PROVIDER NO_DEFAULT_PATH PATHS ${superproject_path})
|
|
endif()
|
|
|
|
list(JOIN _rewritten " " _rewritten_pretty)
|
|
message(STATUS "Resolving super-project find_package(${_rewritten_pretty})")
|
|
set(_therock_rewritten_superproject_find_package_sig ${_rewritten} PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
# Action at a distance: sanitizers need to be able to find their runtime libraries,
|
|
# so if configuring a sanitizer, we set the THEROCK_INCLUDE_CLANG_RESOURCE_DIR_RPATH
|
|
# variable during toolchain setup. Now in the sub-project, we have access to clang
|
|
# and can ask it what its resource dir is. We use this to form a proper relative
|
|
# path and append it to the default RPATH dirs.
|
|
if(THEROCK_INCLUDE_CLANG_RESOURCE_DIR_RPATH)
|
|
block(PROPAGATE THEROCK_PRIVATE_INSTALL_RPATH_DIRS THEROCK_PRIVATE_BUILD_RPATH_DIRS)
|
|
execute_process(
|
|
COMMAND "${CMAKE_CXX_COMPILER}" --print-resource-dir
|
|
OUTPUT_VARIABLE _abs_resource_dir
|
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
COMMAND_ERROR_IS_FATAL ANY
|
|
)
|
|
# This will yield an absolute path like: /some/long/path/lib/llvm/lib/clang/20
|
|
# The version number on the end is all we want as we will form the correct
|
|
# prefix relative path from that.
|
|
# The actual libraries live under lib/linux in that directory. We shamelessly
|
|
# just hardcode "linux" since that is the only system we do RPATH munging for.
|
|
cmake_path(GET _abs_resource_dir FILENAME _clang_version)
|
|
set(_prefix_resource_dir "lib/llvm/lib/clang/${_clang_version}")
|
|
list(APPEND THEROCK_PRIVATE_INSTALL_RPATH_DIRS "${_prefix_resource_dir}/lib/linux")
|
|
# Build tree needs absolute paths to the resource dir.
|
|
list(APPEND THEROCK_PRIVATE_BUILD_RPATH_DIRS "${_abs_resource_dir}/lib/linux")
|
|
message(STATUS "Added clang resource dir to RPATH: ${_prefix_resource_dir} (since sanitizer enabled)")
|
|
endblock()
|
|
endif()
|
|
|
|
# Setup THEROCK_SANITIZER_LAUNCHER.
|
|
# Used by subprojects to run build-time tools (like Python) with the ASAN runtime preloaded.
|
|
# Needed for both ASAN and HOST_ASAN modes.
|
|
block(PROPAGATE THEROCK_SANITIZER_LAUNCHER)
|
|
set(THEROCK_SANITIZER_LAUNCHER)
|
|
if(LINUX AND THEROCK_SANITIZER)
|
|
if(THEROCK_SANITIZER STREQUAL "ASAN" OR THEROCK_SANITIZER STREQUAL "HOST_ASAN")
|
|
set(_suffix "asan")
|
|
elseif(THEROCK_SANITIZER STREQUAL "TSAN" OR THEROCK_SANITIZER STREQUAL "HOST_TSAN")
|
|
set(_suffix "tsan")
|
|
else()
|
|
message(FATAL_ERROR "Unknown Sanitizer: ${THEROCK_SANITIZER}")
|
|
endif()
|
|
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "amd64")
|
|
set(_arch_suffix "x86_64")
|
|
else()
|
|
message(FATAL_ERROR "Unknown processor ${CMAKE_SYSTEM_PROCESSOR}")
|
|
endif()
|
|
execute_process(
|
|
COMMAND ${CMAKE_CXX_COMPILER} "--print-file-name=libclang_rt.${_suffix}-${_arch_suffix}.so"
|
|
OUTPUT_VARIABLE _rt_path
|
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
COMMAND_ERROR_IS_FATAL ANY
|
|
)
|
|
set(THEROCK_SANITIZER_LAUNCHER
|
|
"${CMAKE_COMMAND}" -E env "LD_PRELOAD=${_rt_path}" --
|
|
)
|
|
message(STATUS "Sanitizer launcher: ${THEROCK_SANITIZER_LAUNCHER}")
|
|
endif()
|
|
endblock()
|