############################################################################ # apps/examples/fdpicxip/modules/Makefile # # SPDX-License-Identifier: Apache-2.0 # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. The # ASF licenses this file to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance with the # License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # ############################################################################ # The FDPIC modules that examples/fdpicxip and testing/fs/xipfs carry inside # their images, and the sources they are built from. # # This is NOT part of the application build. Nothing here runs unless it is # asked for: the *_bin.h headers are committed, so both apps build with a # plain toolchain and CI covers them, while the link needs # arm-uclinuxfdpiceabi binutils, which the tree does not require. See # nuttx/tools/fdpic/README.md and Documentation/components/fdpic.rst. # # To rebuild the headers from these sources: # # make -C apps/examples/fdpicxip/modules regen NUTTX_DIR=/path/to/nuttx # # NUTTX_DIR must be a configured, built tree with CONFIG_FDPIC and a system # symbol table: the compile needs its headers and the verify step needs # libs/libc/exec_symtab.c. # # CPU is cortex-m3 rather than the toolchain default, deliberately. A v7-M # module runs on both the v7-M and v8-M targets, so one set of blobs serves # the RP2350 (Cortex-M33) and mps2-an500 (Cortex-M7) alike. Building for # cortex-m33 produces blobs the M7 cannot execute at all. CPU ?= cortex-m3 FDPICDIR = $(NUTTX_DIR)/tools/fdpic MODULE_MK = $(FDPICDIR)/nuttx-fdpic.mk EMBED = $(FDPICDIR)/fdpic-embed # Where each generated header goes, and its path from the repository root -- # fdpic-embed puts that on line 2, which is what nxstyle wants. DEMODIR = .. DEMOREL = apps/examples/fdpicxip TESTDIR = ../../../testing/fs/xipfs TESTREL = apps/testing/fs/xipfs BUILD = $(MAKE) -f $(MODULE_MK) NUTTX_DIR=$(NUTTX_DIR) CPU=$(CPU) # manyneeded needs one library per DT_NEEDED entry, one more than the loader # will follow. They exist only to make the linker record nine entries; the # module is refused while its dynamic section is parsed, before any of them # would be loaded, so none of them is embedded. NEEDLIBS := $(foreach n,0 1 2 3 4 5 6 7 8,need$(n).so) DEMO_HDRS = $(DEMODIR)/qsorter_bin.h $(DEMODIR)/libcounter_bin.h \ $(DEMODIR)/user_bin.h $(DEMODIR)/libshape_bin.h \ $(DEMODIR)/cxxuser_bin.h $(DEMODIR)/lazymod_bin.h TEST_HDRS = $(TESTDIR)/callback_bin.h $(TESTDIR)/counteruser_bin.h \ $(TESTDIR)/cxxuser_bin.h $(TESTDIR)/funcdesc_bin.h \ $(TESTDIR)/lazymod_bin.h $(TESTDIR)/libcounter_bin.h \ $(TESTDIR)/libshape_bin.h $(TESTDIR)/manyneeded_bin.h \ $(TESTDIR)/missingsym_bin.h .PHONY: all regen check-nuttx-dir clean all: @echo "Nothing to do: the *_bin.h headers are committed." @echo "To rebuild them: make regen NUTTX_DIR=/path/to/nuttx" regen: check-nuttx-dir $(DEMO_HDRS) $(TEST_HDRS) @echo "Regenerated the embedded modules for $(DEMOREL) and $(TESTREL)." check-nuttx-dir: ifeq ($(NUTTX_DIR),) $(error Set NUTTX_DIR to a configured, built NuttX tree) endif # The modules. Libraries have no entry point and are named by their SONAME, # which is what a consumer records in DT_NEEDED and what the loader searches # for at run time. qsorter.fdpic: qsorter.c $(BUILD) MODULE=qsorter SRCS=qsorter.c callback.fdpic: callback.c $(BUILD) MODULE=callback SRCS=callback.c funcdesc.fdpic: funcdesc.c $(BUILD) MODULE=funcdesc SRCS=funcdesc.c libcounter.so: libcounter.c $(BUILD) MODULE=libcounter SRCS=libcounter.c ENTRY=0 \ EXTRA_LDFLAGS="-soname libcounter.so" mv libcounter.fdpic libcounter.so user.fdpic: user.c libcounter.so $(BUILD) MODULE=user SRCS=user.c LIBS=libcounter.so # C++ compiles with the stock arm-none-eabi-g++; only the link is FDPIC. libshape.so: libshape.cpp $(BUILD) MODULE=libshape CXXSRCS=libshape.cpp ENTRY=0 \ EXTRA_LDFLAGS="-soname libshape.so" mv libshape.fdpic libshape.so cxxuser.fdpic: cxxuser.cpp libshape.so $(BUILD) MODULE=cxxuser CXXSRCS=cxxuser.cpp LIBS=libshape.so # BINDNOW is emptied so the imported descriptors stay in the lazy binding # table, which is the case this module exists to cover. lazymod.fdpic: lazymod.c $(BUILD) MODULE=lazymod SRCS=lazymod.c BINDNOW= # missingsym is linked with the bare .fdpic target rather than the default # 'verify' one, because it is exactly what fdpic-verify is meant to catch. missingsym.fdpic: missingsym.c $(BUILD) MODULE=missingsym SRCS=missingsym.c missingsym.fdpic need%.so: echo "int need_leaf_$*(void){return $*;}" > need$*.c $(BUILD) MODULE=need$* SRCS=need$*.c ENTRY=0 \ EXTRA_LDFLAGS="-soname need$*.so" mv need$*.fdpic need$*.so manyneeded.c: $(NEEDLIBS) { for n in 0 1 2 3 4 5 6 7 8; do \ echo "extern int need_leaf_$$n(void);"; done; \ echo "int main(int argc, char *argv[]) {"; \ echo " return need_leaf_0() + need_leaf_1() + need_leaf_2() +"; \ echo " need_leaf_3() + need_leaf_4() + need_leaf_5() +"; \ echo " need_leaf_6() + need_leaf_7() + need_leaf_8();"; \ echo "}"; } > manyneeded.c manyneeded.fdpic: manyneeded.c $(NEEDLIBS) $(BUILD) MODULE=manyneeded SRCS=manyneeded.c LIBS="$(NEEDLIBS)" \ manyneeded.fdpic # The headers. One artifact can be embedded under more than one name: the # demo's user_bin.h and the suite's counteruser_bin.h are the same module. $(DEMODIR)/qsorter_bin.h: qsorter.fdpic $(EMBED) $< g_qsorter_nxf $(DEMOREL)/$(@F) > $@ $(DEMODIR)/libcounter_bin.h: libcounter.so $(EMBED) $< g_libcounter $(DEMOREL)/$(@F) > $@ $(DEMODIR)/user_bin.h: user.fdpic $(EMBED) $< g_user $(DEMOREL)/$(@F) > $@ $(DEMODIR)/libshape_bin.h: libshape.so $(EMBED) $< g_libshape $(DEMOREL)/$(@F) > $@ $(DEMODIR)/cxxuser_bin.h: cxxuser.fdpic $(EMBED) $< g_cxxuser $(DEMOREL)/$(@F) > $@ $(DEMODIR)/lazymod_bin.h: lazymod.fdpic $(EMBED) $< g_lazymod $(DEMOREL)/$(@F) > $@ $(TESTDIR)/callback_bin.h: callback.fdpic $(EMBED) $< g_callback $(TESTREL)/$(@F) > $@ $(TESTDIR)/counteruser_bin.h: user.fdpic $(EMBED) $< g_counteruser $(TESTREL)/$(@F) > $@ $(TESTDIR)/cxxuser_bin.h: cxxuser.fdpic $(EMBED) $< g_cxxuser $(TESTREL)/$(@F) > $@ $(TESTDIR)/funcdesc_bin.h: funcdesc.fdpic $(EMBED) $< g_funcdesc $(TESTREL)/$(@F) > $@ $(TESTDIR)/lazymod_bin.h: lazymod.fdpic $(EMBED) $< g_lazymod $(TESTREL)/$(@F) > $@ $(TESTDIR)/libcounter_bin.h: libcounter.so $(EMBED) $< g_libcounter $(TESTREL)/$(@F) > $@ $(TESTDIR)/libshape_bin.h: libshape.so $(EMBED) $< g_libshape $(TESTREL)/$(@F) > $@ $(TESTDIR)/manyneeded_bin.h: manyneeded.fdpic $(EMBED) $< g_manyneeded $(TESTREL)/$(@F) > $@ $(TESTDIR)/missingsym_bin.h: missingsym.fdpic $(EMBED) $< g_missingsym $(TESTREL)/$(@F) > $@ # No NUTTX_DIR needed to clean. clean: $(Q) rm -f *.o *.fdpic *.so .nuttx-exports need*.c manyneeded.c