e211cddbd729927fee21884f94c8861960a1a717
[fedora-riscv.git] / Makefile
1 # Refer to the README file to understand how Fedora on RISC-V is
2 # bootstrapped.
3
4 # Note these are chosen very specifically to ensure the different
5 # versions work together.  Don't blindly update to the latest
6 # versions.  See also:
7 # https://github.com/riscv/riscv-pk/issues/18#issuecomment-206115996
8 RISCV_QEMU_COMMIT               = 94f5eb73091fb4fe272db3e943f173ecc0f78ffd
9 RISCV_QEMU_SHORTCOMMIT          = 94f5eb73
10 RISCV_FESVR_COMMIT              = 0f34d7ad311f78455a674224225f5b3056efba1d
11 RISCV_FESVR_SHORTCOMMIT         = 0f34d7ad
12 RISCV_ISA_SIM_COMMIT            = 3bfc00ef2a1b1f0b0472a39a866261b00f67027e
13 RISCV_ISA_SIM_SHORTCOMMIT       = 3bfc00ef
14 RISCV_GNU_TOOLCHAIN_COMMIT      = 728afcddcb0526a0f6560c4032da82805f054d58
15 RISCV_GNU_TOOLCHAIN_SHORTCOMMIT = 728afcdd
16 RISCV_PK_COMMIT                 = 85ae17aa149b9ea114bdd70cc30ea7e73813fb48
17 RISCV_PK_SHORTCOMMIT            = 85ae17aa
18
19 # For the correct versions, see
20 # riscv-gnu-toolchain/Makefile.in *_version variables
21 BINUTILS_VERSION = 2.25.1
22 GLIBC_VERSION    = 2.22
23 GCC_VERSION      = 5.3.0
24 NEWLIB_VERSION   = 2.2.0
25
26 # See linux-4.1.y-riscv branch of
27 # https://github.com/riscv/riscv-linux
28 KERNEL_VERSION   = 4.1.26
29
30 # A local copy of Linux git repo so you don't have to keep downloading
31 # git commits (optional).
32 LOCAL_LINUX_GIT_COPY = $(HOME)/d/linux
33
34 # The root packages (plus their dependencies) that we want to
35 # cross-compile into the stage 3 chroot.
36 STAGE3_PACKAGES = gcc rpm-build
37
38 # Versions of cross-compiled packages.
39 BASH_VERSION      = 4.3
40 COREUTILS_VERSION = 8.25
41
42 all: stage1 stage2 stage3 stage4
43
44 # Stage 1
45
46 stage1: stage1-riscv-qemu/riscv-qemu-$(RISCV_QEMU_SHORTCOMMIT).tar.gz \
47         stage1-riscv-qemu/riscv-qemu.spec \
48         stamp-riscv-qemu-installed \
49         stage1-riscv-fesvr/riscv-fesvr-$(RISCV_FESVR_SHORTCOMMIT).tar.gz \
50         stage1-riscv-fesvr/riscv-fesvr.spec \
51         stamp-riscv-fesvr-installed \
52         stage1-riscv-isa-sim/riscv-isa-sim-$(RISCV_ISA_SIM_SHORTCOMMIT).tar.gz \
53         stage1-riscv-isa-sim/riscv-isa-sim.spec \
54         stamp-riscv-isa-sim-installed
55
56 stage1-riscv-qemu/riscv-qemu-$(RISCV_QEMU_SHORTCOMMIT).tar.gz:
57         rm -f $@ $@-t
58         wget -O $@-t 'https://github.com/riscv/riscv-qemu/archive/$(RISCV_QEMU_COMMIT)/riscv-qemu-$(RISCV_QEMU_SHORTCOMMIT).tar.gz'
59         mv $@-t $@
60
61 stage1-riscv-qemu/riscv-qemu.spec: stage1-riscv-qemu/riscv-qemu.spec.in
62         sed -e 's/@COMMIT@/$(RISCV_QEMU_COMMIT)/g' \
63             -e 's/@SHORTCOMMIT@/$(RISCV_QEMU_SHORTCOMMIT)/g' \
64             < $^ > $@-t
65         mv $@-t $@
66
67 stamp-riscv-qemu-installed:
68         rm -f $@
69         @rpm -q riscv-qemu >/dev/null || { \
70           echo "ERROR: You must install riscv-qemu:"; \
71           echo; \
72           echo "       dnf copr enable rjones/riscv"; \
73           echo "       dnf install riscv-qemu"; \
74           echo; \
75           echo "OR: you can build it yourself from the stage1-riscv-qemu directory."; \
76           echo; \
77           exit 1; \
78         }
79         @qemu-system-riscv --version || { \
80           echo "ERROR: qemu-system-riscv is not working."; \
81           echo "Make sure you installed the riscv-qemu package."; \
82           exit 1; \
83         }
84         touch $@
85
86 stage1-riscv-fesvr/riscv-fesvr-$(RISCV_FESVR_SHORTCOMMIT).tar.gz:
87         rm -f $@ $@-t
88         wget -O $@-t 'https://github.com/riscv/riscv-fesvr/archive/$(RISCV_FESVR_COMMIT)/riscv-fesvr-$(RISCV_FESVR_SHORTCOMMIT).tar.gz'
89         mv $@-t $@
90
91 stage1-riscv-fesvr/riscv-fesvr.spec: stage1-riscv-fesvr/riscv-fesvr.spec.in
92         sed -e 's/@COMMIT@/$(RISCV_FESVR_COMMIT)/g' \
93             -e 's/@SHORTCOMMIT@/$(RISCV_FESVR_SHORTCOMMIT)/g' \
94             < $^ > $@-t
95         mv $@-t $@
96
97 stamp-riscv-fesvr-installed:
98         rm -f $@
99         @rpm -q riscv-fesvr >/dev/null || { \
100           echo "ERROR: You must install riscv-fesvr:"; \
101           echo; \
102           echo "       dnf copr enable rjones/riscv"; \
103           echo "       dnf install riscv-fesvr"; \
104           echo; \
105           echo "OR: you can build it yourself from the stage1-riscv-fesvr directory."; \
106           echo; \
107           exit 1; \
108         }
109         touch $@
110
111 stage1-riscv-isa-sim/riscv-isa-sim-$(RISCV_ISA_SIM_SHORTCOMMIT).tar.gz:
112         rm -f $@ $@-t
113         wget -O $@-t 'https://github.com/riscv/riscv-isa-sim/archive/$(RISCV_ISA_SIM_COMMIT)/riscv-isa-sim-$(RISCV_ISA_SIM_SHORTCOMMIT).tar.gz'
114         mv $@-t $@
115
116 stage1-riscv-isa-sim/riscv-isa-sim.spec: stage1-riscv-isa-sim/riscv-isa-sim.spec.in
117         sed -e 's/@COMMIT@/$(RISCV_ISA_SIM_COMMIT)/g' \
118             -e 's/@SHORTCOMMIT@/$(RISCV_ISA_SIM_SHORTCOMMIT)/g' \
119             < $^ > $@-t
120         mv $@-t $@
121
122 stamp-riscv-isa-sim-installed:
123         rm -f $@
124         @rpm -q riscv-isa-sim >/dev/null || { \
125           echo "ERROR: You must install riscv-isa-sim:"; \
126           echo; \
127           echo "       dnf copr enable rjones/riscv"; \
128           echo "       dnf install riscv-isa-sim"; \
129           echo; \
130           echo "OR: you can build it yourself from the stage1-riscv-isa-sim directory."; \
131           echo; \
132           exit 1; \
133         }
134         touch $@
135
136 # Stage 2
137
138 stage2: stage2-riscv-gnu-toolchain/riscv-gnu-toolchain-$(RISCV_GNU_TOOLCHAIN_SHORTCOMMIT).tar.gz \
139         stage2-riscv-gnu-toolchain/binutils-$(BINUTILS_VERSION).tar.gz \
140         stage2-riscv-gnu-toolchain/gcc-$(GCC_VERSION).tar.gz \
141         stage2-riscv-gnu-toolchain/glibc-$(GLIBC_VERSION).tar.gz \
142         stage2-riscv-gnu-toolchain/newlib-$(NEWLIB_VERSION).tar.gz \
143         stage2-riscv-gnu-toolchain/riscv-gnu-toolchain.spec \
144         stamp-riscv-gnu-toolchain-installed \
145         stage2-riscv-pk/riscv-pk-$(RISCV_PK_SHORTCOMMIT).tar.gz \
146         stage2-riscv-pk/riscv-pk.spec \
147         stamp-riscv-pk-installed
148
149 stage2-riscv-gnu-toolchain/riscv-gnu-toolchain-$(RISCV_GNU_TOOLCHAIN_SHORTCOMMIT).tar.gz:
150         rm -f $@ $@-t
151         wget -O $@-t https://github.com/lowRISC/riscv-gnu-toolchain/archive/$(RISCV_GNU_TOOLCHAIN_COMMIT)/riscv-gnu-toolchain-$(RISCV_GNU_TOOLCHAIN_SHORTCOMMIT).tar.gz
152         mv $@-t $@
153
154 stage2-riscv-gnu-toolchain/binutils-$(BINUTILS_VERSION).tar.gz:
155         rm -f $@ $@-t
156         wget -O $@-t http://mirrors.kernel.org/gnu/binutils/binutils-$(BINUTILS_VERSION).tar.gz
157         mv $@-t $@
158
159 # GCC 5 no longer compiles with GCC 6 unless we patch it.
160 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69959
161 stage2-riscv-gnu-toolchain/gcc-$(GCC_VERSION).tar.gz:
162         rm -f $@ $@-t
163         wget -O $@-t http://mirrors.kernel.org/gnu/gcc/gcc-$(GCC_VERSION)/gcc-$(GCC_VERSION).tar.gz
164         zcat $@-t | tar xf -
165         cd gcc-$(GCC_VERSION) && patch -p0 < ../stage2-riscv-gnu-toolchain/gcc-5-fix-compilation-with-gcc-6.patch
166         tar zcf $@-t gcc-$(GCC_VERSION)
167         rm -r gcc-$(GCC_VERSION)
168         mv $@-t $@
169
170 stage2-riscv-gnu-toolchain/glibc-$(GLIBC_VERSION).tar.gz:
171         rm -f $@ $@-t
172         wget -O $@-t http://mirrors.kernel.org/gnu/glibc/glibc-$(GLIBC_VERSION).tar.gz
173         mv $@-t $@
174
175 stage2-riscv-gnu-toolchain/newlib-$(NEWLIB_VERSION).tar.gz:
176         rm -f $@ $@-t
177         wget -O $@-t ftp://sourceware.org/pub/newlib/newlib-$(NEWLIB_VERSION).tar.gz
178         mv $@-t $@
179
180 stage2-riscv-gnu-toolchain/riscv-gnu-toolchain.spec: stage2-riscv-gnu-toolchain/riscv-gnu-toolchain.spec.in
181         sed -e 's/@COMMIT@/$(RISCV_GNU_TOOLCHAIN_COMMIT)/g' \
182             -e 's/@SHORTCOMMIT@/$(RISCV_GNU_TOOLCHAIN_SHORTCOMMIT)/g' \
183             -e 's/@BINUTILS_VERSION@/$(BINUTILS_VERSION)/g' \
184             -e 's/@GCC_VERSION@/$(GCC_VERSION)/g' \
185             -e 's/@GLIBC_VERSION@/$(GLIBC_VERSION)/g' \
186             -e 's/@NEWLIB_VERSION@/$(NEWLIB_VERSION)/g' \
187             < $^ > $@-t
188         mv $@-t $@
189
190 stamp-riscv-gnu-toolchain-installed:
191         rm -f $@
192         @rpm -q riscv-gnu-toolchain >/dev/null || { \
193           echo "ERROR: You must install riscv-gnu-toolchain:"; \
194           echo; \
195           echo "       dnf copr enable rjones/riscv"; \
196           echo "       dnf install riscv-gnu-toolchain"; \
197           echo; \
198           echo "OR: you can build it yourself from the stage2-riscv-gnu-toolchain directory."; \
199           echo; \
200           exit 1; \
201         }
202         @riscv64-unknown-elf-gcc --version || { \
203           echo "ERROR: riscv64-unknown-elf-gcc (cross compiler) is not working."; \
204           echo "Make sure you installed the riscv-gnu-toolchain package."; \
205           exit 1; \
206         }
207         touch $@
208
209 stage2-riscv-pk/riscv-pk-$(RISCV_PK_SHORTCOMMIT).tar.gz:
210         rm -f $@ $@-t
211         wget -O $@-t https://github.com/lowRISC/riscv-pk/archive/$(RISCV_PK_COMMIT)/riscv-pk-$(RISCV_PK_SHORTCOMMIT).tar.gz
212         mv $@-t $@
213
214 stage2-riscv-pk/riscv-pk.spec: stage2-riscv-pk/riscv-pk.spec.in
215         sed -e 's/@COMMIT@/$(RISCV_PK_COMMIT)/g' \
216             -e 's/@SHORTCOMMIT@/$(RISCV_PK_SHORTCOMMIT)/g' \
217             < $^ > $@-t
218         mv $@-t $@
219
220 stamp-riscv-pk-installed:
221         rm -f $@
222         @rpm -q riscv-pk >/dev/null || { \
223           echo "ERROR: You must install riscv-pk:"; \
224           echo; \
225           echo "       dnf copr enable rjones/riscv"; \
226           echo "       dnf install riscv-pk"; \
227           echo; \
228           echo "OR: you can build it yourself from the stage2-riscv-pk directory."; \
229           echo; \
230           exit 1; \
231         }
232         touch $@
233
234 # Stage 3
235
236 stage3: stage3-kernel/linux-$(KERNEL_VERSION)/vmlinux \
237         stage3-chroot-original/etc/fedora-release \
238         stage3-chroot/etc/fedora-release \
239         stage3-chroot/lib64/libc.so.6 \
240         stage3-chroot/bin/bash \
241         stage3-chroot/bin/ls \
242         stage3-chroot/init \
243         stage3-disk.img
244
245 stage3-kernel/linux-$(KERNEL_VERSION)/vmlinux:
246         rm -rf stage3-kernel/linux-$(KERNEL_VERSION)
247         cp -a $(LOCAL_LINUX_GIT_COPY) stage3-kernel/linux-$(KERNEL_VERSION) || { \
248           mkdir stage3-kernel/linux-$(KERNEL_VERSION) && \
249           cd stage3-kernel/linux-$(KERNEL_VERSION) && \
250           git init; \
251         }
252         cd stage3-kernel/linux-$(KERNEL_VERSION) && \
253         git remote add riscv https://github.com/riscv/riscv-linux && \
254         git fetch riscv && \
255         git checkout -f linux-4.1.y-riscv && \
256         make mrproper && \
257         make ARCH=riscv defconfig
258         echo CONFIG_CMDLINE=\"root=/dev/htifblk0 init=/init\" >> stage3-kernel/linux-$(KERNEL_VERSION)/.config
259         echo CONFIG_CROSS_COMPILE=riscv64-unknown-elf- >> stage3-kernel/linux-$(KERNEL_VERSION)/.config
260         cd stage3-kernel/linux-$(KERNEL_VERSION) && \
261         make ARCH=riscv olddefconfig
262         cd stage3-kernel/linux-$(KERNEL_VERSION) && \
263         make ARCH=riscv vmlinux
264         ls -l $@
265
266 # Build an original (x86-64) chroot using supermin.  We then aim to
267 # rebuild (using cross-compiled versions) every ELF binary in this
268 # chroot.
269 stage3-chroot-original/etc/fedora-release:
270         rm -rf stage3-chroot-original tmp-supermin.d
271         supermin --prepare $(STAGE3_PACKAGES) -o tmp-supermin.d
272         supermin --build -f chroot tmp-supermin.d -o stage3-chroot-original
273         rm -r tmp-supermin.d
274         @echo -n "Total files in chroot: "
275         @find stage3-chroot-original -type f | wc -l
276         @echo -n "ELF files to be rebuilt: "
277         @find stage3-chroot-original -type f | xargs file -N | grep -E '\bELF.*LSB\b' | wc -l
278
279 # Copy the original chroot to the final chroot, remove all the ELF
280 # files.
281 stage3-chroot/etc/fedora-release: stage3-chroot-original/etc/fedora-release
282         rm -rf stage3-chroot
283         cp -a stage3-chroot-original stage3-chroot
284         find stage3-chroot -type d | xargs chmod u+w
285         find stage3-chroot -type f | xargs chmod u+w
286         find stage3-chroot -type f | xargs file -N | grep -E '\bELF.*LSB\b' | awk -F: '{print $$1}' | xargs rm -f
287         rm -f stage3-chroot/lib64/libc.so.6
288
289 # Copy in compiled glibc from the riscv-gnu-toolchain sysroot.  Only
290 # copy files and symlinks, leave the target directory structure
291 # intact.
292 stage3-chroot/lib64/libc.so.6:
293         mkdir -p stage3-chroot/usr/lib/audit
294         mkdir -p stage3-chroot/usr/lib/gconv
295         for f in `cd /usr/sysroot && find -type f -o -type l`; do \
296             cp -d /usr/sysroot/$$f stage3-chroot/$$f; \
297         done
298         cd stage3-chroot/lib64 && for f in ../lib/*; do ln -sf $$f; done
299
300 # Cross-compile bash.
301 stage3-chroot/bin/bash: bash-$(BASH_VERSION).tar.gz
302         tar zxf $^
303         cd bash-$(BASH_VERSION) && \
304         ./configure --host=riscv64-unknown-linux-gnu CFLAGS="--sysroot=/usr/sysroot" && \
305         make
306         cp bash-$(BASH_VERSION)/bash stage3-chroot/bin/
307
308 bash-$(BASH_VERSION).tar.gz:
309         rm -f $@ $@-t
310         wget -O $@-t ftp://ftp.gnu.org/gnu/bash/bash-$(BASH_VERSION).tar.gz
311         mv $@-t $@
312
313 # Cross-compile coreutils.  Bleah, coreutils cross-compilation is
314 # known-broken and upstream don't care, hence the 'touch' command.
315
316 COREUTILS_PROGRAMS = arch base32 base64 basename cat chcon chgrp chmod chown chroot cksum comm cp csplit cut date dd df dir dircolors dirname du echo env expand expr factor false fmt fold ginstall groups head hostid hostname id install join kill link ln logname ls md5sum mkdir mkfifo mknod mktemp mv nice nl nohup nproc numfmt od paste pathchk pinky pr printenv printf ptx pwd readlink realpath rm rmdir runcon seq sha1sum sha224sum sha256sum sha384sum sha512sum shred shuf sleep sort split stat stdbuf stty sum sync tac tail tee test timeout touch tr true truncate tsort tty uname unexpand uniq unlink uptime users vdir wc who whoami yes
317
318 stage3-chroot/bin/ls: coreutils-$(COREUTILS_VERSION).tar.xz
319         rm -rf coreutils-$(COREUTILS_VERSION)
320         tar Jxf $^
321         cd coreutils-$(COREUTILS_VERSION) && \
322         ./configure --host=riscv64-unknown-linux-gnu CFLAGS="--sysroot=/usr/sysroot"
323         -cd coreutils-$(COREUTILS_VERSION) && make
324         cd coreutils-$(COREUTILS_VERSION)/man && \
325         for f in $(COREUTILS_PROGRAMS); do touch $$f.1; done
326         cd coreutils-$(COREUTILS_VERSION) && make
327         for f in $(COREUTILS_PROGRAMS); do \
328             cp coreutils-$(COREUTILS_VERSION)/src/$$f stage3-chroot/bin/; \
329         done
330
331 coreutils-$(COREUTILS_VERSION).tar.xz:
332         rm -f $@ $@-t
333         wget -O $@-t ftp://ftp.gnu.org/gnu/coreutils/coreutils-$(COREUTILS_VERSION).tar.xz
334         mv $@-t $@
335
336 # Create an /init script.
337 stage3-chroot/init: init.sh
338         install -m 0755 $^ $@
339
340 # Create the stage3 disk image.
341 # Note `-s +...' adds spare space to the disk image.
342 stage3-disk.img: stage3-chroot
343         cd stage3-chroot && virt-make-fs . ../$@ -t ext2 -F raw -s +4G
344
345 # Helper which boots stage3 disk image in spike.
346 boot-stage3-in-spike: stage3-disk.img stage3-kernel/linux-$(KERNEL_VERSION)/vmlinux
347         spike +disk=stage3-disk.img \
348             /usr/bin/bbl stage3-kernel/linux-$(KERNEL_VERSION)/vmlinux
349
350 # Helper which boots stage3 disk image in qemu.
351 boot-stage3-in-qemu: stage3-disk.img stage3-kernel/linux-$(KERNEL_VERSION)/vmlinux
352         qemu-system-riscv -kernel /usr/bin/bbl \
353             -append ./stage3-kernel/linux-$(KERNEL_VERSION)/vmlinux \
354             -drive file=stage3-disk.img,format=raw -nographic
355
356 # Stage 4
357
358 stage4:
359         echo "XXX TO DO"
360         exit 1
361
362 .NOTPARALLEL: