pyyggdrasil 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,92 @@
1
+ name: CI Release
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ - dev
8
+ pull_request:
9
+ workflow_dispatch:
10
+
11
+ jobs:
12
+ build_sdist:
13
+ runs-on: ubuntu-latest
14
+
15
+ steps:
16
+ - name: Checkout repository
17
+ uses: actions/checkout@v6
18
+
19
+ - name: Set up Python
20
+ uses: actions/setup-python@v6
21
+ with:
22
+ python-version: "3.13"
23
+
24
+ - name: Install build frontend
25
+ run: |
26
+ python -m pip install --upgrade pip
27
+ python -m pip install build
28
+
29
+ - name: Build source distribution
30
+ run: python -m build --sdist
31
+
32
+ build_wheels_linux:
33
+ runs-on: ubuntu-latest
34
+ strategy:
35
+ fail-fast: false
36
+ matrix:
37
+ architecture: ["x86_64"]
38
+ python-version: ["cp39", "cp310", "cp311", "cp312", "cp313"]
39
+
40
+ steps:
41
+ - name: Checkout repository
42
+ uses: actions/checkout@v6
43
+
44
+ - name: Set up Python
45
+ uses: actions/setup-python@v6
46
+ with:
47
+ python-version: "3.13"
48
+
49
+ - name: Install cibuildwheel
50
+ run: |
51
+ python -m pip install --upgrade pip
52
+ python -m pip install cibuildwheel
53
+
54
+ - name: Build Linux wheels
55
+ run: cibuildwheel --output-dir wheelhouse
56
+ env:
57
+ CIBW_PLATFORM: linux
58
+ CIBW_BUILD: "${{ matrix.python-version }}-*"
59
+ CIBW_SKIP: "*-musllinux_*"
60
+ CIBW_ARCHS: "${{ matrix.architecture }}"
61
+ CIBW_BUILD_VERBOSITY: "1"
62
+ CIBW_ENVIRONMENT: "YGGDRASIL_JOBS=2"
63
+
64
+ build_wheels_macos:
65
+ runs-on: macos-latest
66
+ strategy:
67
+ fail-fast: false
68
+ matrix:
69
+ python-version: ["cp39", "cp310", "cp311", "cp312", "cp313"]
70
+
71
+ steps:
72
+ - name: Checkout repository
73
+ uses: actions/checkout@v6
74
+
75
+ - name: Set up Python
76
+ uses: actions/setup-python@v6
77
+ with:
78
+ python-version: "3.13"
79
+
80
+ - name: Install cibuildwheel
81
+ run: |
82
+ python -m pip install --upgrade pip
83
+ python -m pip install cibuildwheel
84
+
85
+ - name: Build macOS wheels
86
+ run: cibuildwheel --output-dir wheelhouse
87
+ env:
88
+ CIBW_PLATFORM: macos
89
+ CIBW_BUILD: "${{ matrix.python-version }}-*"
90
+ CIBW_ARCHS: arm64
91
+ CIBW_BUILD_VERBOSITY: "1"
92
+ CIBW_ENVIRONMENT: "YGGDRASIL_JOBS=2"
@@ -0,0 +1,150 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ build_sdist:
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - name: Checkout repository
14
+ uses: actions/checkout@v6
15
+
16
+ - name: Set up Python
17
+ uses: actions/setup-python@v6
18
+ with:
19
+ python-version: "3.13"
20
+
21
+ - name: Install build frontend
22
+ run: |
23
+ python -m pip install --upgrade pip
24
+ python -m pip install build
25
+
26
+ - name: Build source distribution
27
+ run: python -m build --sdist
28
+
29
+ - name: Upload sdist artifact
30
+ uses: actions/upload-artifact@v5
31
+ with:
32
+ name: sdist
33
+ path: dist/*.tar.gz
34
+
35
+ build_wheels_linux:
36
+ runs-on: ubuntu-latest
37
+ strategy:
38
+ fail-fast: false
39
+ matrix:
40
+ architecture: ["x86_64"]
41
+ python-version: ["cp39", "cp310", "cp311", "cp312", "cp313"]
42
+
43
+ steps:
44
+ - name: Checkout repository
45
+ uses: actions/checkout@v6
46
+
47
+ - name: Set up Python
48
+ uses: actions/setup-python@v6
49
+ with:
50
+ python-version: "3.13"
51
+
52
+ - name: Install cibuildwheel
53
+ run: |
54
+ python -m pip install --upgrade pip
55
+ python -m pip install cibuildwheel
56
+
57
+ - name: Build Linux wheels
58
+ run: cibuildwheel --output-dir wheelhouse
59
+ env:
60
+ CIBW_PLATFORM: linux
61
+ CIBW_BUILD: "${{ matrix.python-version }}-*"
62
+ CIBW_SKIP: "*-musllinux_*"
63
+ CIBW_ARCHS: "${{ matrix.architecture }}"
64
+ CIBW_BUILD_VERBOSITY: "1"
65
+ CIBW_ENVIRONMENT: "YGGDRASIL_JOBS=2"
66
+
67
+ - name: Upload Linux wheels artifact
68
+ uses: actions/upload-artifact@v5
69
+ with:
70
+ name: wheels-linux-${{ matrix.python-version }}-${{ matrix.architecture }}
71
+ path: wheelhouse/*.whl
72
+
73
+ build_wheels_macos:
74
+ runs-on: macos-latest
75
+ strategy:
76
+ fail-fast: false
77
+ matrix:
78
+ python-version: ["cp39", "cp310", "cp311", "cp312", "cp313"]
79
+
80
+ steps:
81
+ - name: Checkout repository
82
+ uses: actions/checkout@v6
83
+
84
+ - name: Set up Python
85
+ uses: actions/setup-python@v6
86
+ with:
87
+ python-version: "3.13"
88
+
89
+ - name: Install cibuildwheel
90
+ run: |
91
+ python -m pip install --upgrade pip
92
+ python -m pip install cibuildwheel
93
+
94
+ - name: Build macOS wheels
95
+ run: cibuildwheel --output-dir wheelhouse
96
+ env:
97
+ CIBW_PLATFORM: macos
98
+ CIBW_BUILD: "${{ matrix.python-version }}-*"
99
+ CIBW_ARCHS: arm64
100
+ CIBW_BUILD_VERBOSITY: "1"
101
+ CIBW_ENVIRONMENT: "YGGDRASIL_JOBS=2"
102
+
103
+ - name: Upload macOS wheels artifact
104
+ uses: actions/upload-artifact@v5
105
+ with:
106
+ name: wheels-macos-${{ matrix.python-version }}-arm64
107
+ path: wheelhouse/*.whl
108
+
109
+ publish:
110
+ needs:
111
+ - build_sdist
112
+ - build_wheels_linux
113
+ - build_wheels_macos
114
+ runs-on: ubuntu-latest
115
+
116
+ if: github.repository_owner == 'drexlerd'
117
+
118
+ permissions:
119
+ id-token: write
120
+
121
+ steps:
122
+ - name: Checkout repository
123
+ uses: actions/checkout@v6
124
+
125
+ - name: Check version matches tag
126
+ run: |
127
+ VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['version'])")
128
+ TAG=${GITHUB_REF#refs/tags/v}
129
+
130
+ echo "Package version: $VERSION"
131
+ echo "Git tag: $TAG"
132
+
133
+ if [ "$VERSION" != "$TAG" ]; then
134
+ echo "Version mismatch: pyproject.toml=$VERSION tag=$TAG"
135
+ exit 1
136
+ fi
137
+
138
+ - name: Download all artifacts
139
+ uses: actions/download-artifact@v5
140
+ with:
141
+ path: dist
142
+ merge-multiple: true
143
+
144
+ - name: Inspect distributions
145
+ run: find dist -maxdepth 1 -type f
146
+
147
+ - name: Publish to PyPI
148
+ uses: pypa/gh-action-pypi-publish@release/v1
149
+ with:
150
+ packages-dir: dist
@@ -0,0 +1,9 @@
1
+ /.venv/
2
+ /build*/
3
+ /dependencies-build/
4
+ /dependencies-install/
5
+ /dist/
6
+ /*.egg-info/
7
+ /python/*.egg-info/
8
+ __pycache__/
9
+ *.py[cod]
@@ -0,0 +1,92 @@
1
+ cmake_minimum_required(VERSION 3.21)
2
+
3
+ file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/pyproject.toml" YGGDRASIL_PROJECT_VERSION_LINE REGEX "^version[ \t]*=" LIMIT_COUNT 1)
4
+ if(NOT YGGDRASIL_PROJECT_VERSION_LINE)
5
+ message(FATAL_ERROR "Could not read project version from pyproject.toml")
6
+ endif()
7
+ string(REGEX REPLACE "^version[ \t]*=[ \t]*\"([^\"]+)\".*$" "\\1" YGGDRASIL_PROJECT_VERSION "${YGGDRASIL_PROJECT_VERSION_LINE}")
8
+
9
+ project(yggdrasil VERSION "${YGGDRASIL_PROJECT_VERSION}")
10
+
11
+ include(GNUInstallDirs)
12
+
13
+ set(YGGDRASIL_NATIVE_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/dependencies-install" CACHE PATH "Native dependency prefix to package.")
14
+
15
+ if(NOT EXISTS "${YGGDRASIL_NATIVE_PREFIX}")
16
+ message(FATAL_ERROR "Native prefix does not exist: ${YGGDRASIL_NATIVE_PREFIX}")
17
+ endif()
18
+
19
+ install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/python/src/yggdrasil/__init__.py"
20
+ DESTINATION "yggdrasil"
21
+ COMPONENT yggdrasil)
22
+
23
+ foreach(native_dir IN ITEMS include lib lib64 bin nanobind)
24
+ if(EXISTS "${YGGDRASIL_NATIVE_PREFIX}/${native_dir}")
25
+ install(DIRECTORY "${YGGDRASIL_NATIVE_PREFIX}/${native_dir}"
26
+ DESTINATION "yggdrasil"
27
+ COMPONENT yggdrasil)
28
+ endif()
29
+ endforeach()
30
+
31
+ if(APPLE)
32
+ install(CODE [[
33
+ set(native_lib_dir "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/yggdrasil/lib")
34
+ if(EXISTS "${native_lib_dir}")
35
+ find_program(INSTALL_NAME_TOOL_EXECUTABLE install_name_tool)
36
+ if(INSTALL_NAME_TOOL_EXECUTABLE)
37
+ file(GLOB_RECURSE native_libraries LIST_DIRECTORIES false
38
+ "${native_lib_dir}/*.dylib"
39
+ "${native_lib_dir}/*.dylib.*")
40
+ foreach(native_library IN LISTS native_libraries)
41
+ get_filename_component(native_library_name "${native_library}" NAME)
42
+ execute_process(
43
+ COMMAND "${INSTALL_NAME_TOOL_EXECUTABLE}" -id "@rpath/${native_library_name}" "${native_library}"
44
+ RESULT_VARIABLE install_name_result
45
+ ERROR_VARIABLE install_name_error)
46
+ if(NOT install_name_result EQUAL 0)
47
+ message(WARNING "Could not update install name of ${native_library}: ${install_name_error}")
48
+ endif()
49
+
50
+ execute_process(
51
+ COMMAND "${INSTALL_NAME_TOOL_EXECUTABLE}" -delete_rpath "@loader_path" "${native_library}"
52
+ OUTPUT_QUIET
53
+ ERROR_QUIET)
54
+ execute_process(
55
+ COMMAND "${INSTALL_NAME_TOOL_EXECUTABLE}" -add_rpath "@loader_path" "${native_library}"
56
+ RESULT_VARIABLE rpath_result
57
+ ERROR_VARIABLE rpath_error)
58
+ if(NOT rpath_result EQUAL 0)
59
+ message(WARNING "Could not add @loader_path rpath to ${native_library}: ${rpath_error}")
60
+ endif()
61
+ endforeach()
62
+ else()
63
+ message(WARNING "install_name_tool not found; yggdrasil native libraries keep their original runtime paths")
64
+ endif()
65
+ endif()
66
+ ]] COMPONENT yggdrasil)
67
+ elseif(UNIX)
68
+ install(CODE [[
69
+ set(native_lib_dir "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/yggdrasil/lib")
70
+ if(EXISTS "${native_lib_dir}")
71
+ find_program(PATCHELF_EXECUTABLE patchelf)
72
+ if(PATCHELF_EXECUTABLE)
73
+ file(GLOB_RECURSE native_libraries LIST_DIRECTORIES false
74
+ "${native_lib_dir}/*.so"
75
+ "${native_lib_dir}/*.so.*")
76
+ foreach(native_library IN LISTS native_libraries)
77
+ execute_process(
78
+ COMMAND "${PATCHELF_EXECUTABLE}" --set-rpath "$ORIGIN" "${native_library}"
79
+ RESULT_VARIABLE rpath_result
80
+ ERROR_VARIABLE rpath_error)
81
+ if(NOT rpath_result EQUAL 0)
82
+ message(WARNING "Could not set $ORIGIN rpath on ${native_library}: ${rpath_error}")
83
+ endif()
84
+ endforeach()
85
+ else()
86
+ message(WARNING "patchelf not found; yggdrasil native libraries keep their original runtime paths")
87
+ endif()
88
+ endif()
89
+ ]] COMPONENT yggdrasil)
90
+ endif()
91
+
92
+ add_custom_target(yggdrasil_wheel)
@@ -0,0 +1,67 @@
1
+ Metadata-Version: 2.2
2
+ Name: pyyggdrasil
3
+ Version: 0.0.1
4
+ Summary: Native dependency provider for Dominik Drexler's planning projects
5
+ Author-Email: Dominik Drexler <dominik.drexler@liu.se>
6
+ Project-URL: Homepage, https://github.com/drexlerd/yggdrasil
7
+ Requires-Python: >=3.9
8
+ Provides-Extra: test
9
+ Requires-Dist: pytest; extra == "test"
10
+ Description-Content-Type: text/markdown
11
+
12
+ # Yggdrasil
13
+
14
+ `yggdrasil` packages the native dependency prefix used by the planning projects
15
+ in this repository family.
16
+
17
+ The Python distribution name is `pyyggdrasil`; the import package is
18
+ `yggdrasil`.
19
+
20
+ ## Use From Python
21
+
22
+ Install the wheel and query the native prefix:
23
+
24
+ ```python
25
+ import yggdrasil
26
+
27
+ print(yggdrasil.native_prefix())
28
+ ```
29
+
30
+ Downstream CMake projects can use that path as `CMAKE_PREFIX_PATH`:
31
+
32
+ ```bash
33
+ cmake -S . -B build \
34
+ -DCMAKE_PREFIX_PATH="$(python -c 'import yggdrasil; print(yggdrasil.native_prefix())')"
35
+ ```
36
+
37
+ Python packages that consume this native prefix should depend on:
38
+
39
+ ```toml
40
+ dependencies = [
41
+ "pyyggdrasil>=0.0.1",
42
+ ]
43
+ ```
44
+
45
+ ## Build
46
+
47
+ Build a wheel from source:
48
+
49
+ ```bash
50
+ uv build --wheel
51
+ ```
52
+
53
+ The build creates `dependencies-build/` and `dependencies-install/`. To package
54
+ an existing native prefix without rebuilding dependencies:
55
+
56
+ ```bash
57
+ YGGDRASIL_BUILD_NATIVE=OFF \
58
+ YGGDRASIL_NATIVE_PREFIX=/path/to/dependencies-install \
59
+ uv build --wheel
60
+ ```
61
+
62
+ Runtime libraries are stripped in the wheel by default. Disable that for
63
+ debugging with:
64
+
65
+ ```bash
66
+ YGGDRASIL_STRIP_WHEEL=OFF uv build --wheel
67
+ ```
@@ -0,0 +1,56 @@
1
+ # Yggdrasil
2
+
3
+ `yggdrasil` packages the native dependency prefix used by the planning projects
4
+ in this repository family.
5
+
6
+ The Python distribution name is `pyyggdrasil`; the import package is
7
+ `yggdrasil`.
8
+
9
+ ## Use From Python
10
+
11
+ Install the wheel and query the native prefix:
12
+
13
+ ```python
14
+ import yggdrasil
15
+
16
+ print(yggdrasil.native_prefix())
17
+ ```
18
+
19
+ Downstream CMake projects can use that path as `CMAKE_PREFIX_PATH`:
20
+
21
+ ```bash
22
+ cmake -S . -B build \
23
+ -DCMAKE_PREFIX_PATH="$(python -c 'import yggdrasil; print(yggdrasil.native_prefix())')"
24
+ ```
25
+
26
+ Python packages that consume this native prefix should depend on:
27
+
28
+ ```toml
29
+ dependencies = [
30
+ "pyyggdrasil>=0.0.1",
31
+ ]
32
+ ```
33
+
34
+ ## Build
35
+
36
+ Build a wheel from source:
37
+
38
+ ```bash
39
+ uv build --wheel
40
+ ```
41
+
42
+ The build creates `dependencies-build/` and `dependencies-install/`. To package
43
+ an existing native prefix without rebuilding dependencies:
44
+
45
+ ```bash
46
+ YGGDRASIL_BUILD_NATIVE=OFF \
47
+ YGGDRASIL_NATIVE_PREFIX=/path/to/dependencies-install \
48
+ uv build --wheel
49
+ ```
50
+
51
+ Runtime libraries are stripped in the wheel by default. Disable that for
52
+ debugging with:
53
+
54
+ ```bash
55
+ YGGDRASIL_STRIP_WHEEL=OFF uv build --wheel
56
+ ```
@@ -0,0 +1,51 @@
1
+ cmake_minimum_required(VERSION 3.21)
2
+
3
+ project(yggdrasil_dependencies)
4
+
5
+ include(GNUInstallDirs)
6
+
7
+ ##############################################################
8
+ # Common Settings
9
+ ##############################################################
10
+
11
+ # Option to set the build type (default to Release)
12
+ set(DEFAULT_BUILD_TYPE "Release")
13
+ if(NOT CMAKE_BUILD_TYPE)
14
+ set(CMAKE_BUILD_TYPE ${DEFAULT_BUILD_TYPE} CACHE STRING "Choose the type of build, options are: Debug Release" FORCE)
15
+ endif()
16
+
17
+ # Pass the build type to subdirectories
18
+ set(BUILD_TYPE ${CMAKE_BUILD_TYPE})
19
+
20
+ option(YGGDRASIL_BUILD_SHARED_DEPENDENCIES "Build bundled dependencies as shared libraries." ON)
21
+ message(STATUS "Build shared dependencies: ${YGGDRASIL_BUILD_SHARED_DEPENDENCIES}")
22
+
23
+ if(APPLE)
24
+ set(YGGDRASIL_DEPENDENCY_INSTALL_RPATH "@loader_path")
25
+ else()
26
+ set(YGGDRASIL_DEPENDENCY_INSTALL_RPATH "$ORIGIN")
27
+ endif()
28
+ set(CMAKE_INSTALL_RPATH "${YGGDRASIL_DEPENDENCY_INSTALL_RPATH}" CACHE STRING "Install runtime path for bundled shared dependencies.")
29
+ set(CMAKE_BUILD_WITH_INSTALL_RPATH OFF CACHE BOOL "Use the build-tree runtime path while building bundled dependencies.")
30
+ set(CMAKE_INSTALL_RPATH_USE_LINK_PATH OFF CACHE BOOL "Do not append absolute linked library directories to bundled dependency install runtime paths.")
31
+ message(STATUS "Dependency install rpath: ${YGGDRASIL_DEPENDENCY_INSTALL_RPATH}")
32
+
33
+ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
34
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto=auto")
35
+ endif ()
36
+
37
+
38
+ ##############################################################
39
+ # Add subprojects
40
+ ##############################################################
41
+
42
+ add_subdirectory(argparse)
43
+ add_subdirectory(benchmark)
44
+ add_subdirectory(boost)
45
+ add_subdirectory(cista)
46
+ add_subdirectory(fmt)
47
+ add_subdirectory(googletest)
48
+ add_subdirectory(gtl)
49
+ add_subdirectory(nanobind)
50
+ add_subdirectory(oneTBB)
51
+ add_subdirectory(valla)
@@ -0,0 +1,31 @@
1
+ cmake_minimum_required(VERSION 3.21)
2
+ project(InstallArgparse)
3
+
4
+ include(ExternalProject)
5
+
6
+ set(YGGDRASIL_ARGPARSE_GIT_TAG v3.2 CACHE STRING "Git tag used to build argparse.")
7
+
8
+ message(STATUS "Dependency \"argparse\"...")
9
+
10
+ list(APPEND CMAKE_ARGS
11
+ -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
12
+ -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
13
+ -DCMAKE_PREFIX_PATH=${CMAKE_INSTALL_PREFIX}
14
+ -DCMAKE_POSITION_INDEPENDENT_CODE=ON
15
+ -DBUILD_SHARED_LIBS=${YGGDRASIL_BUILD_SHARED_DEPENDENCIES}
16
+ -DCMAKE_INSTALL_RPATH=${YGGDRASIL_DEPENDENCY_INSTALL_RPATH}
17
+ )
18
+
19
+ message(STATUS "Preparing external project \"argparse\" with args:")
20
+ foreach(CMAKE_ARG ${CMAKE_ARGS})
21
+ message(STATUS "-- ${CMAKE_ARG}")
22
+ endforeach()
23
+ ExternalProject_Add(
24
+ argparse
25
+ GIT_REPOSITORY https://github.com/p-ranav/argparse.git
26
+ GIT_TAG ${YGGDRASIL_ARGPARSE_GIT_TAG}
27
+ PREFIX ${CMAKE_BINARY_DIR}/argparse
28
+ STAMP_DIR ${CMAKE_BINARY_DIR}/argparse/stamp/${YGGDRASIL_ARGPARSE_GIT_TAG}
29
+ UPDATE_COMMAND ""
30
+ CMAKE_ARGS ${CMAKE_ARGS}
31
+ )
@@ -0,0 +1,41 @@
1
+ cmake_minimum_required(VERSION 3.21)
2
+ project(InstallBenchmark)
3
+
4
+ include(ExternalProject)
5
+
6
+ set(YGGDRASIL_BENCHMARK_GIT_TAG v1.8.3 CACHE STRING "Git tag used to build benchmark.")
7
+
8
+ message(STATUS "Dependency \"benchmark\"...")
9
+
10
+ find_package(benchmark QUIET PATHS ${CMAKE_INSTALL_PREFIX} NO_DEFAULT_PATH)
11
+
12
+ if (NOT benchmark_FOUND)
13
+
14
+ list(APPEND CMAKE_ARGS
15
+ -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX}
16
+ -DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR}
17
+ -DCMAKE_BUILD_TYPE=Release
18
+ -DBUILD_SHARED_LIBS:BOOL=${YGGDRASIL_BUILD_SHARED_DEPENDENCIES}
19
+ -DCMAKE_INSTALL_RPATH=${YGGDRASIL_DEPENDENCY_INSTALL_RPATH}
20
+ -DBENCHMARK_ENABLE_GTEST_TESTS=OFF
21
+ )
22
+
23
+ message(STATUS "Preparing external project \"benchmark\" with args:")
24
+ foreach(CMAKE_ARG ${CMAKE_ARGS})
25
+ message(STATUS "-- ${CMAKE_ARG}")
26
+ endforeach()
27
+
28
+ ExternalProject_Add(
29
+ benchmark
30
+ GIT_REPOSITORY https://github.com/google/benchmark.git
31
+ GIT_TAG ${YGGDRASIL_BENCHMARK_GIT_TAG}
32
+ PREFIX ${CMAKE_BINARY_DIR}/benchmark
33
+ STAMP_DIR ${CMAKE_BINARY_DIR}/benchmark/stamp/${YGGDRASIL_BENCHMARK_GIT_TAG}
34
+ UPDATE_COMMAND ""
35
+ CMAKE_ARGS ${CMAKE_ARGS}
36
+ )
37
+
38
+
39
+ else()
40
+ message(STATUS "benchmark is already installed.")
41
+ endif()
@@ -0,0 +1,31 @@
1
+ cmake_minimum_required(VERSION 3.21)
2
+ project(InstallBoost)
3
+
4
+ include(ExternalProject)
5
+
6
+ set(YGGDRASIL_BOOST_VERSION 1.84.0 CACHE STRING "Boost version used to build boost.")
7
+ string(REPLACE "." "_" YGGDRASIL_BOOST_ARCHIVE_VERSION ${YGGDRASIL_BOOST_VERSION})
8
+
9
+ message(STATUS "Preparing external project \"boost\":")
10
+
11
+ if(YGGDRASIL_BUILD_SHARED_DEPENDENCIES)
12
+ set(BOOST_LINK shared)
13
+ set(BOOST_RUNTIME_LINK shared)
14
+ set(BOOST_DLL_PATH_ARGS hardcode-dll-paths=true dll-path=${YGGDRASIL_DEPENDENCY_INSTALL_RPATH})
15
+ else()
16
+ set(BOOST_LINK static)
17
+ set(BOOST_RUNTIME_LINK static)
18
+ set(BOOST_DLL_PATH_ARGS)
19
+ endif()
20
+
21
+ # We need to build boost for cmake support
22
+ ExternalProject_Add(
23
+ boost
24
+ URL https://archives.boost.io/release/${YGGDRASIL_BOOST_VERSION}/source/boost_${YGGDRASIL_BOOST_ARCHIVE_VERSION}.tar.gz
25
+ PREFIX ${CMAKE_BINARY_DIR}/boost
26
+ STAMP_DIR ${CMAKE_BINARY_DIR}/boost/stamp/${YGGDRASIL_BOOST_VERSION}
27
+ CONFIGURE_COMMAND ${CMAKE_COMMAND} -E chdir <SOURCE_DIR> ./bootstrap.sh --prefix=<INSTALL_DIR>
28
+ BUILD_COMMAND ${CMAKE_COMMAND} -E chdir <SOURCE_DIR> ./b2 headers
29
+ INSTALL_COMMAND ${CMAKE_COMMAND} -E chdir <SOURCE_DIR> ./b2 install --without-python link=${BOOST_LINK} runtime-link=${BOOST_RUNTIME_LINK} ${BOOST_DLL_PATH_ARGS}
30
+ INSTALL_DIR ${CMAKE_INSTALL_PREFIX}
31
+ )
@@ -0,0 +1,42 @@
1
+ cmake_minimum_required(VERSION 3.21)
2
+ project(InstallCista)
3
+
4
+ include(ExternalProject)
5
+
6
+ set(YGGDRASIL_CISTA_GIT_TAG 0065e285d25797c52206a570d06ab19aa1cb1887 CACHE STRING "Git tag used to build cista.")
7
+
8
+ message(STATUS "Dependency \"cista\"...")
9
+
10
+ # Attempt to find the installed cista library
11
+ find_package(cista QUIET PATHS ${CMAKE_INSTALL_PREFIX} NO_DEFAULT_PATH)
12
+
13
+ if (NOT cista_FOUND)
14
+
15
+
16
+ list(APPEND CMAKE_ARGS
17
+ -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
18
+ -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
19
+ -DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR}
20
+ -DCMAKE_PREFIX_PATH=${CMAKE_INSTALL_PREFIX}
21
+ -DCMAKE_POSITION_INDEPENDENT_CODE=ON
22
+ -DBUILD_SHARED_LIBS=${YGGDRASIL_BUILD_SHARED_DEPENDENCIES}
23
+ -DCMAKE_INSTALL_RPATH=${YGGDRASIL_DEPENDENCY_INSTALL_RPATH}
24
+ -DCISTA_INSTALL=ON
25
+ )
26
+
27
+ message(STATUS "Preparing external project \"cista\" with args:")
28
+ foreach(CMAKE_ARG ${CMAKE_ARGS})
29
+ message(STATUS "-- ${CMAKE_ARG}")
30
+ endforeach()
31
+ ExternalProject_Add(
32
+ cista
33
+ GIT_REPOSITORY https://github.com/drexlerd/cista.git
34
+ GIT_TAG ${YGGDRASIL_CISTA_GIT_TAG}
35
+ PREFIX ${CMAKE_BINARY_DIR}/cista
36
+ STAMP_DIR ${CMAKE_BINARY_DIR}/cista/stamp/${YGGDRASIL_CISTA_GIT_TAG}
37
+ UPDATE_COMMAND ""
38
+ CMAKE_ARGS ${CMAKE_ARGS}
39
+ )
40
+ else()
41
+ message(STATUS "cista is already installed.")
42
+ endif()
@@ -0,0 +1,30 @@
1
+ cmake_minimum_required(VERSION 3.21)
2
+ project(InstallFMT)
3
+
4
+ include(ExternalProject)
5
+
6
+ set(YGGDRASIL_FMT_GIT_TAG 11.2.0 CACHE STRING "Git tag used to build fmt.")
7
+
8
+ message(STATUS "Dependency \"fmt\"...")
9
+
10
+ list(APPEND CMAKE_ARGS
11
+ -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX}
12
+ -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON
13
+ -DBUILD_SHARED_LIBS:BOOL=${YGGDRASIL_BUILD_SHARED_DEPENDENCIES}
14
+ -DCMAKE_INSTALL_RPATH=${YGGDRASIL_DEPENDENCY_INSTALL_RPATH}
15
+ -DFMT_TEST:BOOL=OFF
16
+ )
17
+ message(STATUS "Preparing external project \"fmt\" with args:")
18
+ foreach (CMAKE_ARG ${CMAKE_ARGS})
19
+ message(STATUS "-- ${CMAKE_ARG}")
20
+ endforeach ()
21
+
22
+ ExternalProject_Add(
23
+ fmt
24
+ GIT_REPOSITORY https://github.com/fmtlib/fmt
25
+ GIT_TAG ${YGGDRASIL_FMT_GIT_TAG}
26
+ PREFIX ${CMAKE_BINARY_DIR}/fmt
27
+ STAMP_DIR ${CMAKE_BINARY_DIR}/fmt/stamp/${YGGDRASIL_FMT_GIT_TAG}
28
+ UPDATE_COMMAND ""
29
+ CMAKE_ARGS ${CMAKE_ARGS}
30
+ )
@@ -0,0 +1,38 @@
1
+ cmake_minimum_required(VERSION 3.21)
2
+ project(InstallGoogletest)
3
+
4
+ include(ExternalProject)
5
+
6
+ set(YGGDRASIL_GOOGLETEST_GIT_TAG release-1.12.1 CACHE STRING "Git tag used to build googletest.")
7
+
8
+ message(STATUS "Dependency \"GTest\"...")
9
+
10
+ # Attempt to find the installed googletest library
11
+ find_package(GTest QUIET PATHS ${CMAKE_INSTALL_PREFIX} NO_DEFAULT_PATH)
12
+
13
+ if (NOT GTest_FOUND)
14
+
15
+ list(APPEND CMAKE_ARGS
16
+ -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX}
17
+ -DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR}
18
+ -DBUILD_SHARED_LIBS:BOOL=${YGGDRASIL_BUILD_SHARED_DEPENDENCIES}
19
+ -DCMAKE_INSTALL_RPATH=${YGGDRASIL_DEPENDENCY_INSTALL_RPATH}
20
+ )
21
+
22
+ message(STATUS "Preparing external project \"googletest\" with args:")
23
+ foreach (CMAKE_ARG ${CMAKE_ARGS})
24
+ message(STATUS "-- ${CMAKE_ARG}")
25
+ endforeach ()
26
+
27
+ ExternalProject_Add(
28
+ googletest
29
+ GIT_REPOSITORY https://github.com/google/googletest.git
30
+ GIT_TAG ${YGGDRASIL_GOOGLETEST_GIT_TAG}
31
+ PREFIX ${CMAKE_BINARY_DIR}/googletest
32
+ STAMP_DIR ${CMAKE_BINARY_DIR}/googletest/stamp/${YGGDRASIL_GOOGLETEST_GIT_TAG}
33
+ UPDATE_COMMAND ""
34
+ CMAKE_ARGS ${CMAKE_ARGS}
35
+ )
36
+ else ()
37
+ message(STATUS "googletest is already installed.")
38
+ endif ()
@@ -0,0 +1,46 @@
1
+ cmake_minimum_required(VERSION 3.21)
2
+ project(InstallGTL)
3
+
4
+ include(ExternalProject)
5
+
6
+ set(YGGDRASIL_GTL_GIT_TAG dc7a24fe4b7f2f94480d954da6562c7381ace41f CACHE STRING "Git tag used to build gtl.")
7
+
8
+ message(STATUS "Dependency \"gtl\"...")
9
+
10
+ list(APPEND CMAKE_ARGS
11
+ -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
12
+ -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
13
+ -DCMAKE_PREFIX_PATH=${CMAKE_INSTALL_PREFIX}
14
+ -DCMAKE_POSITION_INDEPENDENT_CODE=ON
15
+ -DBUILD_SHARED_LIBS=${YGGDRASIL_BUILD_SHARED_DEPENDENCIES}
16
+ -DCMAKE_INSTALL_RPATH=${YGGDRASIL_DEPENDENCY_INSTALL_RPATH}
17
+ # -DCMAKE_CXX_FLAGS="-fsanitize=address"
18
+ # Disable extras that drag in the failing example
19
+ -DGTL_BUILD_EXAMPLES=OFF
20
+ -DGTL_BUILD_TESTS=OFF
21
+ -DGTL_BUILD_BENCHMARKS=OFF
22
+ )
23
+
24
+ message(STATUS "Preparing external project \"gtl\" with args:")
25
+ foreach(CMAKE_ARG ${CMAKE_ARGS})
26
+ message(STATUS "-- ${CMAKE_ARG}")
27
+ endforeach()
28
+ ExternalProject_Add(
29
+ gtl
30
+ GIT_REPOSITORY https://github.com/greg7mdp/gtl.git
31
+ GIT_TAG ${YGGDRASIL_GTL_GIT_TAG}
32
+ PREFIX ${CMAKE_BINARY_DIR}/gtl
33
+ STAMP_DIR ${CMAKE_BINARY_DIR}/gtl/stamp/${YGGDRASIL_GTL_GIT_TAG}
34
+ UPDATE_COMMAND ""
35
+ CMAKE_ARGS ${CMAKE_ARGS}
36
+ )
37
+ ExternalProject_Add_Step(
38
+ gtl install-cmake-package
39
+ COMMAND ${CMAKE_COMMAND}
40
+ -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
41
+ -S ${CMAKE_CURRENT_LIST_DIR}/package
42
+ -B ${CMAKE_BINARY_DIR}/gtl-package
43
+ COMMAND ${CMAKE_COMMAND}
44
+ --install ${CMAKE_BINARY_DIR}/gtl-package
45
+ DEPENDEES install
46
+ )
@@ -0,0 +1,38 @@
1
+ cmake_minimum_required(VERSION 3.21)
2
+
3
+ project(gtlPackage VERSION 1.2.0 LANGUAGES CXX)
4
+
5
+ include(CMakePackageConfigHelpers)
6
+ include(GNUInstallDirs)
7
+
8
+ add_library(gtl INTERFACE)
9
+ add_library(gtl::gtl ALIAS gtl)
10
+
11
+ target_include_directories(gtl INTERFACE
12
+ "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
13
+
14
+ install(
15
+ TARGETS gtl
16
+ EXPORT gtlTargets)
17
+
18
+ install(
19
+ EXPORT gtlTargets
20
+ NAMESPACE gtl::
21
+ FILE gtlTargets.cmake
22
+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/gtl")
23
+
24
+ configure_package_config_file(
25
+ "${CMAKE_CURRENT_SOURCE_DIR}/gtlConfig.cmake.in"
26
+ "${CMAKE_CURRENT_BINARY_DIR}/gtlConfig.cmake"
27
+ INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/gtl")
28
+
29
+ write_basic_package_version_file(
30
+ "${CMAKE_CURRENT_BINARY_DIR}/gtlConfigVersion.cmake"
31
+ VERSION ${PROJECT_VERSION}
32
+ COMPATIBILITY SameMajorVersion)
33
+
34
+ install(
35
+ FILES
36
+ "${CMAKE_CURRENT_BINARY_DIR}/gtlConfig.cmake"
37
+ "${CMAKE_CURRENT_BINARY_DIR}/gtlConfigVersion.cmake"
38
+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/gtl")
@@ -0,0 +1,3 @@
1
+ @PACKAGE_INIT@
2
+
3
+ include("${CMAKE_CURRENT_LIST_DIR}/gtlTargets.cmake")
@@ -0,0 +1,42 @@
1
+ cmake_minimum_required(VERSION 3.21)
2
+ project(InstallNanobind)
3
+
4
+ include(ExternalProject)
5
+
6
+ set(YGGDRASIL_NANOBIND_GIT_TAG v2.12.0 CACHE STRING "Git tag used to build nanobind.")
7
+
8
+ message(STATUS "Dependency \"nanobind\"...")
9
+
10
+ # Attempt to find the installed library
11
+ find_package(Python 3.8
12
+ REQUIRED COMPONENTS Interpreter Development.Module
13
+ OPTIONAL_COMPONENTS Development.SABIModule)
14
+
15
+ find_package(nanobind QUIET PATHS ${CMAKE_INSTALL_PREFIX} NO_DEFAULT_PATH)
16
+
17
+ if (NOT nanobind_FOUND)
18
+ list(APPEND CMAKE_ARGS
19
+ -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX}
20
+ -DNB_TEST=OFF
21
+ )
22
+
23
+ message(STATUS "Preparing external project \"nanobind\" with args:")
24
+ foreach(CMAKE_ARG ${CMAKE_ARGS})
25
+ message(STATUS "-- ${CMAKE_ARG}")
26
+ endforeach()
27
+
28
+
29
+ # If the library is not found, use ExternalProject_Add to download and build it
30
+ ExternalProject_Add(
31
+ nanobind
32
+ GIT_REPOSITORY https://github.com/wjakob/nanobind.git
33
+ GIT_TAG ${YGGDRASIL_NANOBIND_GIT_TAG}
34
+ PREFIX ${CMAKE_BINARY_DIR}/nanobind
35
+ STAMP_DIR ${CMAKE_BINARY_DIR}/nanobind/stamp/${YGGDRASIL_NANOBIND_GIT_TAG}
36
+ UPDATE_COMMAND ""
37
+ CMAKE_ARGS ${CMAKE_ARGS}
38
+ )
39
+ else()
40
+ message(STATUS "nanobind is already installed.")
41
+ endif()
42
+
@@ -0,0 +1,41 @@
1
+ cmake_minimum_required(VERSION 3.21)
2
+ project(InstallOneTBB)
3
+
4
+ include(ExternalProject)
5
+
6
+ set(YGGDRASIL_ONETBB_GIT_TAG v2022.2.0 CACHE STRING "Git tag used to build oneTBB.")
7
+
8
+ message(STATUS "Dependency \"oneTBB\"...")
9
+
10
+ # Attempt to find the installed oneTBB library
11
+ find_package(oneTBB QUIET PATHS ${CMAKE_INSTALL_PREFIX} NO_DEFAULT_PATH)
12
+
13
+ if (NOT oneTBB_FOUND)
14
+ list(APPEND CMAKE_ARGS
15
+ -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
16
+ -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
17
+ -DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR}
18
+ -DCMAKE_PREFIX_PATH=${CMAKE_INSTALL_PREFIX}
19
+ -DCMAKE_POSITION_INDEPENDENT_CODE=ON
20
+ -DBUILD_SHARED_LIBS=${YGGDRASIL_BUILD_SHARED_DEPENDENCIES}
21
+ -DCMAKE_INSTALL_RPATH=${YGGDRASIL_DEPENDENCY_INSTALL_RPATH}
22
+ -DTBB_STRICT=OFF
23
+ -DTBB_TEST=OFF
24
+ )
25
+
26
+ message(STATUS "Preparing external project \"oneTBB\" with args:")
27
+ foreach(CMAKE_ARG ${CMAKE_ARGS})
28
+ message(STATUS "-- ${CMAKE_ARG}")
29
+ endforeach()
30
+ ExternalProject_Add(
31
+ oneTBB
32
+ GIT_REPOSITORY https://github.com/uxlfoundation/oneTBB.git
33
+ GIT_TAG ${YGGDRASIL_ONETBB_GIT_TAG}
34
+ PREFIX ${CMAKE_BINARY_DIR}/oneTBB
35
+ STAMP_DIR ${CMAKE_BINARY_DIR}/oneTBB/stamp/${YGGDRASIL_ONETBB_GIT_TAG}
36
+ UPDATE_COMMAND ""
37
+ CMAKE_ARGS ${CMAKE_ARGS}
38
+ )
39
+ else()
40
+ message(STATUS "oneTBB is already installed.")
41
+ endif()
@@ -0,0 +1,41 @@
1
+ cmake_minimum_required(VERSION 3.21)
2
+ project(InstallValla)
3
+
4
+ include(ExternalProject)
5
+
6
+ set(YGGDRASIL_VALLA_GIT_TAG 6a5ae8e2ce59edf9ce1fe015099e3cb24f249bdd CACHE STRING "Git tag used to build valla.")
7
+
8
+ message(STATUS "Dependency \"valla\"...")
9
+
10
+ # Attempt to find the installed valla library
11
+ find_package(valla QUIET PATHS ${CMAKE_INSTALL_PREFIX} NO_DEFAULT_PATH)
12
+
13
+ if (NOT valla_FOUND)
14
+ list(APPEND CMAKE_ARGS
15
+ -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
16
+ -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
17
+ -DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR}
18
+ -DCMAKE_PREFIX_PATH=${CMAKE_INSTALL_PREFIX}
19
+ -DCMAKE_POSITION_INDEPENDENT_CODE=ON
20
+ -DBUILD_SHARED_LIBS=${YGGDRASIL_BUILD_SHARED_DEPENDENCIES}
21
+ -DCMAKE_INSTALL_RPATH=${YGGDRASIL_DEPENDENCY_INSTALL_RPATH}
22
+ -DTBB_TEST=OFF
23
+ )
24
+
25
+ message(STATUS "Preparing external project \"valla\" with args:")
26
+ foreach(CMAKE_ARG ${CMAKE_ARGS})
27
+ message(STATUS "-- ${CMAKE_ARG}")
28
+ endforeach()
29
+ ExternalProject_Add(
30
+ valla
31
+ GIT_REPOSITORY https://github.com/drexlerd/tree-compression.git
32
+ GIT_TAG ${YGGDRASIL_VALLA_GIT_TAG}
33
+ PREFIX ${CMAKE_BINARY_DIR}/valla
34
+ STAMP_DIR ${CMAKE_BINARY_DIR}/valla/stamp/${YGGDRASIL_VALLA_GIT_TAG}
35
+ UPDATE_COMMAND ""
36
+ DEPENDS boost fmt gtl oneTBB
37
+ CMAKE_ARGS ${CMAKE_ARGS}
38
+ )
39
+ else()
40
+ message(STATUS "valla is already installed.")
41
+ endif()
@@ -0,0 +1,59 @@
1
+ [build-system]
2
+ requires = [
3
+ "scikit-build-core>=0.10",
4
+ ]
5
+ build-backend = "yggdrasil_build_backend"
6
+ backend-path = ["python"]
7
+
8
+ [project]
9
+ name = "pyyggdrasil"
10
+ version = "0.0.1"
11
+ description = "Native dependency provider for Dominik Drexler's planning projects"
12
+ readme = "README.md"
13
+ requires-python = ">=3.9"
14
+ authors = [
15
+ {name = "Dominik Drexler", email = "dominik.drexler@liu.se"},
16
+ ]
17
+ dependencies = []
18
+
19
+ [project.optional-dependencies]
20
+ test = [
21
+ "pytest",
22
+ ]
23
+
24
+ [project.urls]
25
+ Homepage = "https://github.com/drexlerd/yggdrasil"
26
+
27
+ [tool.scikit-build]
28
+ build.targets = ["yggdrasil_wheel"]
29
+ cmake.build-type = "Release"
30
+ install.components = ["yggdrasil"]
31
+ wheel.packages = []
32
+
33
+ [tool.scikit-build.sdist]
34
+ include = [
35
+ "CMakeLists.txt",
36
+ "README.md",
37
+ "pyproject.toml",
38
+ "python/**",
39
+ "dependencies/**",
40
+ ]
41
+ exclude = [
42
+ "build*/**",
43
+ "dependencies-build/**",
44
+ "dependencies-install/**",
45
+ "*.egg-info/**",
46
+ ]
47
+
48
+ [tool.scikit-build.cmake.define]
49
+ YGGDRASIL_NATIVE_PREFIX = {env = "YGGDRASIL_NATIVE_PREFIX", default = "dependencies-install"}
50
+ CMAKE_INSTALL_LIBDIR = "lib"
51
+
52
+ [tool.cibuildwheel]
53
+ container-engine = "docker"
54
+
55
+ [tool.cibuildwheel.linux]
56
+ repair-wheel-command = "LD_LIBRARY_PATH=$PWD/dependencies-install/lib auditwheel repair -w {dest_dir} {wheel}"
57
+
58
+ [tool.cibuildwheel.macos]
59
+ repair-wheel-command = "delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}"
@@ -0,0 +1,25 @@
1
+ from pathlib import Path
2
+ from importlib.metadata import PackageNotFoundError, version
3
+
4
+
5
+ def _source_version() -> str:
6
+ for parent in Path(__file__).resolve().parents:
7
+ pyproject = parent / "pyproject.toml"
8
+ if not pyproject.exists():
9
+ continue
10
+
11
+ for line in pyproject.read_text(encoding="utf-8").splitlines():
12
+ if line.startswith("version"):
13
+ return line.split("=", maxsplit=1)[1].strip().strip("\"")
14
+
15
+ return "0.0.0"
16
+
17
+
18
+ try:
19
+ __version__ = version("pyyggdrasil")
20
+ except PackageNotFoundError:
21
+ __version__ = _source_version()
22
+
23
+
24
+ def native_prefix() -> Path:
25
+ return Path(__file__).resolve().parent
@@ -0,0 +1,11 @@
1
+ import yggdrasil
2
+
3
+
4
+ def test_native_prefix_layout():
5
+ native_prefix = yggdrasil.native_prefix()
6
+
7
+ assert yggdrasil.__version__ != ""
8
+ assert (native_prefix / "include").is_dir()
9
+ assert (native_prefix / "lib").is_dir()
10
+ assert (native_prefix / "include" / "boost").is_dir()
11
+ assert (native_prefix / "lib" / "cmake").is_dir()
@@ -0,0 +1,175 @@
1
+ import base64
2
+ import csv
3
+ import hashlib
4
+ import os
5
+ import platform
6
+ import shutil
7
+ import subprocess
8
+ import sys
9
+ import tempfile
10
+ import zipfile
11
+ from pathlib import Path
12
+
13
+ from scikit_build_core import build as scikit_build
14
+
15
+
16
+ ROOT_DIR = Path(__file__).resolve().parent.parent
17
+ YGGDRASIL_BUILD_DIR = ROOT_DIR / "dependencies-build"
18
+
19
+
20
+ def _native_prefix() -> Path:
21
+ return Path(os.environ.get("YGGDRASIL_NATIVE_PREFIX", ROOT_DIR / "dependencies-install")).resolve()
22
+
23
+
24
+ def _build_type() -> str:
25
+ return os.environ.get("YGGDRASIL_BUILD_TYPE", "Release")
26
+
27
+
28
+ def _num_jobs() -> int:
29
+ return int(os.environ.get("YGGDRASIL_JOBS", "8"))
30
+
31
+
32
+ def _is_disabled(value: str) -> bool:
33
+ return value.upper() in {"0", "FALSE", "OFF", "NO"}
34
+
35
+
36
+ def _configure_and_install_dependencies() -> None:
37
+ if _is_disabled(os.environ.get("YGGDRASIL_BUILD_NATIVE", "ON")):
38
+ return
39
+
40
+ cmake = shutil.which("cmake")
41
+ if cmake is None:
42
+ raise RuntimeError("cmake is required to build yggdrasil")
43
+
44
+ YGGDRASIL_BUILD_DIR.mkdir(parents=True, exist_ok=True)
45
+
46
+ cmake_args = [
47
+ cmake,
48
+ "-S",
49
+ str(ROOT_DIR / "dependencies"),
50
+ "-B",
51
+ str(YGGDRASIL_BUILD_DIR),
52
+ f"-DCMAKE_BUILD_TYPE={_build_type()}",
53
+ f"-DCMAKE_INSTALL_PREFIX={_native_prefix()}",
54
+ "-DCMAKE_INSTALL_LIBDIR=lib",
55
+ "-DYGGDRASIL_BUILD_SHARED_DEPENDENCIES=ON",
56
+ f"-DPython_EXECUTABLE={sys.executable}",
57
+ ]
58
+
59
+ subprocess.run(cmake_args, cwd=ROOT_DIR, check=True)
60
+ subprocess.run([cmake, "--build", str(YGGDRASIL_BUILD_DIR), f"-j{_num_jobs()}"], cwd=ROOT_DIR, check=True)
61
+ subprocess.run([cmake, "--install", str(YGGDRASIL_BUILD_DIR)], cwd=ROOT_DIR, check=True)
62
+
63
+
64
+ def _prepend_cmake_args(*args: str) -> None:
65
+ existing = os.environ.get("CMAKE_ARGS", "")
66
+ os.environ["CMAKE_ARGS"] = " ".join([*args, existing]).strip()
67
+
68
+
69
+ def _prepare_native_build() -> None:
70
+ _configure_and_install_dependencies()
71
+ os.environ.setdefault("CMAKE_BUILD_PARALLEL_LEVEL", str(_num_jobs()))
72
+ _prepend_cmake_args(
73
+ f"-DYGGDRASIL_NATIVE_PREFIX={_native_prefix()}",
74
+ "-DCMAKE_INSTALL_LIBDIR=lib",
75
+ )
76
+
77
+
78
+ def _is_native_library(path: Path) -> bool:
79
+ name = path.name
80
+ return ".so" in name or name.endswith(".dylib") or name.endswith(".pyd")
81
+
82
+
83
+ def _strip_args() -> list[str]:
84
+ if platform.system() == "Darwin":
85
+ return ["-x"]
86
+ return ["--strip-unneeded"]
87
+
88
+
89
+ def _record_digest(path: Path) -> tuple[str, str]:
90
+ content = path.read_bytes()
91
+ digest = base64.urlsafe_b64encode(hashlib.sha256(content).digest()).rstrip(b"=").decode("ascii")
92
+ return f"sha256={digest}", str(len(content))
93
+
94
+
95
+ def _rewrite_record(wheel_root: Path) -> None:
96
+ record_files = list(wheel_root.glob("*.dist-info/RECORD"))
97
+ if len(record_files) != 1:
98
+ raise RuntimeError(f"expected exactly one RECORD file, found {len(record_files)}")
99
+
100
+ record_file = record_files[0]
101
+ rows = []
102
+ for path in sorted(wheel_root.rglob("*")):
103
+ if not path.is_file():
104
+ continue
105
+
106
+ relative_path = path.relative_to(wheel_root).as_posix()
107
+ if path == record_file:
108
+ rows.append((relative_path, "", ""))
109
+ else:
110
+ digest, size = _record_digest(path)
111
+ rows.append((relative_path, digest, size))
112
+
113
+ with record_file.open("w", newline="") as out:
114
+ csv.writer(out).writerows(rows)
115
+
116
+
117
+ def _strip_wheel_native_libraries(wheel_path: Path) -> None:
118
+ if _is_disabled(os.environ.get("YGGDRASIL_STRIP_WHEEL", "ON")):
119
+ return
120
+
121
+ strip = shutil.which("strip")
122
+ if strip is None:
123
+ return
124
+
125
+ with tempfile.TemporaryDirectory(prefix="yggdrasil-wheel-") as tmp:
126
+ wheel_root = Path(tmp) / "wheel"
127
+ with zipfile.ZipFile(wheel_path) as wheel:
128
+ wheel.extractall(wheel_root)
129
+
130
+ for path in wheel_root.rglob("*"):
131
+ if path.is_file() and _is_native_library(path):
132
+ subprocess.run(
133
+ [strip, *_strip_args(), str(path)],
134
+ check=False,
135
+ stdout=subprocess.DEVNULL,
136
+ stderr=subprocess.DEVNULL,
137
+ )
138
+
139
+ _rewrite_record(wheel_root)
140
+
141
+ replacement_path = wheel_path.with_suffix(".tmp")
142
+ with zipfile.ZipFile(replacement_path, "w", compression=zipfile.ZIP_DEFLATED) as wheel:
143
+ for path in sorted(wheel_root.rglob("*")):
144
+ if path.is_file():
145
+ wheel.write(path, path.relative_to(wheel_root).as_posix())
146
+
147
+ replacement_path.replace(wheel_path)
148
+
149
+
150
+ def get_requires_for_build_wheel(config_settings=None):
151
+ return scikit_build.get_requires_for_build_wheel(config_settings)
152
+
153
+
154
+ def get_requires_for_build_editable(config_settings=None):
155
+ return scikit_build.get_requires_for_build_editable(config_settings)
156
+
157
+
158
+ def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None):
159
+ return scikit_build.prepare_metadata_for_build_wheel(metadata_directory, config_settings)
160
+
161
+
162
+ def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
163
+ _prepare_native_build()
164
+ wheel_filename = scikit_build.build_wheel(wheel_directory, config_settings, metadata_directory)
165
+ _strip_wheel_native_libraries(Path(wheel_directory) / wheel_filename)
166
+ return wheel_filename
167
+
168
+
169
+ def build_editable(wheel_directory, config_settings=None, metadata_directory=None):
170
+ _prepare_native_build()
171
+ return scikit_build.build_editable(wheel_directory, config_settings, metadata_directory)
172
+
173
+
174
+ def build_sdist(sdist_directory, config_settings=None):
175
+ return scikit_build.build_sdist(sdist_directory)