Added MSVC/Windows compatibility to a few recipes (and the main script).

This commit is contained in:
Patrick 2024-06-26 10:14:57 +02:00
parent c8554282f9
commit 3171d112ce
5 changed files with 49 additions and 18 deletions

View File

@ -1,6 +1,7 @@
import copy import copy
import os import os
import sys
def _cook(env: Environment, recipe_name: str, *args, **kwargs): def _cook(env: Environment, recipe_name: str, *args, **kwargs):
import importlib.util import importlib.util
@ -53,6 +54,10 @@ def _rglob(env: Environment, root_path: str, pattern: str, **kwargs):
result_nodes.extend(env.Glob(f'{path}/{pattern}', **kwargs)) result_nodes.extend(env.Glob(f'{path}/{pattern}', **kwargs))
return sorted(result_nodes) return sorted(result_nodes)
def _error(env: Environment, message: str):
print(message, file=sys.stderr)
env.Exit(1)
def _wrap_builder(builder, is_lib: bool = False): def _wrap_builder(builder, is_lib: bool = False):
def _wrapped(env, dependencies = [], *args, **kwargs): def _wrapped(env, dependencies = [], *args, **kwargs):
if 'CPPPATH' not in kwargs: if 'CPPPATH' not in kwargs:
@ -219,7 +224,7 @@ tools = ['default', 'compilation_db', 'unity_build']
if 'TOOLS' in config: if 'TOOLS' in config:
tools.extend(config['TOOLS']) tools.extend(config['TOOLS'])
env = Environment(tools = tools, variables = vars) env = Environment(tools = tools, variables = vars, ENV = os.environ)
env['RECIPES_FOLDERS'] = [Dir('recipes')] env['RECIPES_FOLDERS'] = [Dir('recipes')]
env['SYSTEM_CACHE_DIR'] = os.path.join(_find_system_cache_dir(), 'spp_cache') env['SYSTEM_CACHE_DIR'] = os.path.join(_find_system_cache_dir(), 'spp_cache')
env['CLONE_DIR'] = os.path.join(env['SYSTEM_CACHE_DIR'], 'cloned') env['CLONE_DIR'] = os.path.join(env['SYSTEM_CACHE_DIR'], 'cloned')
@ -272,7 +277,7 @@ if not os.path.exists(cache_gitignore):
os.makedirs(env['CLONE_DIR'], exist_ok=True) os.makedirs(env['CLONE_DIR'], exist_ok=True)
# try to detect what compiler we are using # try to detect what compiler we are using
compiler_exe = os.path.basename(env['CC']) compiler_exe = os.path.basename(env.subst(env['CC']))
if 'gcc' in compiler_exe: if 'gcc' in compiler_exe:
env['COMPILER_FAMILY'] = 'gcc' env['COMPILER_FAMILY'] = 'gcc'
elif 'clang' in compiler_exe: elif 'clang' in compiler_exe:
@ -329,10 +334,14 @@ if env['COMPILER_FAMILY'] == 'gcc' or env['COMPILER_FAMILY'] == 'clang':
elif env['COMPILER_FAMILY'] == 'cl': elif env['COMPILER_FAMILY'] == 'cl':
# C4201: nonstandard extension used : nameless struct/union - I use it and want to continue using it # C4201: nonstandard extension used : nameless struct/union - I use it and want to continue using it
# C4127: conditional expression is constant - some libs (CRC, format) don't compile with this enabled # TODO: fix? # C4127: conditional expression is constant - some libs (CRC, format) don't compile with this enabled # TODO: fix?
env.Append(CCFLAGS = ['/W4', '/WX', '/wd4201', '/wd4127', f'/std:{config["CXX_STANDARD"]}', '/permissive-', '/EHsc', '/FS', '/Zc:char8_t']) # C4702: unreachable code, issued after MIJIN_FATAL macro
# C4251: missing dll-interface of some std types, yaml-cpp doesn't compile with this enabled
# C4275: same as above
env.Append(CCFLAGS = ['/W4', '/WX', '/wd4201', '/wd4127', '/wd4702', '/wd4251', '/wd4275', '/bigobj', f'/std:{config["CXX_STANDARD"]}', '/permissive-', '/EHsc', '/FS', '/Zc:char8_t'])
env.Append(CPPDEFINES = ['_CRT_SECURE_NO_WARNINGS']) # I'd like to not use MSVC specific versions of functions because they are "safer" ... env.Append(CPPDEFINES = ['_CRT_SECURE_NO_WARNINGS']) # I'd like to not use MSVC specific versions of functions because they are "safer" ...
if build_type == 'debug': if build_type == 'debug':
env.Append(CCFLAGS = ['/Od', '/Zi'], LINKFLAGS = ' /DEBUG') env.Append(CCFLAGS = ['/Od', '/Zi', '/MDd'], LINKFLAGS = ' /DEBUG')
env.Append(CPPDEFINES = ['_DEBUG', '_ITERATOR_DEBUG_LEVEL=2'])
elif build_type == 'release_debug' or build_type == 'profile': elif build_type == 'release_debug' or build_type == 'profile':
env.Append(CCFLAGS = ['/O2', '/Zi'], LINKFLAGS = ' /DEBUG') env.Append(CCFLAGS = ['/O2', '/Zi'], LINKFLAGS = ' /DEBUG')
else: else:
@ -346,6 +355,7 @@ elif env['COMPILER_FAMILY'] == 'clang':
env.AddMethod(_cook, 'Cook') env.AddMethod(_cook, 'Cook')
env.AddMethod(_parse_lib_conf, 'ParseLibConf') env.AddMethod(_parse_lib_conf, 'ParseLibConf')
env.AddMethod(_rglob, 'RGlob') env.AddMethod(_rglob, 'RGlob')
env.AddMethod(_error, 'Error')
env.AddMethod(_wrap_builder(env.Library, is_lib = True), 'Library') env.AddMethod(_wrap_builder(env.Library, is_lib = True), 'Library')
env.AddMethod(_wrap_builder(env.StaticLibrary, is_lib = True), 'StaticLibrary') env.AddMethod(_wrap_builder(env.StaticLibrary, is_lib = True), 'StaticLibrary')
env.AddMethod(_wrap_builder(env.SharedLibrary, is_lib = True), 'SharedLibrary') env.AddMethod(_wrap_builder(env.SharedLibrary, is_lib = True), 'SharedLibrary')

View File

@ -1,12 +1,13 @@
import os import os
import pathlib import pathlib
import subprocess
import sys
from SCons.Script import * from SCons.Script import *
_BUILT_STAMPFILE = '.spp_built' _BUILT_STAMPFILE = '.spp_built'
def cmd_quote(s: str) -> str:
return f'"{s.replace("\\", "\\\\")}"'
def cook(env: Environment, project_root: str, generate_args: 'list[str]' = [], build_args : 'list[str]' = [], install_args : 'list[str]' = []) -> dict: def cook(env: Environment, project_root: str, generate_args: 'list[str]' = [], build_args : 'list[str]' = [], install_args : 'list[str]' = []) -> dict:
config = env['BUILD_TYPE'] config = env['BUILD_TYPE']
build_dir = os.path.join(project_root, f'build_{config}') build_dir = os.path.join(project_root, f'build_{config}')
@ -21,11 +22,14 @@ def cook(env: Environment, project_root: str, generate_args: 'list[str]' = [], b
'release': 'Release', 'release': 'Release',
'profile': 'RelWithDebInfo' 'profile': 'RelWithDebInfo'
}.get(env['BUILD_TYPE'], 'RelWithDebInfo') }.get(env['BUILD_TYPE'], 'RelWithDebInfo')
environ = os.environ.copy() def run_cmd(args):
environ['CXXFLAGS'] = ' '.join(f'-D{define}' for define in env['CPPDEFINES']) # TODO: who cares about windows? env.Execute(' '.join([str(s) for s in args]))
subprocess.run(('cmake', '-G', 'Ninja', '-B', build_dir, f'-DCMAKE_BUILD_TYPE={build_type}', f'-DCMAKE_INSTALL_PREFIX={install_dir}', '-DBUILD_TESTING=OFF', *generate_args, project_root), env=environ, stdout=sys.stdout, stderr=sys.stderr, check=True) # TODO: is this a problem?
subprocess.run(('cmake', '--build', *build_args, build_dir), stdout=sys.stdout, stderr=sys.stderr, check=True) # environ = os.environ.copy()
subprocess.run(('cmake', '--install', *install_args, build_dir), stdout=sys.stdout, stderr=sys.stderr, check=True) # environ['CXXFLAGS'] = ' '.join(f'-D{define}' for define in env['CPPDEFINES']) # TODO: who cares about windows?
run_cmd(['cmake', '-G', 'Ninja', '-B', build_dir, f'-DCMAKE_BUILD_TYPE={build_type}', f'-DCMAKE_INSTALL_PREFIX={cmd_quote(install_dir)}', '-DBUILD_TESTING=OFF', *generate_args, project_root])
run_cmd(['cmake', '--build', *build_args, cmd_quote(build_dir)])
run_cmd(['cmake', '--install', *install_args, cmd_quote(build_dir)])
pathlib.Path(install_dir, _BUILT_STAMPFILE).touch() pathlib.Path(install_dir, _BUILT_STAMPFILE).touch()
return { return {

View File

@ -1,17 +1,27 @@
import os import os
import platform
from SCons.Script import * from SCons.Script import *
def cook(env: Environment, git_ref: str = "main") -> dict: def cook(env: Environment, git_ref: str = "main") -> dict:
repo = env.Cook('GitBranch', repo_name = 'SDL', remote_url = 'https://github.com/libsdl-org/SDL.git', git_ref = git_ref) repo = env.Cook('GitBranch', repo_name = 'SDL', remote_url = 'https://github.com/libsdl-org/SDL.git', git_ref = git_ref)
checkout_root = repo['checkout_root'] checkout_root = repo['checkout_root']
build_result = env.Cook('CMakeProject', project_root=checkout_root, generate_args = ['-DSDL_STATIC=ON', '-DSDL_SHARED=OFF']) build_result = env.Cook('CMakeProject', project_root=checkout_root, generate_args = ['-DSDL_STATIC=ON', '-DSDL_SHARED=OFF'])
lib_name = { libs = []
'debug': 'SDL2d' if platform.system() == 'Windows':
}.get(env['BUILD_TYPE'], 'SDL2') if env['BUILD_TYPE'] == 'debug':
libs.append('SDL2-staticd')
else:
libs.append('SDL2-static')
libs.extend(('kernel32', 'user32', 'gdi32', 'winmm', 'imm32', 'ole32', 'oleaut32', 'version', 'uuid', 'advapi32', 'setupapi', 'shell32', 'dinput8'))
else:
if env['BUILD_TYPE'] == 'debug':
libs.append('SDL2d')
else:
libs.append('SDL2')
return { return {
'LIBPATH': build_result['LIBPATH'], 'LIBPATH': build_result['LIBPATH'],
'CPPPATH': [os.path.join(build_result['install_dir'], 'include/SDL2')], # SDL is really weird about include paths ... 'CPPPATH': [os.path.join(build_result['install_dir'], 'include/SDL2')], # SDL is really weird about include paths ...
'LIBS': [lib_name] 'LIBS': libs
} }

View File

@ -6,7 +6,6 @@ import os
import pathlib import pathlib
import platform import platform
import shutil import shutil
import subprocess
import sys import sys
_SCRIPT_STAMPFILE = '.spp_script_run' _SCRIPT_STAMPFILE = '.spp_script_run'
@ -21,7 +20,13 @@ def cook(env: Environment, remote: str = 'github', git_ref: str = '') -> dict:
# TODO: windows? # TODO: windows?
did_run_script = os.path.exists(os.path.join(repo['checkout_root'], _SCRIPT_STAMPFILE)) did_run_script = os.path.exists(os.path.join(repo['checkout_root'], _SCRIPT_STAMPFILE))
if not did_run_script or env['UPDATE_REPOSITORIES']: if not did_run_script or env['UPDATE_REPOSITORIES']:
subprocess.run(('/usr/bin/env', 'python3', 'update_glslang_sources.py'), cwd=checkout_root, stdout=sys.stdout, stderr=sys.stderr, check=True) 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() pathlib.Path(repo['checkout_root'], _SCRIPT_STAMPFILE).touch()
# generate the build_info.h # generate the build_info.h
@ -44,7 +49,7 @@ def cook(env: Environment, remote: str = 'github', git_ref: str = '') -> dict:
+ env.RGlob(os.path.join(repo['checkout_root'], 'glslang/OGLCompilersDLL/'), '*.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'], 'glslang/ResourceLimits/'), '*.cpp') \
+ env.RGlob(os.path.join(repo['checkout_root'], 'SPIRV/'), '*.cpp') \ + env.RGlob(os.path.join(repo['checkout_root'], 'SPIRV/'), '*.cpp') \
+ env.RGlob(os.path.join(repo['checkout_root'], f'glslang/OSDependent/{platform_source_dir}/'), '*.cpp') + [os.path.join(repo['checkout_root'], f'glslang/OSDependent/{platform_source_dir}/ossource.cpp')]
# disable a few warnings when compiling with clang # disable a few warnings when compiling with clang
additional_cxx_flags = { additional_cxx_flags = {

View File

@ -2,6 +2,8 @@
from SCons.Script import * from SCons.Script import *
def cook(env: Environment, git_ref = 'master') -> dict: def cook(env: Environment, git_ref = 'master') -> dict:
if env['COMPILER_FAMILY'] not in ('gcc', 'clang'):
env.Error('libbacktrace requires gcc or clang.')
repo = env.Cook('GitBranch', repo_name = 'libbacktrace', remote_url = 'https://github.com/ianlancetaylor/libbacktrace.git', git_ref = git_ref) repo = env.Cook('GitBranch', repo_name = 'libbacktrace', remote_url = 'https://github.com/ianlancetaylor/libbacktrace.git', git_ref = git_ref)
checkout_root = repo['checkout_root'] checkout_root = repo['checkout_root']
build_result = env.Cook('AutotoolsProject', checkout_root) build_result = env.Cook('AutotoolsProject', checkout_root)