Add build system for fusee

This commit is contained in:
TuxSH 2018-03-14 21:14:02 +01:00
parent 965971edbd
commit 171c82ea9e
8 changed files with 499 additions and 1 deletions

2
.gitignore vendored
View file

@ -57,3 +57,5 @@ exosphere/bpmpfw/out/**
exosphere/bpmpfw/build/** exosphere/bpmpfw/build/**
exosphere/build/** exosphere/build/**
exosphere/out/** exosphere/out/**
fusee/out/**
fusee/build/**

View file

@ -1,7 +1,7 @@
rwildcard = $(foreach d, $(wildcard $1*), $(filter $(subst *, %, $2), $d) $(call rwildcard, $d/, $2)) rwildcard = $(foreach d, $(wildcard $1*), $(filter $(subst *, %, $2), $d) $(call rwildcard, $d/, $2))
ifeq ($(strip $(DEVKITPRO)),) ifeq ($(strip $(DEVKITPRO)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM") $(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitPro")
endif endif
include $(DEVKITPRO)/devkitA64/base_tools include $(DEVKITPRO)/devkitA64/base_tools

77
fusee/Makefile Normal file
View file

@ -0,0 +1,77 @@
rwildcard = $(foreach d, $(wildcard $1*), $(filter $(subst *, %, $2), $d) $(call rwildcard, $d/, $2))
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
include $(DEVKITARM)/base_tools
name := fusee
dir_source := src
dir_build := build
dir_out := out
dir_exosphere := ../exosphere
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
ASFLAGS := -g $(ARCH)
# For debug builds, replace -O2 by -Og and comment -fomit-frame-pointer out
CFLAGS = \
$(ARCH) \
-g \
-O2 \
-fomit-frame-pointer \
-ffunction-sections \
-fdata-sections \
-std=gnu11 \
-Werror \
-Wall
LDFLAGS = -specs=linker.specs -g $(ARCH)
objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
$(call rwildcard, $(dir_source), *.s *.c))) \
$(dir_build)/exosphere.bin.o
define bin2o
bin2s $< | $(AS) -o $(@)
endef
.PHONY: all
all: $(dir_out)/$(name).bin
.PHONY: clean
clean:
@$(MAKE) -C $(dir_exosphere) clean
@rm -rf $(dir_build)
@rm -rf $(dir_out)
.PHONY: $(dir_exosphere)
$(dir_out)/$(name).bin: $(dir_build)/$(name).elf
@mkdir -p "$(@D)"
$(OBJCOPY) -S -O binary $< $@
$(dir_build)/$(name).elf: $(objects)
$(LINK.o) $(OUTPUT_OPTION) $^
$(dir_exosphere)/out/exosphere.bin: $(dir_exosphere)
@$(MAKE) -C $<
$(dir_build)/exosphere.bin: $(dir_exosphere)/out/exosphere.bin
@mkdir -p "$(@D)"
@cp $< $(@D)
$(dir_build)/%.bin.o: $(dir_build)/%.bin
@$(bin2o)
$(dir_build)/%.o: $(dir_source)/%.c
@mkdir -p "$(@D)"
$(COMPILE.c) $(OUTPUT_OPTION) $<
$(dir_build)/%.o: $(dir_source)/%.s
@mkdir -p "$(@D)"
$(COMPILE.c) -x assembler-with-cpp $(OUTPUT_OPTION) $<

151
fusee/linker.ld Normal file
View file

@ -0,0 +1,151 @@
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
/* Mostly copied from https://github.com/devkitPro/buildscripts/blob/master/dkarm-eabi/crtls/3dsx.ld */
SECTIONS
{
PROVIDE(__start__ = 0x40010000);
. = __start__;
. = ALIGN(32);
.text :
{
. = ALIGN(32);
/* .init */
KEEP( *(.text.start) )
KEEP( *(.init) )
. = ALIGN(4);
/* .text */
*(.text)
*(.text.*)
*(.glue_7)
*(.glue_7t)
*(.stub)
*(.gnu.warning)
*(.gnu.linkonce.t*)
. = ALIGN(4);
/* .fini */
KEEP( *(.fini) )
. = ALIGN(4);
}
.rodata :
{
*(.rodata)
*(.roda)
*(.rodata.*)
*all.rodata*(*)
*(.gnu.linkonce.r*)
SORT(CONSTRUCTORS)
. = ALIGN(4);
}
.preinit_array ALIGN(4) :
{
PROVIDE (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE (__preinit_array_end = .);
}
.init_array ALIGN(4) :
{
PROVIDE (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE (__init_array_end = .);
}
.fini_array ALIGN(4) :
{
PROVIDE (__fini_array_start = .);
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
PROVIDE (__fini_array_end = .);
}
.ctors ALIGN(4) :
{
KEEP (*crtbegin.o(.ctors)) /* MUST be first -- GCC requires it */
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors ALIGN(4) :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) }
__exidx_start = .;
ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }
__exidx_end = .;
.data :
{
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
CONSTRUCTORS
. = ALIGN(4);
}
__bss_start__ = ALIGN(32);
.bss :
{
*(.dynbss)
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b*)
*(COMMON)
. = ALIGN(8);
}
__bss_end__ = .;
__end__ = ABSOLUTE(.) ;
/* ==================
==== Metadata ====
================== */
/* Discard sections that difficult post-processing */
/DISCARD/ : { *(.group .comment .note) }
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
}

7
fusee/linker.specs Normal file
View file

@ -0,0 +1,7 @@
%rename link old_link
*link:
%(old_link) -T linker.ld --nmagic --gc-sections
*startfile:
crti%O%s crtbegin%O%s

4
fusee/src/main.c Normal file
View file

@ -0,0 +1,4 @@
int main(void) {
/* TODO */
return 0;
}

207
fusee/src/preprocessor.h Normal file
View file

@ -0,0 +1,207 @@
/* TuxSH: I added INC/DEC_10 to INC/DEC_32; tuples */
#ifndef FUSEE_PREPROCESSOR_H
#define FUSEE_PREPROCESSOR_H
/*=============================================================================
Copyright (c) 2015 Paul Fultz II
cloak.h
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
/*#ifndef CLOAK_GUARD_H
#define CLOAK_GUARD_H*/
#define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__)
#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__
#define COMPL(b) PRIMITIVE_CAT(COMPL_, b)
#define COMPL_0 1
#define COMPL_1 0
#define BITAND(x) PRIMITIVE_CAT(BITAND_, x)
#define BITAND_0(y) 0
#define BITAND_1(y) y
#define INC(x) PRIMITIVE_CAT(INC_, x)
#define INC_0 1
#define INC_1 2
#define INC_2 3
#define INC_3 4
#define INC_4 5
#define INC_5 6
#define INC_6 7
#define INC_7 8
#define INC_8 9
#define INC_9 10
#define INC_10 11
#define INC_11 12
#define INC_12 13
#define INC_13 14
#define INC_14 15
#define INC_15 16
#define INC_16 17
#define INC_17 18
#define INC_18 19
#define INC_19 20
#define INC_20 21
#define INC_21 22
#define INC_22 23
#define INC_23 24
#define INC_24 25
#define INC_25 26
#define INC_26 27
#define INC_27 28
#define INC_28 29
#define INC_29 30
#define INC_30 31
#define INC_31 32
#define INC_32 32
#define INC_33 33
#define DEC(x) PRIMITIVE_CAT(DEC_, x)
#define DEC_0 0
#define DEC_1 0
#define DEC_2 1
#define DEC_3 2
#define DEC_4 3
#define DEC_5 4
#define DEC_6 5
#define DEC_7 6
#define DEC_8 7
#define DEC_9 8
#define DEC_10 9
#define DEC_11 10
#define DEC_12 11
#define DEC_13 12
#define DEC_14 13
#define DEC_15 14
#define DEC_16 15
#define DEC_17 16
#define DEC_18 17
#define DEC_19 18
#define DEC_20 19
#define DEC_21 20
#define DEC_22 21
#define DEC_23 22
#define DEC_24 23
#define DEC_25 24
#define DEC_26 25
#define DEC_27 26
#define DEC_28 27
#define DEC_29 28
#define DEC_30 29
#define DEC_31 30
#define DEC_32 31
#define DEC_33 32
#define CHECK_N(x, n, ...) n
#define CHECK(...) CHECK_N(__VA_ARGS__, 0,)
#define PROBE(x) x, 1,
#define IS_PAREN(x) CHECK(IS_PAREN_PROBE x)
#define IS_PAREN_PROBE(...) PROBE(~)
#define NOT(x) CHECK(PRIMITIVE_CAT(NOT_, x))
#define NOT_0 PROBE(~)
#define COMPL(b) PRIMITIVE_CAT(COMPL_, b)
#define COMPL_0 1
#define COMPL_1 0
#define BOOL(x) COMPL(NOT(x))
#define IIF(c) PRIMITIVE_CAT(IIF_, c)
#define IIF_0(t, ...) __VA_ARGS__
#define IIF_1(t, ...) t
#define IF(c) IIF(BOOL(c))
#define EAT(...)
#define EXPAND(...) __VA_ARGS__
#define WHEN(c) IF(c)(EXPAND, EAT)
#define EMPTY()
#define DEFER(id) id EMPTY()
#define OBSTRUCT(id) id DEFER(EMPTY)()
#define EVAL(...) EVAL1(EVAL1(EVAL1(__VA_ARGS__)))
#define EVAL1(...) EVAL2(EVAL2(EVAL2(__VA_ARGS__)))
#define EVAL2(...) EVAL3(EVAL3(EVAL3(__VA_ARGS__)))
#define EVAL3(...) EVAL4(EVAL4(EVAL4(__VA_ARGS__)))
#define EVAL4(...) EVAL5(EVAL5(EVAL5(__VA_ARGS__)))
#define EVAL5(...) __VA_ARGS__
#define REPEAT(count, macro, ...) \
WHEN(count) \
( \
OBSTRUCT(REPEAT_INDIRECT) () \
( \
DEC(count), macro, __VA_ARGS__ \
) \
OBSTRUCT(macro) \
( \
DEC(count), __VA_ARGS__ \
) \
)
#define REPEAT_INDIRECT() REPEAT
#define WHILE(pred, op, ...) \
IF(pred(__VA_ARGS__)) \
( \
OBSTRUCT(WHILE_INDIRECT) () \
( \
pred, op, op(__VA_ARGS__) \
), \
__VA_ARGS__ \
)
#define WHILE_INDIRECT() WHILE
#define PRIMITIVE_COMPARE(x, y) IS_PAREN \
( \
COMPARE_ ## x ( COMPARE_ ## y) (()) \
)
#define IS_COMPARABLE(x) IS_PAREN( CAT(COMPARE_, x) (()) )
#define NOT_EQUAL(x, y) \
IIF(BITAND(IS_COMPARABLE(x))(IS_COMPARABLE(y)) ) \
( \
PRIMITIVE_COMPARE, \
1 EAT \
)(x, y)
#define EQUAL(x, y) COMPL(NOT_EQUAL(x, y))
#define COMMA() ,
#define COMMA_IF(n) IF(n)(COMMA, EAT)()
#define PLUS() +
#define _TUPLE_ELEM_0(a, ...) a
#define _TUPLE_ELEM_1(a, b, ...) b
#define _TUPLE_ELEM_2(a, b, c, ...) c
#define _TUPLE_ELEM_3(a, b, c, d, ...) d
#define _TUPLE_ELEM_4(a, b, c, d, e, ...) e
#define TUPLE_ELEM_0(T) EVAL(_TUPLE_ELEM_0 T)
#define TUPLE_ELEM_1(T) EVAL(_TUPLE_ELEM_1 T)
#define TUPLE_ELEM_2(T) EVAL(_TUPLE_ELEM_2 T)
#define TUPLE_ELEM_3(T) EVAL(_TUPLE_ELEM_3 T)
#define TUPLE_ELEM_4(T) EVAL(_TUPLE_ELEM_4 T)
#define _TUPLE_FOLD_LEFT_0(i, T, op) (_TUPLE_ELEM_0 CAT(T,i)) op()
#define _TUPLE_FOLD_LEFT_1(i, T, op) (_TUPLE_ELEM_1 CAT(T,i)) op()
#define _TUPLE_FOLD_LEFT_2(i, T, op) (_TUPLE_ELEM_2 CAT(T,i)) op()
#define _TUPLE_FOLD_LEFT_3(i, T, op) (_TUPLE_ELEM_3 CAT(T,i)) op()
#define _TUPLE_FOLD_LEFT_4(i, T, op) (_TUPLE_ELEM_4 CAT(T,i)) op()
#define TUPLE_FOLD_LEFT_0(len, T, op) EVAL(REPEAT(len, _TUPLE_FOLD_LEFT_0, T, op))
#define TUPLE_FOLD_LEFT_1(len, T, op) EVAL(REPEAT(len, _TUPLE_FOLD_LEFT_1, T, op))
#define TUPLE_FOLD_LEFT_2(len, T, op) EVAL(REPEAT(len, _TUPLE_FOLD_LEFT_2, T, op))
#define TUPLE_FOLD_LEFT_3(len, T, op) EVAL(REPEAT(len, _TUPLE_FOLD_LEFT_3, T, op))
#define TUPLE_FOLD_LEFT_4(len, T, op) EVAL(REPEAT(len, _TUPLE_FOLD_LEFT_4, T, op))
#endif

50
fusee/src/start.s Normal file
View file

@ -0,0 +1,50 @@
.macro CLEAR_GPR_REG_ITER
mov r\@, #0
.endm
.section .text.start
.arm
.align 5
.global _start
_start:
/* Switch to supervisor mode, mask all interrupts, clear all flags */
msr cpsr_cxsf, #0xDF
/* Relocate ourselves if necessary */
ldr r0, =__start__
adr r1, _start
cmp r0, r1
bne _relocation_loop_end
ldr r2, =__bss_start__
sub r2, r2, r0 /* size >= 32, obviously */
_relocation_loop:
ldmia r1!, {r3-r10}
stmia r0!, {r3-r10}
subs r2, #0x20
bne _relocation_loop
ldr r12, =_relocation_loop_end
bx r12
_relocation_loop_end:
/* Set the stack pointer */
ldr sp, =0x40008000
mov fp, #0
/* Clear .bss */
ldr r0, =__bss_start__
mov r1, #0
ldr r2, =__bss_end__
sub r2, r2, r0
bl memset
/* Call global constructors */
bl __libc_init_array
/* Set r0 to r12 to 0 (because why not?) & call main */
.rept 13
CLEAR_GPR_REG_ITER
.endr
bl main
b .