Skip to content

Commit

Permalink
Make build system fully configurable
Browse files Browse the repository at this point in the history
With the inclusion of kconfiglib [1], the build system is now fully
configurable like "menuconfig" when building the Linux kernel. It allows
users to select the desired backend, choose whether to build
applications, and specify supported image loaders. This flexibility is
also useful for developers to integrate additional backends such as
Linux framebuffer and DRM device support.

[1] https://pypi.org/project/kconfiglib/
  • Loading branch information
jserv committed Jul 25, 2024
1 parent 9ec45b4 commit e5f1e88
Show file tree
Hide file tree
Showing 17 changed files with 11,214 additions and 15 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ libbackend.a
.libbackend.a
libapps.a
.libapps.a
.config
.config.old
config.h
__pycache__
*.pyc

# Tools
tools/ttf/twin-ttf
67 changes: 67 additions & 0 deletions Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
mainmenu "Mado System Configuration"

config CONFIGURED
bool
default y

choice
prompt "Backend Selection"
default BACKEND_SDL

config BACKEND_FBDEV
bool "Linux framebuffer support"

config BACKEND_SDL
bool "SDL video output support"

endchoice

menu "Image Loaders"

config LOADER_PNG
bool "Enable PNG loader"
default y

config LOADER_JPEG
bool "Enable JPEG loader"
default y

endmenu

menu "Demo Applications"

config DEMO_APPLICATIONS
bool "Build demo applications"
default y

config DEMO_MULTI
bool "Build multi demo"
default y
depends on DEMO_APPLICATIONS

config DEMO_HELLO
bool "Build Hello world demo"
default y
depends on DEMO_APPLICATIONS

config DEMO_CLOCK
bool "Build clock demo"
default y
depends on DEMO_APPLICATIONS

config DEMO_CALCULATOR
bool "Build calculator demo"
default y
depends on DEMO_APPLICATIONS

config DEMO_LINE
bool "Build line demo"
default y
depends on DEMO_APPLICATIONS

config DEMO_SPLINE
bool "Build spline demp"
default y
depends on DEMO_APPLICATIONS

endmenu
49 changes: 34 additions & 15 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
# FIXME: make these entries configurable
CONFIG_BACKEND_SDL ?= y
CONFIG_LOADER_JPEG ?= y
CONFIG_LOADER_PNG ?= y
-include .config

check_goal := $(strip $(MAKECMDGOALS))
ifneq ($(check_goal), config)
ifneq "$(CONFIG_CONFIGURED)" "y"
$(error You must first run 'make config')
endif
endif

# Rules

target-y :=
target.o-y :=
TARGET_LIBS :=

target.a-y = \
libapps.a \
libtwin.a
target.a-y :=
target.a-$(CONFIG_DEMO_APPLICATIONS) += libapps.a
target.a-y += libtwin.a

# Core library

Expand Down Expand Up @@ -68,17 +72,18 @@ endif

# Applications

libapps.a_files-y = \
apps/calc.c \
apps/spline.c \
apps/clock.c \
apps/line.c \
apps/hello.c \
apps/demo.c
libapps.a_files-y := apps/dummy.c
libapps.a_files-$(CONFIG_DEMO_MULTI) += apps/demo.c
libapps.a_files-$(CONFIG_DEMO_HELLO) += apps/hello.c
libapps.a_files-$(CONFIG_DEMO_CLOCK) += apps/clock.c
libapps.a_files-$(CONFIG_DEMO_CALCULATOR) += apps/calc.c
libapps.a_files-$(CONFIG_DEMO_LINE) += apps/line.c
libapps.a_files-$(CONFIG_DEMO_SPLINE) += apps/spline.c

libapps.a_includes-y := include

# Graphical backends

BACKEND := none

ifeq ($(CONFIG_BACKEND_SDL), y)
Expand All @@ -88,13 +93,27 @@ libtwin.a_cflags-y += $(shell sdl2-config --cflags)
TARGET_LIBS += $(shell sdl2-config --libs)
endif

# Platform-specific executables
# Standalone application

ifeq ($(CONFIG_DEMO_APPLICATIONS), y)
target-y += demo-$(BACKEND)
demo-$(BACKEND)_depends-y += $(target.a-y)
demo-$(BACKEND)_files-y = apps/main.c
demo-$(BACKEND)_includes-y := include
demo-$(BACKEND)_ldflags-y := \
$(target.a-y) \
$(TARGET_LIBS)
endif

CFLAGS += -include config.h

check_goal := $(strip $(MAKECMDGOALS))
ifneq ($(check_goal), config)
include mk/common.mk
endif

# Menuconfig
.PHONY: config
config:
@tools/kconfig/menuconfig.py
@tools/kconfig/genconfig.py
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ have the [SDL2 library](https://www.libsdl.org/), [libjpeg](https://www.ijg.org/
* macOS: `brew install sdl2 jpeg libpng`
* Ubuntu Linux / Debian: `sudo apt install libsdl2-dev libjpeg-dev libpng-dev`

Configure via [Kconfiglib](https://pypi.org/project/kconfiglib/)
```shell
$ make config
```

Build the library and demo program.
```shell
$ make
Expand Down
1 change: 1 addition & 0 deletions apps/dummy.c
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/* Placeholder */
17 changes: 17 additions & 0 deletions apps/main.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Twin - A Tiny Window System
* Copyright (c) 2024 National Cheng Kung University, Taiwan
* Copyright (c) 2004 Keith Packard <[email protected]>
* All rights reserved.
*/
Expand Down Expand Up @@ -33,6 +34,7 @@
static twin_pixmap_t *load_background(twin_screen_t *screen,
const char *filename)
{
#if defined(CONFIG_LOADER_PNG)
twin_pixmap_t *raw_background = twin_png_to_pixmap(filename, TWIN_ARGB32);
if (!raw_background) /* Fallback to a default pattern */
return twin_make_pattern();
Expand Down Expand Up @@ -65,6 +67,9 @@ static twin_pixmap_t *load_background(twin_screen_t *screen,
twin_pixmap_destroy(raw_background);

return scaled_background;
#else
return twin_make_pattern();
#endif
}

static twin_context_t *tx = NULL;
Expand Down Expand Up @@ -99,12 +104,24 @@ int main(void)
twin_screen_set_background(
tx->screen, load_background(tx->screen, ASSET_PATH "/tux.png"));

#if defined(CONFIG_DEMO_MULTI)
apps_demo_start(tx->screen, "Demo", 100, 100, 400, 400);
#endif
#if defined(CONFIG_DEMO_HELLO)
apps_hello_start(tx->screen, "Hello, World", 0, 0, 200, 200);
#endif
#if defined(CONFIG_DEMO_CLOCK)
apps_clock_start(tx->screen, "Clock", 10, 10, 200, 200);
#endif
#if defined(CONFIG_DEMO_CALCULATOR)
apps_calc_start(tx->screen, "Calculator", 100, 100, 200, 200);
#endif
#if defined(CONFIG_DEMO_LINE)
apps_line_start(tx->screen, "Line", 0, 0, 200, 200);
#endif
#if defined(CONFIG_DEMO_SPLINE)
apps_spline_start(tx->screen, "Spline", 20, 20, 400, 400);
#endif

twin_dispatch();

Expand Down
4 changes: 4 additions & 0 deletions tools/kconfig/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.py[co]
build/
*.egg-info/
dist/
13 changes: 13 additions & 0 deletions tools/kconfig/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Copyright (c) 2011-2019, Ulf Magnusson <[email protected]>

Permission to use, copy, modify, and/or distribute this software for any purpose
with or without fee is hereby granted, provided that the above copyright notice
and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
5 changes: 5 additions & 0 deletions tools/kconfig/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Kconfiglib

A flexible Python 2/3 Kconfig implementation and library.

Taken from https://github.com/ulfalizer/Kconfiglib
43 changes: 43 additions & 0 deletions tools/kconfig/defconfig.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env python3

# Copyright (c) 2019, Ulf Magnusson
# SPDX-License-Identifier: ISC

"""
Reads a specified configuration file, then writes a new configuration file.
This can be used to initialize the configuration from e.g. an arch-specific
configuration file. This input configuration file would usually be a minimal
configuration file, as generated by e.g. savedefconfig.
The default output filename is '.config'. A different filename can be passed in
the KCONFIG_CONFIG environment variable.
"""
import argparse

import kconfiglib


def main():
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
description=__doc__)

parser.add_argument(
"--kconfig",
default="Kconfig",
help="Top-level Kconfig file (default: Kconfig)")

parser.add_argument(
"config",
metavar="CONFIGURATION",
help="Input configuration file")

args = parser.parse_args()

kconf = kconfiglib.Kconfig(args.kconfig, suppress_traceback=True)
print(kconf.load_config(args.config))
print(kconf.write_config())


if __name__ == "__main__":
main()
Loading

0 comments on commit e5f1e88

Please sign in to comment.