Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
3 changes: 2 additions & 1 deletion .github/docker/ubuntu.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ apt-get install -y \
libc6:arm64 \
libstdc++6:arm64 \
git \
ninja-build
ninja-build \
python3
rm -rf /var/lib/apt/lists/*
EOF
16 changes: 8 additions & 8 deletions .github/workflows/check-abi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ jobs:
run: |
mkdir base/build
cd base/build
cmake -E env CXXFLAGS="-Og -g" cmake -DCMAKE_BUILD_TYPE=Debug ..
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="-Og -g -fno-lto" -DCMAKE_EXE_LINKER_FLAGS="-fno-lto" -DCMAKE_SHARED_LINKER_FLAGS="-fno-lto" ..
make -j$(nproc)
- name: Build debug head
run: |
mkdir head/build
cd head/build
cmake -E env CXXFLAGS="-Og -g" cmake -DCMAKE_BUILD_TYPE=Debug ..
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="-Og -g -fno-lto" -DCMAKE_EXE_LINKER_FLAGS="-fno-lto" -DCMAKE_SHARED_LINKER_FLAGS="-fno-lto" ..
make -j$(nproc)
- name: Download and setup abi-dumper
run: |
Expand All @@ -56,14 +56,14 @@ jobs:
run: |
./abi-dumper.pl \
./base/build/lib/libze_loader.so \
-lver $(cat ./base/build/VERSION) \
-vnum $(cat ./base/build/VERSION) -lambda \
-public-headers ./base/include \
-o ./base.dump
- name: Generate dump for head
run: |
./abi-dumper.pl \
./head/build/lib/libze_loader.so \
-lver $(cat ./head/build/VERSION)-1 \
-vnum $(cat ./head/build/VERSION)-1 -lambda \
-public-headers ./head/include \
-o ./head.dump
- name: Download and setup abi-compliance-checker
Expand Down Expand Up @@ -107,13 +107,13 @@ jobs:
run: |
mkdir base/build
cd base/build
cmake -E env CXXFLAGS="-Og -g" cmake -DCMAKE_BUILD_TYPE=Debug ..
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="-Og -g -fno-lto" -DCMAKE_EXE_LINKER_FLAGS="-fno-lto" -DCMAKE_SHARED_LINKER_FLAGS="-fno-lto" ..
make -j$(nproc)
- name: Build debug head
run: |
mkdir head/build
cd head/build
cmake -E env CXXFLAGS="-Og -g" cmake -DCMAKE_BUILD_TYPE=Debug ..
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="-Og -g -fno-lto" -DCMAKE_EXE_LINKER_FLAGS="-fno-lto" -DCMAKE_SHARED_LINKER_FLAGS="-fno-lto" ..
make -j$(nproc)
- name: Download and setup abi-dumper
run: |
Expand All @@ -124,14 +124,14 @@ jobs:
run: |
./abi-dumper.pl \
./base/build/lib/libze_loader.so \
-lver $(cat ./base/build/VERSION) \
-vnum $(cat ./base/build/VERSION) -lambda \
-public-headers ./base/include \
-o ./base.dump
- name: Generate dump for head
run: |
./abi-dumper.pl \
./head/build/lib/libze_loader.so \
-lver $(cat ./head/build/VERSION)-1 \
-vnum $(cat ./head/build/VERSION)-1 -lambda \
-public-headers ./head/include \
-o ./head.dump
- name: Download and setup abi-compliance-checker
Expand Down
66 changes: 53 additions & 13 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (C) 2020-2025 Intel Corporation
# Copyright (C) 2020-2026 Intel Corporation
# SPDX-License-Identifier: MIT

cmake_minimum_required(VERSION 3.12.0 FATAL_ERROR)
Expand Down Expand Up @@ -38,17 +38,6 @@ else()
endif()
add_definitions(-DLOADER_VERSION_SHA="${VERSION_SHA}")

if(SYSTEM_SPDLOG)
find_package(spdlog CONFIG)
if(spdlog_FOUND)
message(STATUS "System spdlog found.")
else()
message(FATAL_ERROR "SYSTEM_SPDLOG specified but spdlog wasn't found.")
endif()
else()
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/third_party/spdlog_headers")
endif()

include(FetchContent)

if(BUILD_L0_LOADER_TESTS)
Expand Down Expand Up @@ -222,6 +211,12 @@ include_directories("${CMAKE_CURRENT_SOURCE_DIR}")

set(TARGET_LOADER_NAME ze_loader)

# Canonical Ubuntu/Debian package names (libze1 / libze-dev)
# produced alongside the existing level-zero / level-zero-devel packages.
if(NOT BUILD_INSTALLER)
set(CANONICAL_LIB_COMPONENT "libze1")
set(CANONICAL_SDK_COMPONENT "libze-dev")
endif()

add_subdirectory(source)
add_subdirectory(samples)
Expand Down Expand Up @@ -265,6 +260,29 @@ install(FILES ${LEVEL_ZERO_LOADER_API_HEADERS}
COMPONENT ${SDK_COMPONENT_STRING}
)

# Canonical Ubuntu/Debian package naming (libze1 / libze-dev) mirrors Canonical's own packaging.
# EXCLUDE_FROM_ALL prevents these rules from running during 'make install' — the same files are
# already installed by the level-zero / level-zero-devel components above. CPack ignores
# EXCLUDE_FROM_ALL when building component packages, so 'cmake --build . --target package'
# still produces all four .deb files without duplicating entries in install_manifest.txt.
if(CANONICAL_SDK_COMPONENT)
install(FILES ${LEVEL_ZERO_API_HEADERS}
DESTINATION ./include/level_zero
COMPONENT ${CANONICAL_SDK_COMPONENT}
EXCLUDE_FROM_ALL
)
install(FILES ${LEVEL_ZERO_LAYERS_API_HEADERS}
DESTINATION ./include/level_zero/layers
COMPONENT ${CANONICAL_SDK_COMPONENT}
EXCLUDE_FROM_ALL
)
install(FILES ${LEVEL_ZERO_LOADER_API_HEADERS}
DESTINATION ./include/level_zero/loader
COMPONENT ${CANONICAL_SDK_COMPONENT}
EXCLUDE_FROM_ALL
)
endif()

if (MSVC)
set (PYTHON_EXECUTABLE "python")
else()
Expand Down Expand Up @@ -357,7 +375,7 @@ set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "oneAPI Level Zero")
set(CPACK_PACKAGE_VENDOR "Intel Corporation")

set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CMAKE_INSTALL_PREFIX})
set(CPACK_PACKAGE_CONTACT "Intel Corporation")
set(CPACK_PACKAGE_CONTACT "Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>")

set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
Expand Down Expand Up @@ -409,6 +427,28 @@ if(CPACK_GENERATOR MATCHES "DEB")
set(CPACK_DEBIAN_LEVEL-ZERO_FILE_NAME "${PROJECT_NAME}_${PROJECT_VERSION}+${os_name}${os_version}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}.deb")
set(CPACK_DEBIAN_LEVEL-ZERO-DEVEL_FILE_NAME "${PROJECT_NAME}-devel_${PROJECT_VERSION}+${os_name}${os_version}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}.deb")
set(CPACK_DEBIAN_LEVEL-ZERO-DEVEL_PACKAGE_DEPENDS "level-zero(=${PROJECT_VERSION})")
# Mutual exclusion with the canonical libze1 / libze-dev packages
set(CPACK_DEBIAN_LEVEL-ZERO_PACKAGE_CONFLICTS "libze1")
set(CPACK_DEBIAN_LEVEL-ZERO_PACKAGE_PROVIDES "libze1")
set(CPACK_DEBIAN_LEVEL-ZERO_PACKAGE_REPLACES "libze1")
set(CPACK_DEBIAN_LEVEL-ZERO-DEVEL_PACKAGE_CONFLICTS "libze-dev")
set(CPACK_DEBIAN_LEVEL-ZERO-DEVEL_PACKAGE_PROVIDES "libze-dev")
set(CPACK_DEBIAN_LEVEL-ZERO-DEVEL_PACKAGE_REPLACES "libze-dev")

# Canonical Ubuntu naming: libze1 (runtime) and libze-dev (development)
set(CPACK_DEBIAN_LIBZE1_PACKAGE_NAME "libze1")
set(CPACK_DEBIAN_LIBZE-DEV_PACKAGE_NAME "libze-dev")
set(CPACK_DEBIAN_LIBZE1_FILE_NAME "libze1_${PROJECT_VERSION}+${os_name}${os_version}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}.deb")
set(CPACK_DEBIAN_LIBZE-DEV_FILE_NAME "libze-dev_${PROJECT_VERSION}+${os_name}${os_version}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}.deb")
set(CPACK_DEBIAN_LIBZE-DEV_PACKAGE_DEPENDS "libze1 (= ${PROJECT_VERSION})")
# Mutual exclusion with the level-zero / level-zero-devel packages
set(CPACK_DEBIAN_LIBZE1_PACKAGE_CONFLICTS "level-zero")
set(CPACK_DEBIAN_LIBZE1_PACKAGE_PROVIDES "level-zero")
set(CPACK_DEBIAN_LIBZE1_PACKAGE_REPLACES "level-zero")
set(CPACK_DEBIAN_LIBZE-DEV_PACKAGE_CONFLICTS "level-zero-devel")
set(CPACK_DEBIAN_LIBZE-DEV_PACKAGE_PROVIDES "level-zero-devel")
set(CPACK_DEBIAN_LIBZE-DEV_PACKAGE_REPLACES "level-zero-devel")

set(CPACK_DEB_COMPONENT_INSTALL ON)
set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
endif()
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (C) 2019-2021 Intel Corporation
Copyright (C) 2019-2026 Intel Corporation

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
2 changes: 1 addition & 1 deletion PRODUCT_GUID.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
1.28.4
Comment thread
rwmcguir marked this conversation as resolved.
cfa0eed1-ba15-4a52-8efe-5d532373fded
cfa0eed1-ba15-4a52-8efe-5d532373fded
67 changes: 46 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,39 +46,62 @@ When the `-DBUILD_STATIC=1` is executed, the dynamic loader and layers are not b
Testing with the static loader requires a build of the dynamic loader or an installation of the dynamic loader to exist in the library path.

# Debug Trace

> **Deprecated:** `ZE_ENABLE_LOADER_DEBUG_TRACE` is deprecated and will be removed in a future release.
> Use `ZEL_LOADER_LOG_CONSOLE=1` with `ZEL_LOADER_LOGGING_LEVEL=trace` instead, which provides
> the same or enhanced information with structured timestamps, thread IDs, and log levels via the logging system.

The Level Zero Loader has the ability to print warnings and errors which occur within the internals of the Level Zero Loader itself.

To enable this debug tracing feature, set the environment variable `ZE_ENABLE_LOADER_DEBUG_TRACE=1`.

This will enforce the Loader to print all errors whether fatal or non-fatal to stderr with the PREFIX `ZE_LOADER_DEBUG_TRACE:`.


# Logging to File - PREVIEW
The Level Zero Loader uses spdlog logging and can be controlled via environment variables:
# Logging to File or Console
The Level Zero Loader provides built-in logging controlled via environment variables:

`ZEL_ENABLE_LOADER_LOGGING=1`
| Environment Variable | Default | Description |
|---|---|---|
| `ZEL_ENABLE_LOADER_LOGGING` | `0` | Set to `1` to enable file logging |
| `ZEL_LOADER_LOG_CONSOLE` | `0` | Set to `1` to enable console (stderr) logging, overrides file logging |
| `ZEL_LOADER_LOGGING_LEVEL` | `warn` | Log level: `trace`, `debug`, `info`, `warn`, `error`, `critical`, `off` |
| `ZEL_LOADER_LOG_DIR` | `~/.oneapi_logs` | Directory to write the log file into |
| `ZEL_LOADER_LOG_FILE` | `ze_loader.log` | Log filename |
| `ZEL_LOADER_LOG_PATTERN` | see below | Custom log format pattern |

## Output destination

`ZEL_LOADER_LOG_DIR='/directory/path'`
The two flags control output as follows:

`ZEL_LOADER_LOGGING_LEVEL=debug`
| `ZEL_ENABLE_LOADER_LOGGING` | `ZEL_LOADER_LOG_CONSOLE` | Output |
|---|---|---|
| `0` (default) | `0` (default) | Logging disabled — no file or console output |
| `0` | `1` | Console output to **stderr** at the configured level |
| `1` | `0` | File output to `ZEL_LOADER_LOG_DIR/ZEL_LOADER_LOG_FILE` |
| `1` | `1` | Console output to **stderr** — file path is ignored |

Default Log Pattern (Does not need to be set, please see below):
`ZEL_LOADER_LOG_PATTERN='[%Y-%m-%d %H:%M:%S.%e] [thread-id: %t] [%^%l%$] %v'`
> **Note:** When both `ZEL_ENABLE_LOADER_LOGGING=1` and `ZEL_LOADER_LOG_CONSOLE=1` are set,
> output goes to the console only. The file path configuration is not used. If persistent file
> capture is required, set `ZEL_LOADER_LOG_CONSOLE=0`.

Valid logging levels are trace, debug, info, warn, error, critical, off.
Logging is disabled by default but when enabled the default level is 'warn'.
The default log file is 'ze_loader.log' in '.oneapi_logs' in the current
user's home directory.
The log directory (`ZEL_LOADER_LOG_DIR`) is created automatically on first use if it does not exist.

The default log pattern includes timestamps, thread IDs, log levels, and messages.
You can customize the pattern using `ZEL_LOADER_LOG_PATTERN`. Common pattern flags:
- `%t` - thread id
- `%Y-%m-%d %H:%M:%S.%e` - timestamp with milliseconds
- `%l` - log level
- `%v` - the actual log message
See spdlog documentation for more pattern options.
## Log pattern

Default pattern (used when `ZEL_LOADER_LOG_PATTERN` is not set):
```
[%Y-%m-%d %H:%M:%S.%e] [thread-id: %t] [%^%l%$] %v
```

This feature is in early development and is preview only.
Supported pattern tokens:
- `%Y-%m-%d %H:%M:%S.%e` — timestamp with milliseconds (must appear as this exact sequence)
- `%t` — thread id
- `%P` — process id
- `%l` — log level label
- `%^` — begin color range (no-op when output is not a TTY)
- `%$` — end color range
- `%v` — log message

# Logging API calls
The Level Zero Loader will log all API calls whenever logging level is set to `trace` and
Expand All @@ -95,8 +118,10 @@ To print successful API call results, set
Otherwise, only error results will be printed in the API trace output.
NOTE: This will become the default behavior in future releases. for now, please set the env var to enable this logging feature.

By default logs will be written to the log file, as described above. To print the logs
to stderr instead, `ZEL_LOADER_LOG_CONSOLE=1` needs to be set.
By default logs will be written to the log file as described above. To print logs
to stderr instead of a file, set `ZEL_LOADER_LOG_CONSOLE=1`. Note that when
`ZEL_LOADER_LOG_CONSOLE=1`, the file path configuration is ignored — output goes
to the console only.

The API logging output format includes both function entry and exit information, showing parameter names on entry and parameter values with the result code on exit. Each log entry is timestamped and includes the thread-id, logger name, log level. Example output:

Expand Down
5 changes: 2 additions & 3 deletions scripts/templates/ze_loader_internal.h.mako
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ from templates import helper as th
#include "zer_ldrddi.h"

#include "loader/ze_loader.h"
#include "../utils/logging.h"
#include "spdlog/spdlog.h"
#include "../utils/ze_logger.h"
#include "source/lib/error_state.h"
namespace loader
{
Expand Down Expand Up @@ -139,7 +138,7 @@ namespace loader
bool instrumentationEnabled = false;
bool pciOrderingRequested = false;
dditable_t tracing_dditable = {};
std::shared_ptr<Logger> zel_logger;
std::shared_ptr<ZeLogger> zel_logger;
ze_driver_handle_t defaultZerDriverHandle = nullptr;
};

Expand Down
21 changes: 21 additions & 0 deletions source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,19 @@ install(TARGETS ze_loader
NAMELINK_COMPONENT ${SDK_COMPONENT_STRING}
)

# EXCLUDE_FROM_ALL: canonical libze1/libze-dev components are for CPack .deb packaging only.
# 'make install' uses the level-zero/level-zero-devel components above to avoid duplicate
# entries in install_manifest.txt which would cause 'xargs rm' uninstall to fail.
if(CANONICAL_LIB_COMPONENT)
install(TARGETS ze_loader
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${CANONICAL_SDK_COMPONENT}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${CANONICAL_LIB_COMPONENT}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${CANONICAL_LIB_COMPONENT}
NAMELINK_COMPONENT ${CANONICAL_SDK_COMPONENT}
EXCLUDE_FROM_ALL
)
endif()

if(NOT BUILD_INSTALLER)
file(RELATIVE_PATH pkgconfig_prefix "${CMAKE_INSTALL_FULL_LIBDIR}/pkgconfig" "${CMAKE_INSTALL_PREFIX}")
file(RELATIVE_PATH pkgconfig_include_dir "${CMAKE_INSTALL_PREFIX}" "${CMAKE_INSTALL_FULL_INCLUDEDIR}")
Expand All @@ -85,4 +98,12 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/level-zero.pc.in ${CMAKE_CURRENT_BINA
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libze_loader.pc"
"${CMAKE_CURRENT_BINARY_DIR}/level-zero.pc"
DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/pkgconfig" COMPONENT ${SDK_COMPONENT_STRING})

if(CANONICAL_SDK_COMPONENT)
# EXCLUDE_FROM_ALL: CPack-only; avoids duplicate install_manifest.txt entries.
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libze_loader.pc"
"${CMAKE_CURRENT_BINARY_DIR}/level-zero.pc"
DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/pkgconfig" COMPONENT ${CANONICAL_SDK_COMPONENT}
EXCLUDE_FROM_ALL)
endif()
endif()
12 changes: 12 additions & 0 deletions source/drivers/null/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,18 @@ if(INSTALL_NULL_DRIVER)
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT level-zero
NAMELINK_COMPONENT level-zero-devel
)
# EXCLUDE_FROM_ALL: canonical libze1/libze-dev components are for CPack .deb packaging only.
# 'make install' uses the level-zero/level-zero-devel components above to avoid duplicate
# entries in install_manifest.txt which would cause 'xargs rm' uninstall to fail.
if(CANONICAL_LIB_COMPONENT)
install(TARGETS ze_null
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${CANONICAL_SDK_COMPONENT}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${CANONICAL_LIB_COMPONENT}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${CANONICAL_LIB_COMPONENT}
NAMELINK_COMPONENT ${CANONICAL_SDK_COMPONENT}
EXCLUDE_FROM_ALL
)
endif()
endif()

if (BUILD_L0_LOADER_TESTS)
Expand Down
13 changes: 13 additions & 0 deletions source/layers/tracing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,16 @@ install(TARGETS ze_tracing_layer
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${LIB_COMPONENT_STRING}
NAMELINK_COMPONENT ${SDK_COMPONENT_STRING}
)

# EXCLUDE_FROM_ALL: canonical libze1/libze-dev components are for CPack .deb packaging only.
# 'make install' uses the level-zero/level-zero-devel components above to avoid duplicate
# entries in install_manifest.txt which would cause 'xargs rm' uninstall to fail.
if(CANONICAL_LIB_COMPONENT)
install(TARGETS ze_tracing_layer
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${CANONICAL_SDK_COMPONENT}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${CANONICAL_LIB_COMPONENT}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${CANONICAL_LIB_COMPONENT}
NAMELINK_COMPONENT ${CANONICAL_SDK_COMPONENT}
EXCLUDE_FROM_ALL
)
endif()
13 changes: 13 additions & 0 deletions source/layers/validation/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,18 @@ install(TARGETS ze_validation_layer
NAMELINK_COMPONENT ${SDK_COMPONENT_STRING}
)

# EXCLUDE_FROM_ALL: canonical libze1/libze-dev components are for CPack .deb packaging only.
# 'make install' uses the level-zero/level-zero-devel components above to avoid duplicate
# entries in install_manifest.txt which would cause 'xargs rm' uninstall to fail.
if(CANONICAL_LIB_COMPONENT)
install(TARGETS ze_validation_layer
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${CANONICAL_SDK_COMPONENT}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${CANONICAL_LIB_COMPONENT}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${CANONICAL_LIB_COMPONENT}
NAMELINK_COMPONENT ${CANONICAL_SDK_COMPONENT}
EXCLUDE_FROM_ALL
)
endif()

add_subdirectory(handle_lifetime_tracking)
add_subdirectory(checkers)
Loading
Loading