Skip to content

Commit 2f89025

Browse files
committed
Add support for picolibc
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]>
1 parent d033e91 commit 2f89025

File tree

6 files changed

+273
-7
lines changed

6 files changed

+273
-7
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ build
33
config.log
44
config.status
55
Makefile
6+
picolibc-cross.txt
67
.DS_Store
78
!/regression/Makefile
89
/build-*/

Makefile.in

Lines changed: 150 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ INSTALL_DIR := @prefix@
55
GCC_SRCDIR := @with_gcc_src@
66
BINUTILS_SRCDIR := @with_binutils_src@
77
NEWLIB_SRCDIR := @with_newlib_src@
8+
PICOLIBC_SRCDIR := @with_picolibc_src@
89
GLIBC_SRCDIR := @with_glibc_src@
910
MUSL_SRCDIR := @with_musl_src@
1011
LINUX_HEADERS_SRCDIR := @with_linux_headers_src@
@@ -59,9 +60,11 @@ MULTILIB_FLAGS := @multilib_flags@
5960
MULTILIB_GEN := @multilib_gen@
6061
ifeq ($(MULTILIB_GEN),)
6162
NEWLIB_MULTILIB_NAMES := @newlib_multilib_names@
63+
PICOLIBC_MULTILIB_NAMES := @picolibc_multilib_names@
6264
GCC_MULTILIB_FLAGS := $(MULTILIB_FLAGS)
6365
else
6466
NEWLIB_MULTILIB_NAMES := $(shell echo "$(MULTILIB_GEN)" | $(SED) 's/;/\n/g'| $(AWK) '{split($$0,a,"-"); printf "%s-%s ", a[1],a[2]}')
67+
PICOLIBC_MULTILIB_NAMES := $(shell echo "$(MULTILIB_GEN)" | $(SED) 's/;/\n/g'| $(AWK) '{split($$0,a,"-"); printf "%s-%s ", a[1],a[2]}')
6568
GCC_MULTILIB_FLAGS := $(MULTILIB_FLAGS) --with-multilib-generator="$(MULTILIB_GEN)"
6669
endif
6770
GLIBC_MULTILIB_NAMES := @glibc_multilib_names@
@@ -75,6 +78,7 @@ endif
7578
make_tuple = riscv$(1)-unknown-$(2)
7679
LINUX_TUPLE ?= $(call make_tuple,$(XLEN),linux-gnu)
7780
NEWLIB_TUPLE ?= $(call make_tuple,$(XLEN),elf)
81+
PICOLIBC_TUPLE ?= $(call make_tuple,$(XLEN),elf)
7882
MUSL_TUPLE ?= $(call make_tuple,$(XLEN),linux-musl)
7983

8084
CFLAGS_FOR_TARGET := $(CFLAGS_FOR_TARGET_EXTRA) @target_cflags@ @cmodel@
@@ -96,6 +100,10 @@ NEWLIB_CXX_FOR_TARGET ?= $(NEWLIB_TUPLE)-g++
96100
NEWLIB_TARGET_BOARDS ?= $(shell echo "$(NEWLIB_MULTILIB_NAMES)" | sed 's!\([_a-z0-9]*\)-\([_a-z0-9]*\)!riscv-sim/-march=\1/-mabi=\2/@cmodel@!g')
97101
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')
98102

103+
PICOLIBC_CC_FOR_TARGET ?= $(PICOLIBC_TUPLE)-gcc
104+
PICOLIBC_CXX_FOR_TARGET ?= $(PICOLIBC_TUPLE)-g++
105+
PICOLIBC_TARGET_BOARDS ?= $(shell echo "$(PICOLIBC_MULTILIB_NAMES)" | sed 's!\([_a-z0-9]*\)-\([_a-z0-9]*\)!riscv-sim/-march=\1/-mabi=\2/@cmodel@!g')
106+
99107
MUSL_TARGET_FLAGS := $(MUSL_TARGET_FLAGS_EXTRA)
100108
MUSL_CC_FOR_TARGET ?= $(MUSL_TUPLE)-gcc
101109
MUSL_CXX_FOR_TARGET ?= $(MUSL_TUPLE)-g++
@@ -104,6 +112,7 @@ CONFIGURE_HOST = @configure_host@
104112

105113
all: @default_target@
106114
newlib: stamps/build-gcc-newlib-stage2
115+
picolibc: stamps/build-gcc-picolibc-stage2
107116
linux: stamps/build-gcc-linux-stage2
108117
ifneq (,$(findstring riscv32,$(MUSL_TUPLE)))
109118
.PHONY: musl
@@ -114,6 +123,7 @@ musl: stamps/build-gcc-musl-stage2
114123
endif
115124
ifeq (@enable_gdb@,--enable-gdb)
116125
newlib: stamps/build-gdb-newlib
126+
picolibc: stamps/build-gdb-picolibc
117127
linux: stamps/build-gdb-linux
118128
endif
119129
linux-native: stamps/build-gcc-linux-native
@@ -125,33 +135,40 @@ build-gcc%: stamps/build-gcc-@default_target@-stage%
125135
ifeq (@default_target@,linux)
126136
build-libc: $(addprefix stamps/build-glibc-linux-,$(GLIBC_MULTILIB_NAMES))
127137
else
138+
ifeq (@default_target@,picolibc)
139+
build-libc: stamps/build-picolibc
140+
else
128141
build-libc: stamps/build-newlib stamps/build-newlib-nano \
129142
stamps/merge-newlib-nano
130143
endif
144+
endif
131145
build-qemu: stamps/build-qemu
132146

133147
REGRESSION_TEST_LIST = gcc
134148

135149
.PHONY: check
136150
check: check-@default_target@
137-
.PHONY: check-linux check-newlib
151+
.PHONY: check-linux check-newlib check-picolibc
138152
check-linux: $(patsubst %,check-%-linux,$(REGRESSION_TEST_LIST))
139153
check-newlib: $(patsubst %,check-%-newlib,$(REGRESSION_TEST_LIST))
140154
check-newlib-nano: $(patsubst %,check-%-newlib-nano,$(REGRESSION_TEST_LIST))
141-
.PHONY: check-gcc check-gcc-linux check-gcc-newlib check-gcc-newlib-nano
155+
check-picolibc: $(patsubst %,check-%-picolibc,$(REGRESSION_TEST_LIST))
156+
.PHONY: check-gcc check-gcc-linux check-gcc-newlib check-gcc-newlib-nano check-gcc-picolibc
142157
check-gcc: check-gcc-@default_target@
143158
check-gcc-linux: stamps/check-gcc-linux
144159
check-gcc-newlib: stamps/check-gcc-newlib
145160
check-gcc-newlib-nano: stamps/check-gcc-newlib-nano
161+
check-gcc-picolibc: stamps/check-gcc-picolibc
146162
.PHONY: check-glibc-linux
147163
check-glibc-linux: $(addprefix stamps/check-glibc-linux-,$(GLIBC_MULTILIB_NAMES))
148164
.PHONY: check-dhrystone check-dhrystone-linux check-dhrystone-newlib
149165
check-dhrystone: check-dhrystone-@default_target@
150-
.PHONY: check-binutils check-binutils-linux check-binutils-newlib
166+
.PHONY: check-binutils check-binutils-linux check-binutils-newlib check-binutils-picolibc
151167
check-binutils: check-binutils-@default_target@
152168
check-binutils-linux: stamps/check-binutils-linux
153169
check-binutils-newlib: stamps/check-binutils-newlib
154170
check-binutils-newlib-nano: stamps/check-binutils-newlib-nano
171+
check-binutils-picolibc: stamps/check-binutils-picolibc
155172
.PHONY: check-gdb check-gdb-linux check-gdb-newlib
156173
check-gdb: check-gdb-@default_target@
157174
check-gdb-linux: stamps/check-gdb-linux
@@ -688,6 +705,119 @@ stamps/build-gcc-newlib-stage2: $(GCC_SRCDIR) $(GCC_SRC_GIT) stamps/build-newlib
688705
$(MAKE) -C $(notdir $@) install
689706
mkdir -p $(dir $@) && touch $@
690707

708+
#
709+
# PICOLIBC
710+
#
711+
712+
stamps/build-binutils-picolibc: $(BINUTILS_SRCDIR) $(BINUTILS_SRC_GIT) stamps/check-write-permission
713+
rm -rf $@ $(notdir $@)
714+
mkdir $(notdir $@)
715+
# CC_FOR_TARGET is required for the ld testsuite.
716+
cd $(notdir $@) && CC_FOR_TARGET=$(PICOLIBC_CC_FOR_TARGET) $</configure \
717+
--target=$(PICOLIBC_TUPLE) \
718+
$(CONFIGURE_HOST) \
719+
--prefix=$(INSTALL_DIR) \
720+
@with_guile@ \
721+
--disable-werror \
722+
$(BINUTILS_TARGET_FLAGS) \
723+
--disable-gdb \
724+
--disable-sim \
725+
--disable-libdecnumber \
726+
--disable-readline \
727+
$(WITH_ISA_SPEC)
728+
$(MAKE) -C $(notdir $@)
729+
$(MAKE) -C $(notdir $@) install
730+
mkdir -p $(dir $@) && touch $@
731+
732+
stamps/build-gdb-picolibc: $(GDB_SRCDIR) $(GDB_SRC_GIT)
733+
rm -rf $@ $(notdir $@)
734+
mkdir $(notdir $@)
735+
# CC_FOR_TARGET is required for the ld testsuite.
736+
cd $(notdir $@) && CC_FOR_TARGET=$(PICOLIBC_CC_FOR_TARGET) $</configure \
737+
--target=$(PICOLIBC_TUPLE) \
738+
$(CONFIGURE_HOST) \
739+
--prefix=$(INSTALL_DIR) \
740+
@with_guile@ \
741+
--disable-werror \
742+
$(GDB_TARGET_FLAGS) \
743+
--enable-gdb \
744+
--disable-gas \
745+
--disable-binutils \
746+
--disable-ld \
747+
--disable-gold \
748+
--disable-gprof
749+
$(MAKE) -C $(notdir $@)
750+
$(MAKE) -C $(notdir $@) install
751+
mkdir -p $(dir $@) && touch $@
752+
753+
GCC_PICOLIBC_ARGS = \
754+
--target=$(PICOLIBC_TUPLE) \
755+
$(CONFIGURE_HOST) \
756+
--disable-wchar_t \
757+
--prefix=$(INSTALL_DIR) \
758+
--disable-shared \
759+
--disable-threads \
760+
--enable-languages=c,c++ \
761+
--with-pkgversion="$(GCCPKGVER)" \
762+
@with_system_zlib@ \
763+
--enable-tls \
764+
--with-newlib \
765+
--with-sysroot=$(INSTALL_DIR)/$(PICOLIBC_TUPLE) \
766+
--disable-libmudflap \
767+
--disable-libssp \
768+
--disable-libquadmath \
769+
--disable-libgomp \
770+
--disable-nls \
771+
--disable-tm-clone-registry \
772+
--src=$(gccsrcdir) \
773+
$(GCC_CHECKING_FLAGS) \
774+
$(GCC_MULTILIB_FLAGS) \
775+
$(WITH_ABI) \
776+
$(WITH_ARCH) \
777+
$(WITH_TUNE) \
778+
$(WITH_ISA_SPEC) \
779+
CFLAGS_FOR_TARGET="-Os $(CFLAGS_FOR_TARGET)" \
780+
CXXFLAGS_FOR_TARGET="-Os $(CXXFLAGS_FOR_TARGET)"
781+
782+
stamps/build-gcc-picolibc-stage1: $(GCC_SRCDIR) $(GCC_SRC_GIT) stamps/build-binutils-picolibc
783+
if test -f $</contrib/download_prerequisites && test "@NEED_GCC_EXTERNAL_LIBRARIES@" = "true"; then cd $< && ./contrib/download_prerequisites; fi
784+
rm -rf $@ $(notdir $@)
785+
mkdir $(notdir $@)
786+
cd $(notdir $@) && $</configure $(GCC_PICOLIBC_ARGS)
787+
$(MAKE) -C $(notdir $@) all-gcc
788+
$(MAKE) -C $(notdir $@) install-gcc
789+
mkdir -p $(dir $@) && touch $@
790+
791+
stamps/build-picolibc: $(PICOLIBC_SRCDIR) $(PICOLIBC_SRC_GIT) stamps/build-gcc-picolibc-stage1 picolibc-cross.txt
792+
rm -rf $@ $(notdir $@)
793+
mkdir $(notdir $@)
794+
meson setup --cross-file picolibc-cross.txt \
795+
--prefix=$(INSTALL_DIR)/$(PICOLIBC_TUPLE) \
796+
-Dincludedir=include \
797+
-Dlibdir=lib \
798+
-Dsysroot-install=true \
799+
-Dsystem-libc=true \
800+
$(PICOLIBC_SRCDIR) \
801+
$(notdir $@)
802+
ninja -C $(notdir $@) install
803+
mkdir -p $(dir $@) && touch $@
804+
805+
picolibc-cross.txt: make-picolibc-cross Makefile
806+
sh ./make-picolibc-cross $(INSTALL_DIR)/bin/$(PICOLIBC_TUPLE) -Os $(CFLAGS_FOR_TARGET) > $@
807+
808+
stamps/build-gcc-picolibc-stage2: $(GCC_SRCDIR) $(GCC_SRC_GIT) stamps/build-picolibc
809+
rm -rf $@ $(notdir $@)
810+
mkdir $(notdir $@)
811+
cd $(notdir $@) && $</configure \
812+
$(GCC_PICOLIBC_ARGS) \
813+
--enable-stdio=stdio_pure \
814+
--with-default-libc=picolibc \
815+
--with-native-system-header-dir=/include
816+
$(MAKE) -C $(notdir $@)
817+
$(MAKE) -C $(notdir $@) install
818+
mkdir -p $(dir $@) && touch $@
819+
820+
691821
#
692822
# MUSL
693823
#
@@ -888,6 +1018,12 @@ stamps/check-gcc-newlib-nano: stamps/build-gcc-newlib-stage2 $(SIM_STAMP) stamps
8881018
mkdir -p $(dir $@)
8891019
date > $@
8901020

1021+
stamps/check-gcc-picolibc: stamps/build-gcc-picolibc-stage2 stamps/build-qemu
1022+
cd build-picolibc && meson configure -Dtests=true
1023+
ninja -C build-picolibc test
1024+
mkdir -p $(dir $@)
1025+
date > $@
1026+
8911027
stamps/check-gcc-linux: stamps/build-gcc-linux-stage2 $(SIM_STAMP) stamps/build-dejagnu
8921028
$(SIM_PREPARE) $(MAKE) -C build-gcc-linux-stage2 check-gcc "RUNTESTFLAGS=$(RUNTESTFLAGS) --target_board='$(GLIBC_TARGET_BOARDS)'"
8931029
mkdir -p $(dir $@)
@@ -942,6 +1078,10 @@ stamps/check-binutils-newlib-nano: stamps/build-gcc-newlib-stage2 $(SIM_STAMP) s
9421078
$(SIM_PREPARE) $(MAKE) -C build-binutils-newlib check-binutils check-gas check-ld -k "RUNTESTFLAGS=--target_board='$(NEWLIB_NANO_TARGET_BOARDS)'" || true
9431079
date > $@
9441080

1081+
stamps/check-binutils-picolibc: stamps/build-gcc-picolibc-stage2 $(SIM_STAMP) stamps/build-dejagnu
1082+
$(SIM_PREPARE) $(MAKE) -C build-binutils-picolibc check-binutils check-gas check-ld -k "RUNTESTFLAGS=--target_board='$(PICOLIBC_TARGET_BOARDS)'" || true
1083+
date > $@
1084+
9451085
stamps/check-binutils-linux: stamps/build-gcc-linux-stage2 $(SIM_STAMP) stamps/build-dejagnu
9461086
$(SIM_PREPARE) $(MAKE) -C build-binutils-linux check-binutils check-gas check-ld -k "RUNTESTFLAGS=--target_board='$(GLIBC_TARGET_BOARDS)'" || true
9471087
date > $@
@@ -990,14 +1130,20 @@ report-binutils-newlib-nano: stamps/check-binutils-newlib-nano
9901130
$(srcdir)/test/allowlist \
9911131
`find build-binutils-newlib/ -name *.sum |paste -sd "," -`
9921132

1133+
.PHONY: report-binutils-picolibc
1134+
report-binutils-picolibc: stamps/check-binutils-picolibc
1135+
$(srcdir)/scripts/testsuite-filter binutils picolibc \
1136+
$(srcdir)/test/allowlist \
1137+
`find build-binutils-picolibc/ -name *.sum |paste -sd "," -`
1138+
9931139
.PHONY: report-binutils-linux
9941140
report-binutils-linux: stamps/check-binutils-linux
9951141
$(srcdir)/scripts/testsuite-filter binutils glibc \
9961142
$(srcdir)/test/allowlist \
9971143
`find build-binutils-linux/ -name *.sum |paste -sd "," -`
9981144

9991145
clean:
1000-
rm -rf build-* stamps install-newlib-nano
1146+
rm -rf build-* stamps install-newlib-nano picolibc-cross.txt
10011147

10021148
.PHONY: report-gdb-newlib report-gdb-newlib-nano
10031149
report-gdb-newlib: stamps/check-gdb-newlib

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,17 @@ run the following command:
5959

6060
You should now be able to use riscv64-unknown-elf-gcc and its cousins.
6161

62+
### Installation (Picolibc multilib)
63+
64+
To build the Picolibc cross-compiler, pick an install path. If you choose,
65+
say, `/opt/riscv`, then add `/opt/riscv/bin` to your `PATH` now. Then, simply
66+
run the following command:
67+
68+
./configure --prefix=/opt/riscv --enable-picolibc --enable-multilib
69+
make
70+
71+
You should now be able to use riscv64-unknown-elf-gcc and its cousins.
72+
6273
### Installation (Linux)
6374

6475
To build the Linux cross-compiler, pick an install path (that is writeable.)

0 commit comments

Comments
 (0)