Add commands to deal with Orca source code:

- Add a vendor commands
- Add a command that helps you set up a C compiler
- Move ext into the src folder
- Update Mac build scripts for consistency
- Update Windows batch scripts
This commit is contained in:
Ben Visness 2023-08-28 22:15:16 -05:00 committed by Martin Fouilleul
parent 731b1c7334
commit 29cb9f50e4
326 changed files with 487 additions and 215 deletions

4
.gitignore vendored
View File

@ -35,6 +35,8 @@ src/graphics/orca_gl31.h
__pycache__ __pycache__
scripts/files scripts/files
ext/angle # explicitly abandon old ext dir
/ext
src/ext/angle
sketches/*/bin sketches/*/bin

View File

@ -1,4 +0,0 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore

View File

@ -1,15 +0,0 @@
M3_SRC_DIR := ../../../source
SOURCES := ../../app/main.c \
$(shell find $(M3_SRC_DIR) -type f -name '*.c')
override CFLAGS += -std=c99 -O3 -flto -Dd_m3HasWASI -Wno-error=format-security -Wfatal-errors -I$(M3_SRC_DIR)
all: wasm3
wasm3: $(SOURCES)
$(CC) $(CFLAGS) $(SOURCES) -o wasm3 -lm
clean:
$(RM) wasm3

6
orca
View File

@ -41,9 +41,9 @@ if use_source:
# Use the source checkout's scripts instead of the system-installed scripts. # Use the source checkout's scripts instead of the system-installed scripts.
if not is_source: if not is_source:
print("The Orca tool is running from a local source checkout and will") print("The Orca tool is running from a local source checkout and will", file=sys.stderr)
print("use that instead of the system Orca installation.") print("use that instead of the system Orca installation.", file=sys.stderr)
print() print(file=sys.stderr)
sys.path.append(source_dir) sys.path.append(source_dir)
import scripts.orca import scripts.orca

View File

@ -1,19 +1,21 @@
@echo off @echo off
set ORCA_DIR=..\..
set STDLIB_DIR=%ORCA_DIR%\src\libc-shim
:: compile wasm module :: compile wasm module
set wasmFlags=--target=wasm32^ set wasmFlags=--target=wasm32^
--no-standard-libraries ^ --no-standard-libraries ^
-fno-builtin ^ -mbulk-memory ^
-g -O2 ^
-D__ORCA__ ^
-Wl,--no-entry ^ -Wl,--no-entry ^
-Wl,--export-dynamic ^ -Wl,--export-dynamic ^
-g ^ -isystem %STDLIB_DIR%\include ^
-O2 ^ -I%ORCA_DIR%\src ^
-mbulk-memory ^ -I%ORCA_DIR%\src\ext
-D__ORCA__ ^
-isystem ..\..\src\libc-shim\include ^
-I..\..\ext -I ..\..\src
clang %wasmFlags% -o .\module.wasm ..\..\src\orca.c ..\..\src\libc-shim\src\*.c src\main.c clang %wasmFlags% -o .\module.wasm %ORCA_DIR%\src\orca.c %STDLIB_DIR%\src\*.c src\main.c
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
orca bundle --orca-dir ..\.. --name Breakout --icon icon.png --resource-dir data module.wasm orca bundle --orca-dir %ORCA_DIR% --name Breakout --icon icon.png --resource-dir data module.wasm

View File

@ -12,21 +12,19 @@ else
fi fi
ORCA_DIR=../.. ORCA_DIR=../..
STDLIB_DIR=../../src/libc-shim STDLIB_DIR=$ORCA_DIR/src/libc-shim
wasmFlags="--target=wasm32 \ wasmFlags="--target=wasm32 \
--no-standard-libraries \ --no-standard-libraries \
-fno-builtin \ -mbulk-memory \
-g -O2 \
-D__ORCA__ \
-Wl,--no-entry \ -Wl,--no-entry \
-Wl,--export-dynamic \ -Wl,--export-dynamic \
-g \ -isystem $STDLIB_DIR/include \
-O2 \ -I $ORCA_DIR/src \
-mbulk-memory \ -I $ORCA_DIR/src/ext"
-D__ORCA__ \
-I $STDLIB_DIR/include \
-I $ORCA_DIR/ext \
-I $ORCA_DIR/src"
$CLANG $wasmFlags -o ./module.wasm ../../src/orca.c $STDLIB_DIR/src/*.c src/main.c $CLANG $wasmFlags -o ./module.wasm $ORCA_DIR/src/orca.c $STDLIB_DIR/src/*.c src/main.c
orca bundle --orca-dir ../.. --name Breakout --icon icon.png --resource-dir data module.wasm orca bundle --orca-dir $ORCA_DIR --name Breakout --icon icon.png --resource-dir data module.wasm

View File

@ -1,19 +1,21 @@
@echo off @echo off
set ORCA_DIR=..\..
set STDLIB_DIR=%ORCA_DIR%\src\libc-shim
:: compile wasm module :: compile wasm module
set wasmFlags=--target=wasm32^ set wasmFlags=--target=wasm32^
--no-standard-libraries ^ --no-standard-libraries ^
-fno-builtin ^ -mbulk-memory ^
-g -O2 ^
-D__ORCA__ ^
-Wl,--no-entry ^ -Wl,--no-entry ^
-Wl,--export-dynamic ^ -Wl,--export-dynamic ^
-g ^ -isystem %STDLIB_DIR%\include ^
-O2 ^ -I%ORCA_DIR%\src ^
-mbulk-memory ^ -I%ORCA_DIR%\src\ext
-D__ORCA__ ^
-isystem ..\..\src\libc-shim\include ^
-I..\..\ext -I ..\..\src
clang %wasmFlags% -o .\module.wasm ..\..\src\orca.c ..\..\src\libc-shim\src\*.c src\main.c clang %wasmFlags% -o .\module.wasm %ORCA_DIR%\src\orca.c %STDLIB_DIR%\src\*.c src\main.c
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
orca bundle --orca-dir ..\.. --name Clock --icon icon.png --resource-dir data module.wasm orca bundle --orca-dir %ORCA_DIR% --name Clock --icon icon.png --resource-dir data module.wasm

View File

@ -12,21 +12,19 @@ else
fi fi
ORCA_DIR=../.. ORCA_DIR=../..
STDLIB_DIR=../../src/libc-shim STDLIB_DIR=$ORCA_DIR/src/libc-shim
wasmFlags="--target=wasm32 \ wasmFlags="--target=wasm32 \
--no-standard-libraries \ --no-standard-libraries \
-fno-builtin \ -mbulk-memory \
-g -O2 \
-D__ORCA__ \
-Wl,--no-entry \ -Wl,--no-entry \
-Wl,--export-dynamic \ -Wl,--export-dynamic \
-g \ -isystem $STDLIB_DIR/include \
-O2 \ -I $ORCA_DIR/src \
-mbulk-memory \ -I $ORCA_DIR/src/ext"
-D__ORCA__ \
-I $STDLIB_DIR/include \
-I $ORCA_DIR/ext \
-I $ORCA_DIR/src"
$CLANG $wasmFlags -o ./module.wasm ../../src/orca.c $STDLIB_DIR/src/*.c src/main.c $CLANG $wasmFlags -o ./module.wasm $ORCA_DIR/src/orca.c $STDLIB_DIR/src/*.c src/main.c
orca bundle --orca-dir ../.. --name Clock --icon icon.png --resource-dir data module.wasm orca bundle --orca-dir $ORCA_DIR --name Clock --icon icon.png --resource-dir data module.wasm

View File

@ -1,17 +1,19 @@
@echo off @echo off
set ORCA_DIR=..\..
set STDLIB_DIR=%ORCA_DIR%\src\libc-shim
:: compile wasm module :: compile wasm module
set wasmFlags=--target=wasm32^ set wasmFlags=--target=wasm32^
--no-standard-libraries ^ --no-standard-libraries ^
-fno-builtin ^ -mbulk-memory ^
-g -O2 ^
-D__ORCA__ ^
-Wl,--no-entry ^ -Wl,--no-entry ^
-Wl,--export-dynamic ^ -Wl,--export-dynamic ^
-g ^ -isystem %STDLIB_DIR%\include ^
-O2 ^ -I%ORCA_DIR%\src ^
-mbulk-memory ^ -I%ORCA_DIR%\src\ext
-D__ORCA__ ^
-isystem ..\..\src\libc-shim\include ^
-I..\..\ext -I ..\..\src
set shaders=src/shaders/advect.glsl^ set shaders=src/shaders/advect.glsl^
src/shaders/blit_div_fragment.glsl^ src/shaders/blit_div_fragment.glsl^
@ -31,7 +33,7 @@ set shaders=src/shaders/advect.glsl^
call python3 ../../scripts/embed_text_files.py --prefix=glsl_ --output src/glsl_shaders.h %shaders% call python3 ../../scripts/embed_text_files.py --prefix=glsl_ --output src/glsl_shaders.h %shaders%
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
clang %wasmFlags% -o .\module.wasm ..\..\src\orca.c ..\..\src\libc-shim\src\*.c src\main.c clang %wasmFlags% -o .\module.wasm %ORCA_DIR%\src\orca.c %STDLIB_DIR%\src\*.c src\main.c
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
orca bundle --orca-dir ..\.. --icon icon.png --name Fluid module.wasm orca bundle --orca-dir %ORCA_DIR% --name Fluid --icon icon.png module.wasm

View File

@ -12,23 +12,21 @@ else
fi fi
ORCA_DIR=../.. ORCA_DIR=../..
STDLIB_DIR=../../src/libc-shim STDLIB_DIR=$ORCA_DIR/src/libc-shim
python3 ../../scripts/embed_text_files.py --prefix=glsl_ --output src/glsl_shaders.h src/shaders/*.glsl python3 ../../scripts/embed_text_files.py --prefix=glsl_ --output src/glsl_shaders.h src/shaders/*.glsl
wasmFlags="--target=wasm32 \ wasmFlags="--target=wasm32 \
--no-standard-libraries \ --no-standard-libraries \
-fno-builtin \ -mbulk-memory \
-g -O2 \
-D__ORCA__ \
-Wl,--no-entry \ -Wl,--no-entry \
-Wl,--export-dynamic \ -Wl,--export-dynamic \
-g \ -isystem $STDLIB_DIR/include \
-O2 \ -I $ORCA_DIR/src \
-mbulk-memory \ -I $ORCA_DIR/src/ext"
-D__ORCA__ \
-I $STDLIB_DIR/include \
-I $ORCA_DIR/ext \
-I $ORCA_DIR/src"
$CLANG $wasmFlags -o ./module.wasm ../../src/orca.c $STDLIB_DIR/src/*.c src/main.c $CLANG $wasmFlags -o ./module.wasm $ORCA_DIR/src/orca.c $STDLIB_DIR/src/*.c src/main.c
orca bundle --orca-dir ../.. --icon icon.png --name Fluid module.wasm orca bundle --orca-dir $ORCA_DIR --name Fluid --icon icon.png module.wasm

View File

@ -1,19 +1,21 @@
@echo off @echo off
set ORCA_DIR=..\..
set STDLIB_DIR=%ORCA_DIR%\src\libc-shim
:: compile wasm module :: compile wasm module
set wasmFlags=--target=wasm32^ set wasmFlags=--target=wasm32^
--no-standard-libraries ^ --no-standard-libraries ^
-fno-builtin ^ -mbulk-memory ^
-g -O2 ^
-D__ORCA__ ^
-Wl,--no-entry ^ -Wl,--no-entry ^
-Wl,--export-dynamic ^ -Wl,--export-dynamic ^
-g ^ -isystem %STDLIB_DIR%\include ^
-O2 ^ -I%ORCA_DIR%\src ^
-mbulk-memory ^ -I%ORCA_DIR%\src\ext
-D__ORCA__ ^
-isystem ..\..\src\libc-shim\include ^
-I..\..\ext -I ..\..\src
clang %wasmFlags% -o .\module.wasm ..\..\src\orca.c ..\..\src\libc-shim\src\*.c src\main.c clang %wasmFlags% -o .\module.wasm %ORCA_DIR%\src\orca.c %STDLIB_DIR%\src\*.c src\main.c
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
orca bundle --orca-dir ..\.. --name Triangle module.wasm orca bundle --orca-dir %ORCA_DIR% --name Triangle module.wasm

View File

@ -12,21 +12,19 @@ else
fi fi
ORCA_DIR=../.. ORCA_DIR=../..
STDLIB_DIR=../../src/libc-shim STDLIB_DIR=$ORCA_DIR/src/libc-shim
wasmFlags="--target=wasm32 \ wasmFlags="--target=wasm32 \
--no-standard-libraries \ --no-standard-libraries \
-fno-builtin \ -mbulk-memory \
-g -O2 \
-D__ORCA__ \
-Wl,--no-entry \ -Wl,--no-entry \
-Wl,--export-dynamic \ -Wl,--export-dynamic \
-g \ -isystem $STDLIB_DIR/include \
-O2 \ -I $ORCA_DIR/src \
-mbulk-memory \ -I $ORCA_DIR/src/ext"
-D__ORCA__ \
-I $STDLIB_DIR/include \
-I $ORCA_DIR/ext \
-I $ORCA_DIR/src"
$CLANG $wasmFlags -o ./module.wasm ../../src/orca.c ../../src/libc-shim/src/*.c src/main.c $CLANG $wasmFlags -o ./module.wasm $ORCA_DIR/src/orca.c $STDLIB_DIR/src/*.c src/main.c
orca bundle --orca-dir ../.. --name Triangle module.wasm orca bundle --orca-dir $ORCA_DIR --name Triangle module.wasm

View File

@ -1,19 +1,21 @@
@echo off @echo off
set ORCA_DIR=..\..
set STDLIB_DIR=%ORCA_DIR%\src\libc-shim
:: compile wasm module :: compile wasm module
set wasmFlags=--target=wasm32^ set wasmFlags=--target=wasm32^
--no-standard-libraries ^ --no-standard-libraries ^
-fno-builtin ^ -mbulk-memory ^
-g -O2 ^
-D__ORCA__ ^
-Wl,--no-entry ^ -Wl,--no-entry ^
-Wl,--export-dynamic ^ -Wl,--export-dynamic ^
-g ^ -isystem %STDLIB_DIR%\include ^
-O2 ^ -I%ORCA_DIR%\src ^
-mbulk-memory ^ -I%ORCA_DIR%\src\ext
-D__ORCA__ ^
-isystem ..\..\src\libc-shim\include ^
-I..\..\ext -I ..\..\src
clang %wasmFlags% -o .\module.wasm ..\..\src\orca.c ..\..\src\libc-shim\src\*.c src\main.c clang %wasmFlags% -o .\module.wasm %ORCA_DIR%\src\orca.c %STDLIB_DIR%\src\*.c src\main.c
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
orca bundle --orca-dir ..\.. --name UI --resource-dir data module.wasm orca bundle --orca-dir %ORCA_DIR% --name UI --resource-dir data module.wasm

View File

@ -12,21 +12,19 @@ else
fi fi
ORCA_DIR=../.. ORCA_DIR=../..
STDLIB_DIR=../../src/libc-shim STDLIB_DIR=$ORCA_DIR/src/libc-shim
wasmFlags="--target=wasm32 \ wasmFlags="--target=wasm32 \
--no-standard-libraries \ --no-standard-libraries \
-mbulk-memory \
-g -O2 \
-D__ORCA__ \
-Wl,--no-entry \ -Wl,--no-entry \
-Wl,--export-dynamic \ -Wl,--export-dynamic \
-g \ -isystem $STDLIB_DIR/include \
-O2 \ -I $ORCA_DIR/src \
-mbulk-memory \ -I $ORCA_DIR/src/ext"
-D__ORCA__ \
-I $ORCA_DIR/ext \
-I $STDLIB_DIR/include \
-I $ORCA_DIR/ext \
-I $ORCA_DIR/src"
$CLANG $wasmFlags -o ./module.wasm ../../src/orca.c $STDLIB_DIR/src/*.c src/main.c $CLANG $wasmFlags -o ./module.wasm $ORCA_DIR/src/orca.c $STDLIB_DIR/src/*.c src/main.c
orca bundle --orca-dir ../.. --name UI --resource-dir data module.wasm orca bundle --orca-dir $ORCA_DIR --name UI --resource-dir data module.wasm

View File

@ -70,8 +70,8 @@ def macos_make_app(args):
#----------------------------------------------------------- #-----------------------------------------------------------
orca_exe = os.path.join(args.orca_dir, 'build/bin/orca_runtime') orca_exe = os.path.join(args.orca_dir, 'build/bin/orca_runtime')
orca_lib = os.path.join(args.orca_dir, 'build/bin/liborca.dylib') orca_lib = os.path.join(args.orca_dir, 'build/bin/liborca.dylib')
gles_lib = os.path.join(args.orca_dir, 'ext/angle/bin/libGLESv2.dylib') gles_lib = os.path.join(args.orca_dir, 'src/ext/angle/bin/libGLESv2.dylib')
egl_lib = os.path.join(args.orca_dir, 'ext/angle/bin/libEGL.dylib') egl_lib = os.path.join(args.orca_dir, 'src/ext/angle/bin/libEGL.dylib')
renderer_lib = os.path.join(args.orca_dir, 'build/bin/mtl_renderer.metallib') renderer_lib = os.path.join(args.orca_dir, 'build/bin/mtl_renderer.metallib')
shutil.copy(orca_exe, exe_dir) shutil.copy(orca_exe, exe_dir)

View File

@ -1,10 +1,10 @@
{ {
"scripts/files/angle-windows-2019-2023-07-05.zip": "a333b5ccc8462151ee8df65c43cfacd70d9db2413f2e495da65670737b5b2d96", "scripts/files/angle-windows-2019-2023-07-05.zip": "a333b5ccc8462151ee8df65c43cfacd70d9db2413f2e495da65670737b5b2d96",
"scripts/files/angle-macos-jank-2023-07-05.zip": "c234b8db179a24757ab9f46610a032123718dd9bed967d2bf8e27d0d17eb0aff", "scripts/files/angle-macos-jank-2023-07-05.zip": "c234b8db179a24757ab9f46610a032123718dd9bed967d2bf8e27d0d17eb0aff",
"ext/angle/bin/libEGL.dll": "b7bf51f83e88129ddc20c0c2cb904ec04c89059a30a2cd29b9b1ea11c80388fb", "src/ext/angle/bin/libEGL.dll": "b7bf51f83e88129ddc20c0c2cb904ec04c89059a30a2cd29b9b1ea11c80388fb",
"ext/angle/lib/libEGL.dll.lib": "4cec54c534136da413dea86bd271ccb9c5ae88e40aa91d1de7a01e701be8e1d7", "src/ext/angle/lib/libEGL.dll.lib": "4cec54c534136da413dea86bd271ccb9c5ae88e40aa91d1de7a01e701be8e1d7",
"ext/angle/bin/libGLESv2.dll": "193b53b0a16b702eaa28a73e84527acf7aecfd665e3e3f54a8d9db9ae73111e1", "src/ext/angle/bin/libGLESv2.dll": "193b53b0a16b702eaa28a73e84527acf7aecfd665e3e3f54a8d9db9ae73111e1",
"ext/angle/lib/libGLESv2.dll.lib": "ee87aac129efe8fe871825d181b85da1b1ea6626cb48be52c2e689f2804b953f", "src/ext/angle/lib/libGLESv2.dll.lib": "ee87aac129efe8fe871825d181b85da1b1ea6626cb48be52c2e689f2804b953f",
"ext/angle/bin/libEGL.dylib": "96baea4b1c8578d30738764784d07b509d1153df694c094faba2ee8ccbfde2a9", "src/ext/angle/bin/libEGL.dylib": "96baea4b1c8578d30738764784d07b509d1153df694c094faba2ee8ccbfde2a9",
"ext/angle/bin/libGLESv2.dylib": "98ce9f6248a6447ba9199e96b8f6d87df9548d43ce583a2615717aab168ecb71" "src/ext/angle/bin/libGLESv2.dylib": "98ce9f6248a6447ba9199e96b8f6d87df9548d43ce583a2615717aab168ecb71"
} }

View File

@ -1,4 +1,3 @@
from datetime import datetime
import glob import glob
import os import os
import platform import platform
@ -11,14 +10,15 @@ from . import checksum
from .bindgen import bindgen from .bindgen import bindgen
from .gles_gen import gles_gen from .gles_gen import gles_gen
from .log import * from .log import *
from .utils import pushd, removeall from .utils import pushd, removeall, yeetdir, yeetfile
from .embed_text_files import * from .embed_text_files import *
from .version import check_if_source, is_orca_source, orca_version
ANGLE_VERSION = "2023-07-05" ANGLE_VERSION = "2023-07-05"
def attach_dev_commands(subparsers): def attach_dev_commands(subparsers):
dev_cmd = subparsers.add_parser("dev", help="Commands for building Orca itself. Must be run from the root of an Orca source checkout.") dev_cmd = subparsers.add_parser("dev", help="Commands for building Orca itself. Must be run from within an Orca source checkout.")
dev_cmd.set_defaults(func=orca_source_only) dev_cmd.set_defaults(func=orca_source_only)
dev_sub = dev_cmd.add_subparsers(required=is_orca_source(), title='commands') dev_sub = dev_cmd.add_subparsers(required=is_orca_source(), title='commands')
@ -38,38 +38,6 @@ def attach_dev_commands(subparsers):
uninstall_cmd.set_defaults(func=dev_shellish(uninstall)) uninstall_cmd.set_defaults(func=dev_shellish(uninstall))
# Checks if the Orca tool should use a source checkout of Orca instead of a system install.
# This is copy-pasted to the command-line tool so it can work before loading anything.
#
# Returns: (use source, source directory, is actually the source's tool)
def check_if_source():
def path_is_in_orca_source(path):
dir = path
while True:
try:
os.stat(os.path.join(dir, ".orcaroot"))
return (True, dir)
except FileNotFoundError:
pass
newdir = os.path.dirname(dir)
if newdir == dir: # TODO: Verify on Windows (it will probably not work)
return (False, None)
dir = newdir
in_source, current_source_dir = path_is_in_orca_source(os.getcwd())
script_is_source, script_source_dir = path_is_in_orca_source(os.path.dirname(os.path.abspath(__file__)))
use_source = in_source or script_is_source
source_dir = current_source_dir or script_source_dir
return (use_source, source_dir, script_is_source)
def is_orca_source():
use_source, _, _ = check_if_source()
return use_source
def orca_source_only(args): def orca_source_only(args):
print("The Orca dev commands can only be run from an Orca source checkout.") print("The Orca dev commands can only be run from an Orca source checkout.")
print() print()
@ -99,10 +67,10 @@ def build_runtime(args):
def clean(args): def clean(args):
yeet("build") yeetdir("build")
yeet("ext/angle") yeetdir("src/ext/angle")
yeet("scripts/files") yeetdir("scripts/files")
yeet("scripts/__pycache__") yeetdir("scripts/__pycache__")
def build_platform_layer(target, release): def build_platform_layer(target, release):
@ -145,8 +113,8 @@ def build_platform_layer_lib_win(release):
includes = [ includes = [
"/I", "src", "/I", "src",
"/I", "ext", "/I", "src/ext",
"/I", "ext/angle/include", "/I", "src/ext/angle/include",
] ]
libs = [ libs = [
"user32.lib", "user32.lib",
@ -161,7 +129,7 @@ def build_platform_layer_lib_win(release):
"shlwapi.lib", "shlwapi.lib",
"dxgi.lib", "dxgi.lib",
"dxguid.lib", "dxguid.lib",
"/LIBPATH:ext/angle/lib", "/LIBPATH:src/ext/angle/lib",
"libEGL.dll.lib", "libEGL.dll.lib",
"libGLESv2.dll.lib", "libGLESv2.dll.lib",
"/DELAYLOAD:libEGL.dll", "/DELAYLOAD:libEGL.dll",
@ -189,7 +157,7 @@ def build_platform_layer_lib_mac(release):
cflags = ["-std=c11"] cflags = ["-std=c11"]
debug_flags = ["-O3"] if release else ["-g", "-DOC_DEBUG", "-DOC_LOG_COMPILE_DEBUG"] debug_flags = ["-O3"] if release else ["-g", "-DOC_DEBUG", "-DOC_LOG_COMPILE_DEBUG"]
ldflags = [f"-L{sdk_dir}/usr/lib", f"-F{sdk_dir}/System/Library/Frameworks/"] ldflags = [f"-L{sdk_dir}/usr/lib", f"-F{sdk_dir}/System/Library/Frameworks/"]
includes = ["-Isrc", "-Isrc/util", "-Isrc/platform", "-Iext", "-Iext/angle/include"] includes = ["-Isrc", "-Isrc/util", "-Isrc/platform", "-Isrc/ext", "-Isrc/ext/angle/include"]
# compile metal shader # compile metal shader
subprocess.run([ subprocess.run([
@ -228,7 +196,7 @@ def build_platform_layer_lib_mac(release):
*ldflags, "-dylib", *ldflags, "-dylib",
"-o", "build/bin/liborca.dylib", "-o", "build/bin/liborca.dylib",
"build/orca_c.o", "build/orca_objc.o", "build/orca_c.o", "build/orca_objc.o",
"-Lext/angle/bin", "-lc", "-Lsrc/ext/angle/bin", "-lc",
"-framework", "Carbon", "-framework", "Cocoa", "-framework", "Metal", "-framework", "QuartzCore", "-framework", "Carbon", "-framework", "Cocoa", "-framework", "Metal", "-framework", "QuartzCore",
"-weak-lEGL", "-weak-lGLESv2", "-weak-lEGL", "-weak-lGLESv2",
], check=True) ], check=True)
@ -271,14 +239,14 @@ def build_wasm3(release):
def build_wasm3_lib_win(release): def build_wasm3_lib_win(release):
for f in glob.iglob("./ext/wasm3/source/*.c"): for f in glob.iglob("./src/ext/wasm3/source/*.c"):
name = os.path.splitext(os.path.basename(f))[0] name = os.path.splitext(os.path.basename(f))[0]
subprocess.run([ subprocess.run([
"cl", "/nologo", "cl", "/nologo",
"/Zi", "/Zc:preprocessor", "/c", "/Zi", "/Zc:preprocessor", "/c",
"/O2", "/O2",
f"/Fo:build/obj/{name}.obj", f"/Fo:build/obj/{name}.obj",
"/I", "./ext/wasm3/source", "/I", "./src/ext/wasm3/source",
f, f,
], check=True) ], check=True)
subprocess.run([ subprocess.run([
@ -288,7 +256,7 @@ def build_wasm3_lib_win(release):
def build_wasm3_lib_mac(release): def build_wasm3_lib_mac(release):
includes = ["-Iext/wasm3/source"] includes = ["-Isrc/ext/wasm3/source"]
debug_flags = ["-g", "-O2"] debug_flags = ["-g", "-O2"]
flags = [ flags = [
*debug_flags, *debug_flags,
@ -297,7 +265,7 @@ def build_wasm3_lib_mac(release):
"-Dd_m3VerboseErrorMessages", "-Dd_m3VerboseErrorMessages",
] ]
for f in glob.iglob("ext/wasm3/source/*.c"): for f in glob.iglob("src/ext/wasm3/source/*.c"):
name = os.path.splitext(os.path.basename(f))[0] + ".o" name = os.path.splitext(os.path.basename(f))[0] + ".o"
subprocess.run([ subprocess.run([
"clang", "-c", *flags, *includes, "clang", "-c", *flags, *includes,
@ -330,9 +298,9 @@ def build_orca_win(release):
# compile orca # compile orca
includes = [ includes = [
"/I", "src", "/I", "src",
"/I", "ext", "/I", "src/ext",
"/I", "ext/angle/include", "/I", "src/ext/angle/include",
"/I", "ext/wasm3/source", "/I", "src/ext/wasm3/source",
] ]
libs = [ libs = [
"/LIBPATH:build/bin", "/LIBPATH:build/bin",
@ -355,9 +323,9 @@ def build_orca_mac(release):
includes = [ includes = [
"-Isrc", "-Isrc",
"-Iext", "-Isrc/ext",
"-Iext/angle/include", "-Isrc/ext/angle/include",
"-Iext/wasm3/source" "-Isrc/ext/wasm3/source"
] ]
libs = ["-Lbuild/bin", "-Lbuild/lib", "-lorca", "-lwasm3"] libs = ["-Lbuild/bin", "-Lbuild/lib", "-lorca", "-lwasm3"]
debug_flags = ["-O2"] if release else ["-g", "-DOC_DEBUG -DOC_LOG_COMPILE_DEBUG"] debug_flags = ["-O2"] if release else ["-g", "-DOC_DEBUG -DOC_LOG_COMPILE_DEBUG"]
@ -390,7 +358,7 @@ def build_orca_mac(release):
def gen_all_bindings(): def gen_all_bindings():
gles_gen("ext/gl.xml", gles_gen("src/ext/gl.xml",
"src/wasmbind/gles_api.json", "src/wasmbind/gles_api.json",
"src/graphics/orca_gl31.h" "src/graphics/orca_gl31.h"
) )
@ -459,15 +427,15 @@ def verify_angle():
checkfiles = None checkfiles = None
if platform.system() == "Windows": if platform.system() == "Windows":
checkfiles = [ checkfiles = [
"ext/angle/bin/libEGL.dll", "src/ext/angle/bin/libEGL.dll",
"ext/angle/lib/libEGL.dll.lib", "src/ext/angle/lib/libEGL.dll.lib",
"ext/angle/bin/libGLESv2.dll", "src/ext/angle/bin/libGLESv2.dll",
"ext/angle/lib/libGLESv2.dll.lib", "src/ext/angle/lib/libGLESv2.dll.lib",
] ]
elif platform.system() == "Darwin": elif platform.system() == "Darwin":
checkfiles = [ checkfiles = [
"ext/angle/bin/libEGL.dylib", "src/ext/angle/bin/libEGL.dylib",
"ext/angle/bin/libGLESv2.dylib", "src/ext/angle/bin/libGLESv2.dylib",
] ]
if checkfiles is None: if checkfiles is None:
@ -512,11 +480,7 @@ def download_angle():
with ZipFile(filepath, "r") as anglezip: with ZipFile(filepath, "r") as anglezip:
anglezip.extractall(path="scripts/files") anglezip.extractall(path="scripts/files")
shutil.copytree(f"scripts/files/angle/", "ext/angle", dirs_exist_ok=True) shutil.copytree(f"scripts/files/angle/", "src/ext/angle", dirs_exist_ok=True)
def yeet(path):
os.makedirs(path, exist_ok=True)
shutil.rmtree(path)
def prompt(msg): def prompt(msg):
@ -529,29 +493,40 @@ def prompt(msg):
else: else:
print("Please enter \"yes\" or \"no\" and press return.") print("Please enter \"yes\" or \"no\" and press return.")
def install_dir():
def install_path():
if platform.system() == "Windows": if platform.system() == "Windows":
orca_dir = os.path.join(os.getenv("LOCALAPPDATA"), "orca") return os.path.join(os.getenv("LOCALAPPDATA"), "orca")
else: else:
orca_dir = os.path.expanduser(os.path.join("~", ".orca")) return os.path.expanduser(os.path.join("~", ".orca"))
bin_dir = os.path.join(orca_dir, "bin")
return (orca_dir, bin_dir)
def install(args): def install(args):
dest, bin_dir = install_path() dest = install_dir()
bin_dir = os.path.join(dest, "bin")
src_dir = os.path.join(dest, "src")
version_file = os.path.join(dest, ".orcaversion")
version = orca_version()
existing_version = None
try:
with open(version_file, "r") as f:
existing_version = f.read().strip()
except FileNotFoundError:
pass
if not args.no_confirm: if not args.no_confirm:
print("The Orca command-line tools will be installed to:") print(f"The Orca command-line tools (version {version}) will be installed to:")
print(dest) print(dest)
print() print()
if existing_version is not None:
print(f"This will overwrite version {existing_version}.")
print()
if not prompt("Proceed with the installation?"): if not prompt("Proceed with the installation?"):
return return
yeet(bin_dir) yeetdir(bin_dir)
yeetdir(src_dir)
yeetfile(version_file)
# The MS Store version of Python does some really stupid stuff with AppData: # The MS Store version of Python does some really stupid stuff with AppData:
# https://git.handmade.network/hmn/orca/issues/32 # https://git.handmade.network/hmn/orca/issues/32
@ -562,14 +537,19 @@ def install(args):
# paths we need, the following scripts work regardless of Python install. # paths we need, the following scripts work regardless of Python install.
# #
# Also apparently you can't just do mkdir in a subprocess call here, hence the # Also apparently you can't just do mkdir in a subprocess call here, hence the
# trivial batch script. # trivial batch scripts.
if platform.system() == "Windows": if platform.system() == "Windows":
subprocess.run(["scripts\\mkdir.bat", bin_dir], check=True) subprocess.run(["scripts\\mkdir.bat", bin_dir], check=True)
subprocess.run(["scripts\\mkdir.bat", src_dir], check=True)
subprocess.run(["scripts\\touch.bat", version_file], check=True)
shutil.copytree("scripts", os.path.join(bin_dir, "sys_scripts")) shutil.copytree("scripts", os.path.join(bin_dir, "sys_scripts"))
shutil.copy("orca", bin_dir) shutil.copy("orca", bin_dir)
shutil.copytree("src", src_dir, dirs_exist_ok=True)
if platform.system() == "Windows": if platform.system() == "Windows":
shutil.copy("orca.bat", bin_dir) shutil.copy("orca.bat", bin_dir)
with open(version_file, "w") as f:
f.write(version)
print() print()
if platform.system() == "Windows": if platform.system() == "Windows":
@ -582,7 +562,7 @@ def install(args):
print("Orca has been added to your PATH. Restart any open terminals to use it.") print("Orca has been added to your PATH. Restart any open terminals to use it.")
else: else:
print("No worries. You can manually add Orca to your PATH in the Windows settings") print("No worries. You can manually add Orca to your PATH in the Windows settings")
print("this in the Windows settings by searching for \"environment variables\".") print("by searching for \"environment variables\".")
else: else:
print("The Orca tools have been installed. Make sure the Orca tools are on your PATH by") print("The Orca tools have been installed. Make sure the Orca tools are on your PATH by")
print("adding the following to your shell config:") print("adding the following to your shell config:")

View File

@ -1,15 +1,28 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import argparse import argparse
import sys
from .bundle import attach_bundle_commands from .bundle import attach_bundle_commands
from .source import attach_source_commands
from .dev import attach_dev_commands from .dev import attach_dev_commands
from .version import attach_version_command
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("-?", action="help", help=argparse.SUPPRESS)
subparsers = parser.add_subparsers(required=True, title='commands') subparsers = parser.add_subparsers(required=True, title="commands")
attach_bundle_commands(subparsers) attach_bundle_commands(subparsers)
attach_source_commands(subparsers)
attach_dev_commands(subparsers) attach_dev_commands(subparsers)
attach_version_command(subparsers)
args = parser.parse_args() # Hack to run the actual version command if we pass -v or --version.
# Using argparse action="version" requires us to pass a single string
# and doesn't allow us to run our own custom version-printing function.
argv = sys.argv[1:]
if argv[0] in ["-v", "--version"]:
argv = ["version"]
args = parser.parse_args(argv)
args.func(args) args.func(args)

189
scripts/source.py Normal file
View File

@ -0,0 +1,189 @@
import hashlib
import json
import os
import re
import shutil
from .log import *
from .utils import yeetdir
from .version import src_dir, orca_version
def attach_source_commands(subparsers):
source_cmd = subparsers.add_parser("source", help="Commands for helping compile the Orca source code into your project.")
source_sub = source_cmd.add_subparsers(title="commands")
cflags_cmd = source_sub.add_parser("cflags", help="Get help setting up a C or C++ compiler to compile the Orca source.")
cflags_cmd.add_argument("srcdir", nargs="?", default=src_dir(), help="the directory containing the Orca source code (defaults to system installation)")
cflags_cmd.set_defaults(func=shellish(cflags))
vendor_cmd = source_sub.add_parser("vendor", help="Copy the Orca source code into your project.")
vendor_cmd.add_argument("dir", type=str, help="the directory into which the Orca source code will be copied")
vendor_cmd.set_defaults(func=shellish(vendor))
def vendor(args):
# Verify that we are ok to vendor into the requested dir.
if os.path.exists(args.dir):
try:
with open(vendor_file_path(args.dir), "r") as f:
vendor_info = json.load(f)
version = vendor_info["version"]
print(f"Orca version {version} is currently installed in that directory.")
if vendor_checksum(args.dir) != vendor_info["checksum"]:
log_error(f"The contents of your vendor directory have been modified. This command will exit to avoid overwriting any local changes. To proceed, manually delete {args.dir} and try again.")
exit(1)
except FileNotFoundError:
if len(os.listdir(args.dir)) > 0:
log_error(f"The requested directory already exists and does not appear to contain Orca source code. To avoid deleting anything important, please either provide the correct path or manually empty {args.dir} first.")
exit(1)
yeetdir(args.dir)
shutil.copytree(src_dir(), args.dir)
with open(vendor_file_path(args.dir), "w") as f:
json.dump({
"version": orca_version(),
"checksum": vendor_checksum(args.dir),
}, f, indent=2)
print(f"Version {orca_version()} of the Orca source code has been copied to {args.dir}.")
def vendor_file_path(vendor_dir):
return os.path.join(vendor_dir, ".orcavendor")
def vendor_checksum(dir):
return dirhash(dir, excluded_extensions=["orcavendor"])
def cflags(args):
if not os.path.exists(os.path.join(args.srcdir, "orca.h")):
log_error(f"The provided path does not seem to contain the Orca source code: {args.srcdir}")
exit(1)
def path_contains(a, b):
a_abs = os.path.abspath(a)
b_abs = os.path.abspath(b)
return os.path.commonpath([a_abs, b_abs]) == a_abs
def nicepath(path):
path_abs = os.path.abspath(path)
if path_contains(os.getcwd(), path_abs):
return os.path.relpath(path_abs)
else:
return path_abs
include = nicepath(args.srcdir)
orcac = nicepath(os.path.join(args.srcdir, "orca.c"))
extinclude = nicepath(os.path.join(args.srcdir, "ext"))
sysinclude = nicepath(os.path.join(args.srcdir, "libc-shim/include"))
libcsource = nicepath(os.path.join(args.srcdir, "libc-shim/src/*.c"))
print("To compile Orca as part of your C or C++ project, you must:")
print(f"> Put the following directory on your SYSTEM include search path:")
print(f" {sysinclude}")
print(f"> Put the following directories on your include search path:")
print(f" {include}")
print(f" {extinclude}")
print(f"> Compile the following file as a single translation unit:")
print(f" {orcac}")
print(f"> Compile the following files as separate translation units:")
print(f" {libcsource}")
print()
print("The following clang flags are also required:")
print("> --target=wasm32 (to compile to wasm)")
print("> --no-standard-libraries (to use only our libc shim)")
print("> -mbulk-memory (to enable memset/memcpy intrinsics, which are required)")
print("> -D__ORCA__ (to signal that the Orca source code is being compiled to run on Orca itself)")
print("> -Wl,--no-entry (to prevent wasm-ld from looking for a _start symbol)")
print("> -Wl,--export-dynamic (to expose your module's functions to Orca)")
print()
print("And the following clang flags are recommended:")
print("> -g -O2 (to compile with optimizations and debug info)")
print()
print("Complete clang example:")
print()
print(f"clang --target=wasm32 --no-standard-libraries -mbulk-memory -g -O2 -D__ORCA__ -Wl,--no-entry -Wl,--export-dynamic -isystem {sysinclude} -I {include} -I {extinclude} {orcac} {libcsource} your-main.c")
print()
if not path_contains(os.getcwd(), args.srcdir):
print("If these paths look crazy to you, consider vendoring the source code into your")
print("project using `orca source vendor`.")
print()
# -----------------------------------------------------------------------------
# Directory-hashing implementation pulled from the checksumdir package on pypi.
# Licensed under the MIT license.
# -----------------------------------------------------------------------------
def dirhash(
dirname,
hash_func=hashlib.sha1,
excluded_files=None,
ignore_hidden=False,
followlinks=False,
excluded_extensions=None,
include_paths=False
):
if not excluded_files:
excluded_files = []
if not excluded_extensions:
excluded_extensions = []
if not os.path.isdir(dirname):
raise TypeError("{} is not a directory.".format(dirname))
hashvalues = []
for root, dirs, files in os.walk(dirname, topdown=True, followlinks=followlinks):
if ignore_hidden and re.search(r"/\.", root):
continue
dirs.sort()
files.sort()
for fname in files:
if ignore_hidden and fname.startswith("."):
continue
if fname.split(".")[-1:][0] in excluded_extensions:
continue
if fname in excluded_files:
continue
hashvalues.append(_filehash(os.path.join(root, fname), hash_func))
if include_paths:
hasher = hash_func()
# get the resulting relative path into array of elements
path_list = os.path.relpath(os.path.join(root, fname)).split(os.sep)
# compute the hash on joined list, removes all os specific separators
hasher.update(''.join(path_list).encode('utf-8'))
hashvalues.append(hasher.hexdigest())
return _reduce_hash(hashvalues, hash_func)
def _filehash(filepath, hashfunc):
hasher = hashfunc()
blocksize = 64 * 1024
if not os.path.exists(filepath):
return hasher.hexdigest()
with open(filepath, "rb") as fp:
while True:
data = fp.read(blocksize)
if not data:
break
hasher.update(data)
return hasher.hexdigest()
def _reduce_hash(hashlist, hashfunc):
hasher = hashfunc()
for hashvalue in sorted(hashlist):
hasher.update(hashvalue.encode("utf-8"))
return hasher.hexdigest()

3
scripts/touch.bat Normal file
View File

@ -0,0 +1,3 @@
@echo off
type nul > %1
exit /b %errorlevel%

View File

@ -1,7 +1,6 @@
import glob import glob
import os import os
import subprocess import shutil
import traceback
from contextlib import contextmanager from contextlib import contextmanager
@ -18,3 +17,13 @@ def pushd(new_dir):
def removeall(dir): def removeall(dir):
[os.remove(f) for f in glob.iglob("{}/*".format(dir), recursive=True)] [os.remove(f) for f in glob.iglob("{}/*".format(dir), recursive=True)]
os.removedirs(dir) os.removedirs(dir)
def yeetdir(path):
os.makedirs(path, exist_ok=True)
shutil.rmtree(path)
def yeetfile(path):
if os.path.exists(path):
os.remove(path)

95
scripts/version.py Normal file
View File

@ -0,0 +1,95 @@
import os
import subprocess
import sys
from .log import *
from .utils import pushd
# Checks if the Orca tool should use a source checkout of Orca instead of a system install.
# This is copy-pasted to the command-line tool so it can work before loading anything.
#
# Returns: (use source, source directory, is actually the source's tool)
def check_if_source():
def path_is_in_orca_source(path):
dir = path
while True:
try:
os.stat(os.path.join(dir, ".orcaroot"))
return (True, dir)
except FileNotFoundError:
pass
newdir = os.path.dirname(dir)
if newdir == dir:
return (False, None)
dir = newdir
in_source, current_source_dir = path_is_in_orca_source(os.getcwd())
script_is_source, script_source_dir = path_is_in_orca_source(os.path.dirname(os.path.abspath(__file__)))
use_source = in_source or script_is_source
source_dir = current_source_dir or script_source_dir
return (use_source, source_dir, script_is_source)
def is_orca_source():
use_source, _, _ = check_if_source()
return use_source
def actual_install_dir():
# The path adjustment in here is technically sort of fragile because it depends
# on the current location of this actual file. But oh well.
if is_orca_source():
raise Exception("actual_install_dir should not be called when using the source version of the Orca tools")
return os.path.normpath(os.path.join(os.path.abspath(__file__), "../../.."))
def src_dir():
# More fragile path adjustments! Yay!
if is_orca_source():
return os.path.normpath(os.path.join(os.path.abspath(__file__), "../../src"))
else:
return os.path.normpath(os.path.join(os.path.abspath(__file__), "../../../src"))
def orca_version():
is_source, source_dir, _ = check_if_source()
if is_source:
with pushd(source_dir):
version = "unknown"
if os.path.exists(".git"):
try:
res = subprocess.run(["git", "rev-parse", "--short", "HEAD"], check=True, capture_output=True, text=True)
version = res.stdout.strip()
except subprocess.CalledProcessError:
log_warning("failed to look up current git hash for version number")
return f"dev-{version}"
else:
try:
with open(os.path.join(actual_install_dir(), ".orcaversion"), "r") as f:
version = f.read().strip()
return version
except FileNotFoundError:
return "dev-unknown"
def attach_version_command(subparsers):
version_cmd = subparsers.add_parser("version", help="Print the current Orca version.")
version_cmd.set_defaults(func=print_orca_version)
def print_orca_version(args):
use_source, source_dir, _ = check_if_source()
# This function prints the bare version number to stdout and everything else
# to stderr. This makes it easy to use the version number in shell pipelines
# without requiring extra flags or parsing a weird output format.
sys.stdout.write(orca_version() + "\n")
if use_source:
sys.stderr.write(f"Orca is running from a source checkout.\n")
sys.stderr.write(f"Source dir: {source_dir}\n")
else:
sys.stderr.write(f"Orca is running from a system installation.\n")
sys.stderr.write(f"Install dir: {actual_install_dir()}\n")

View File

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

View File

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 86 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Some files were not shown because too many files have changed in this diff Show More