Skip to content

Fix building umfd.dll on single-config generators #1238

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

Merged
merged 2 commits into from
Apr 16, 2025
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
32 changes: 27 additions & 5 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ permissions:

env:
BUILD_DIR : "${{github.workspace}}/build"
INSTALL_DIR: "${{github.workspace}}/build/install"

jobs:
fuzz-test:
Expand Down Expand Up @@ -95,14 +96,14 @@ jobs:
name: Windows ${{matrix.generator}} generator
strategy:
matrix:
os: ['windows-2019', 'windows-2022']
build_type: [Release]
build_type: [Debug, Release]
compiler: [{c: cl, cxx: cl}]
shared_library: ['ON', 'OFF']
static_hwloc: ['ON', 'OFF']
generator: ['Ninja', 'NMake Makefiles']
umfd_lib: ['ON', 'OFF']

runs-on: ${{matrix.os}}
runs-on: windows-latest

steps:
- name: Checkout
Expand All @@ -112,11 +113,11 @@ jobs:

- name: Set VCPKG_PATH with hwloc
if: matrix.static_hwloc == 'OFF'
run: echo "VCPKG_PATH='${{github.workspace}}/build/vcpkg/packages/hwloc_x64-windows;${{github.workspace}}/build/vcpkg/packages/tbb_x64-windows;${{github.workspace}}/build/vcpkg/packages/jemalloc_x64-windows'" >> $env:GITHUB_ENV
run: echo "VCPKG_PATH=${{github.workspace}}/build/vcpkg/packages/hwloc_x64-windows;${{github.workspace}}/build/vcpkg/packages/tbb_x64-windows;${{github.workspace}}/build/vcpkg/packages/jemalloc_x64-windows" >> $env:GITHUB_ENV

- name: Set VCPKG_PATH without hwloc
if: matrix.static_hwloc == 'ON'
run: echo "VCPKG_PATH='${{github.workspace}}/build/vcpkg/packages/tbb_x64-windows;${{github.workspace}}/build/vcpkg/packages/jemalloc_x64-windows'" >> $env:GITHUB_ENV
run: echo "VCPKG_PATH=${{github.workspace}}/build/vcpkg/packages/tbb_x64-windows;${{github.workspace}}/build/vcpkg/packages/jemalloc_x64-windows" >> $env:GITHUB_ENV

- name: Initialize vcpkg
uses: lukka/run-vcpkg@5e0cab206a5ea620130caf672fce3e4a6b5666a1 # v11.5
Expand All @@ -141,6 +142,7 @@ jobs:
run: >
cmake
-B ${{env.BUILD_DIR}}
-DCMAKE_BUILD_TYPE=${{matrix.build_type}}
-DCMAKE_PREFIX_PATH="${{env.VCPKG_PATH}}"
-DCMAKE_C_COMPILER=${{matrix.compiler.c}}
-DCMAKE_CXX_COMPILER=${{matrix.compiler.cxx}}
Expand All @@ -153,6 +155,7 @@ jobs:
-DUMF_BUILD_LEVEL_ZERO_PROVIDER=ON
-DUMF_BUILD_CUDA_PROVIDER=ON
-DUMF_TESTS_FAIL_ON_SKIP=ON
${{ matrix.umfd_lib == 'ON' && '-DUMF_USE_DEBUG_POSTFIX=ON' || '' }}

- name: Build UMF
shell: cmd
Expand All @@ -163,6 +166,25 @@ jobs:
working-directory: ${{env.BUILD_DIR}}
run: ctest -C ${{matrix.build_type}} --output-on-failure --test-dir test

- name: Get UMF version
run: |
$version = (git describe --tags --abbrev=0 | Select-String -Pattern '\d+\.\d+\.\d+').Matches.Value
echo "UMF_VERSION=$version" >> $env:GITHUB_ENV
shell: pwsh

- name: Test UMF installation and uninstallation
# The '--shared-library' parameter is added to the installation test when the UMF is built as a shared library
# The '--umfd-lib' parameter is added when the UMF is built with the umfd library
run: >
python3 ${{github.workspace}}/test/test_installation.py
--build-dir ${{env.BUILD_DIR}}
--install-dir ${{env.INSTALL_DIR}}
--build-type ${{matrix.build_type}}
--umf-version ${{env.UMF_VERSION}}
${{ matrix.shared_library == 'ON' && '--proxy --shared-library' || '' }}
${{ matrix.umfd_lib == 'ON' && '--umfd-lib' || ''}}
${{ matrix.static_hwloc == 'ON' && '--hwloc' || '' }}

icx:
name: ICX
env:
Expand Down
98 changes: 78 additions & 20 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ macro(umf_option)
option(${ARGV})
endmacro()

# All CMake options have to be explicitly set in the build_umfd target's
# configuration command
umf_option(UMF_BUILD_SHARED_LIBRARY "Build UMF as shared library" OFF)
umf_option(UMF_BUILD_LEVEL_ZERO_PROVIDER "Build Level Zero memory provider" ON)
umf_option(UMF_BUILD_CUDA_PROVIDER "Build CUDA memory provider" ON)
Expand Down Expand Up @@ -148,6 +150,8 @@ if(UMF_DEVELOPER_MODE)
UMF_DEVELOPER_MODE=1)
endif()

message(STATUS "CMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}")

if(NOT UMF_BUILD_LIBUMF_POOL_JEMALLOC)
set(UMF_POOL_JEMALLOC_ENABLED FALSE)
set(JEMALLOC_FOUND FALSE)
Expand Down Expand Up @@ -285,6 +289,7 @@ else()
set(HWLOC_ENABLE_TESTING OFF)
set(HWLOC_SKIP_LSTOPO ON)
set(HWLOC_SKIP_TOOLS ON)
set(HWLOC_SKIP_INCLUDES ON)

FetchContent_Declare(
hwloc_targ
Expand Down Expand Up @@ -428,25 +433,72 @@ elseif(UMF_BUILD_CUDA_PROVIDER)
message(STATUS "CUDA_INCLUDE_DIRS = ${CUDA_INCLUDE_DIRS}")
endif()

# Build the umfd target in a separate directory with Debug configuration
if(WINDOWS AND UMF_USE_DEBUG_POSTFIX)
# Build debug umf library with the d suffix that is compiled with /MDd so
# users can link against it in debug builds.
set(CMAKE_DEBUG_POSTFIX d)

# The build_umfd target's configuration command requires to have
# CMAKE_PREFIX_PATH with semicolons escaped
string(JOIN "\;" UMFD_CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH})
add_custom_target(
umfd ALL
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target umf
--config Debug
COMMENT "Building debug umf library with the d suffix")
build_umfd ALL
COMMAND
${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" -S ${UMF_CMAKE_SOURCE_DIR}
-B ${CMAKE_BINARY_DIR}/umfd_build -DCMAKE_BUILD_TYPE=Debug
-DCMAKE_DEBUG_POSTFIX=d
-DCMAKE_PREFIX_PATH="${UMFD_CMAKE_PREFIX_PATH}"
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DUMF_USE_DEBUG_POSTFIX=OFF
-DUMF_BUILD_SHARED_LIBRARY=${UMF_BUILD_SHARED_LIBRARY}
-DUMF_BUILD_LEVEL_ZERO_PROVIDER=${UMF_BUILD_LEVEL_ZERO_PROVIDER}
-DUMF_BUILD_CUDA_PROVIDER=${UMF_BUILD_CUDA_PROVIDER}
-DUMF_BUILD_LIBUMF_POOL_JEMALLOC=${UMF_BUILD_LIBUMF_POOL_JEMALLOC}
-DUMF_BUILD_TESTS=OFF -DUMF_BUILD_GPU_TESTS=OFF
-DUMF_BUILD_BENCHMARKS=OFF -DUMF_BUILD_BENCHMARKS_MT=OFF
-DUMF_BUILD_EXAMPLES=OFF -DUMF_BUILD_GPU_EXAMPLES=OFF
-DUMF_BUILD_FUZZTESTS=OFF -DUMF_DISABLE_HWLOC=${UMF_DISABLE_HWLOC}
-DUMF_LINK_HWLOC_STATICALLY=${UMF_LINK_HWLOC_STATICALLY}
-DUMF_HWLOC_NAME=${UMF_HWLOC_NAME}
-DUMF_INSTALL_RPATH=${UMF_INSTALL_RPATH} -DUMF_DEVELOPER_MODE=OFF
-DUMF_FORMAT_CODE_STYLE=OFF -DUMF_TESTS_FAIL_ON_SKIP=OFF
-DUMF_USE_ASAN=OFF -DUMF_USE_UBSAN=OFF -DUMF_USE_TSAN=OFF
-DUMF_USE_MSAN=OFF -DUMF_USE_VALGRIND=OFF -DUMF_USE_COVERAGE=OFF
-DUMF_PROXY_LIB_BASED_ON_POOL=${UMF_PROXY_LIB_BASED_ON_POOL}
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}/umfd_build --target
umf --config Debug
COMMENT
"Configuring and building umfd.dll in a separate directory with Debug configuration"
)

# Copy built UMF libraries to the Release build subdirectory
# Copy built UMF libraries to the main binary directory and remove
# umfd_build
if(CMAKE_CONFIGURATION_TYPES)
# Multi-config generator (e.g., Visual Studio)
set(UMFD_DLL_SRC "${CMAKE_BINARY_DIR}/umfd_build/bin/Debug/umfd.dll")
set(UMFD_LIB_SRC "${CMAKE_BINARY_DIR}/umfd_build/lib/Debug/umfd.lib")
set(UMFD_DLL "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/umfd.dll")
set(UMFD_LIB "${CMAKE_BINARY_DIR}/lib/$<CONFIG>/umfd.lib")
else()
# Single-config generator (e.g., Ninja)
set(UMFD_DLL_SRC "${CMAKE_BINARY_DIR}/umfd_build/bin/umfd.dll")
set(UMFD_LIB_SRC "${CMAKE_BINARY_DIR}/umfd_build/lib/umfd.lib")
set(UMFD_DLL "${CMAKE_BINARY_DIR}/bin/umfd.dll")
set(UMFD_LIB "${CMAKE_BINARY_DIR}/lib/umfd.lib")
endif()

if(UMF_BUILD_SHARED_LIBRARY)
add_custom_command(
TARGET build_umfd
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${UMFD_DLL_SRC}
${UMFD_DLL}
COMMENT "Copying umfd.dll to the main binary directory")
endif()
add_custom_command(
TARGET umfd
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/bin/Debug/umfd.dll
${CMAKE_BINARY_DIR}/bin/Release/umfd.dll
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/lib/Debug/umfd.lib
${CMAKE_BINARY_DIR}/lib/Release/umfd.lib
COMMENT "Copying debug libraries to the Release build directory")
TARGET build_umfd
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${UMFD_LIB_SRC}
${UMFD_LIB}
COMMAND ${CMAKE_COMMAND} -E remove_directory
${CMAKE_BINARY_DIR}/umfd_build DEPENDS ${UMFD_DLL}
COMMENT "Copying umfd.lib to the main library directory")
endif()

# This build type check is not possible on Windows when CMAKE_BUILD_TYPE is not
Expand Down Expand Up @@ -841,12 +893,18 @@ endif()
# --------------------------------------------------------------------------- #
# Configure make install/uninstall and packages
# --------------------------------------------------------------------------- #
# Install umfd target
# Install the umfd library files as part of the umfd component
if(WINDOWS AND UMF_USE_DEBUG_POSTFIX)
install(FILES ${CMAKE_BINARY_DIR}/bin/Debug/umfd.dll
DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES ${CMAKE_BINARY_DIR}/lib/Debug/umfd.lib
DESTINATION ${CMAKE_INSTALL_LIBDIR})
if(UMF_BUILD_SHARED_LIBRARY)
install(
FILES ${UMFD_DLL}
DESTINATION ${CMAKE_INSTALL_BINDIR}
COMPONENT umfd)
endif()
install(
FILES ${UMFD_LIB}
DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT umfd)
endif()

install(FILES ${PROJECT_SOURCE_DIR}/LICENSE.TXT
Expand Down
21 changes: 16 additions & 5 deletions test/test_installation.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ class UmfInstaller:
proxy (bool): Determines whether the proxy library should be built together with the UMF library
pools (List[str]): A list of enabled pools during the UMF compilation
umf_version (Version): UMF version currently being built and installed
match_list (List[str]): A list of relative paths of files that should be installed
umfd_lib (bool): Determines if the UMF was built with the umfd library
hwloc (bool): Determines if hwloc is installed and should be checked
"""

def __init__(
Expand All @@ -42,6 +43,7 @@ def __init__(
pools: List[str],
umf_version: Version,
umfd_lib: bool,
hwloc: bool,
):
self.workspace_dir = workspace_dir
self.build_dir = build_dir
Expand All @@ -52,6 +54,7 @@ def __init__(
self.pools = pools
self.umf_version = umf_version
self.umfd_lib = umfd_lib
self.hwloc = hwloc
self.match_list = self._create_match_list()

def _create_match_list(self) -> List[str]:
Expand All @@ -76,9 +79,7 @@ def _create_match_list(self) -> List[str]:
lib_prefix = "lib"

bin = []
if platform.system() == "Windows" and (
self.shared_library or self.proxy or self.umfd_lib
):
if platform.system() == "Windows" and (self.shared_library or self.proxy):
bin.append("bin")
if self.shared_library:
bin.append("bin/umf.dll")
Expand All @@ -103,8 +104,11 @@ def _create_match_list(self) -> List[str]:
f"lib/cmake/umf/umf-targets-{self.build_type}.cmake",
"lib/cmake/umf/umf-targets.cmake",
]

for pool in self.pools:
lib.append(f"lib/{lib_prefix}{pool}.{lib_ext_static}")
if platform.system() == "Windows" and self.hwloc:
lib.append(f"lib/{lib_prefix}hwloc.{lib_ext_static}")
if self.shared_library:
lib.append(f"lib/{lib_prefix}umf.{lib_ext_shared}")
if platform.system() == "Windows" and self.umfd_lib:
Expand All @@ -122,6 +126,8 @@ def _create_match_list(self) -> List[str]:
lib.append(f"lib/{lib_prefix}umf.{self.umf_version}.{lib_ext_shared}")
else:
lib.append(f"lib/{lib_prefix}umf.{lib_ext_static}")
if self.umfd_lib and platform.system() == "Windows":
lib.append(f"lib/{lib_prefix}umfd.{lib_ext_static}")

if self.proxy:
lib.append(f"lib/{lib_prefix}umf_proxy.{lib_ext_shared}")
Expand All @@ -135,7 +141,6 @@ def _create_match_list(self) -> List[str]:
f"lib/{lib_prefix}umf_proxy.{self.umf_version.major}.{lib_ext_shared}"
)

share = []
share = [
"share",
"share/doc",
Expand Down Expand Up @@ -296,6 +301,11 @@ def parse_arguments(self) -> argparse.Namespace:
action="store_true",
help="Add this argument if the UMF was built with the umfd library",
)
self.parser.add_argument(
"--hwloc",
action="store_true",
help="Add this argument if hwloc is installed and should be checked",
)
return self.parser.parse_args()

def run(self) -> None:
Expand All @@ -320,6 +330,7 @@ def run(self) -> None:
pools,
umf_version,
self.args.umfd_lib,
self.args.hwloc,
)

print("Installation test - BEGIN", flush=True)
Expand Down
Loading