Skip to content

Commit 3ec1f5e

Browse files
authored
Merge pull request #136 from sysprog21/cross-compile
Support cross-compilation
2 parents cdda0ea + ee9cdee commit 3ec1f5e

File tree

18 files changed

+1506
-111
lines changed

18 files changed

+1506
-111
lines changed

Makefile

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,21 @@ ifeq ($(filter $(check_goal),config defconfig),)
1010
endif
1111
endif
1212

13+
# Detect Emscripten early (before including toolchain.mk)
14+
CC_VERSION := $(shell $(CC) --version 2>/dev/null)
15+
ifneq ($(findstring emcc,$(CC_VERSION)),)
16+
CC_IS_EMCC := 1
17+
endif
18+
19+
# Enforce SDL backend for Emscripten builds (skip during config targets)
20+
ifeq ($(filter $(check_goal),config defconfig),)
21+
ifeq ($(CC_IS_EMCC),1)
22+
ifneq ($(CONFIG_BACKEND_SDL),y)
23+
$(error Emscripten (WebAssembly) builds require SDL backend. Please run: env CC=emcc make defconfig)
24+
endif
25+
endif
26+
endif
27+
1328
# Target variables initialization
1429

1530
target-y :=
@@ -23,6 +38,8 @@ target.a-y += libtwin.a
2338
# Core library
2439

2540
libtwin.a_cflags-y :=
41+
# Emscripten size optimization
42+
libtwin.a_cflags-$(CC_IS_EMCC) += -Oz
2643

2744
libtwin.a_files-y = \
2845
src/box.c \
@@ -85,14 +102,26 @@ endif
85102

86103
ifeq ($(CONFIG_LOADER_JPEG), y)
87104
libtwin.a_files-y += src/image-jpeg.c
105+
ifneq ($(CC_IS_EMCC), 1)
88106
libtwin.a_cflags-y += $(shell pkg-config --cflags libjpeg)
89107
TARGET_LIBS += $(shell pkg-config --libs libjpeg)
108+
else
109+
# Emscripten libjpeg port - flags needed for both compile and link
110+
libtwin.a_cflags-y += -sUSE_LIBJPEG=1
111+
TARGET_LIBS += -sUSE_LIBJPEG=1
112+
endif
90113
endif
91114

92115
ifeq ($(CONFIG_LOADER_PNG), y)
93116
libtwin.a_files-y += src/image-png.c
117+
ifneq ($(CC_IS_EMCC), 1)
94118
libtwin.a_cflags-y += $(shell pkg-config --cflags libpng)
95119
TARGET_LIBS += $(shell pkg-config --libs libpng)
120+
else
121+
# Emscripten libpng port (includes zlib) - flags needed for both compile and link
122+
libtwin.a_cflags-y += -sUSE_LIBPNG=1 -sUSE_ZLIB=1
123+
TARGET_LIBS += -sUSE_LIBPNG=1 -sUSE_ZLIB=1
124+
endif
96125
endif
97126

98127
ifeq ($(CONFIG_LOADER_GIF), y)
@@ -116,6 +145,8 @@ libapps.a_files-$(CONFIG_DEMO_ANIMATION) += apps/animation.c
116145
libapps.a_files-$(CONFIG_DEMO_IMAGE) += apps/image.c
117146

118147
libapps.a_includes-y := include
148+
# Emscripten size optimization
149+
libapps.a_cflags-$(CC_IS_EMCC) += -Oz
119150

120151
# Graphical backends
121152

@@ -124,8 +155,15 @@ BACKEND := none
124155
ifeq ($(CONFIG_BACKEND_SDL), y)
125156
BACKEND = sdl
126157
libtwin.a_files-y += backend/sdl.c
158+
# Emscripten uses ports system for SDL2
159+
ifneq ($(CC_IS_EMCC), 1)
127160
libtwin.a_cflags-y += $(shell sdl2-config --cflags)
128161
TARGET_LIBS += $(shell sdl2-config --libs)
162+
else
163+
# Emscripten SDL2 port - flags needed for both compile and link
164+
libtwin.a_cflags-y += -sUSE_SDL=2
165+
TARGET_LIBS += -sUSE_SDL=2
166+
endif
129167
endif
130168

131169
ifeq ($(CONFIG_BACKEND_FBDEV), y)
@@ -149,7 +187,6 @@ libtwin.a_files-y += backend/headless.c
149187
endif
150188

151189
# Performance tester
152-
153190
ifeq ($(CONFIG_PERF_TEST), y)
154191
target-$(CONFIG_PERF_TEST) += mado-perf
155192
mado-perf_depends-y += $(target.a-y)
@@ -167,13 +204,34 @@ target-y += demo-$(BACKEND)
167204
demo-$(BACKEND)_depends-y += $(target.a-y)
168205
demo-$(BACKEND)_files-y = apps/main.c
169206
demo-$(BACKEND)_includes-y := include
207+
# Emscripten size optimization
208+
demo-$(BACKEND)_cflags-$(CC_IS_EMCC) += -Oz
170209
demo-$(BACKEND)_ldflags-y := \
171210
$(target.a-y) \
172211
$(TARGET_LIBS)
212+
213+
# Emscripten-specific linker flags for WebAssembly builds
214+
ifeq ($(CC_IS_EMCC), 1)
215+
demo-$(BACKEND)_ldflags-y += \
216+
-sINITIAL_MEMORY=33554432 \
217+
-sALLOW_MEMORY_GROWTH=1 \
218+
-sSTACK_SIZE=1048576 \
219+
-sUSE_SDL=2 \
220+
-sMINIMAL_RUNTIME=0 \
221+
-sDYNAMIC_EXECUTION=0 \
222+
-sASSERTIONS=0 \
223+
-sEXPORTED_FUNCTIONS=_main,_malloc,_free \
224+
-sEXPORTED_RUNTIME_METHODS=ccall,cwrap \
225+
-sNO_EXIT_RUNTIME=1 \
226+
-Oz \
227+
--preload-file assets \
228+
--exclude-file assets/web
229+
endif
173230
endif
174231

175232
# Font editor tool
176-
233+
# Tools should not be built for WebAssembly
234+
ifneq ($(CC_IS_EMCC), 1)
177235
ifeq ($(CONFIG_TOOLS), y)
178236
target-$(CONFIG_TOOL_FONTEDIT) += font-edit
179237
font-edit_files-y = \
@@ -194,6 +252,7 @@ headless-ctl_files-y = tools/headless-ctl.c
194252
headless-ctl_includes-y := include
195253
headless-ctl_ldflags-y := # -lrt
196254
endif
255+
endif
197256

198257
# Build system integration
199258

@@ -237,3 +296,26 @@ defconfig: $(KCONFIGLIB)
237296
config: $(KCONFIGLIB) configs/Kconfig
238297
@tools/kconfig/menuconfig.py configs/Kconfig
239298
@tools/kconfig/genconfig.py configs/Kconfig
299+
300+
# WebAssembly post-build: Copy artifacts to assets/web/
301+
.PHONY: wasm-install
302+
wasm-install:
303+
@if [ "$(CC_IS_EMCC)" = "1" ]; then \
304+
echo "Installing WebAssembly artifacts to assets/web/..."; \
305+
mkdir -p assets/web; \
306+
cp -f .demo-$(BACKEND)/demo-$(BACKEND) .demo-$(BACKEND)/demo-$(BACKEND).wasm .demo-$(BACKEND)/demo-$(BACKEND).data assets/web/ 2>/dev/null || true; \
307+
echo "✓ WebAssembly build artifacts copied to assets/web/"; \
308+
echo ""; \
309+
echo "\033[1;32m========================================\033[0m"; \
310+
echo "\033[1;32mWebAssembly build complete!\033[0m"; \
311+
echo "\033[1;32m========================================\033[0m"; \
312+
echo ""; \
313+
echo "To test in browser, run:"; \
314+
echo " \033[1;34m./scripts/serve-wasm.py --open\033[0m"; \
315+
echo ""; \
316+
fi
317+
318+
# Override all target to add post-build hook for Emscripten
319+
ifeq ($(CC_IS_EMCC), 1)
320+
all: wasm-install
321+
endif

apps/main.c

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,39 @@ static void sigint_handler(int sig)
8282
exit(1);
8383
}
8484

85+
/* Initialize demo applications based on build configuration.
86+
* Shared by both native and WebAssembly builds.
87+
*/
88+
static void init_demo_apps(twin_context_t *ctx)
89+
{
90+
twin_screen_t *screen = ctx->screen;
91+
#if defined(CONFIG_DEMO_MULTI)
92+
apps_multi_start(screen, "Demo", 100, 100, 400, 400);
93+
#endif
94+
#if defined(CONFIG_DEMO_HELLO)
95+
apps_hello_start(screen, "Hello, World", 0, 0, 200, 200);
96+
#endif
97+
#if defined(CONFIG_DEMO_CLOCK)
98+
apps_clock_start(screen, "Clock", 10, 10, 200, 200);
99+
#endif
100+
#if defined(CONFIG_DEMO_CALCULATOR)
101+
apps_calc_start(screen, "Calculator", 100, 100, 200, 200);
102+
#endif
103+
#if defined(CONFIG_DEMO_LINE)
104+
apps_line_start(screen, "Line", 0, 0, 200, 200);
105+
#endif
106+
#if defined(CONFIG_DEMO_SPLINE)
107+
apps_spline_start(screen, "Spline", 20, 20, 400, 400);
108+
#endif
109+
#if defined(CONFIG_DEMO_ANIMATION)
110+
apps_animation_start(screen, "Viewer", ASSET_PATH "nyancat.gif", 20, 20);
111+
#endif
112+
#if defined(CONFIG_DEMO_IMAGE)
113+
apps_image_start(screen, "Viewer", 20, 20);
114+
#endif
115+
twin_screen_set_active(screen, screen->top);
116+
}
117+
85118
int main(void)
86119
{
87120
tx = twin_create(WIDTH, HEIGHT);
@@ -106,34 +139,8 @@ int main(void)
106139
twin_screen_set_background(
107140
tx->screen, load_background(tx->screen, ASSET_PATH "/tux.png"));
108141

109-
#if defined(CONFIG_DEMO_MULTI)
110-
apps_multi_start(tx->screen, "Demo", 100, 100, 400, 400);
111-
#endif
112-
#if defined(CONFIG_DEMO_HELLO)
113-
apps_hello_start(tx->screen, "Hello, World", 0, 0, 200, 200);
114-
#endif
115-
#if defined(CONFIG_DEMO_CLOCK)
116-
apps_clock_start(tx->screen, "Clock", 10, 10, 200, 200);
117-
#endif
118-
#if defined(CONFIG_DEMO_CALCULATOR)
119-
apps_calc_start(tx->screen, "Calculator", 100, 100, 200, 200);
120-
#endif
121-
#if defined(CONFIG_DEMO_LINE)
122-
apps_line_start(tx->screen, "Line", 0, 0, 200, 200);
123-
#endif
124-
#if defined(CONFIG_DEMO_SPLINE)
125-
apps_spline_start(tx->screen, "Spline", 20, 20, 400, 400);
126-
#endif
127-
#if defined(CONFIG_DEMO_ANIMATION)
128-
apps_animation_start(tx->screen, "Viewer", ASSET_PATH "nyancat.gif", 20,
129-
20);
130-
#endif
131-
#if defined(CONFIG_DEMO_IMAGE)
132-
apps_image_start(tx->screen, "Viewer", 20, 20);
133-
#endif
134-
135-
twin_screen_set_active(tx->screen, tx->screen->top);
136-
twin_dispatch(tx);
142+
/* Start application with unified API (handles native and WebAssembly) */
143+
twin_run(tx, init_demo_apps);
137144

138145
return 0;
139146
}

assets/web/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# WebAssembly runtime files (generated by build)
2+
demo-sdl
3+
demo-sdl.wasm
4+
demo-sdl.data

0 commit comments

Comments
 (0)