Skip to content

Commit

Permalink
Add support for picolibc
Browse files Browse the repository at this point in the history
This allows the creation of an embedded toolchain which uses picolibc
as the C library instead of newlib.

Signed-off-by: Keith Packard <[email protected]>
  • Loading branch information
keith-packard committed Aug 25, 2022
1 parent 20e683a commit e9402ea
Show file tree
Hide file tree
Showing 5 changed files with 297 additions and 8 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ build
config.log
config.status
Makefile
picolibc-cross.txt
.DS_Store
!/regression/Makefile
/build-*/
Expand Down
213 changes: 206 additions & 7 deletions Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ INSTALL_DIR := @prefix@
GCC_SRCDIR := @with_gcc_src@
BINUTILS_SRCDIR := @with_binutils_src@
NEWLIB_SRCDIR := @with_newlib_src@
PICOLIBC_SRCDIR := @with_picolibc_src@
GLIBC_SRCDIR := @with_glibc_src@
MUSL_SRCDIR := @with_musl_src@
LINUX_HEADERS_SRCDIR := @with_linux_headers_src@
Expand Down Expand Up @@ -57,9 +58,11 @@ MULTILIB_FLAGS := @multilib_flags@
MULTILIB_GEN := @multilib_gen@
ifeq ($(MULTILIB_GEN),)
NEWLIB_MULTILIB_NAMES := @newlib_multilib_names@
PICOLIBC_MULTILIB_NAMES := @picolibc_multilib_names@
GCC_MULTILIB_FLAGS := $(MULTILIB_FLAGS)
else
NEWLIB_MULTILIB_NAMES := $(shell echo "$(MULTILIB_GEN)" | $(SED) 's/;/\n/g'| $(AWK) '{split($$0,a,"-"); printf "%s-%s ", a[1],a[2]}')
PICOLIBC_MULTILIB_NAMES := $(shell echo "$(MULTILIB_GEN)" | $(SED) 's/;/\n/g'| $(AWK) '{split($$0,a,"-"); printf "%s-%s ", a[1],a[2]}')
GCC_MULTILIB_FLAGS := $(MULTILIB_FLAGS) --with-multilib-generator="$(MULTILIB_GEN)"
endif
GLIBC_MULTILIB_NAMES := @glibc_multilib_names@
Expand All @@ -73,6 +76,7 @@ endif
make_tuple = riscv$(1)-unknown-$(2)
LINUX_TUPLE ?= $(call make_tuple,$(XLEN),linux-gnu)
NEWLIB_TUPLE ?= $(call make_tuple,$(XLEN),elf)
PICOLIBC_TUPLE ?= $(call make_tuple,$(XLEN),elf)
MUSL_TUPLE ?= $(call make_tuple,$(XLEN),linux-musl)

CFLAGS_FOR_TARGET := $(CFLAGS_FOR_TARGET_EXTRA) @target_cflags@ @cmodel@
Expand All @@ -94,6 +98,10 @@ NEWLIB_CXX_FOR_TARGET ?= $(NEWLIB_TUPLE)-g++
NEWLIB_TARGET_BOARDS ?= $(shell echo "$(NEWLIB_MULTILIB_NAMES)" | sed 's!\([_a-z0-9]*\)-\([_a-z0-9]*\)!riscv-sim/-march=\1/-mabi=\2/@cmodel@!g')
NEWLIB_NANO_TARGET_BOARDS ?= $(shell echo "$(NEWLIB_MULTILIB_NAMES)" | sed 's!\([_a-z0-9]*\)-\([_a-z0-9]*\)!riscv-sim-nano/-march=\1/-mabi=\2/@cmodel@!g')

PICOLIBC_CC_FOR_TARGET ?= $(PICOLIBC_TUPLE)-gcc
PICOLIBC_CXX_FOR_TARGET ?= $(PICOLIBC_TUPLE)-g++
PICOLIBC_TARGET_BOARDS ?= $(shell echo "$(PICOLIBC_MULTILIB_NAMES)" | sed 's!\([_a-z0-9]*\)-\([_a-z0-9]*\)!riscv-sim/-march=\1/-mabi=\2/@cmodel@!g')

MUSL_TARGET_FLAGS := $(MUSL_TARGET_FLAGS_EXTRA)
MUSL_CC_FOR_TARGET ?= $(MUSL_TUPLE)-gcc
MUSL_CXX_FOR_TARGET ?= $(MUSL_TUPLE)-g++
Expand All @@ -102,6 +110,7 @@ CONFIGURE_HOST = @configure_host@

all: @default_target@
newlib: stamps/build-gcc-newlib-stage2
picolibc: stamps/build-gcc-picolibc-stage2
linux: stamps/build-gcc-linux-stage2
ifneq (,$(findstring riscv32,$(MUSL_TUPLE)))
.PHONY: musl
Expand All @@ -112,6 +121,7 @@ musl: stamps/build-gcc-musl-stage2
endif
ifeq (@enable_gdb@,--enable-gdb)
newlib: stamps/build-gdb-newlib
picolibc: stamps/build-gdb-picolibc
linux: stamps/build-gdb-linux
endif
linux-native: stamps/build-gcc-linux-native
Expand All @@ -123,43 +133,52 @@ build-gcc%: stamps/build-gcc-@default_target@-stage%
ifeq (@default_target@,linux)
build-libc: $(addprefix stamps/build-glibc-linux-,$(GLIBC_MULTILIB_NAMES))
else
ifeq (@default_target@,picolibc)
build-libc: stamps/build-picolibc
else
build-libc: stamps/build-newlib stamps/build-newlib-nano \
stamps/merge-newlib-nano
endif
endif
build-qemu: stamps/build-qemu

REGRESSION_TEST_LIST = gcc

.PHONY: check
check: check-@default_target@
.PHONY: check-linux check-newlib
.PHONY: check-linux check-newlib check-picolibc
check-linux: $(patsubst %,check-%-linux,$(REGRESSION_TEST_LIST))
check-newlib: $(patsubst %,check-%-newlib,$(REGRESSION_TEST_LIST))
check-newlib-nano: $(patsubst %,check-%-newlib-nano,$(REGRESSION_TEST_LIST))
.PHONY: check-gcc check-gcc-linux check-gcc-newlib check-gcc-newlib-nano
check-picolibc: $(patsubst %,check-%-picolibc,$(REGRESSION_TEST_LIST))
.PHONY: check-gcc check-gcc-linux check-gcc-newlib check-gcc-newlib-nano check-gcc-picolibc
check-gcc: check-gcc-@default_target@
check-gcc-linux: stamps/check-gcc-linux
check-gcc-newlib: stamps/check-gcc-newlib
check-gcc-newlib-nano: stamps/check-gcc-newlib-nano
.PHONY: check-dhrystone check-dhrystone-linux check-dhrystone-newlib
check-gcc-picolibc: stamps/check-gcc-picolibc
.PHONY: check-dhrystone check-dhrystone-linux check-dhrystone-newlib check-dhrystone-picolibc
check-dhrystone: check-dhrystone-@default_target@
.PHONY: check-binutils check-binutils-linux check-binutils-newlib
.PHONY: check-binutils check-binutils-linux check-binutils-newlib check-binutils-picolibc
check-binutils: check-binutils-@default_target@
check-binutils-linux: stamps/check-binutils-linux
check-binutils-newlib: stamps/check-binutils-newlib
check-binutils-newlib-nano: stamps/check-binutils-newlib-nano
.PHONY: check-gdb check-gdb-linux check-gdb-newlib
check-binutils-picolibc: stamps/check-binutils-picolibc
.PHONY: check-gdb check-gdb-linux check-gdb-newlib check-gdb-picolibc
check-gdb: check-gdb-@default_target@
check-gdb-linux: stamps/check-gdb-linux
check-gdb-newlib: stamps/check-gdb-newlib
check-gdb-newlib-nano: stamps/check-gdb-newlib-nano
check-gdb-picolibc: stamps/check-gdb-picolibc

.PHONY: report
report: report-@default_target@
.PHONY: report-linux report-newlib report-newlib-nano
.PHONY: report-linux report-newlib report-newlib-nano report-picolibc
report-linux: $(patsubst %,report-%-linux,$(REGRESSION_TEST_LIST))
report-newlib: $(patsubst %,report-%-newlib,$(REGRESSION_TEST_LIST))
report-newlib-nano: $(patsubst %,report-%-newlib-nano,$(REGRESSION_TEST_LIST))
report-picolibc: $(patsubst %,report-%-picolibc,$(REGRESSION_TEST_LIST))
.PHONY: report-gcc
report-gcc: report-gcc-@default_target@
.PHONY: report-dhrystone
Expand Down Expand Up @@ -678,6 +697,141 @@ stamps/build-gcc-newlib-stage2: $(GCC_SRCDIR) $(GCC_SRC_GIT) stamps/build-newlib
$(MAKE) -C $(notdir $@) install
mkdir -p $(dir $@) && touch $@

#
# PICOLIBC
#

stamps/build-binutils-picolibc: $(BINUTILS_SRCDIR) $(BINUTILS_SRC_GIT) stamps/check-write-permission
rm -rf $@ $(notdir $@)
mkdir $(notdir $@)
# CC_FOR_TARGET is required for the ld testsuite.
cd $(notdir $@) && CC_FOR_TARGET=$(PICOLIBC_CC_FOR_TARGET) $</configure \
--target=$(PICOLIBC_TUPLE) \
$(CONFIGURE_HOST) \
--prefix=$(INSTALL_DIR) \
@with_guile@ \
--disable-werror \
$(BINUTILS_TARGET_FLAGS) \
--disable-gdb \
--disable-sim \
--disable-libdecnumber \
--disable-readline \
$(WITH_ISA_SPEC)
$(MAKE) -C $(notdir $@)
$(MAKE) -C $(notdir $@) install
mkdir -p $(dir $@) && touch $@

stamps/build-gdb-picolibc: $(GDB_SRCDIR) $(GDB_SRC_GIT)
rm -rf $@ $(notdir $@)
mkdir $(notdir $@)
# CC_FOR_TARGET is required for the ld testsuite.
cd $(notdir $@) && CC_FOR_TARGET=$(PICOLIBC_CC_FOR_TARGET) $</configure \
--target=$(PICOLIBC_TUPLE) \
$(CONFIGURE_HOST) \
--prefix=$(INSTALL_DIR) \
@with_guile@ \
--disable-werror \
$(GDB_TARGET_FLAGS) \
--enable-gdb \
--disable-gas \
--disable-binutils \
--disable-ld \
--disable-gold \
--disable-gprof
$(MAKE) -C $(notdir $@)
$(MAKE) -C $(notdir $@) install
mkdir -p $(dir $@) && touch $@

stamps/build-gcc-picolibc-stage1: $(GCC_SRCDIR) $(GCC_SRC_GIT) stamps/build-binutils-picolibc
if test -f $</contrib/download_prerequisites && test "@NEED_GCC_EXTERNAL_LIBRARIES@" = "true"; then cd $< && ./contrib/download_prerequisites; fi
rm -rf $@ $(notdir $@)
mkdir $(notdir $@)
cd $(notdir $@) && $</configure \
--target=$(PICOLIBC_TUPLE) \
$(CONFIGURE_HOST) \
--prefix=$(INSTALL_DIR) \
--disable-shared \
--disable-threads \
--disable-tls \
--enable-languages=c,c++ \
@with_system_zlib@ \
--with-newlib \
--with-sysroot=$(INSTALL_DIR)/$(PICOLIBC_TUPLE) \
--disable-libmudflap \
--disable-libssp \
--disable-libquadmath \
--disable-libgomp \
--disable-nls \
--disable-tm-clone-registry \
--src=$(gccsrcdir) \
$(GCC_CHECKING_FLAGS) \
$(GCC_MULTILIB_FLAGS) \
$(WITH_ABI) \
$(WITH_ARCH) \
$(WITH_TUNE) \
$(WITH_ISA_SPEC) \
CFLAGS_FOR_TARGET="-Os $(CFLAGS_FOR_TARGET)" \
CXXFLAGS_FOR_TARGET="-Os $(CXXFLAGS_FOR_TARGET)"
$(MAKE) -C $(notdir $@) all-gcc
$(MAKE) -C $(notdir $@) install-gcc
mkdir -p $(dir $@) && touch $@

stamps/build-picolibc: $(PICOLIBC_SRCDIR) $(PICOLIBC_SRC_GIT) stamps/build-gcc-picolibc-stage1 picolibc-cross.txt
rm -rf $@ $(notdir $@)
mkdir $(notdir $@)
meson --cross-file picolibc-cross.txt \
--prefix=$(INSTALL_DIR)/$(PICOLIBC_TUPLE) \
-Dincludedir=include \
-Dlibdir=lib \
-Dsysroot-install=true \
-Dsystem-libc=true \
$(PICOLIBC_SRCDIR) \
$(notdir $@)
ninja -C $(notdir $@) install
mkdir -p $(dir $@) && touch $@

picolibc-cross.txt: make-picolibc-cross Makefile
sh ./make-picolibc-cross $(PICOLIBC_TUPLE) $(CFLAGS_FOR_TARGET) > $@

stamps/build-gcc-picolibc-stage2: $(GCC_SRCDIR) $(GCC_SRC_GIT) stamps/build-picolibc
rm -rf $@ $(notdir $@)
mkdir $(notdir $@)
cd $(notdir $@) && $</configure \
--target=$(PICOLIBC_TUPLE) \
$(CONFIGURE_HOST) \
--enable-stdio=stdio_pure \
--with-default-libc=picolibc \
--disable-wchar_t \
--prefix=$(INSTALL_DIR) \
--disable-shared \
--disable-threads \
--enable-languages=c,c++ \
--with-pkgversion="$(GCCPKGVER)" \
@with_system_zlib@ \
--enable-tls \
--with-newlib \
--with-sysroot=$(INSTALL_DIR)/$(PICOLIBC_TUPLE) \
--with-native-system-header-dir=/include \
--disable-libmudflap \
--disable-libssp \
--disable-libquadmath \
--disable-libgomp \
--disable-nls \
--disable-tm-clone-registry \
--src=$(gccsrcdir) \
$(GCC_CHECKING_FLAGS) \
$(GCC_MULTILIB_FLAGS) \
$(WITH_ABI) \
$(WITH_ARCH) \
$(WITH_TUNE) \
$(WITH_ISA_SPEC) \
CFLAGS_FOR_TARGET="-Os $(CFLAGS_FOR_TARGET)" \
CXXFLAGS_FOR_TARGET="-Os $(CXXFLAGS_FOR_TARGET)"
$(MAKE) -C $(notdir $@)
$(MAKE) -C $(notdir $@) install
mkdir -p $(dir $@) && touch $@


#
# MUSL
#
Expand Down Expand Up @@ -876,6 +1030,11 @@ stamps/check-gcc-newlib-nano: stamps/build-gcc-newlib-stage2 $(SIM_STAMP) stamps
mkdir -p $(dir $@)
date > $@

stamps/check-gcc-picolibc: stamps/build-gcc-picolibc-stage2 $(SIM_STAMP) stamps/build-dejagnu
$(SIM_PREPARE) $(MAKE) -C build-gcc-picolibc-stage2 check-gcc "RUNTESTFLAGS=--target_board='$(PICOLIBC_TARGET_BOARDS)'"
mkdir -p $(dir $@)
date > $@

stamps/check-gcc-linux: stamps/build-gcc-linux-stage2 $(SIM_STAMP) stamps/build-dejagnu
$(SIM_PREPARE) $(MAKE) -C build-gcc-linux-stage2 check-gcc "RUNTESTFLAGS=--target_board='$(GLIBC_TARGET_BOARDS)'"
mkdir -p $(dir $@)
Expand Down Expand Up @@ -903,6 +1062,17 @@ stamps/check-dhrystone-newlib-nano-%: \
$(eval $@_XLEN := $(patsubst rv32%,32,$(patsubst rv64%,64,$($@_ARCH))))
$(SIM_PREPARE) $(srcdir)/test/benchmarks/dhrystone/check -march=$($@_ARCH) -mabi=$($@_ABI) -specs=nano.specs -cc=riscv$(XLEN)-unknown-elf-gcc -objdump=riscv$(XLEN)-unknown-elf-objdump -sim=riscv$($@_XLEN)-unknown-elf-run -out=$@ $(filter %.c,$^) || true

.PHONY: check-dhrystone-picolibc
check-dhrystone-picolibc: $(patsubst %,stamps/check-dhrystone-picolibc-%,$(PICOLIBC_MULTILIB_NAMES))
stamps/check-dhrystone-picolibc-%: \
stamps/build-gcc-picolibc-stage2 \
$(SIM_STAMP) \
$(wildcard $(srcdir)/test/benchmarks/dhrystone/*)
$(eval $@_ARCH := $(word 4,$(subst -, ,$@)))
$(eval $@_ABI := $(word 5,$(subst -, ,$@)))
$(eval $@_XLEN := $(patsubst rv32%,32,$(patsubst rv64%,64,$($@_ARCH))))
$(SIM_PREPARE) $(srcdir)/test/benchmarks/dhrystone/check -march=$($@_ARCH) -mabi=$($@_ABI) -cc=riscv$(XLEN)-unknown-elf-gcc -objdump=riscv$(XLEN)-unknown-elf-objdump -sim=riscv$($@_XLEN)-unknown-elf-run -out=$@ $(filter %.c,$^) || true

.PHONY: check-dhrystone-linux
check-dhrystone-linux: $(patsubst %,stamps/check-dhrystone-linux-%,$(GLIBC_MULTILIB_NAMES))

Expand All @@ -923,6 +1093,10 @@ stamps/check-binutils-newlib-nano: stamps/build-gcc-newlib-stage2 $(SIM_STAMP) s
$(SIM_PREPARE) $(MAKE) -C build-binutils-newlib check-binutils check-gas check-ld -k "RUNTESTFLAGS=--target_board='$(NEWLIB_NANO_TARGET_BOARDS)'" || true
date > $@

stamps/check-binutils-picolibc: stamps/build-gcc-picolibc-stage2 $(SIM_STAMP) stamps/build-dejagnu
$(SIM_PREPARE) $(MAKE) -C build-binutils-picolibc check-binutils check-gas check-ld -k "RUNTESTFLAGS=--target_board='$(PICOLIBC_TARGET_BOARDS)'" || true
date > $@

stamps/check-binutils-linux: stamps/build-gcc-linux-stage2 $(SIM_STAMP) stamps/build-dejagnu
$(SIM_PREPARE) $(MAKE) -C build-binutils-linux check-binutils check-gas check-ld -k "RUNTESTFLAGS=--target_board='$(GLIBC_TARGET_BOARDS)'" || true
date > $@
Expand All @@ -935,6 +1109,10 @@ stamps/check-gdb-newlib-nano: stamps/build-gcc-newlib-stage2 stamps/build-gdb-ne
$(SIM_PREPARE) $(MAKE) -C build-gdb-newlib check-gdb -k "RUNTESTFLAGS=--target_board='$(NEWLIB_NANO_TARGET_BOARDS)'" || true
date > $@

stamps/check-gdb-picolibc: stamps/build-gcc-picolibc-stage2 stamps/build-gdb-picolibc $(SIM_STAMP) stamps/build-dejagnu
$(SIM_PREPARE) $(MAKE) -C build-gdb-picolibc check-gdb -k "RUNTESTFLAGS=--target_board='$(PICOLIBC_TARGET_BOARDS)'" || true
date > $@

stamps/check-gdb-linux: stamps/build-gcc-linux-stage2 stamps/build-gdb-linux $(SIM_STAMP) stamps/build-dejagnu
$(SIM_PREPARE) $(MAKE) -C build-gdb-linux check-gdb -k "RUNTESTFLAGS=--target_board='$(GLIBC_TARGET_BOARDS)'" || true
date > $@
Expand All @@ -946,6 +1124,10 @@ report-gcc-newlib: stamps/check-gcc-newlib
report-gcc-newlib-nano: stamps/check-gcc-newlib-nano
$(srcdir)/scripts/testsuite-filter gcc newlib-nano $(srcdir)/test/allowlist `find build-gcc-newlib-stage2/gcc/testsuite/ -name *.sum |paste -sd "," -`

.PHONY: report-gcc-picolibc
report-gcc-picolibc: stamps/check-gcc-picolibc
$(srcdir)/scripts/testsuite-filter gcc picolibc $(srcdir)/test/allowlist `find build-gcc-picolibc-stage2/gcc/testsuite/ -name *.sum |paste -sd "," -`

.PHONY: report-gcc-linux
report-gcc-linux: stamps/check-gcc-linux
$(srcdir)/scripts/testsuite-filter gcc glibc $(srcdir)/test/allowlist `find build-gcc-linux-stage2/gcc/testsuite/ -name *.sum |paste -sd "," -`
Expand All @@ -956,6 +1138,10 @@ report-dhrystone-newlib: $(patsubst %,stamps/check-dhrystone-newlib-%,$(NEWLIB_M
report-dhrystone-newlib-nano: $(patsubst %,stamps/check-dhrystone-newlib-nano-%,$(NEWLIB_MULTILIB_NAMES))
if cat $^ | grep -v '^PASS'; then false; else true; fi

.PHONY: report-dhrystone-picolibc
report-dhrystone-picolibc: $(patsubst %,stamps/check-dhrystone-picolibc-%,$(PICOLIBC_MULTILIB_NAMES))
if cat $^ | grep -v '^PASS'; then false; else true; fi

.PHONY: report-dhrystone-linux
report-dhrystone-linux: $(patsubst %,stamps/check-dhrystone-linux-%,$(GLIBC_MULTILIB_NAMES))
if cat $^ | grep -v '^PASS'; then false; else true; fi
Expand All @@ -971,14 +1157,20 @@ report-binutils-newlib-nano: stamps/check-binutils-newlib-nano
$(srcdir)/test/allowlist \
`find build-binutils-newlib/ -name *.sum |paste -sd "," -`

.PHONY: report-binutils-picolibc
report-binutils-picolibc: stamps/check-binutils-picolibc
$(srcdir)/scripts/testsuite-filter binutils picolibc \
$(srcdir)/test/allowlist \
`find build-binutils-picolibc/ -name *.sum |paste -sd "," -`

.PHONY: report-binutils-linux
report-binutils-linux: stamps/check-binutils-linux
$(srcdir)/scripts/testsuite-filter binutils glibc \
$(srcdir)/test/allowlist \
`find build-binutils-linux/ -name *.sum |paste -sd "," -`

clean:
rm -rf build-* stamps install-newlib-nano
rm -rf build-* stamps install-newlib-nano picolibc-cross.txt

.PHONY: report-gdb-newlib report-gdb-newlib-nano
report-gdb-newlib: stamps/check-gdb-newlib
Expand All @@ -993,6 +1185,13 @@ report-gdb-newlib-nano: stamps/check-gdb-newlib-nano
if grep '^$$' $(patsubst %,$(srcdir)/test/gdb-newlib/%.log,$(NEWLIB_MULTILIB_NAMES)); then exit 1; fi
if find build-gdb-newlib -iname '*.sum' | xargs grep ^FAIL | sort | grep -F -v $(patsubst %,--file=$(srcdir)/test/gdb-newlib/%.log,$(NEWLIB_MULTILIB_NAMES)); then false; else true; fi

.PHONY: report-gdb-picolibc
report-gdb-picolibc: stamps/check-gdb-picolibc
stat $(patsubst %,$(srcdir)/test/gdb-picolibc/%.log,$(PICOLIBC_MULTILIB_NAMES)) || exit 1
# Fail if there are blank lines in the log file used as input for grep below.
if grep '^$$' $(patsubst %,$(srcdir)/test/gdb-picolibc/%.log,$(PICOLIBC_MULTILIB_NAMES)); then exit 1; fi
if find build-gdb-picolibc -iname '*.sum' | xargs grep ^FAIL | sort | grep -F -v $(patsubst %,--file=$(srcdir)/test/gdb-picolibc/%.log,$(PICOLIBC_MULTILIB_NAMES)); then false; else true; fi

.PHONY: report-gdb-linux
report-gdb-linux: stamps/check-gdb-linux
stat $(patsubst %,$(srcdir)/test/gdb-linux/%.log,$(GLIBC_MULTILIB_NAMES)) || exit 1
Expand Down
Loading

0 comments on commit e9402ea

Please sign in to comment.