From: Simon Glass <sjg@chromium.org>
It is possible to have some files that build in the system environment
and some in the U-Boot environment. To build for the system, the system
headers must be used, or at least have priority. For a U-Boot file, its
headers must be used exclusively.
Expand the Makefile example to have two files, one of which is built
using U-Boot headers. This shows how a program can be built which
straddles both domains.
Signed-off-by: Simon Glass <sjg@chromium.org>
---
examples/ulib/Makefile | 58 ++++++++++++++++++++++++++-----------
examples/ulib/demo.c | 12 ++++++--
examples/ulib/demo_helper.c | 30 +++++++++++++++++++
examples/ulib/demo_helper.h | 31 ++++++++++++++++++++
4 files changed, 111 insertions(+), 20 deletions(-)
create mode 100644 examples/ulib/demo_helper.c
create mode 100644 examples/ulib/demo_helper.h
@@ -35,36 +35,60 @@ LIB_STATIC_LDS ?= static.lds
# The main Makefile passes in Q=@ for quiet output
Q ?=
+# Common compiler flags for programs using system headers first
+SYSTEM_CFLAGS := -I$(UBOOT_BUILD)/include -idirafter$(srctree)/include \
+ -include $(srctree)/include/linux/compiler_attributes.h
+
+# Common compiler flags for programs using U-Boot headers first (like U-Boot
+# internal build)
+UBOOT_CFLAGS := -nostdinc -isystem $(shell $(CC) -print-file-name=include) \
+ -I$(UBOOT_BUILD)/include \
+ -I$(srctree)/include \
+ -I$(srctree)/arch/sandbox/include \
+ -include $(UBOOT_BUILD)/include/config.h \
+ -include $(srctree)/include/linux/kconfig.h \
+ -I$(srctree)/dts/upstream/include \
+ -D__KERNEL__ -DCONFIG_SYS_TEXT_BASE=0
+
+SHARED_LDFLAGS := -L$(UBOOT_BUILD) -lu-boot -Wl,-rpath,$(UBOOT_BUILD)
+
+STATIC_LDFLAGS := -Wl,-T,$(LIB_STATIC_LDS) \
+ -Wl,--whole-archive $(UBOOT_BUILD)/libu-boot.a -Wl,--no-whole-archive \
+ -lpthread -ldl $(PLATFORM_LIBS) -Wl,-z,noexecstack
+
+# Program definitions - can be single file or multi-object
DEMO_SRC := $(EXAMPLE_DIR)/demo.c
+demo-objs := demo.o demo_helper.o
DEMO_BINS := $(OUTDIR)/demo $(OUTDIR)/demo_static
+ALL_BINS := $(DEMO_BINS)
+
# Default target builds both programs
-all: $(DEMO_BINS)
+all: $(ALL_BINS)
# Create the output directory if it doesn't exist
$(OUTDIR):
@mkdir -p $@
-# The U-Boot library must be built before we can link against it. This is
-# signalled by the presence of the $(UBOOT_BUILD)/examples/ulib directory.
-# This is an order-only prerequisite, so it does not trigger a rebuild if the
-# timestamp of the directory changes.
-$(DEMO_BINS): | $(UBOOT_BUILD)/examples/ulib $(OUTDIR)
+# Pattern rule for building object files with system headers first (default)
+$(OUTDIR)/%.o: $(EXAMPLE_DIR)/%.c | $(OUTDIR)
+ $(CC) $(CFLAGS) $(SYSTEM_CFLAGS) -c -o $@ $<
+
+# Pattern rule for building object files with U-Boot headers first
+$(OUTDIR)/%_uboot.o: $(EXAMPLE_DIR)/%.c | $(OUTDIR)
+ $(CC) $(CFLAGS) $(UBOOT_CFLAGS) -c -o $@ $<
+
+# The U-Boot library must be built before we can link against it
+# Order-only prerequisites ensure libraries exist before linking
+$(ALL_BINS): | $(UBOOT_BUILD)/libu-boot.a $(UBOOT_BUILD)/libu-boot.so $(OUTDIR)
# Build demo (dynamically linked with libu-boot.so)
-$(OUTDIR)/demo: $(DEMO_SRC)
- $(CC) $(CFLAGS) \
- -idirafter$(srctree)/include -o $@ $< \
- -L$(UBOOT_BUILD) -lu-boot \
- -Wl,-rpath,$(UBOOT_BUILD)
+$(OUTDIR)/demo: $(if $(demo-objs),$(addprefix $(OUTDIR)/,$(demo-objs)),$(DEMO_SRC))
+ $(if $(demo-objs),$(CC) $(CFLAGS) -o $@ $^ $(SHARED_LDFLAGS),$(CC) $(CFLAGS) $(SYSTEM_CFLAGS) -o $@ $< $(SHARED_LDFLAGS))
# Build demo_static (statically linked with libu-boot.a)
-$(OUTDIR)/demo_static: $(DEMO_SRC)
- $(CC) $(CFLAGS) \
- -idirafter$(srctree)/include -o $@ $< \
- -Wl,-T,$(LIB_STATIC_LDS) \
- -Wl,--whole-archive $(UBOOT_BUILD)/libu-boot.a -Wl,--no-whole-archive \
- -lpthread -ldl $(PLATFORM_LIBS) -Wl,-z,noexecstack
+$(OUTDIR)/demo_static: $(if $(demo-objs),$(addprefix $(OUTDIR)/,$(demo-objs)),$(DEMO_SRC))
+ $(if $(demo-objs),$(CC) $(CFLAGS) -o $@ $^ $(STATIC_LDFLAGS),$(CC) $(CFLAGS) $(SYSTEM_CFLAGS) -o $@ $< $(STATIC_LDFLAGS))
clean:
$(Q)rm -f $(DEMO_BINS)
@@ -17,10 +17,11 @@
#include <os.h>
#include <u-boot-lib.h>
#include <version_string.h>
+#include "demo_helper.h"
int main(int argc, char *argv[])
{
- int fd, lines = 0;
+ int fd, result, lines = 0;
char line[256];
/* Init U-Boot library */
@@ -29,8 +30,7 @@ int main(int argc, char *argv[])
return 1;
}
- printf("1U-Boot Library Demo\n");
- printf("================================\n");
+ demo_show_banner();
printf("U-Boot version: %s\n", version_string);
printf("\n");
@@ -54,6 +54,12 @@ int main(int argc, char *argv[])
printf("\nRead %d line(s) using U-Boot library functions.\n", lines);
+ /* Test the helper function */
+ result = demo_add_numbers(42, 13);
+ printf("Helper function result: %d\n", result);
+
+ demo_show_footer();
+
/* Clean up */
ulib_uninit();
new file mode 100644
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Helper functions for U-Boot library demo
+ *
+ * Copyright 2025 Canonical Ltd.
+ * Written by Simon Glass <simon.glass@canonical.com>
+ */
+
+#include <u-boot-api.h>
+
+void demo_show_banner(void)
+{
+ ub_printf("=================================\n");
+ ub_printf(" U-Boot Library Demo Helper\n");
+ ub_printf("=================================\n");
+}
+
+void demo_show_footer(void)
+{
+ ub_printf("=================================\n");
+ ub_printf(" Demo Complete!\n");
+ ub_printf("=================================\n");
+}
+
+int demo_add_numbers(int a, int b)
+{
+ ub_printf("Helper: Adding %d + %d = %d\n", a, b, a + b);
+
+ return a + b;
+}
new file mode 100644
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Helper functions for U-Boot library demo
+ *
+ * Copyright 2025 Canonical Ltd.
+ * Written by Simon Glass <simon.glass@canonical.com>
+ */
+
+#ifndef __DEMO_HELPER_H
+#define __DEMO_HELPER_H
+
+/**
+ * demo_show_banner() - Show the demo banner
+ */
+void demo_show_banner(void);
+
+/**
+ * demo_show_footer() - Show the demo footer
+ */
+void demo_show_footer(void);
+
+/**
+ * demo_add_numbers() - Add two numbers and print the result
+ *
+ * @a: First number
+ * @b: Second number
+ * Return: Sum of the two numbers
+ */
+int demo_add_numbers(int a, int b);
+
+#endif /* __DEMO_HELPER_H */