From 54b4bb8232ec477b3679ecc8d47b90d5adf0bddf Mon Sep 17 00:00:00 2001 From: Patrick Wuttke Date: Thu, 13 Mar 2025 22:38:50 +0100 Subject: [PATCH] initial commit --- .gitignore | 174 +++++++++++++++++++++++ recipes/Catch2/recipe.py | 31 ++++ recipes/ImageMagick/recipe.py | 31 ++++ recipes/SDL/fix_sdl3_from_worktree.patch | 13 ++ recipes/SDL/recipe.py | 55 +++++++ recipes/VulkanHeaders/recipe.py | 45 ++++++ recipes/X11/recipe.py | 23 +++ recipes/Xft/recipe.py | 25 ++++ recipes/argparse/recipe.py | 18 +++ recipes/boost/recipe.py | 70 +++++++++ recipes/cgltf/recipe.py | 19 +++ recipes/curl/recipe.py | 54 +++++++ recipes/directx12/recipe.py | 23 +++ recipes/dxc/recipe.py | 31 ++++ recipes/fmt/recipe.py | 27 ++++ recipes/fontconfig/recipe.py | 25 ++++ recipes/freetype/recipe.py | 23 +++ recipes/glm/recipe.py | 52 +++++++ recipes/glslang/recipe.py | 120 ++++++++++++++++ recipes/gsl/recipe.py | 20 +++ recipes/icon_font_cpp_headers/recipe.py | 26 ++++ recipes/idn2/recipe.py | 48 +++++++ recipes/imgui-node-editor/recipe.py | 48 +++++++ recipes/imgui/recipe.py | 64 +++++++++ recipes/iwa/recipe.py | 20 +++ recipes/json/recipe.py | 22 +++ recipes/libbacktrace/recipe.py | 21 +++ recipes/libjpeg-turbo/recipe.py | 21 +++ recipes/libpng/recipe.py | 39 +++++ recipes/lua/recipe.py | 54 +++++++ recipes/magic_enum/recipe.py | 20 +++ recipes/mecab/recipe.py | 21 +++ recipes/mijin/recipe.py | 20 +++ recipes/mikktspace/recipe.py | 27 ++++ recipes/nana/recipe.py | 37 +++++ recipes/openssl/recipe.py | 21 +++ recipes/portable-file-dialogs/recipe.py | 22 +++ recipes/psl/recipe.py | 48 +++++++ recipes/raid/recipe.py | 20 +++ recipes/rectpack2D/recipe.py | 20 +++ recipes/sdlpp/recipe.py | 18 +++ recipes/spdlog/recipe.py | 34 +++++ recipes/sqlite/recipe.py | 83 +++++++++++ recipes/stb/recipe.py | 19 +++ recipes/tinyobjloader/recipe.py | 24 ++++ recipes/unistring/recipe.py | 42 ++++++ recipes/wincrypt/recipe.py | 23 +++ recipes/winldap/recipe.py | 23 +++ recipes/winsock2/recipe.py | 23 +++ recipes/yaml-cpp/recipe.py | 26 ++++ recipes/zlib/recipe.py | 69 +++++++++ 51 files changed, 1882 insertions(+) create mode 100644 .gitignore create mode 100644 recipes/Catch2/recipe.py create mode 100644 recipes/ImageMagick/recipe.py create mode 100644 recipes/SDL/fix_sdl3_from_worktree.patch create mode 100644 recipes/SDL/recipe.py create mode 100644 recipes/VulkanHeaders/recipe.py create mode 100644 recipes/X11/recipe.py create mode 100644 recipes/Xft/recipe.py create mode 100644 recipes/argparse/recipe.py create mode 100644 recipes/boost/recipe.py create mode 100644 recipes/cgltf/recipe.py create mode 100644 recipes/curl/recipe.py create mode 100644 recipes/directx12/recipe.py create mode 100644 recipes/dxc/recipe.py create mode 100644 recipes/fmt/recipe.py create mode 100644 recipes/fontconfig/recipe.py create mode 100644 recipes/freetype/recipe.py create mode 100644 recipes/glm/recipe.py create mode 100644 recipes/glslang/recipe.py create mode 100644 recipes/gsl/recipe.py create mode 100644 recipes/icon_font_cpp_headers/recipe.py create mode 100644 recipes/idn2/recipe.py create mode 100644 recipes/imgui-node-editor/recipe.py create mode 100644 recipes/imgui/recipe.py create mode 100644 recipes/iwa/recipe.py create mode 100644 recipes/json/recipe.py create mode 100644 recipes/libbacktrace/recipe.py create mode 100644 recipes/libjpeg-turbo/recipe.py create mode 100644 recipes/libpng/recipe.py create mode 100644 recipes/lua/recipe.py create mode 100644 recipes/magic_enum/recipe.py create mode 100644 recipes/mecab/recipe.py create mode 100644 recipes/mijin/recipe.py create mode 100644 recipes/mikktspace/recipe.py create mode 100644 recipes/nana/recipe.py create mode 100644 recipes/openssl/recipe.py create mode 100644 recipes/portable-file-dialogs/recipe.py create mode 100644 recipes/psl/recipe.py create mode 100644 recipes/raid/recipe.py create mode 100644 recipes/rectpack2D/recipe.py create mode 100644 recipes/sdlpp/recipe.py create mode 100644 recipes/spdlog/recipe.py create mode 100644 recipes/sqlite/recipe.py create mode 100644 recipes/stb/recipe.py create mode 100644 recipes/tinyobjloader/recipe.py create mode 100644 recipes/unistring/recipe.py create mode 100644 recipes/wincrypt/recipe.py create mode 100644 recipes/winldap/recipe.py create mode 100644 recipes/winsock2/recipe.py create mode 100644 recipes/yaml-cpp/recipe.py create mode 100644 recipes/zlib/recipe.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0a19790 --- /dev/null +++ b/.gitignore @@ -0,0 +1,174 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# UV +# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +#uv.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/latest/usage/project/#working-with-version-control +.pdm.toml +.pdm-python +.pdm-build/ + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +# Ruff stuff: +.ruff_cache/ + +# PyPI configuration file +.pypirc diff --git a/recipes/Catch2/recipe.py b/recipes/Catch2/recipe.py new file mode 100644 index 0000000..b59109f --- /dev/null +++ b/recipes/Catch2/recipe.py @@ -0,0 +1,31 @@ + +import re +from SCons.Script import * + +def _git_cook(env: Environment, repo) -> dict: + checkout_root = repo['checkout_root'] + build_result = env.CMakeProject(project_root=checkout_root) + + lib_name = { + 'debug': 'Catch2d' + }.get(env['BUILD_TYPE'], 'Catch2') + libs = [] + if not env.get('CATCH2_OWN_MAIN'): + libs.append({ + 'debug': 'Catch2Maind' + }.get(env['BUILD_TYPE'], 'Catch2Main')) + libs.append(lib_name) + return { + 'CPPPATH': build_result['CPPPATH'], + 'LIBS': [env.FindLib(lib, paths=build_result['LIBPATH']) for lib in libs] + } + + +env.GitRecipe( + globals = globals(), + repo_name = 'Catch2', + repo_url = 'https://github.com/catchorg/Catch2.git', + tag_pattern = re.compile(r'^v([0-9]+)\.([0-9]+)\.([0-9]+)$'), + tag_fn = lambda version: f'v{version[0]}.{version[1]}.{version[2]}', + cook_fn = _git_cook +) \ No newline at end of file diff --git a/recipes/ImageMagick/recipe.py b/recipes/ImageMagick/recipe.py new file mode 100644 index 0000000..d70b20d --- /dev/null +++ b/recipes/ImageMagick/recipe.py @@ -0,0 +1,31 @@ + +import re +from SCons.Script import * + +_REPO_NAME = 'ImageMagick' +_REPO_URL = 'https://github.com/ImageMagick/ImageMagick.git' +_TAG_PATTERN = re.compile(r'^([0-9]+)\.([0-9]+)\.([0-9]+)-([0-9]+)$') + +def versions(env: Environment, update: bool = False): + tags = env.GitTags(repo_name = _REPO_NAME, remote_url = _REPO_URL, force_fetch=update) + result = [] + for tag in tags: + match = _TAG_PATTERN.match(tag) + if match: + result.append((int(match.groups()[0]), int(match.groups()[1]), int(match.groups()[2]), int(match.groups()[3]))) + return result + +def dependencies(env: Environment, version) -> 'dict': + return {} + +def cook(env: Environment, version) -> dict: + raise Exception('this still needs to be implemented property :/') + # git_ref = f'refs/tags/{version[0]}.{version[1]}.{version[2]}-{version[3]}' + # repo = env.GitBranch(repo_name = _REPO_NAME, remote_url = _REPO_URL, git_ref = git_ref) + # checkout_root = repo['checkout_root'] + # build_result = env.AutotoolsProject(checkout_root) + # return { + # 'LIBPATH': build_result['LIBPATH'], + # 'CPPPATH': build_result['CPPPATH'], + # 'LIBS': ['backtrace'] + # } diff --git a/recipes/SDL/fix_sdl3_from_worktree.patch b/recipes/SDL/fix_sdl3_from_worktree.patch new file mode 100644 index 0000000..fd28285 --- /dev/null +++ b/recipes/SDL/fix_sdl3_from_worktree.patch @@ -0,0 +1,13 @@ +diff --git a/cmake/GetGitRevisionDescription.cmake b/cmake/GetGitRevisionDescription.cmake +index a08895c64..d3873387d 100644 +--- a/cmake/GetGitRevisionDescription.cmake ++++ b/cmake/GetGitRevisionDescription.cmake +@@ -143,7 +143,7 @@ function(get_git_head_revision _refspecvar _hashvar) + string(REGEX REPLACE "gitdir: (.*)$" "\\1" git_worktree_dir + ${worktree_ref}) + string(STRIP ${git_worktree_dir} git_worktree_dir) +- _git_find_closest_git_dir("${git_worktree_dir}" GIT_DIR) ++ set(GIT_DIR "${git_worktree_dir}") + set(HEAD_SOURCE_FILE "${git_worktree_dir}/HEAD") + endif() + else() diff --git a/recipes/SDL/recipe.py b/recipes/SDL/recipe.py new file mode 100644 index 0000000..f351c1a --- /dev/null +++ b/recipes/SDL/recipe.py @@ -0,0 +1,55 @@ + +import os +import platform +import re +from SCons.Script import * + + +def _git_cook(env: Environment, repo: dict) -> dict: + checkout_root = repo['checkout_root'] + + if os.path.exists(os.path.join(repo['checkout_root'], 'cmake', 'GetGitRevisionDescription.cmake')): + try: + repo['repo'].git.apply('--unsafe-paths', '--directory', repo['checkout_root'], os.path.join(env['SPP_DIR'], 'recipes', 'SDL', 'fix_sdl3_from_worktree.patch')) + except: + # either already applied or not applicable anymore + pass + + build_result = env.CMakeProject(project_root=checkout_root, generate_args = ['-DSDL_STATIC=ON', '-DSDL_SHARED=OFF']) + libs = [] + if platform.system() == 'Windows': + if env['BUILD_TYPE'] == 'debug': + lib_names = ['SDL2-staticd', 'SDL3-static'] + else: + lib_names = ['SDL2-static', 'SDL3-static'] + libs.extend(('kernel32', 'user32', 'gdi32', 'winmm', 'imm32', 'ole32', 'oleaut32', 'version', 'uuid', 'advapi32', 'setupapi', 'shell32', 'dinput8')) + else: + if env['BUILD_TYPE'] == 'debug': + lib_names = ['SDL2d', 'SDL3'] + else: + lib_names = ['SDL2', 'SDL3'] + lib_file = None + is_sdl3 = False + for lib_name in lib_names: + lib_file = env.FindLib(lib_name, paths=build_result['LIBPATH'], allow_fail=True) + if lib_file: + is_sdl3 = "SDL3" in lib_name + break + if not lib_file: + env.Error('Could not find SDL lib file.') + libs.insert(0, lib_file) + return { + 'CPPPATH': [os.path.join(build_result['install_dir'], (is_sdl3 and 'include' or 'include/SDL2'))], # SDL is really weird about include paths ... + 'LIBS': libs + } + + +env.GitRecipe( + globals = globals(), + repo_name = 'SDL', + repo_url = 'https://github.com/libsdl-org/SDL.git', + tag_pattern = re.compile(r'^release-([0-9]+)\.([0-9]+)\.([0-9]+)$'), + tag_fn = lambda version: f'release-{version[0]}.{version[1]}.{version[2]}', + cook_fn = _git_cook +) + diff --git a/recipes/VulkanHeaders/recipe.py b/recipes/VulkanHeaders/recipe.py new file mode 100644 index 0000000..fcd8726 --- /dev/null +++ b/recipes/VulkanHeaders/recipe.py @@ -0,0 +1,45 @@ + +import re +from SCons.Script import * + +_REPO_NAMES = { + 'default': 'VulkanHeaders', + 'mewin': 'VulkanHeaders_mewin' +} +_REPO_URLS = { + 'default': 'https://github.com/KhronosGroup/Vulkan-Headers.git', + 'mewin': 'https://git.mewin.de/mewin/vulkan-headers.git' +} +_TAG_PATTERN = re.compile(r'^v([0-9]+)\.([0-9]+)\.([0-9]+)$') + + +def _get_repo_name(env: Environment) -> str: + return _REPO_NAMES[env.get('VULKANHEADERS_REMOTE', 'default')] + +def _get_repo_url(env: Environment) -> str: + return _REPO_URLS[env.get('VULKANHEADERS_REMOTE', 'default')] + +def versions(env: Environment, update: bool = False): + if env.get('VULKANHEADERS_REMOTE') == 'mewin': + return [(0, 0, 0)] + tags = env.GitTags(repo_name = _get_repo_name(env), remote_url = _get_repo_url(env), force_fetch=update) + result = [] + for tag in tags: + match = _TAG_PATTERN.match(tag) + if match: + result.append((int(match.groups()[0]), int(match.groups()[1]), int(match.groups()[2]))) + return result + +def dependencies(env: Environment, version) -> 'dict': + return {} + +def cook(env: Environment, version) -> dict: + if env.get('VULKANHEADERS_REMOTE') == 'mewin': + git_ref = 'main' + else: + git_ref = f'refs/tags/v{version[0]}.{version[1]}.{version[2]}' + repo = env.GitBranch(repo_name = _get_repo_name(env), remote_url = _get_repo_url(env), git_ref = git_ref) + checkout_root = repo['checkout_root'] + return { + 'CPPPATH': [os.path.join(checkout_root, 'include')] + } diff --git a/recipes/X11/recipe.py b/recipes/X11/recipe.py new file mode 100644 index 0000000..d74bd0b --- /dev/null +++ b/recipes/X11/recipe.py @@ -0,0 +1,23 @@ + + +import os +from SCons.Script import * + + +def available(env: Environment): + if os.name != 'posix': + return 'X11 is only available on Linux.' + +def versions(env: Environment, update: bool = False): + if os.name == 'posix': + return [(0, 0, 0)] + else: + return [] + +def dependencies(env: Environment, version) -> 'dict': + return {} + +def cook(env: Environment, version) -> dict: + return { + 'LIBS': ['X11'] + } diff --git a/recipes/Xft/recipe.py b/recipes/Xft/recipe.py new file mode 100644 index 0000000..f7533b4 --- /dev/null +++ b/recipes/Xft/recipe.py @@ -0,0 +1,25 @@ + + +import os +from SCons.Script import * + + +def available(env: Environment): + if os.name != 'posix': + return 'Xft is only available on Linux.' + +def versions(env: Environment, update: bool = False): + if os.name == 'posix': + return [(0, 0, 0)] + else: + return [] + +def dependencies(env: Environment, version) -> 'dict': + return { + 'fontconfig': {} + } + +def cook(env: Environment, version) -> dict: + return { + 'LIBS': ['Xft'] + } diff --git a/recipes/argparse/recipe.py b/recipes/argparse/recipe.py new file mode 100644 index 0000000..bf25eca --- /dev/null +++ b/recipes/argparse/recipe.py @@ -0,0 +1,18 @@ + +import re +from SCons.Script import * + +def _git_cook(env: Environment, repo: dict) -> dict: + checkout_root = repo['checkout_root'] + return { + 'CPPPATH': [os.path.join(checkout_root, 'include')] + } + +env.GitRecipe( + globals = globals(), + repo_name = 'argparse', + repo_url = 'https://github.com/p-ranav/argparse.git', + tag_pattern = re.compile(r'^v([0-9]+)\.([0-9]+)$'), + tag_fn = lambda version: f'v{version[0]}.{version[1]}', + cook_fn = _git_cook +) diff --git a/recipes/boost/recipe.py b/recipes/boost/recipe.py new file mode 100644 index 0000000..73bc190 --- /dev/null +++ b/recipes/boost/recipe.py @@ -0,0 +1,70 @@ + + +import json +import os +import re +import requests +from SCons.Script import * + +_VERSIONS_URL = 'https://api.github.com/repos/boostorg/boost/releases' +_VERSION_PATTERN = re.compile(r'^boost-([0-9]+)\.([0-9]+)\.([0-9]+)$') + +def versions(env: Environment, update: bool = False): + versions_file = os.path.join(env['DOWNLOAD_DIR'], 'boost_versions.json') + if update or not os.path.exists(versions_file): + req = requests.get(_VERSIONS_URL) + versions_data = json.loads(req.text) + result = [] + for version_data in versions_data: + match = _VERSION_PATTERN.match(version_data['name']) + if not match: + continue + result.append((int(match.groups()[0]), int(match.groups()[1]), int(match.groups()[2]))) + with open(versions_file, 'w') as f: + json.dump(result, f) + return result + else: + try: + with open(versions_file, 'r') as f: + return [tuple(v) for v in json.load(f)] + except: + print('boost_versions.json is empty or broken, redownloading.') + return versions(env, update=True) + +def dependencies(env: Environment, version) -> 'dict': + return {} + +def cook(env: Environment, version) -> dict: + if env.get('BOOST_LIBS') is None: + raise Exception('BOOST_LIBS not set. Set to a list of boost libs to link or "*" to link everything.') + if version >= (1, 85, 0): + url = f'https://github.com/boostorg/boost/releases/download/boost-{version[0]}.{version[1]}.{version[2]}/boost-{version[0]}.{version[1]}.{version[2]}-cmake.tar.gz' + else: + url = f'https://github.com/boostorg/boost/releases/download/boost-{version[0]}.{version[1]}.{version[2]}/boost-{version[0]}.{version[1]}.{version[2]}.tar.gz' + repo = env.DownloadAndExtract(f'boost_{version[0]}.{version[1]}.{version[2]}', url = url, skip_folders = 1) + checkout_root = repo['extracted_root'] + build_result = env.CMakeProject(checkout_root) + + libs = [] + if '*' in env['BOOST_LIBS']: + lib_dir = build_result['LIBPATH'][0] + for lib_file in os.listdir(lib_dir): + fname = os.path.join(lib_dir, lib_file) + if not os.path.isfile(fname): + continue + libs.append(fname) + else: + for lib in set(env['BOOST_LIBS']): + if os.name == 'posix': + libs.append(env.FindLib(f'boost_{lib}', paths=build_result['LIBPATH'])) + elif os.name == 'nt': + libs.append(env.FindLib(f'libboost_{lib}-*', paths=build_result['LIBPATH'], use_glob=True)) + else: + raise Exception('Boost not supported on this platform.') + cpppath = { + 'nt': [f'{build_result['CPPPATH'][0]}/boost-{version[0]}_{version[1]}'] + }.get(os.name, build_result['CPPPATH']) + return { + 'CPPPATH': cpppath, + 'LIBS': libs + } diff --git a/recipes/cgltf/recipe.py b/recipes/cgltf/recipe.py new file mode 100644 index 0000000..b821bcb --- /dev/null +++ b/recipes/cgltf/recipe.py @@ -0,0 +1,19 @@ + +import re +from SCons.Script import * + +def _git_cook(env: Environment, repo) -> dict: + checkout_root = repo['checkout_root'] + return { + 'CPPPATH': [checkout_root] + } + + +env.GitRecipe( + globals = globals(), + repo_name = 'cgltf', + repo_url = 'https://github.com/jkuhlmann/cgltf.git', + tag_pattern = re.compile(r'^v([0-9]+)\.([0-9]+)$'), + tag_fn = lambda version: f'v{version[0]}.{version[1]}', + cook_fn = _git_cook +) diff --git a/recipes/curl/recipe.py b/recipes/curl/recipe.py new file mode 100644 index 0000000..0fb85fc --- /dev/null +++ b/recipes/curl/recipe.py @@ -0,0 +1,54 @@ + +import re +from SCons.Script import * + +def _build_lib_name(env: Environment) -> str: + if os.name == 'posix': + return { + 'debug': 'curl-d' + }.get(env['BUILD_TYPE'], 'curl') + elif os.name == 'nt': + return { + 'debug': 'libcurl-d' + }.get(env['BUILD_TYPE'], 'libcurl') + else: + raise Exception('curl is not supported yet on this OS') + +def _git_cook(env: Environment, repo: dict) -> dict: + checkout_root = repo['checkout_root'] + build_result = env.CMakeProject(checkout_root, generate_args=['-DBUILD_CURL_EXE=OFF','-DBUILD_SHARED_LIBS=OFF', + '-DBUILD_STATIC_LIBS=ON', '-DHTTP_ONLY=ON', + '-DCURL_USE_LIBSSH2=OFF']) + lib_name = _build_lib_name(env) + return { + 'CPPPATH': build_result['CPPPATH'], + 'LIBS': [env.FindLib(lib_name, paths=build_result['LIBPATH'])], + 'CPPDEFINES': ['CURL_STATICLIB=1'] + } + +def _git_dependencies(env: Environment, version) -> 'dict': + deps = { + 'posix': { + 'openssl': {}, + 'zlib': {}, + 'psl': {} + }, + 'nt': { + 'wincrypt': {}, + 'winldap': {}, + 'winsock2': {} + } + }.get(os.name, {}) + if os.name == 'posix' and version >= (8, 10, 0): + deps['nghttp2'] = {} + return deps + +env.GitRecipe( + globals = globals(), + repo_name = 'curl', + repo_url = 'https://github.com/curl/curl.git', + tag_pattern = re.compile(r'^curl-([0-9]+)_([0-9]+)_([0-9]+)$'), + tag_fn = lambda version: f'curl-{version[0]}_{version[1]}_{version[2]}', + cook_fn = _git_cook, + dependencies = _git_dependencies +) diff --git a/recipes/directx12/recipe.py b/recipes/directx12/recipe.py new file mode 100644 index 0000000..f9ff8be --- /dev/null +++ b/recipes/directx12/recipe.py @@ -0,0 +1,23 @@ + + +import os +from SCons.Script import * + + +def available(env: Environment): + if os.name != 'nt': + return 'DirectX12 is only available on Windows.' + +def versions(env: Environment, update: bool = False): + if os.name == 'nt': + return [(0, 0, 0)] + else: + return [] + +def dependencies(env: Environment, version) -> 'dict': + return {} + +def cook(env: Environment, version) -> dict: + return { + 'LIBS': ['dxgi', 'd3d12'] + } diff --git a/recipes/dxc/recipe.py b/recipes/dxc/recipe.py new file mode 100644 index 0000000..8b6a685 --- /dev/null +++ b/recipes/dxc/recipe.py @@ -0,0 +1,31 @@ + + +import re +from SCons.Script import * + + +def _git_cook(env: Environment, repo: dict) -> dict: + checkout_root = repo['checkout_root'] + build_result = env.CMakeProject(checkout_root, generate_args = [ + f'-C{repo['checkout_root']}/cmake/caches/PredefinedParams.cmake', + '-DLLVM_INSTALL_TOOLCHAIN_ONLY=ON' + ]) + + link_flags = [] + if env['COMPILER_FAMILY'] in ('gcc', 'clang') and env['BUILD_TYPE'] != 'release': + link_flags.append(f'-Wl,-rpath,{build_result["LIBPATH"][0]}') + return { + 'CPPPATH': build_result['CPPPATH'], + 'LIBS': [env.FindLib('dxcompiler', type='shared', paths=build_result['LIBPATH'])], + 'LINKFLAGS': link_flags + } + + +env.GitRecipe( + globals = globals(), + repo_name = 'dxc', + repo_url = 'https://github.com/microsoft/DirectXShaderCompiler.git', + tag_pattern = re.compile(r'^v([0-9]+)\.([0-9]+)\.([0-9]+)$'), + tag_fn = lambda version: f'v{version[0]}.{version[1]}.{version[2]}', + cook_fn = _git_cook +) diff --git a/recipes/fmt/recipe.py b/recipes/fmt/recipe.py new file mode 100644 index 0000000..e08805c --- /dev/null +++ b/recipes/fmt/recipe.py @@ -0,0 +1,27 @@ + + +import re +from SCons.Script import * + + +def _git_cook(env: Environment, repo: dict) -> dict: + checkout_root = repo['checkout_root'] + build_result = env.CMakeProject(checkout_root, generate_args=['-DFMT_TEST=OFF']) + + lib_name = { + 'debug': 'fmtd' + }.get(env['BUILD_TYPE'], 'fmt') + return { + 'CPPPATH': build_result['CPPPATH'], + 'LIBS': [env.FindLib(lib_name, paths=build_result['LIBPATH'])] + } + + +env.GitRecipe( + globals = globals(), + repo_name = 'fmt', + repo_url = 'https://github.com/fmtlib/fmt.git', + tag_pattern = re.compile(r'^([0-9]+)\.([0-9]+)\.([0-9]+)$'), + tag_fn = lambda version: f'{version[0]}.{version[1]}.{version[2]}', + cook_fn = _git_cook +) diff --git a/recipes/fontconfig/recipe.py b/recipes/fontconfig/recipe.py new file mode 100644 index 0000000..1f5435b --- /dev/null +++ b/recipes/fontconfig/recipe.py @@ -0,0 +1,25 @@ + + +import os +from SCons.Script import * + + +def available(env: Environment): + if os.name != 'posix': + return 'Fontconfig is only available on Linux.' + +def versions(env: Environment, update: bool = False): + if os.name == 'posix': + return [(0, 0, 0)] + else: + return [] + +def dependencies(env: Environment, version) -> 'dict': + return { + 'freetype': {} + } + +def cook(env: Environment, version) -> dict: + return { + 'LIBS': ['fontconfig'] + } diff --git a/recipes/freetype/recipe.py b/recipes/freetype/recipe.py new file mode 100644 index 0000000..774f096 --- /dev/null +++ b/recipes/freetype/recipe.py @@ -0,0 +1,23 @@ + + +import os +from SCons.Script import * + + +def available(env: Environment): + if os.name != 'posix': + return 'Freetype is only available on Linux.' + +def versions(env: Environment, update: bool = False): + if os.name == 'posix': + return [(0, 0, 0)] + else: + return [] + +def dependencies(env: Environment, version) -> 'dict': + return {} + +def cook(env: Environment, version) -> dict: + return { + 'LIBS': ['freetype'] + } diff --git a/recipes/glm/recipe.py b/recipes/glm/recipe.py new file mode 100644 index 0000000..6960ede --- /dev/null +++ b/recipes/glm/recipe.py @@ -0,0 +1,52 @@ + +import re +from SCons.Script import * + +_REPO_NAMES = { + 'default': 'glm', + 'mewin': 'glm_mewin' +} +_REPO_URLS = { + 'default': 'https://github.com/g-truc/glm.git', + 'mewin': 'https://git.mewin.de/mewin/glm.git' +} +_TAG_PATTERN = re.compile(r'^([0-9]+)\.([0-9]+)\.([0-9]+)$') +_TAG_PATTERN_ALT = re.compile(r'^0\.([0-9]+)\.([0-9]+)\.([0-9]+)$') + +def _get_repo_name(env: Environment) -> str: + return _REPO_NAMES[env.get('GLM_REMOTE', 'default')] + +def _get_repo_url(env: Environment) -> str: + return _REPO_URLS[env.get('GLM_REMOTE', 'default')] + +def versions(env: Environment, update: bool = False): + if env.get('GLM_REMOTE') == 'mewin': + return [(0, 0, 0)] + + tags = env.GitTags(repo_name = _get_repo_name(env), remote_url = _get_repo_url(env), force_fetch=update) + result = [] + for tag in tags: + match = _TAG_PATTERN.match(tag) + if match: + result.append((int(match.groups()[0]), int(match.groups()[1]), int(match.groups()[2]))) + else: + match = _TAG_PATTERN_ALT.match(tag) + if match: + result.append((0, int(match.groups()[0]), int(match.groups()[1]) * 10 + int(match.groups()[2]))) + return result + +def dependencies(env: Environment, version) -> 'dict': + return {} + +def cook(env: Environment, version) -> dict: + if env.get('GLM_REMOTE') == 'mewin': + git_ref = 'master' + elif version[0] == 0: + git_ref = f'refs/tags/0.{version[1]}.{int(version[2]/10)}.{version[2]%10}' + else: + git_ref = f'refs/tags/{version[0]}.{version[1]}.{version[2]}' + repo = env.GitBranch(repo_name = _get_repo_name(env), remote_url = _get_repo_url(env), git_ref = git_ref) + checkout_root = repo['checkout_root'] + return { + 'CPPPATH': [checkout_root], + } diff --git a/recipes/glslang/recipe.py b/recipes/glslang/recipe.py new file mode 100644 index 0000000..c1a4d16 --- /dev/null +++ b/recipes/glslang/recipe.py @@ -0,0 +1,120 @@ + +import glob +import pathlib +import platform +import re +import shutil +from SCons.Script import * + +_SCRIPT_STAMPFILE = '.spp_script_run' + + +def _git_cook(env: Environment, repo, options: dict = {}) -> dict: + checkout_root = repo['checkout_root'] + enable_hlsl = options.get('enable_hlsl', False) + + # TODO: windows? + did_run_script = os.path.exists(os.path.join(repo['checkout_root'], _SCRIPT_STAMPFILE)) + if not did_run_script or env['UPDATE_REPOSITORIES']: + python_exe = os.path.realpath(sys.executable) + script_file = os.path.join(repo['checkout_root'], 'update_glslang_sources.py') + prev_cwd = os.getcwd() + os.chdir(repo['checkout_root']) + if env.Execute(f'"{python_exe}" {script_file}'): + env.Exit(1) + os.chdir(prev_cwd) + pathlib.Path(repo['checkout_root'], _SCRIPT_STAMPFILE).touch() + + # generate the build_info.h + generator_script = os.path.join(repo['checkout_root'], 'build_info.py') + generator_script_input = os.path.join(repo['checkout_root'], 'build_info.h.tmpl') + generator_script_output = os.path.join(repo['checkout_root'], 'glslang/build_info.h') + env.Command( + target = generator_script_output, + source = [generator_script, generator_script_input, os.path.join(repo['checkout_root'], 'CHANGES.md')], + action = f'"$PYTHON" "{generator_script}" "{repo["checkout_root"]}" -i "{generator_script_input}" -o "$TARGET"' + ) + + platform_source_dir = { + 'Linux': 'Unix', + 'Windows': 'Windows', + 'Darwin': 'Unix' + }.get(platform.system(), 'Unix') + glslang_source_files = env.RGlob(os.path.join(repo['checkout_root'], 'glslang/GenericCodeGen/'), '*.cpp') \ + + env.RGlob(os.path.join(repo['checkout_root'], 'glslang/MachineIndependent/'), '*.cpp') \ + + env.RGlob(os.path.join(repo['checkout_root'], 'glslang/OGLCompilersDLL/'), '*.cpp') \ + + env.RGlob(os.path.join(repo['checkout_root'], 'glslang/ResourceLimits/'), '*.cpp') \ + + env.RGlob(os.path.join(repo['checkout_root'], 'SPIRV/'), '*.cpp') \ + + [os.path.join(repo['checkout_root'], f'glslang/OSDependent/{platform_source_dir}/ossource.cpp')] + if enable_hlsl: + glslang_source_files.extend(env.RGlob(os.path.join(repo['checkout_root'], 'glslang/HLSL/'), '*.cpp')) + + # disable warnings + additional_cxx_flags = { + 'clang': ['-w'], + 'gcc': ['-w'], + 'cl': ['/w'] + }.get(env['COMPILER_FAMILY'], []) + additional_cppdefines = [] + + if enable_hlsl: + additional_cppdefines.append('ENABLE_HLSL=1') + + env.StaticLibrary( + CCFLAGS = env['CCFLAGS'] + additional_cxx_flags, + CPPPATH = repo['checkout_root'], + CPPDEFINES = list(env['CPPDEFINES']) + additional_cppdefines, + target = env['LIB_DIR'] + '/glslang_full', + source = glslang_source_files + ) + + # build the include folder + include_dir = os.path.join(checkout_root, 'include') + if not os.path.exists(include_dir) or env['UPDATE_REPOSITORIES']: + def copy_headers(dst, src): + os.makedirs(dst, exist_ok=True) + for file in glob.glob(os.path.join(src, '*.h')): + shutil.copy(file, dst) + + copy_headers(os.path.join(include_dir, 'glslang/HLSL'), os.path.join(checkout_root, 'glslang/HLSL')) + copy_headers(os.path.join(include_dir, 'glslang/Include'), os.path.join(checkout_root, 'glslang/Include')) + copy_headers(os.path.join(include_dir, 'glslang/MachineIndependent'), os.path.join(checkout_root, 'glslang/MachineIndependent')) + copy_headers(os.path.join(include_dir, 'glslang/Public'), os.path.join(checkout_root, 'glslang/Public')) + copy_headers(os.path.join(include_dir, 'glslang/SPIRV'), os.path.join(checkout_root, 'SPIRV')) + + return { + 'CPPPATH': [include_dir], + 'LIBS': [os.path.join(env['LIB_DIR'], env.LibFilename('glslang_full'))] + } + + + +_REPO_NAMES = { + 'default': 'glslang', + 'mewin': 'glslang_mewin' +} +_REPO_URLS = { + 'default': 'https://github.com/KhronosGroup/glslang.git', + 'mewin': 'https://git.mewin.de/mewin/glslang.git' +} +_TAG_PATTERNS = { + 'default': re.compile(r'^([0-9]+)\.([0-9]+)\.([0-9]+)$'), + 'mewin': None +} +def _ref_fn(env: Environment, version) -> str: + remote = env.get('GLSLANG_REMOTE', 'default') + if remote == 'default': + return f'refs/tags/{version[0]}.{version[1]}.{version[2]}' + elif remote == 'mewin': + return 'master' + else: + raise Exception('invalid glslang remote') + +env.GitRecipe( + globals = globals(), + repo_name = lambda env: _REPO_NAMES[env.get('GLSLANG_REMOTE', 'default')], + repo_url = lambda env: _REPO_URLS[env.get('GLSLANG_REMOTE', 'default')], + tag_pattern = lambda env: _TAG_PATTERNS[env.get('GLSLANG_REMOTE', 'default')], + cook_fn = _git_cook, + ref_fn = _ref_fn +) diff --git a/recipes/gsl/recipe.py b/recipes/gsl/recipe.py new file mode 100644 index 0000000..d40527c --- /dev/null +++ b/recipes/gsl/recipe.py @@ -0,0 +1,20 @@ + +import os +import re +from SCons.Script import * + +def _git_cook(env: Environment, repo: dict) -> dict: + checkout_root = repo['checkout_root'] + return { + 'CPPPATH': [os.path.join(checkout_root, 'include')] + } + + +env.GitRecipe( + globals = globals(), + repo_name = 'gsl', + repo_url = 'https://github.com/microsoft/GSL.git', + tag_pattern = re.compile(r'^v([0-9]+)\.([0-9]+)\.([0-9]+)$'), + tag_fn = lambda version: f'v{version[0]}.{version[1]}.{version[2]}', + cook_fn = _git_cook +) diff --git a/recipes/icon_font_cpp_headers/recipe.py b/recipes/icon_font_cpp_headers/recipe.py new file mode 100644 index 0000000..b4565a3 --- /dev/null +++ b/recipes/icon_font_cpp_headers/recipe.py @@ -0,0 +1,26 @@ + +import glob +import os +import shutil +from SCons.Script import * + +_REPO_NAME = 'icon_font_cpp_headers' +_REPO_URL = 'https://github.com/juliettef/IconFontCppHeaders.git' + +def versions(env: Environment, update: bool = False): + return [(0, 0, 0)] + +def dependencies(env: Environment, version) -> 'dict': + return {} + +def cook(env: Environment, version) -> dict: + repo = env.GitBranch(repo_name = _REPO_NAME, remote_url = _REPO_URL, git_ref = 'main') + checkout_root = repo['checkout_root'] + include_dir = os.path.join(checkout_root, 'include') + headers_dir = os.path.join(include_dir, 'ifch') + os.makedirs(headers_dir, exist_ok=True) + for header_file in glob.glob(os.path.join(checkout_root, '*.h')): + shutil.copy(header_file, headers_dir) + return { + 'CPPPATH': [include_dir] + } diff --git a/recipes/idn2/recipe.py b/recipes/idn2/recipe.py new file mode 100644 index 0000000..fe2c65d --- /dev/null +++ b/recipes/idn2/recipe.py @@ -0,0 +1,48 @@ + + + +import json +import os +import re +import requests +from SCons.Script import * + +_VERSIONS_URL = 'https://gitlab.com/api/v4/projects/2882658/releases' +_VERSION_PATTERN = re.compile(r'^([0-9]+)\.([0-9]+)\.([0-9]+)$') + +def versions(env: Environment, update: bool = False): + versions_file = os.path.join(env['DOWNLOAD_DIR'], 'libidn2_versions.json') + if update or not os.path.exists(versions_file): + req = requests.get(_VERSIONS_URL) + versions_data = json.loads(req.text) + result = [] + for version_data in versions_data: + match = _VERSION_PATTERN.match(version_data['name']) + if not match: + continue + result.append((int(match.groups()[0]), int(match.groups()[1]), int(match.groups()[2]))) + with open(versions_file, 'w') as f: + json.dump(result, f) + return result + else: + try: + with open(versions_file, 'r') as f: + return [tuple(v) for v in json.load(f)] + except: + print('libidn2_versions.json is empty or broken, redownloading.') + return versions(env, update=True) + +def dependencies(env: Environment, version) -> 'dict': + return { + 'unistring': {} + } + +def cook(env: Environment, version) -> dict: + url = f'https://ftp.gnu.org/gnu/libidn/libidn2-{version[0]}.{version[1]}.{version[2]}.tar.gz' + repo = env.DownloadAndExtract(f'libidn2_{version[0]}.{version[1]}.{version[2]}', url = url, skip_folders = 1) + checkout_root = repo['extracted_root'] + build_result = env.AutotoolsProject(checkout_root) + return { + 'CPPPATH': build_result['CPPPATH'], + 'LIBS': [env.FindLib('idn2', paths=build_result['LIBPATH'])] + } diff --git a/recipes/imgui-node-editor/recipe.py b/recipes/imgui-node-editor/recipe.py new file mode 100644 index 0000000..27a2a36 --- /dev/null +++ b/recipes/imgui-node-editor/recipe.py @@ -0,0 +1,48 @@ + + +import re +from SCons.Script import * + + +def _git_cook(env: Environment, repo: dict) -> dict: + ine_source_files = [ + os.path.join(repo['checkout_root'], 'crude_json.cpp'), + os.path.join(repo['checkout_root'], 'imgui_canvas.cpp'), + os.path.join(repo['checkout_root'], 'imgui_node_editor.cpp'), + os.path.join(repo['checkout_root'], 'imgui_node_editor_api.cpp') + ] + + + ccflags = list(env['CCFLAGS']) + if env['COMPILER_FAMILY'] == 'cl': + ccflags.append('/wd4100') + elif env['COMPILER_FAMILY'] == 'gcc': + ccflags.extend(('-Wno-comment', '-Wno-unused-but-set-variable', '-Wno-unused-parameter')) + lib_ine = env.StaticLibrary( + CPPPATH = [repo['checkout_root']], + CCFLAGS = ccflags, + target = env['LIB_DIR'] + '/imgui_node_editor', + source = ine_source_files, + dependencies = { + 'imgui': { + 'min': (1, 72, 0) + } + } + ) + return { + 'CPPPATH': [repo['checkout_root']], + 'LIBS': [lib_ine] + } + + +env.GitRecipe( + globals = globals(), + repo_name = 'imgui-node-editor', + repo_url = 'https://github.com/thedmd/imgui-node-editor.git', + tag_pattern = re.compile(r'^v([0-9]+)\.([0-9]+)\.([0-9]+)$'), + tag_fn = lambda version: f'v{version[0]}.{version[1]}.{version[2]}', + cook_fn = _git_cook, + dependencies = { + 'imgui': {} + } +) diff --git a/recipes/imgui/recipe.py b/recipes/imgui/recipe.py new file mode 100644 index 0000000..c357069 --- /dev/null +++ b/recipes/imgui/recipe.py @@ -0,0 +1,64 @@ + + +from itertools import chain +import re +from SCons.Script import * + +_BACKEND_DEPENDENCIES = { + 'sdl3': { + 'SDL': { + 'min': (3, 0, 0) + } + } +} + +def _dependencies(env: Environment, version, options: dict) -> dict: + deps = {} + for backend in chain(env.get('IMGUI_BACKENDS', []), options.get('backends', [])): + deps.update(_BACKEND_DEPENDENCIES.get(backend, {})) + return deps + +def _git_cook(env: Environment, repo: dict, options: dict) -> dict: + imgui_source_files = [ + os.path.join(repo['checkout_root'], 'imgui.cpp'), + os.path.join(repo['checkout_root'], 'imgui_draw.cpp'), + os.path.join(repo['checkout_root'], 'imgui_tables.cpp'), + os.path.join(repo['checkout_root'], 'imgui_widgets.cpp') + ] + + for backend in chain(env.get('IMGUI_BACKENDS', []), options.get('backends', [])): + imgui_source_files.append(os.path.join(repo['checkout_root'], 'backends', f'imgui_impl_{backend}.cpp')) + + lib_imgui = env.StaticLibrary( + CPPPATH = [repo['checkout_root']], + CPPDEFINES = ['IMGUI_IMPL_VULKAN_NO_PROTOTYPES=1'], + target = env['LIB_DIR'] + '/imgui', + source = imgui_source_files, + dependencies = _dependencies(env, None, options) + ) + return { + 'CPPPATH': [repo['checkout_root']], + 'LIBS': [lib_imgui] + } + +def _tag_pattern(env, options: dict): + if options.get('docking'): + return re.compile(r'^v([0-9]+)\.([0-9]+)\.([0-9]+)\-docking$') + else: + return re.compile(r'^v([0-9]+)\.([0-9]+)\.([0-9]+)$') + +def _tag_fn(version, options: dict) -> str: + if options.get('docking'): + return f'v{version[0]}.{version[1]}.{version[2]}-docking' + else: + return f'v{version[0]}.{version[1]}.{version[2]}' + +env.GitRecipe( + globals = globals(), + repo_name = 'imgui', + repo_url = 'https://github.com/ocornut/imgui.git', + tag_pattern = _tag_pattern, + tag_fn = _tag_fn, + cook_fn = _git_cook, + dependencies = _dependencies +) diff --git a/recipes/iwa/recipe.py b/recipes/iwa/recipe.py new file mode 100644 index 0000000..9c2a2b2 --- /dev/null +++ b/recipes/iwa/recipe.py @@ -0,0 +1,20 @@ + +import json +from SCons.Script import * + +_REPO_NAME = 'iwa' +_REPO_URL = 'https://git.mewin.de/mewin/iwa.git' + +def versions(env: Environment, update: bool = False): + return [(0, 0, 0)] + +def dependencies(env: Environment, version) -> 'dict': + repo = env.GitBranch(repo_name = _REPO_NAME, remote_url = _REPO_URL, git_ref = 'master') + checkout_root = repo['checkout_root'] + with open(os.path.join(checkout_root, 'dependencies.json'), 'r') as f: + return env.DepsFromJson(json.load(f)) + +def cook(env: Environment, version) -> dict: + repo = env.GitBranch(repo_name = _REPO_NAME, remote_url = _REPO_URL, git_ref = 'master') + checkout_root = repo['checkout_root'] + return env.Module(os.path.join(checkout_root, 'SModule')) diff --git a/recipes/json/recipe.py b/recipes/json/recipe.py new file mode 100644 index 0000000..6888cb8 --- /dev/null +++ b/recipes/json/recipe.py @@ -0,0 +1,22 @@ + + +import re +from SCons.Script import * + + +def _git_cook(env: Environment, repo: dict) -> dict: + checkout_root = repo['checkout_root'] + build_result = env.CMakeProject(project_root=checkout_root) + return { + 'CPPPATH': build_result['CPPPATH'] + } + + +env.GitRecipe( + globals = globals(), + repo_name = 'json', + repo_url = 'https://github.com/nlohmann/json.git', + tag_pattern = re.compile(r'^v([0-9]+)\.([0-9]+)\.([0-9]+)$'), + tag_fn = lambda version: f'v{version[0]}.{version[1]}.{version[2]}', + cook_fn = _git_cook +) diff --git a/recipes/libbacktrace/recipe.py b/recipes/libbacktrace/recipe.py new file mode 100644 index 0000000..00d4d89 --- /dev/null +++ b/recipes/libbacktrace/recipe.py @@ -0,0 +1,21 @@ + + +from SCons.Script import * + +def versions(env: Environment, update: bool = False): + return [(1, 0)] + +def dependencies(env: Environment, version) -> 'dict': + return {} + +def cook(env: Environment, version) -> dict: + if env['COMPILER_FAMILY'] not in ('gcc', 'clang'): + env.Error('libbacktrace requires gcc or clang.') + repo = env.GitBranch(repo_name = 'libbacktrace', remote_url = 'https://github.com/ianlancetaylor/libbacktrace.git', git_ref = 'master') + checkout_root = repo['checkout_root'] + build_result = env.AutotoolsProject(checkout_root) + return { + 'LIBPATH': build_result['LIBPATH'], + 'CPPPATH': build_result['CPPPATH'], + 'LIBS': ['backtrace'] + } diff --git a/recipes/libjpeg-turbo/recipe.py b/recipes/libjpeg-turbo/recipe.py new file mode 100644 index 0000000..bb6278c --- /dev/null +++ b/recipes/libjpeg-turbo/recipe.py @@ -0,0 +1,21 @@ + +import re +from SCons.Script import * + +def _git_cook(env: Environment, repo: dict) -> dict: + checkout_root = repo['checkout_root'] + build_result = env.CMakeProject(checkout_root) + return { + 'CPPPATH': build_result['CPPPATH'], + 'LIBS': [env.FindLib('jpeg', paths=build_result['LIBPATH'])], + } + + +env.GitRecipe( + globals = globals(), + repo_name = 'libjpeg-turbo', + repo_url = 'https://github.com/libjpeg-turbo/libjpeg-turbo.git', + tag_pattern = re.compile(r'^([0-9]+)\.([0-9]+)\.([0-9]+)$'), + tag_fn = lambda version: f'{version[0]}.{version[1]}.{version[2]}', + cook_fn = _git_cook +) diff --git a/recipes/libpng/recipe.py b/recipes/libpng/recipe.py new file mode 100644 index 0000000..57b020d --- /dev/null +++ b/recipes/libpng/recipe.py @@ -0,0 +1,39 @@ + +import os +import re +from SCons.Script import * + +def _build_lib_name(env: Environment) -> str: + if os.name == 'posix': + return { + 'debug': 'png16d' + }.get(env['BUILD_TYPE'], 'png16') + elif os.name == 'nt': + return { + 'debug': 'libpng16_staticd' + }.get(env['BUILD_TYPE'], 'libpng16_static') + else: + raise Exception('libpng is not supported yet on this OS') + +def _git_cook(env: Environment, repo: dict) -> dict: + lib_zlib = env.Cook('zlib') + checkout_root = repo['checkout_root'] + build_result = env.CMakeProject(checkout_root, dependencies = [lib_zlib]) + lib_name = _build_lib_name(env) + return { + 'CPPPATH': build_result['CPPPATH'], + 'LIBS': [env.FindLib(lib_name, paths=build_result['LIBPATH'])] + } + + +env.GitRecipe( + globals = globals(), + repo_name = 'libpng', + repo_url = 'https://git.code.sf.net/p/libpng/code.git', + tag_pattern = re.compile(r'^v([0-9]+)\.([0-9]+)\.([0-9]+)$'), + tag_fn = lambda version: f'v{version[0]}.{version[1]}.{version[2]}', + cook_fn = _git_cook, + dependencies = { + 'zlib': {} + } +) diff --git a/recipes/lua/recipe.py b/recipes/lua/recipe.py new file mode 100644 index 0000000..ee09c73 --- /dev/null +++ b/recipes/lua/recipe.py @@ -0,0 +1,54 @@ + + + +import json +import os +import re +import requests +from SCons.Script import * + +_VERSIONS_URL = 'https://www.lua.org/ftp/' +_VERSION_PATTERN = re.compile(r'HREF="lua-([0-9]+)\.([0-9]+)\.([0-9]+)\.tar\.gz"') + +def versions(env: Environment, update: bool = False): + versions_file = os.path.join(env['DOWNLOAD_DIR'], 'lua_versions.json') + if update or not os.path.exists(versions_file): + req = requests.get(_VERSIONS_URL) + result = [] + for match in _VERSION_PATTERN.finditer(req.text): + result.append((int(match.groups()[0]), int(match.groups()[1]), int(match.groups()[2]))) + with open(versions_file, 'w') as f: + json.dump(result, f) + return result + else: + try: + with open(versions_file, 'r') as f: + return [tuple(v) for v in json.load(f)] + except: + print('lua_versions.json is empty or broken, redownloading.') + return versions(env, update=True) + +def dependencies(env: Environment, version) -> 'dict': + return {} + +def cook(env: Environment, version) -> dict: + url = f'https://www.lua.org/ftp/lua-{version[0]}.{version[1]}.{version[2]}.tar.gz' + repo = env.DownloadAndExtract(f'lua_{version[0]}.{version[1]}.{version[2]}', url = url, skip_folders = 1) + checkout_root = repo['extracted_root'] + src_folder = os.path.join(checkout_root, 'src') + lua_source_files = [f for f in env.RGlob(src_folder, '*.c') if f.name != 'lua.c'] + additional_ccflags = [] + if env['COMPILER_FAMILY'] in ('gcc', 'clang'): + additional_ccflags.append('-Wno-pedantic') + elif env['COMPILER_FAMILY'] == 'cl': + additional_ccflags.extend(['/wd4244', '/wd4310', '/wd4324', '/wd4701']) + lib_lua = env.StaticLibrary( + CCFLAGS = env['CCFLAGS'] + additional_ccflags, # Lua uses a GNU extension for taking addresses of labels + target = env['LIB_DIR'] + '/lua_full', + source = lua_source_files + ) + + return { + 'CPPPATH': [src_folder], + 'LIBS': [lib_lua] + } diff --git a/recipes/magic_enum/recipe.py b/recipes/magic_enum/recipe.py new file mode 100644 index 0000000..826602b --- /dev/null +++ b/recipes/magic_enum/recipe.py @@ -0,0 +1,20 @@ + +import os +import re +from SCons.Script import * + +def _git_cook(env: Environment, repo: dict) -> dict: + checkout_root = repo['checkout_root'] + return { + 'CPPPATH': [os.path.join(checkout_root, 'include')] + } + + +env.GitRecipe( + globals = globals(), + repo_name = 'magic_enum', + repo_url = 'https://github.com/Neargye/magic_enum.git', + tag_pattern = re.compile(r'^v([0-9]+)\.([0-9]+)\.([0-9]+)$'), + tag_fn = lambda version: f'v{version[0]}.{version[1]}.{version[2]}', + cook_fn = _git_cook +) diff --git a/recipes/mecab/recipe.py b/recipes/mecab/recipe.py new file mode 100644 index 0000000..3e58c62 --- /dev/null +++ b/recipes/mecab/recipe.py @@ -0,0 +1,21 @@ + +from SCons.Script import * + +import os + + +def versions(env: Environment, update: bool = False): + return [(1, 0)] + +def dependencies(env: Environment, version) -> 'dict': + return {} + +def cook(env: Environment, version) -> dict: + repo = env.GitBranch(repo_name = 'mecab', remote_url = 'https://github.com/taku910/mecab.git', git_ref = 'master') + checkout_root = repo['checkout_root'] + build_result = env.AutotoolsProject(os.path.join(checkout_root, 'mecab')) + return { + 'LIBPATH': build_result['LIBPATH'], + 'CPPPATH': build_result['CPPPATH'], + 'LIBS': ['mecab'] + } diff --git a/recipes/mijin/recipe.py b/recipes/mijin/recipe.py new file mode 100644 index 0000000..e9031f3 --- /dev/null +++ b/recipes/mijin/recipe.py @@ -0,0 +1,20 @@ + +import json +from SCons.Script import * + +_REPO_NAME = 'mijin' +_REPO_URL = 'https://git.mewin.de/mewin/mijin2.git' + +def versions(env: Environment, update: bool = False): + return [(0, 0, 0)] + +def dependencies(env: Environment, version) -> 'dict': + repo = env.GitBranch(repo_name = _REPO_NAME, remote_url = _REPO_URL, git_ref = 'master') + checkout_root = repo['checkout_root'] + with open(os.path.join(checkout_root, 'dependencies.json'), 'r') as f: + return env.DepsFromJson(json.load(f)) + +def cook(env: Environment, version) -> dict: + repo = env.GitBranch(repo_name = _REPO_NAME, remote_url = _REPO_URL, git_ref = 'master') + checkout_root = repo['checkout_root'] + return env.Module(os.path.join(checkout_root, 'SModule')) diff --git a/recipes/mikktspace/recipe.py b/recipes/mikktspace/recipe.py new file mode 100644 index 0000000..c4826bb --- /dev/null +++ b/recipes/mikktspace/recipe.py @@ -0,0 +1,27 @@ + + +from SCons.Script import * + +def versions(env: Environment, update: bool = False): + return [(1, 0)] + +def dependencies(env: Environment, version) -> 'dict': + return {} + +def cook(env: Environment, version) -> dict: + repo = env.GitBranch(repo_name = 'mikktspace', remote_url = 'https://github.com/mmikk/MikkTSpace.git', git_ref = 'master') + checkout_root = repo['checkout_root'] + ccflags = env['CCFLAGS'].copy() + if env['COMPILER_FAMILY'] == 'cl': + ccflags.append('/wd4456') + lib_mikktspace = env.StaticLibrary( + CCFLAGS = ccflags, + CPPPATH = [checkout_root], + target = env['LIB_DIR'] + '/mikktspace', + source = [os.path.join(repo['checkout_root'], 'mikktspace.c')] + ) + return { + 'CPPPATH': [checkout_root], + 'LIBS': [lib_mikktspace] + } + diff --git a/recipes/nana/recipe.py b/recipes/nana/recipe.py new file mode 100644 index 0000000..b0c88a4 --- /dev/null +++ b/recipes/nana/recipe.py @@ -0,0 +1,37 @@ + + +import os +import re +from SCons.Script import * + + +def _git_cook(env: Environment, repo: dict) -> dict: + checkout_root = repo['checkout_root'] + build_result = env.CMakeProject(checkout_root, generate_args = ['-DNANA_CMAKE_INSTALL=ON']) + + lib_name = 'nana' + return { + 'CPPPATH': build_result['CPPPATH'], + 'LIBS': [env.FindLib(lib_name, paths=build_result['LIBPATH'])] + } + +def _dependencies(env: Environment, version) -> dict: + result = {} + if os.name == 'nt': + pass + elif os.name == 'posix': + result.update({ + 'X11': {}, + 'Xft': {} + }) + return result + +env.GitRecipe( + globals = globals(), + repo_name = 'nana', + repo_url = 'httpshttps://github.com/mewin/nana.git', + tag_pattern = re.compile(r'^v([0-9]+)\.([0-9]+)\.([0-9]+)$'), + tag_fn = lambda version: f'v{version[0]}.{version[1]}.{version[2]}', + cook_fn = _git_cook, + dependencies = _dependencies +) diff --git a/recipes/openssl/recipe.py b/recipes/openssl/recipe.py new file mode 100644 index 0000000..4df1d99 --- /dev/null +++ b/recipes/openssl/recipe.py @@ -0,0 +1,21 @@ + + +import re +from SCons.Script import * + +def _git_cook(env: Environment, repo: dict) -> dict: + checkout_root = repo['checkout_root'] + build_result = env.AutotoolsProject(checkout_root, config_args = ['no-shared', 'no-tests', 'no-docs'], configure_script_path='Configure') + return { + 'CPPPATH': build_result['CPPPATH'], + 'LIBS': [env.FindLib(libname, paths=build_result['LIBPATH']) for libname in ('ssl', 'crypto')] + } + +env.GitRecipe( + globals = globals(), + repo_name = 'openssl', + repo_url = 'https://github.com/openssl/openssl.git', + tag_pattern = re.compile(r'^openssl-([0-9]+)\.([0-9]+)\.([0-9]+)$'), + tag_fn = lambda version: f'openssl-{version[0]}.{version[1]}.{version[2]}', + cook_fn = _git_cook +) diff --git a/recipes/portable-file-dialogs/recipe.py b/recipes/portable-file-dialogs/recipe.py new file mode 100644 index 0000000..17bc265 --- /dev/null +++ b/recipes/portable-file-dialogs/recipe.py @@ -0,0 +1,22 @@ + + +import re +from SCons.Script import * + + +def _git_cook(env: Environment, repo: dict) -> dict: + checkout_root = repo['checkout_root'] + + return { + 'CPPPATH': [checkout_root] + } + + +env.GitRecipe( + globals = globals(), + repo_name = 'portable-file-dialogs', + repo_url = 'https://github.com/samhocevar/portable-file-dialogs.git', + tag_pattern = re.compile(r'^([0-9]+)\.([0-9]+)\.([0-9]+)$'), + tag_fn = lambda version: f'{version[0]}.{version[1]}.{version[2]}', + cook_fn = _git_cook +) diff --git a/recipes/psl/recipe.py b/recipes/psl/recipe.py new file mode 100644 index 0000000..ddcd3eb --- /dev/null +++ b/recipes/psl/recipe.py @@ -0,0 +1,48 @@ + + +import json +import os +import re +import requests +from SCons.Script import * + +_VERSIONS_URL = 'https://api.github.com/repos/rockdaboot/libpsl/releases' +_VERSION_PATTERN = re.compile(r'^Release v([0-9]+)\.([0-9]+)\.([0-9]+)$') + +def versions(env: Environment, update: bool = False): + versions_file = os.path.join(env['DOWNLOAD_DIR'], 'libpsl_versions.json') + if update or not os.path.exists(versions_file): + req = requests.get(_VERSIONS_URL) + versions_data = json.loads(req.text) + result = [] + for version_data in versions_data: + match = _VERSION_PATTERN.match(version_data['name']) + if not match: + continue + result.append((int(match.groups()[0]), int(match.groups()[1]), int(match.groups()[2]))) + with open(versions_file, 'w') as f: + json.dump(result, f) + return result + else: + try: + with open(versions_file, 'r') as f: + return [tuple(v) for v in json.load(f)] + except: + print('libpsl_versions.json is empty or broken, redownloading.') + return versions(env, update=True) + +def dependencies(env: Environment, version) -> 'dict': + return { + 'idn2': {}, + 'unistring': {} + } + +def cook(env: Environment, version) -> dict: + url = f'https://github.com/rockdaboot/libpsl/releases/download/{version[0]}.{version[1]}.{version[2]}/libpsl-{version[0]}.{version[1]}.{version[2]}.tar.gz' + repo = env.DownloadAndExtract(f'libpsl_{version[0]}.{version[1]}.{version[2]}', url = url, skip_folders = 1) + checkout_root = repo['extracted_root'] + build_result = env.AutotoolsProject(checkout_root) + return { + 'CPPPATH': build_result['CPPPATH'], + 'LIBS': [env.FindLib('psl', paths=build_result['LIBPATH'])] + } diff --git a/recipes/raid/recipe.py b/recipes/raid/recipe.py new file mode 100644 index 0000000..fa0f3d0 --- /dev/null +++ b/recipes/raid/recipe.py @@ -0,0 +1,20 @@ + +import json +from SCons.Script import * + +_REPO_NAME = 'raid' +_REPO_URL = 'https://git.mewin.de/mewin/raid.git' + +def versions(env: Environment, update: bool = False): + return [(0, 0, 0)] + +def dependencies(env: Environment, version) -> 'dict': + repo = env.GitBranch(repo_name = _REPO_NAME, remote_url = _REPO_URL, git_ref = 'master') + checkout_root = repo['checkout_root'] + with open(os.path.join(checkout_root, 'dependencies.json'), 'r') as f: + return env.DepsFromJson(json.load(f)) + +def cook(env: Environment, version) -> dict: + repo = env.GitBranch(repo_name = _REPO_NAME, remote_url = _REPO_URL, git_ref = 'master') + checkout_root = repo['checkout_root'] + return env.Module(os.path.join(checkout_root, 'SModule')) diff --git a/recipes/rectpack2D/recipe.py b/recipes/rectpack2D/recipe.py new file mode 100644 index 0000000..b2d89e7 --- /dev/null +++ b/recipes/rectpack2D/recipe.py @@ -0,0 +1,20 @@ + +import os +from SCons.Script import * + +_REPO_NAME = 'rectpack2D' +_REPO_URL = 'https://github.com/TeamHypersomnia/rectpack2D.git' + + +def versions(env: Environment, update: bool = False): + return [(0, 0, 0)] + +def dependencies(env: Environment, version) -> 'dict': + return {} + +def cook(env: Environment, version) -> dict: + repo = env.GitBranch(repo_name = _REPO_NAME, remote_url = _REPO_URL, git_ref = 'master') + checkout_root = repo['checkout_root'] + return { + 'CPPPATH': [os.path.join(checkout_root, 'src')] + } diff --git a/recipes/sdlpp/recipe.py b/recipes/sdlpp/recipe.py new file mode 100644 index 0000000..6072914 --- /dev/null +++ b/recipes/sdlpp/recipe.py @@ -0,0 +1,18 @@ + +from SCons.Script import * + +_REPO_NAME = 'sdlpp' +_REPO_URL = 'https://git.mewin.de/mewin/sdlpp.git' + +def versions(env: Environment, update: bool = False): + return [(0, 0, 0)] + +def dependencies(env: Environment, version) -> 'dict': + return { + 'SDL': {} + } + +def cook(env: Environment, version) -> dict: + repo = env.GitBranch(repo_name = _REPO_NAME, remote_url = _REPO_URL, git_ref = 'master') + checkout_root = repo['checkout_root'] + return env.Module(os.path.join(checkout_root, 'SModule')) diff --git a/recipes/spdlog/recipe.py b/recipes/spdlog/recipe.py new file mode 100644 index 0000000..498cac5 --- /dev/null +++ b/recipes/spdlog/recipe.py @@ -0,0 +1,34 @@ + +import re +from SCons.Script import * + + +def _git_cook(env: Environment, repo: dict) -> dict: + lib_fmt = env.Cook('fmt') + checkout_root = repo['checkout_root'] + build_result = env.CMakeProject(project_root=checkout_root, dependencies=[lib_fmt]) + + lib_name = { + 'debug': 'spdlogd' + }.get(env['BUILD_TYPE'], 'spdlog') + + cppdefines = ['SPDLOG_COMPILE_LIB=1', 'SPDLOG_FMT_EXTERNAL=1'] + + return { + 'CPPPATH': build_result['CPPPATH'], + 'CPPDEFINES': cppdefines, + 'LIBS': [env.FindLib(lib_name, paths=build_result['LIBPATH'])] + } + + +env.GitRecipe( + globals = globals(), + repo_name = 'spdlog', + repo_url = 'https://github.com/gabime/spdlog.git', + tag_pattern = re.compile(r'^v([0-9]+)\.([0-9]+)\.([0-9]+)$'), + tag_fn = lambda version: f'v{version[0]}.{version[1]}.{version[2]}', + cook_fn = _git_cook, + dependencies = { + 'fmt': {} + } +) diff --git a/recipes/sqlite/recipe.py b/recipes/sqlite/recipe.py new file mode 100644 index 0000000..51e14d5 --- /dev/null +++ b/recipes/sqlite/recipe.py @@ -0,0 +1,83 @@ + +import glob +import os +import pathlib +import re +import shutil +from SCons.Script import * + + +_BUILT_STAMPFILE = '.spp_built' + +def _git_cook(env: Environment, repo: dict) -> dict: + if os.name == 'nt': + def run_cmd(args): + if env.Execute(' '.join([str(s) for s in args])): + Exit(1) + install_dir = os.path.join(repo['checkout_root'], 'install') + stamp_file = pathlib.Path(install_dir, _BUILT_STAMPFILE) + + include_path = os.path.join(install_dir, 'include') + bin_path = os.path.join(install_dir, 'bin') + lib_path = os.path.join(install_dir, 'lib') + if not stamp_file.exists(): + os.makedirs(include_path, exist_ok=True) + os.makedirs(bin_path, exist_ok=True) + os.makedirs(lib_path, exist_ok=True) + + old_cwd = os.getcwd() + os.chdir(repo['checkout_root']) + run_cmd(['nmake', '/f', 'Makefile.msc', 'sqlite3.dll']) + os.chdir(old_cwd) + + include_files = ['sqlite3.h'] + bin_files = ['sqlite3.dll'] + lib_files = ['sqlite3.def', 'sqlite3.lib'] + for file in include_files: + shutil.copy(os.path.join(repo['checkout_root'], file), include_path) + for file in bin_files: + shutil.copy(os.path.join(repo['checkout_root'], file), bin_path) + for file in lib_files: + shutil.copy(os.path.join(repo['checkout_root'], file), lib_path) + stamp_file.touch() + return { + 'CPPPATH': [include_path], + 'LIBPATH': [lib_path], + 'LIBS': ['sqlite3'] + } + else: + checkout_root = repo['checkout_root'] + build_result = env.AutotoolsProject(checkout_root, skip_steps=('install',)) + + # the install script seems borked, do the install manually + include_dir = os.path.join(build_result['install_dir'], 'include') + lib_dir = os.path.join(build_result['install_dir'], 'lib') + os.makedirs(include_dir, exist_ok=True) + os.makedirs(lib_dir, exist_ok=True) + + for ext in ('*.a', '*.so'): + lib_files = glob.glob(os.path.join(build_result['build_dir'], ext)) + for lib_file in lib_files: + out_path = os.path.join(lib_dir, os.path.basename(lib_file)) + if not os.path.exists(out_path): + shutil.copy(lib_file, out_path) + for h_file in ('sqlite3.h',): + out_path = os.path.join(include_dir, h_file) + if not os.path.exists(out_path): + in_path = os.path.join(build_result['build_dir'], h_file) + shutil.copy(in_path, out_path) + + return { + 'CPPPATH': build_result['CPPPATH'], + 'LIBS': [env.FindLib('sqlite3', paths=build_result['LIBPATH'])] + } + +env.GitRecipe( + globals = globals(), + repo_name = 'sqlite', + repo_url = 'https://github.com/sqlite/sqlite.git', + tag_pattern = re.compile(r'^version-([0-9]+)\.([0-9]+)\.([0-9]+)$'), + tag_fn = lambda version: f'version-{version[0]}.{version[1]}.{version[2]}', + cook_fn = _git_cook +) + diff --git a/recipes/stb/recipe.py b/recipes/stb/recipe.py new file mode 100644 index 0000000..29e4e49 --- /dev/null +++ b/recipes/stb/recipe.py @@ -0,0 +1,19 @@ + +from SCons.Script import * + +_REPO_NAME = 'stb' +_REPO_URL = 'https://github.com/nothings/stb.git' + + +def versions(env: Environment, update: bool = False): + return [(0, 0, 0)] + +def dependencies(env: Environment, version) -> 'dict': + return {} + +def cook(env: Environment, version) -> dict: + repo = env.GitBranch(repo_name = _REPO_NAME, remote_url = _REPO_URL, git_ref = 'master') + checkout_root = repo['checkout_root'] + return { + 'CPPPATH': [checkout_root] + } diff --git a/recipes/tinyobjloader/recipe.py b/recipes/tinyobjloader/recipe.py new file mode 100644 index 0000000..a92bb09 --- /dev/null +++ b/recipes/tinyobjloader/recipe.py @@ -0,0 +1,24 @@ + + +import re +from SCons.Script import * + + +def _git_cook(env: Environment, repo: dict) -> dict: + checkout_root = repo['checkout_root'] + build_result = env.CMakeProject(checkout_root) + + return { + 'CPPPATH': build_result['CPPPATH'], + 'LIBS': [env.FindLib('tinyobjloader', paths=build_result['LIBPATH'])] + } + + +env.GitRecipe( + globals = globals(), + repo_name = 'tinyobjloader', + repo_url = 'https://github.com/tinyobjloader/tinyobjloader.git', + tag_pattern = re.compile(r'^v([0-9]+)\.([0-9]+)\.([0-9]+)$'), + tag_fn = lambda version: f'v{version[0]}.{version[1]}.{version[2]}', + cook_fn = _git_cook +) diff --git a/recipes/unistring/recipe.py b/recipes/unistring/recipe.py new file mode 100644 index 0000000..01fa31c --- /dev/null +++ b/recipes/unistring/recipe.py @@ -0,0 +1,42 @@ + + + +import json +import os +import re +import requests +from SCons.Script import * + +_VERSIONS_URL = 'https://ftp.gnu.org/gnu/libunistring/?F=0' +_VERSION_PATTERN = re.compile(r'href="libunistring-([0-9]+)\.([0-9]+)\.([0-9]+)\.tar\.gz"') + +def versions(env: Environment, update: bool = False): + versions_file = os.path.join(env['DOWNLOAD_DIR'], 'libunistring_versions.json') + if update or not os.path.exists(versions_file): + req = requests.get(_VERSIONS_URL) + result = [] + for match in _VERSION_PATTERN.finditer(req.text): + result.append((int(match.groups()[0]), int(match.groups()[1]), int(match.groups()[2]))) + with open(versions_file, 'w') as f: + json.dump(result, f) + return result + else: + try: + with open(versions_file, 'r') as f: + return [tuple(v) for v in json.load(f)] + except: + print('libunistring_versions.json is empty or broken, redownloading.') + return versions(env, update=True) + +def dependencies(env: Environment, version) -> 'dict': + return {} + +def cook(env: Environment, version) -> dict: + url = f'https://ftp.gnu.org/gnu/libunistring/libunistring-{version[0]}.{version[1]}.{version[2]}.tar.gz' + repo = env.DownloadAndExtract(f'libunistring_{version[0]}.{version[1]}.{version[2]}', url = url, skip_folders = 1) + checkout_root = repo['extracted_root'] + build_result = env.AutotoolsProject(checkout_root) + return { + 'CPPPATH': build_result['CPPPATH'], + 'LIBS': [env.FindLib('unistring', paths=build_result['LIBPATH'])] + } diff --git a/recipes/wincrypt/recipe.py b/recipes/wincrypt/recipe.py new file mode 100644 index 0000000..86e4667 --- /dev/null +++ b/recipes/wincrypt/recipe.py @@ -0,0 +1,23 @@ + + +import os +from SCons.Script import * + + +def available(env: Environment): + if os.name != 'nt': + return 'Wincrypt is only available on Windows.' + +def versions(env: Environment, update: bool = False): + if os.name == 'nt': + return [(0, 0, 0)] + else: + return [] + +def dependencies(env: Environment, version) -> 'dict': + return {} + +def cook(env: Environment, version) -> dict: + return { + 'LIBS': ['Advapi32'] + } diff --git a/recipes/winldap/recipe.py b/recipes/winldap/recipe.py new file mode 100644 index 0000000..a6565b7 --- /dev/null +++ b/recipes/winldap/recipe.py @@ -0,0 +1,23 @@ + + +import os +from SCons.Script import * + + +def available(env: Environment): + if os.name != 'nt': + return 'Winldap is only available on Windows.' + +def versions(env: Environment, update: bool = False): + if os.name == 'nt': + return [(0, 0, 0)] + else: + return [] + +def dependencies(env: Environment, version) -> 'dict': + return {} + +def cook(env: Environment, version) -> dict: + return { + 'LIBS': ['Wldap32'] + } diff --git a/recipes/winsock2/recipe.py b/recipes/winsock2/recipe.py new file mode 100644 index 0000000..6d96684 --- /dev/null +++ b/recipes/winsock2/recipe.py @@ -0,0 +1,23 @@ + + +import os +from SCons.Script import * + + +def available(env: Environment): + if os.name != 'nt': + return 'Winsock2 is only available on Windows.' + +def versions(env: Environment, update: bool = False): + if os.name == 'nt': + return [(0, 0, 0)] + else: + return [] + +def dependencies(env: Environment, version) -> 'dict': + return {} + +def cook(env: Environment, version) -> dict: + return { + 'LIBS': ['Ws2_32'] + } diff --git a/recipes/yaml-cpp/recipe.py b/recipes/yaml-cpp/recipe.py new file mode 100644 index 0000000..cf79ef1 --- /dev/null +++ b/recipes/yaml-cpp/recipe.py @@ -0,0 +1,26 @@ + + +import re +from SCons.Script import * + + +def _git_cook(env: Environment, repo: dict) -> dict: + checkout_root = repo['checkout_root'] + build_result = env.CMakeProject(project_root=checkout_root) + lib_name = { + 'debug': 'yaml-cppd' + }.get(env['BUILD_TYPE'], 'yaml-cpp') + return { + 'CPPPATH': build_result['CPPPATH'], + 'LIBS': [env.FindLib(lib_name, paths=build_result['LIBPATH'])] + } + + +env.GitRecipe( + globals = globals(), + repo_name = 'yaml-cpp', + repo_url = 'https://github.com/jbeder/yaml-cpp.git', + tag_pattern = re.compile(r'^yaml-cpp-([0-9]+)\.([0-9]+)\.([0-9]+)$'), + tag_fn = lambda version: f'yaml-cpp-{version[0]}.{version[1]}.{version[2]}', + cook_fn = _git_cook +) diff --git a/recipes/zlib/recipe.py b/recipes/zlib/recipe.py new file mode 100644 index 0000000..23a9158 --- /dev/null +++ b/recipes/zlib/recipe.py @@ -0,0 +1,69 @@ + +import os +import re +from SCons.Script import * + +_REPO_NAME = 'zlib' +_REPO_URL = 'https://github.com/madler/zlib.git' +_TAG_PATTERN = re.compile(r'^v([0-9]+)\.([0-9]+)(?:\.([0-9]+))?$') +_VERSION_SOURCE = ''' + #include + #include + + int main(int, char**) + { + puts(ZLIB_VERSION); + return 0; + } +''' + +def _build_lib_name(env: Environment) -> str: + if os.name == 'posix': + return 'z' + elif os.name == 'nt': + return { + 'debug': 'zlibstaticd' + }.get(env['BUILD_TYPE'], 'zlibstatic') + else: + raise Exception('libpng is not supported yet on this OS') + +def versions(env: Environment, update: bool = False, options: dict = {}): + tags = env.GitTags(repo_name = _REPO_NAME, remote_url = _REPO_URL, force_fetch=update) + result = [] + + if options.get('use_system_library'): + version = env.VersionFromSource('pkgconf --cflags-only-I zlib', _VERSION_SOURCE) + if version: + env['SYSTEM_ZLIB_VERSION'] = version + result.append(version) + else: + for tag in tags: + match = _TAG_PATTERN.match(tag) + if match: + result.append((int(match.groups()[0]), int(match.groups()[1]), int(match.groups()[2] or 0))) + return result + +def dependencies(env: Environment, version) -> 'dict': + return {} + +def cook(env: Environment, version, options: dict = {}) -> dict: + if options.get('use_system_library'): + return env.PkgCook('pkgconf --cflags --libs zlib') + + git_ref = f'refs/tags/v{version[0]}.{version[1]}' + if version[2] != 0: + git_ref = git_ref + f'.{version[2]}' + repo = env.GitBranch(repo_name = _REPO_NAME, remote_url = _REPO_URL, git_ref = git_ref) + checkout_root = repo['checkout_root'] + build_result = env.CMakeProject(project_root=checkout_root) + include_dir = os.path.join(build_result['install_dir'], 'include') + lib_name = _build_lib_name(env) + lib_file = env.FindLib(lib_name, paths=build_result['LIBPATH']) + return { + 'CPPPATH': [include_dir], + 'LIBS': [lib_file], + 'CMAKE_VARS': { + 'ZLIB_LIBRARY': lib_file, + 'ZLIB_INCLUDE_DIR': include_dir + } + }