Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 139 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
# LLVM apt repo is added so clang-format-20 is available on ubuntu-24.04
# (which ships clang-format-18 by default).
#
# All eight top-level jobs (lint, build, debug-build, sanitize, motif,
# osiris, xfig, gimp) run in parallel. Osiris and Xfig each have no Motif
# All nine top-level jobs (lint, build, debug-build, sanitize, motif,
# osiris, xfig, gimp, sdl3) run in parallel. The sdl3 job builds the
# compat stack against the native SDL3 backend (SDL_BACKEND=sdl3); every
# other job uses the default SDL2 backend, so the SDL3 translation shim in
# src/sdl-compat.h is only exercised there. Osiris and Xfig each have no Motif
# dependency, so they live in their own jobs rather than queueing behind
# the Motif + ViolaWWW + Mosaic chain. GIMP 0.54 is a Motif client but
# gets its own job too: its plug-in build pulls in libpng/jpeg/tiff that
Expand Down Expand Up @@ -970,3 +973,137 @@ jobs:
- name: ccache stats
if: ${{ !cancelled() }}
run: ccache --show-stats

# ---- Native SDL3 backend build + regression tests ----
# ubuntu-24.04 ships no SDL3 in its repos (SDL3 GA'd after noble), and no
# GitHub runner image or readily-available PPA carries libsdl3-dev for
# noble (the savoury1 multimedia PPA, for instance, packages only SDL2),
# so build SDL3 + SDL3_ttf from their latest stable release-3.2.* tags
# into a cached prefix, then build the compat stack with SDL_BACKEND=sdl3
# and run the sanitizer-friendly regression subset. This is the only job
# that exercises the native-SDL3 translation shim (src/sdl-compat.h).
sdl3:
runs-on: ubuntu-24.04
env:
SDL3_PREFIX: ${{ github.workspace }}/.sdl3-prefix
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Install build dependencies
# cmake/ninja drive the SDL3 source build; freetype/harfbuzz back
# SDL3_ttf (built with SDLTTF_VENDORED=OFF). No libsdl2-dev: the SDL3
# backend links the libSDL3 / libSDL3_ttf built below directly.
#
# libx11-dev is still needed: the staged upstream libXt/libX11 sources
# fall through to a few system X11 protocol/private headers (e.g.
# X11/Xpoll.h) that the compat header tree does not stage. The other
# jobs pull these in transitively via libsdl2-dev -> libx11-dev; this
# job has no SDL2, so install libx11-dev explicitly.
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
clang ccache make pkg-config python3 libpixman-1-dev \
cmake ninja-build git libfreetype-dev libharfbuzz-dev libx11-dev

- name: Cache SDL3 + SDL3_ttf prefix
id: sdl3-cache
uses: actions/cache@v5
with:
path: ${{ env.SDL3_PREFIX }}
key: sdl3-src-prefix-v1-${{ runner.os }}

- name: Build SDL3 + SDL3_ttf from source
if: steps.sdl3-cache.outputs.cache-hit != 'true'
# --filter=blob:none keeps history + tags cheap so the latest stable
# release-3.2.* tag can be selected without a full checkout.
# SDL_UNIX_CONSOLE_BUILD=ON builds the dummy/offscreen video drivers
# without requiring X11 or Wayland development libraries; the compat
# regression tests run under SDL_VIDEODRIVER=dummy with the software
# renderer, so no real windowing backend is needed in CI.
run: |
set -eux
tmp="$(mktemp -d)"
git clone --filter=blob:none --no-checkout \
https://github.com/libsdl-org/SDL.git "$tmp/SDL"
git -C "$tmp/SDL" checkout \
"$(git -C "$tmp/SDL" tag -l 'release-3.2.*' | sort -V | tail -1)"
cmake -S "$tmp/SDL" -B "$tmp/SDL/b" -G Ninja \
-DCMAKE_INSTALL_PREFIX="$SDL3_PREFIX" -DCMAKE_BUILD_TYPE=Release \
-DSDL_SHARED=ON -DSDL_STATIC=OFF -DSDL_TEST_LIBRARY=OFF \
-DSDL_UNIX_CONSOLE_BUILD=ON
cmake --build "$tmp/SDL/b"
cmake --install "$tmp/SDL/b"
git clone --filter=blob:none --no-checkout \
https://github.com/libsdl-org/SDL_ttf.git "$tmp/SDL_ttf"
git -C "$tmp/SDL_ttf" checkout \
"$(git -C "$tmp/SDL_ttf" tag -l 'release-3.2.*' | sort -V | tail -1)"
cmake -S "$tmp/SDL_ttf" -B "$tmp/SDL_ttf/b" -G Ninja \
-DCMAKE_INSTALL_PREFIX="$SDL3_PREFIX" -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH="$SDL3_PREFIX" -DBUILD_SHARED_LIBS=ON \
-DSDLTTF_VENDORED=OFF -DSDLTTF_SAMPLES=OFF
cmake --build "$tmp/SDL_ttf/b"
cmake --install "$tmp/SDL_ttf/b"
rm -rf "$tmp"

- name: Cache upstream tarballs and extracted source/headers
uses: actions/cache@v5
with:
path: |
build/upstream
!build/upstream/**/*.o
!build/upstream/**/*.d
!build/upstream/motif
!build/upstream/mosaic
!build/upstream/osiris
!build/upstream/xfig-*
!build/upstream/.cache/xfig-*
!build/upstream/gimp-*
!build/upstream/.cache/gimp-*
key: upstream-src-v2-${{ runner.os }}-${{ hashFiles('scripts/sync-upstream-headers.py') }}
restore-keys: |
upstream-src-v2-${{ runner.os }}-

- name: Cache ccache
uses: actions/cache@v5
with:
path: ~/.cache/ccache
key: ccache-sdl3-v1-${{ runner.os }}-${{ github.sha }}
restore-keys: |
ccache-sdl3-v1-${{ runner.os }}-

- name: Configure ccache and SDL3 environment
# PKG_CONFIG_PATH lets the build auto-detect sdl3/sdl3-ttf from the
# prefix; LD_LIBRARY_PATH lets the test binaries find libSDL3 at
# runtime. Both lib and lib64 are covered regardless of the prefix's
# GNUInstallDirs layout.
run: |
ccache --max-size=400M
ccache --zero-stats
{
echo "CC=ccache clang"
echo "PKG_CONFIG_PATH=$SDL3_PREFIX/lib/pkgconfig:$SDL3_PREFIX/lib64/pkgconfig"
echo "LD_LIBRARY_PATH=$SDL3_PREFIX/lib:$SDL3_PREFIX/lib64"
} >>"$GITHUB_ENV"

- name: Confirm SDL3 is detected
run: |
pkg-config --exists sdl3 sdl3-ttf
echo "SDL3 $(pkg-config --modversion sdl3), SDL3_ttf $(pkg-config --modversion sdl3-ttf)"

- name: Build libX11-compat.so (SDL_BACKEND=sdl3)
run: make SDL_BACKEND=sdl3 -j"$(nproc)"

- name: Run regression tests (SDL_BACKEND=sdl3 make check-unit)
# check-unit runs the in-tree binaries headless (SDL_VIDEODRIVER=
# dummy, software renderer) plus symbol coverage; it does not need
# Xvfb. The make test runner also folds SDL_RUNTIME_LIBDIR (the sdl3
# pkg-config libdir) onto LD_LIBRARY_PATH so libSDL3 resolves.
run: make SDL_BACKEND=sdl3 check-unit

- name: Build bundled examples (SDL_BACKEND=sdl3)
run: make SDL_BACKEND=sdl3 examples -j"$(nproc)"

- name: ccache stats
if: ${{ !cancelled() }}
run: ccache --show-stats
38 changes: 34 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
# libx11-compat

`libx11-compat` is an in-process implementation of the [X Window System](https://en.wikipedia.org/wiki/X_Window_System) client library (Xlib) layered on top of [SDL2](https://www.libsdl.org/), SDL2_ttf, and pixman.
`libx11-compat` is an in-process implementation of the [X Window System](https://en.wikipedia.org/wiki/X_Window_System) client library (Xlib) layered on top of [SDL](https://www.libsdl.org/) (SDL2 or SDL3), SDL_ttf, and pixman.
It lets existing Xlib clients keep their source unchanged while running on platforms where a conventional X server is unavailable or inconvenient:
macOS without XQuartz, Wayland-only sessions, headless CI, Android apps with their own SDL2 integration, and similar environments.
macOS without XQuartz, Wayland-only sessions, headless CI, Android apps with their own SDL integration, and similar environments.

Both SDL major versions are supported from a single source tree: the build
auto-detects SDL3 (when both SDL3 and SDL3_ttf are visible to `pkg-config`) and
otherwise uses SDL2, and the backend can be selected explicitly. See
[SDL backend](#sdl-backend) below.

The library is not a re-implementation of the X11 wire protocol and does not replace a real X server.
Its goal is to keep legacy Xlib code building and running while it is being migrated to a different toolkit or display stack.

## Building

The build is Makefile-based and organized as small `mk/` fragments.
The required dependencies are SDL2, SDL2_ttf, and pixman.
The required dependencies are pixman plus one SDL stack: either SDL2 + SDL2_ttf
or SDL3 + SDL3_ttf (see [SDL backend](#sdl-backend)).
Optional validation workloads may need their upstream build tools; Osiris uses
Meson and Ninja at build time and links against libjpeg, libpng, and freetype.

Expand All @@ -19,6 +25,30 @@ make
make check
```

### SDL backend

The same source builds against either SDL major version, selected by the
`SDL_BACKEND` make variable:

```sh
make # auto-detect: SDL3 if present, otherwise SDL2
make SDL_BACKEND=sdl2 # force the SDL2 backend
make SDL_BACKEND=sdl3 # force the native SDL3 backend
```

When `SDL_BACKEND` is unset, the build prefers SDL3 when both `sdl3` and
`sdl3-ttf` are visible to `pkg-config`, and falls back to SDL2 otherwise; an
explicit `SDL_BACKEND=...` always wins.

Under the SDL2 backend the compat stack links small in-tree wrapper shims
(`libSDL2-x11compat.so`, `libSDL2_ttf-x11compat.so`) that `dlopen` the host SDL2
at runtime, so a system SDL2 that is itself
[sdl2-compat](https://github.com/libsdl-org/sdl2-compat) over SDL3 also works.
Under the SDL3 backend the stack links `libSDL3` and `libSDL3_ttf` directly; a
single chokepoint header (`src/sdl-compat.h`) translates the SDL2-spelled API
the sources are written against to SDL3, so no source changes are needed to
switch backends.

`make check` runs the in-tree C tests, exported-symbol coverage, Motif link and demo checks, replay-driven UI smoke tests, and system-X11 differential checks.
For faster local loops, use `make check-unit`, `make check-smoke`, or `make check-differential` depending on the subsystem being changed.

Expand Down Expand Up @@ -152,7 +182,7 @@ See [`docs/COVERAGE.md`](docs/COVERAGE.md) for the per-subsystem status table, s
Most Xlib sources need no edits (porting is a build-system and runtime-environment exercise).
The general shape:

1. Link the application against `build/libX11-compat.so` plus SDL2, SDL2_ttf, and pixman, replacing the system `-lX11`.
1. Link the application against `build/libX11-compat.so` plus the SDL stack it was built with (SDL2 + SDL2_ttf, or SDL3 + SDL3_ttf) and pixman, replacing the system `-lX11`.
2. Keep the existing Xlib source unchanged.
3. Drive the event loop with `XPending` / `XNextEvent` and `ConnectionNumber` + `select()`;
the library pumps SDL internally.
Expand Down
2 changes: 1 addition & 1 deletion examples/clipboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <SDL2/SDL.h>
#include "sdl-compat.h"
#include <limits.h>
#include <signal.h>
#include <stdbool.h>
Expand Down
5 changes: 2 additions & 3 deletions mk/common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ endef
$(OUT):
@mkdir -p $@

$(OUT)/%.o: %.c | $(OUT)
$(OUT)/%.o: %.c $(SDL_BACKEND_STAMP) | $(OUT)
@mkdir -p $(dir $@)
@echo " CC $<"
$(Q)$(CC) $(CPPFLAGS) $(CFLAGS) $(STRICT_CFLAGS) $(CFLAGS_EXTRA) \
Expand All @@ -51,12 +51,11 @@ $(OUT)/%.o: %.c | $(OUT)
# compiling these translation units and keeps the WIN32 macro rewrites in
# Xlibint.h disabled so the function-pointer storage in src/xlibint-stubs.c
# stays consistent across platforms.
$(OUT)/upstream/src/%.o: $(OUT)/upstream/src/%.c | $(OUT)
$(OUT)/upstream/src/%.o: $(OUT)/upstream/src/%.c $(SDL_BACKEND_STAMP) | $(OUT)
@mkdir -p $(dir $@)
@echo " CC $<"
$(Q)$(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_EXTRA) -Wno-sign-compare -D_XLIBINT_ \
-MMD -MP -MF $(@:.o=.d) -MT $@ -MT $(@:.o=.d) -c $< -o $@

.PHONY: clean distclean

## Remove build artifacts
Expand Down
3 changes: 2 additions & 1 deletion mk/libxaw.mk
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ $(LIBXAW_OBJ_DIR):

$(LIBXAW_SRCS): $(UPSTREAM_HEADERS_STAMP)

$(LIBXAW_OBJ_DIR)/%.o: $(UPSTREAM_HEADERS_STAMP) $(LIBXT_STAGED_H) | $(LIBXAW_OBJ_DIR)
$(LIBXAW_OBJ_DIR)/%.o: $(UPSTREAM_HEADERS_STAMP) $(LIBXT_STAGED_H) \
$(SDL_BACKEND_STAMP) | $(LIBXAW_OBJ_DIR)
@echo " CC $(LIBXAW_SRC_DIR)/$*.c"
$(Q)$(CC) $(LIBXAW_CPPFLAGS) $(CFLAGS) $(LIBXAW_CFLAGS) $(CFLAGS_EXTRA) \
-MMD -MP -MF $(@:.o=.d) -MT $@ -MT $(@:.o=.d) \
Expand Down
3 changes: 2 additions & 1 deletion mk/libxpm.mk
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ $(LIBXPM_OBJ_DIR):

$(LIBXPM_SRCS): $(UPSTREAM_HEADERS_STAMP)

$(LIBXPM_OBJ_DIR)/%.o: $(LIBXPM_SRC_DIR)/%.c $(UPSTREAM_HEADERS_STAMP) | $(LIBXPM_OBJ_DIR)
$(LIBXPM_OBJ_DIR)/%.o: $(LIBXPM_SRC_DIR)/%.c $(UPSTREAM_HEADERS_STAMP) \
$(SDL_BACKEND_STAMP) | $(LIBXPM_OBJ_DIR)
@echo " CC $<"
$(Q)$(CC) $(LIBXPM_CPPFLAGS) $(CFLAGS) $(LIBXPM_CFLAGS) $(CFLAGS_EXTRA) \
-MMD -MP -MF $(@:.o=.d) -MT $@ -MT $(@:.o=.d) -c $< -o $@
Expand Down
9 changes: 5 additions & 4 deletions mk/libxt.mk
Original file line number Diff line number Diff line change
Expand Up @@ -142,16 +142,17 @@ $(OUT)/upstream/include/X11/Shell.h: $(LIBXT_GEN_DIR)/Shell.h
# files have been staged before the recipe reads them; the explicit
# dependency on LIBXT_GEN_HEADERS ensures StringDefs.h is available before
# any unit that quotes it compiles.
$(LIBXT_OBJ_DIR)/%.o: $(UPSTREAM_HEADERS_STAMP) $(LIBXT_GEN_HEADERS) $(LIBXT_STAGED_H) | \
$(LIBXT_OBJ_DIR)
$(LIBXT_OBJ_DIR)/%.o: $(UPSTREAM_HEADERS_STAMP) $(LIBXT_GEN_HEADERS) \
$(LIBXT_STAGED_H) $(SDL_BACKEND_STAMP) | $(LIBXT_OBJ_DIR)
@echo " CC $(LIBXT_SRC_DIR)/$*.c"
$(Q)$(CC) $(LIBXT_CPPFLAGS) $(CFLAGS) $(LIBXT_CFLAGS) $(CFLAGS_EXTRA) \
-MMD -MP -MF $(@:.o=.d) -MT $@ -MT $(@:.o=.d) \
-c $(LIBXT_SRC_DIR)/$*.c -o $@

# StringDefs.c lives in $(LIBXT_GEN_DIR), not LIBXT_SRC_DIR.
$(LIBXT_OBJ_DIR)/StringDefs.o: $(LIBXT_GEN_C) $(LIBXT_GEN_HEADERS) $(LIBXT_STAGED_H) | \
$(LIBXT_OBJ_DIR) $(UPSTREAM_HEADERS_STAMP)
$(LIBXT_OBJ_DIR)/StringDefs.o: $(LIBXT_GEN_C) $(LIBXT_GEN_HEADERS) \
$(LIBXT_STAGED_H) $(SDL_BACKEND_STAMP) | $(LIBXT_OBJ_DIR) \
$(UPSTREAM_HEADERS_STAMP)
@echo " CC $<"
$(Q)$(CC) $(LIBXT_CPPFLAGS) $(CFLAGS) $(LIBXT_CFLAGS) $(CFLAGS_EXTRA) \
-MMD -MP -MF $(@:.o=.d) -MT $@ -MT $(@:.o=.d) -c $< -o $@
Expand Down
9 changes: 9 additions & 0 deletions mk/sdl-wrapper.mk
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# The dlopen wrapper shims exist only for the SDL2 backend. Under
# SDL_BACKEND=sdl3 the compat stack links libSDL3 directly (see mk/sdl.mk), so
# this whole fragment collapses to an empty target list.
ifneq ($(SDL_USE_WRAPPER),1)
SDL_WRAPPER_TARGETS :=
else

SDL_WRAPPER_TARGET := $(OUT)/libSDL2-x11compat.so
SDL_TTF_WRAPPER_TARGET := $(OUT)/libSDL2_ttf-x11compat.so
SDL_WRAPPER_TARGETS := $(SDL_WRAPPER_TARGET) $(SDL_TTF_WRAPPER_TARGET)
Expand Down Expand Up @@ -36,3 +43,5 @@ $(SDL_TTF_WRAPPER_TARGET): $(SDL_TTF_WRAPPER_OBJS) | $(OUT)
@echo " LD $@"
$(Q)$(CC) $(LDFLAGS) $(call shared_lib_rpath_ldflags,$(notdir $@)) \
-shared -o $@ $(SDL_TTF_WRAPPER_OBJS) $(SDL_WRAPPER_LDLIBS)

endif
66 changes: 63 additions & 3 deletions mk/sdl.mk
Original file line number Diff line number Diff line change
@@ -1,14 +1,37 @@
# SDL detection and derived flags, isolated from config.mk so the rest of the
# build consumes one stable interface and a future SDL3 path can live here
# alongside SDL2 rather than being scattered across config / toolchain / tests.
# build consumes one stable interface across both SDL major versions rather
# than scattering the choice across config / toolchain / tests.
#
# Consumers use:
# SDL_CPPFLAGS include flags to fold into CPPFLAGS
# SDL_COMPAT_LIBS link flags for the in-tree SDL wrapper shims
# SDL_COMPAT_LIBS link flags (wrapper shims for sdl2, real libSDL3 for sdl3)
# SDL_RUNTIME_LIBDIR loader path dir tests need at runtime (may be empty)
# SDL_USE_WRAPPER 1 when the in-tree dlopen wrapper shims are built
# SDL2_PREFIX install prefix, also read by mk/sdl-wrapper.mk and
# mk/libxt.mk for the dlopen override and include path
#
# SDL_BACKEND selects the SDL major version.
# sdl2: source compiles against the SDL2 API and links the in-tree dlopen
# wrapper shims (the runtime SDL2 may itself be sdl2-compat over SDL3).
# sdl3: source compiles against the native SDL3 API through src/sdl-compat.h
# and links libSDL3 / libSDL3_ttf directly, skipping the wrapper
# (extending the ~300-symbol wrapper to SDL3's renamed surface buys
# nothing).
# When SDL_BACKEND is not set on the command line or environment, auto-detect:
# prefer SDL3 (both sdl3 and sdl3-ttf present via pkg-config), else fall back to
# SDL2. An explicit SDL_BACKEND=... always wins.
ifeq ($(origin SDL_BACKEND),undefined)
SDL_BACKEND := $(shell $(PKG_CONFIG) --exists sdl3 sdl3-ttf 2>/dev/null && echo sdl3 || echo sdl2)
endif

# Reject anything but the two known backends so a typo (e.g. SDL_BACKEND=SDL3)
# fails loudly instead of silently selecting the sdl2 branch below.
ifeq ($(filter $(SDL_BACKEND),sdl2 sdl3),)
$(error Invalid SDL_BACKEND '$(SDL_BACKEND)'; expected 'sdl2' or 'sdl3')
endif

SDL_BACKEND_STAMP := $(OUT)/.sdl-backend

# Detection prefers pkg-config (the interface sdl2-compat standardizes on) and
# falls back to sdl2-config for a classic SDL2 install. sdl2-compat ships both
# today, but a distro that packages it with only the .pc file must still
Expand All @@ -24,6 +47,24 @@ SDL2_TTF_PREFIX := $(shell $(PKG_CONFIG) --variable=prefix SDL2_ttf 2>/dev/null
SDL2_TTF_CFLAGS := $(shell $(PKG_CONFIG) --cflags SDL2_ttf 2>/dev/null)
SDL2_TTF_LIBS := $(shell $(PKG_CONFIG) --libs SDL2_ttf 2>/dev/null)

ifeq ($(SDL_BACKEND),sdl3)
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.

# Native SDL3 leg. The pkg-config modules are sdl3 and sdl3-ttf.
SDL3_CFLAGS := $(shell $(PKG_CONFIG) --cflags sdl3 2>/dev/null)
SDL3_LIBS := $(shell $(PKG_CONFIG) --libs sdl3 2>/dev/null)
SDL3_TTF_CFLAGS := $(shell $(PKG_CONFIG) --cflags sdl3-ttf 2>/dev/null)
SDL3_TTF_LIBS := $(shell $(PKG_CONFIG) --libs sdl3-ttf 2>/dev/null)
SDL3_LIBDIR := $(shell $(PKG_CONFIG) --variable=libdir sdl3 2>/dev/null)

SDL_CPPFLAGS := $(SDL3_CFLAGS) $(SDL3_TTF_CFLAGS) -DLIBX11_COMPAT_SDL3
SDL_COMPAT_LIBS := $(SDL3_LIBS) $(SDL3_TTF_LIBS)
SDL_RUNTIME_LIBDIR := $(SDL3_LIBDIR)
SDL_USE_WRAPPER := 0

else

SDL_USE_WRAPPER := 1

SDL_CPPFLAGS := $(if $(SDL2_PREFIX),-I$(SDL2_PREFIX)/include) \
$(if $(SDL2_TTF_PREFIX),-I$(SDL2_TTF_PREFIX)/include) \
$(SDL2_CFLAGS) $(SDL2_TTF_CFLAGS)
Expand All @@ -38,3 +79,22 @@ SDL_COMPAT_LIBS := -L$(abspath $(OUT)) -lSDL2-x11compat -lSDL2_ttf-x11compat
# installs); fall back to prefix/lib for the sdl2-config-only case. Empty when
# SDL is undetected.
SDL_RUNTIME_LIBDIR := $(if $(SDL2_LIBDIR),$(SDL2_LIBDIR),$(if $(SDL2_PREFIX),$(SDL2_PREFIX)/lib))

endif

.PHONY: sdl-backend-force

$(SDL_BACKEND_STAMP): sdl-backend-force | $(OUT)
$(Q){ \
printf '%s\n' 'SDL_BACKEND=$(SDL_BACKEND)'; \
printf '%s\n' 'SDL_CPPFLAGS=$(SDL_CPPFLAGS)'; \
printf '%s\n' 'SDL_COMPAT_LIBS=$(SDL_COMPAT_LIBS)'; \
} > $@.tmp
$(Q)if test -r $@ && cmp -s $@.tmp $@; then \
rm -f $@.tmp; \
else \
echo " SDL $(SDL_BACKEND)"; \
mv $@.tmp $@; \
sleep 1; \
touch $@; \
fi
Loading
Loading