Skip to content

Commit 504fa8a

Browse files
committed
updated render_cpp script to work
1 parent 329991a commit 504fa8a

File tree

4 files changed

+56
-19
lines changed

4 files changed

+56
-19
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
/.quarto/
2+
/__pycache__/

_quarto.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
project:
22
type: website
33
pre-render: scripts/render_cpp.py
4+
resources: "*.wasm"
45

56
execute:
67
freeze: auto

scripts/includes/wasm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#define WASM_EXPORT __attribute__((visibility("default"))) extern "C"
2+
#define WASM_IMPORT extern "C"

scripts/render_cpp.py

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,40 @@
66
and compile them to wasm for use in quarto web pages.
77
"""
88

9+
import ctypes
910
import os
11+
import shutil
1012
import subprocess
1113
import sys
1214

1315
import exdown
1416

17+
# --- CONSTANTS --- #
18+
CFLAGS = [
19+
"-Wall",
20+
"--target=wasm32",
21+
"-I./scripts/includes/", # this includes the wasm.h file
22+
"-Os",
23+
"-flto",
24+
"--no-standard-libraries",
25+
"-fvisibility=hidden",
26+
"-std=c++14",
27+
"-ffunction-sections", # This makes the function names normal
28+
"-fdata-sections",
29+
]
30+
31+
LDFLAGS = [
32+
"--no-entry",
33+
"--strip-all",
34+
"--export-dynamic",
35+
"--allow-undefined", # This allows for external definitions in js
36+
"--initial-memory=131072",
37+
"--error-limit=0",
38+
"--lto-O3",
39+
"-O3",
40+
"--gc-sections",
41+
]
42+
1543
file_str = os.getenv("QUARTO_PROJECT_INPUT_FILES")
1644
if file_str is None:
1745
print("Error: needs to be run as a pre-render script", file=sys.stderr)
@@ -29,34 +57,39 @@ def has_cpp(filename: str) -> bool:
2957
return False
3058

3159

60+
# Get all the files to be compiled to
3261
cpp_files = [file for file in files if has_cpp(file)]
3362

3463
if cpp_files == []:
3564
print("Note: No cpp code blocks to render")
3665
sys.exit(0)
3766

3867

39-
def compile_cpp(filename: str, directory: str) -> None:
40-
command = [
41-
"clang",
42-
"--target=wasm32",
43-
"--no-standard-libraries",
44-
"-Wl,--export-all",
45-
"-Wl,--no-entry",
46-
"-o",
47-
f"{directory}/{filename}.wasm",
48-
f"{directory}/{filename}.cpp",
49-
]
68+
def compile_cpp(filepath: str) -> None:
69+
command = (
70+
["clang"]
71+
+ CFLAGS
72+
+ [f"-Wl,{flag}" for flag in LDFLAGS]
73+
+ [
74+
"-o",
75+
f"{filepath}.wasm",
76+
f"{filepath}.cpp",
77+
]
78+
)
5079
subprocess.run(command, check=True)
5180

5281

5382
for file in cpp_files:
5483
print(f"Parsing: {file}")
55-
cpp_code = "\n".join(line[0] for line in exdown.extract(file, syntax_filter="cpp"))
56-
if (filename := os.path.basename(file)) is not None:
57-
filename = filename.split(".")[0]
58-
directory = os.path.dirname(file)
59-
with open(f"{directory}/{filename}.cpp", "w", encoding="UTF-8") as f:
60-
f.write(cpp_code)
61-
# TODO: Implement compilation to wasm
62-
# compile_cpp(filename, directory)
84+
85+
# check if the file exists and get the filename
86+
if file is not None:
87+
# Extract cpp code from qmd codeblocks
88+
cpp_code = "\n".join(
89+
line[0] for line in exdown.extract(file, syntax_filter="cpp")
90+
)
91+
filename = file.split(".")[0]
92+
93+
with open(f"{filename}.cpp", "w", encoding="UTF-8") as f:
94+
f.write(cpp_code)
95+
compile_cpp(filename)

0 commit comments

Comments
 (0)