summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGriffinR <griffin.g.richards@gmail.com>2021-06-13 17:51:17 -0400
committerGitHub <noreply@github.com>2021-06-13 17:51:17 -0400
commitb0dfaa92be48b4dc88af0c1502689fcad7da99ea (patch)
tree5b60e917fc89f39426fd54babfcb0dd5c12822c2
parentf85fb3af8923b7dce601591dede2d3bee0729d1e (diff)
parent7189e4e26f3da36ed9d373f77a9f51a36fc8ddaf (diff)
Merge pull request #1460 from luckytyphlosion/remove-temps
Buildsystem no longer builds temporary files for C compilation by default, and other makefile optimizations.
-rw-r--r--Makefile120
-rw-r--r--make_tools.mk11
-rw-r--r--tools/preproc/c_file.cpp55
-rw-r--r--tools/preproc/c_file.h5
-rw-r--r--tools/preproc/preproc.cpp22
5 files changed, 158 insertions, 55 deletions
diff --git a/Makefile b/Makefile
index a78949b3f..d7d4b9566 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,10 @@
TOOLCHAIN := $(DEVKITARM)
COMPARE ?= 0
+ifeq (compare,$(MAKECMDGOALS))
+ COMPARE := 1
+endif
+
# don't use dkP's base_tools anymore
# because the redefinition of $(CC) conflicts
# with when we want to use $(CC) to preprocess files
@@ -36,6 +40,10 @@ MAKER_CODE := 01
REVISION := 0
MODERN ?= 0
+ifeq (modern,$(MAKECMDGOALS))
+ MODERN := 1
+endif
+
# use arm-none-eabi-cpp for macOS
# as macOS's default compiler is clang
# and clang's preprocessor will warn on \u
@@ -143,12 +151,28 @@ infoshell = $(foreach line, $(shell $1 | sed "s/ /__SPACE__/g"), $(info $(subst
# Build tools when building the rom
# Disable dependency scanning for clean/tidy/tools
+# Use a separate minimal makefile for speed
+# Since we don't need to reload most of this makefile
ifeq (,$(filter-out all rom compare modern berry_fix libagbsyscall,$(MAKECMDGOALS)))
-$(call infoshell, $(MAKE) tools)
+$(call infoshell, $(MAKE) -f make_tools.mk)
else
-NODEP := 1
+NODEP ?= 1
endif
+# check if we need to scan dependencies based on the rule
+ifeq (,$(MAKECMDGOALS))
+ SCAN_DEPS ?= 1
+else
+ # clean, tidy, tools, mostlyclean, clean-tools, $(TOOLDIRS), tidymodern, tidynonmodern don't even build the ROM
+ # berry_fix and libagbsyscall do their own thing
+ ifeq (,$(filter-out clean tidy tools mostlyclean clean-tools $(TOOLDIRS) tidymodern tidynonmodern berry_fix libagbsyscall,$(MAKECMDGOALS)))
+ SCAN_DEPS ?= 0
+ else
+ SCAN_DEPS ?= 1
+ endif
+endif
+
+ifeq ($(SCAN_DEPS),1)
C_SRCS_IN := $(wildcard $(C_SUBDIR)/*.c $(C_SUBDIR)/*/*.c $(C_SUBDIR)/*/*/*.c)
C_SRCS := $(foreach src,$(C_SRCS_IN),$(if $(findstring .inc.c,$(src)),,$(src)))
C_OBJS := $(patsubst $(C_SUBDIR)/%.c,$(C_BUILDDIR)/%.o,$(C_SRCS))
@@ -178,11 +202,11 @@ OBJS := $(C_OBJS) $(GFLIB_OBJS) $(C_ASM_OBJS) $(ASM_OBJS) $(DATA_ASM_OBJS) $
OBJS_REL := $(patsubst $(OBJ_DIR)/%,%,$(OBJS))
SUBDIRS := $(sort $(dir $(OBJS)))
+$(shell mkdir -p $(SUBDIRS))
+endif
AUTO_GEN_TARGETS :=
-$(shell mkdir -p $(SUBDIRS))
-
all: rom
tools: $(TOOLDIRS)
@@ -196,7 +220,7 @@ ifeq ($(COMPARE),1)
endif
# For contributors to make sure a change didn't affect the contents of the ROM.
-compare: ; @$(MAKE) COMPARE=1
+compare: all
clean: mostlyclean clean-tools
@@ -270,48 +294,80 @@ else
$(C_BUILDDIR)/librfu_intr.o: CFLAGS := -mthumb-interwork -O2 -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -fno-toplevel-reorder -Wno-pointer-to-int-cast
endif
-ifeq ($(NODEP),1)
-$(C_BUILDDIR)/%.o: c_dep :=
-else
-$(C_BUILDDIR)/%.o: c_dep = $(shell [[ -f $(C_SUBDIR)/$*.c ]] && $(SCANINC) -I include -I tools/agbcc/include -I gflib $(C_SUBDIR)/$*.c)
-endif
-
ifeq ($(DINFO),1)
override CFLAGS += -g
endif
-$(C_BUILDDIR)/%.o : $(C_SUBDIR)/%.c $$(c_dep)
+# The dep rules have to be explicit or else missing files won't be reported.
+# As a side effect, they're evaluated immediately instead of when the rule is invoked.
+# It doesn't look like $(shell) can be deferred so there might not be a better way.
+
+ifeq ($(SCAN_DEPS),1)
+ifeq ($(NODEP),1)
+$(C_BUILDDIR)/%.o: $(C_SUBDIR)/%.c
+ifeq (,$(KEEP_TEMPS))
+ @echo "$(CC1) <flags> -o $@ $<"
+ @$(CPP) $(CPPFLAGS) $< | $(PREPROC) $< charmap.txt -i | $(CC1) $(CFLAGS) -o - - | cat - <(echo -e ".text\n\t.align\t2, 0") | $(AS) $(ASFLAGS) -o $@ -
+else
@$(CPP) $(CPPFLAGS) $< -o $(C_BUILDDIR)/$*.i
@$(PREPROC) $(C_BUILDDIR)/$*.i charmap.txt | $(CC1) $(CFLAGS) -o $(C_BUILDDIR)/$*.s
@echo -e ".text\n\t.align\t2, 0\n" >> $(C_BUILDDIR)/$*.s
$(AS) $(ASFLAGS) -o $@ $(C_BUILDDIR)/$*.s
-
-ifeq ($(NODEP),1)
-$(GFLIB_BUILDDIR)/%.o: c_dep :=
+endif
else
-$(GFLIB_BUILDDIR)/%.o: c_dep = $(shell [[ -f $(GFLIB_SUBDIR)/$*.c ]] && $(SCANINC) -I include -I tools/agbcc/include -I gflib $(GFLIB_SUBDIR)/$*.c)
+define C_DEP
+$1: $2 $$(shell $(SCANINC) -I include -I tools/agbcc/include -I gflib $2)
+ifeq (,$$(KEEP_TEMPS))
+ @echo "$$(CC1) <flags> -o $$@ $$<"
+ @$$(CPP) $$(CPPFLAGS) $$< | $$(PREPROC) $$< charmap.txt -i | $$(CC1) $$(CFLAGS) -o - - | cat - <(echo -e ".text\n\t.align\t2, 0") | $$(AS) $$(ASFLAGS) -o $$@ -
+else
+ @$$(CPP) $$(CPPFLAGS) $$< -o $$(C_BUILDDIR)/$3.i
+ @$$(PREPROC) $$(C_BUILDDIR)/$3.i charmap.txt | $$(CC1) $$(CFLAGS) -o $$(C_BUILDDIR)/$3.s
+ @echo -e ".text\n\t.align\t2, 0\n" >> $$(C_BUILDDIR)/$3.s
+ $$(AS) $$(ASFLAGS) -o $$@ $$(C_BUILDDIR)/$3.s
+endif
+endef
+$(foreach src, $(C_SRCS), $(eval $(call C_DEP,$(patsubst $(C_SUBDIR)/%.c,$(C_BUILDDIR)/%.o,$(src)),$(src),$(patsubst $(C_SUBDIR)/%.c,%,$(src)))))
endif
-$(GFLIB_BUILDDIR)/%.o : $(GFLIB_SUBDIR)/%.c $$(c_dep)
+ifeq ($(NODEP),1)
+$(GFLIB_BUILDDIR)/%.o: $(GFLIB_SUBDIR)/%.c $$(c_dep)
+ifeq (,$(KEEP_TEMPS))
+ @echo "$(CC1) <flags> -o $@ $<"
+ @$(CPP) $(CPPFLAGS) $< | $(PREPROC) $< charmap.txt -i | $(CC1) $(CFLAGS) -o - - | cat - <(echo -e ".text\n\t.align\t2, 0") | $(AS) $(ASFLAGS) -o $@ -
+else
@$(CPP) $(CPPFLAGS) $< -o $(GFLIB_BUILDDIR)/$*.i
@$(PREPROC) $(GFLIB_BUILDDIR)/$*.i charmap.txt | $(CC1) $(CFLAGS) -o $(GFLIB_BUILDDIR)/$*.s
@echo -e ".text\n\t.align\t2, 0\n" >> $(GFLIB_BUILDDIR)/$*.s
$(AS) $(ASFLAGS) -o $@ $(GFLIB_BUILDDIR)/$*.s
+endif
+else
+define GFLIB_DEP
+$1: $2 $$(shell $(SCANINC) -I include -I tools/agbcc/include -I gflib $2)
+ifeq (,$$(KEEP_TEMPS))
+ @echo "$$(CC1) <flags> -o $$@ $$<"
+ @$$(CPP) $$(CPPFLAGS) $$< | $$(PREPROC) $$< charmap.txt -i | $$(CC1) $$(CFLAGS) -o - - | cat - <(echo -e ".text\n\t.align\t2, 0") | $$(AS) $$(ASFLAGS) -o $$@ -
+else
+ @$$(CPP) $$(CPPFLAGS) $$< -o $$(GFLIB_BUILDDIR)/$3.i
+ @$$(PREPROC) $$(GFLIB_BUILDDIR)/$3.i charmap.txt | $$(CC1) $$(CFLAGS) -o $$(GFLIB_BUILDDIR)/$3.s
+ @echo -e ".text\n\t.align\t2, 0\n" >> $$(GFLIB_BUILDDIR)/$3.s
+ $$(AS) $$(ASFLAGS) -o $$@ $$(GFLIB_BUILDDIR)/$3.s
+endif
+endef
+$(foreach src, $(GFLIB_SRCS), $(eval $(call GFLIB_DEP,$(patsubst $(GFLIB_SUBDIR)/%.c,$(GFLIB_BUILDDIR)/%.o, $(src)),$(src),$(patsubst $(GFLIB_SUBDIR)/%.c,%, $(src)))))
+endif
ifeq ($(NODEP),1)
-$(C_BUILDDIR)/%.o: c_asm_dep :=
+$(C_BUILDDIR)/%.o: $(C_SUBDIR)/%.s
+ $(PREPROC) $< charmap.txt | $(CPP) -I include - | $(AS) $(ASFLAGS) -o $@
else
-$(C_BUILDDIR)/%.o: c_asm_dep = $(shell [[ -f $(C_SUBDIR)/$*.s ]] && $(SCANINC) -I "" $(C_SUBDIR)/$*.s)
+define SRC_ASM_DATA_DEP
+$1: $2 $$(shell $(SCANINC) -I include -I "" $2)
+ $$(PREPROC) $$< charmap.txt | $$(CPP) -I include - | $$(AS) $$(ASFLAGS) -o $$@
+endef
+$(foreach src, $(C_ASM_SRCS), $(eval $(call SRC_ASM_DATA_DEP,$(patsubst $(C_SUBDIR)/%.s,$(C_BUILDDIR)/%.o, $(src)),$(src))))
endif
-$(C_BUILDDIR)/%.o: $(C_SUBDIR)/%.s $$(c_asm_dep)
- $(AS) $(ASFLAGS) -o $@ $<
-
-# The dep rules have to be explicit or else missing files won't be reported.
-# As a side effect, they're evaluated immediately instead of when the rule is invoked.
-# It doesn't look like $(shell) can be deferred so there might not be a better way.
-
-
ifeq ($(NODEP),1)
$(ASM_BUILDDIR)/%.o: $(ASM_SUBDIR)/%.s
$(AS) $(ASFLAGS) -o $@ $<
@@ -327,12 +383,8 @@ ifeq ($(NODEP),1)
$(DATA_ASM_BUILDDIR)/%.o: $(DATA_ASM_SUBDIR)/%.s
$(PREPROC) $< charmap.txt | $(CPP) -I include - | $(AS) $(ASFLAGS) -o $@
else
-define DATA_ASM_DEP
-$1: $2 $$(shell $(SCANINC) -I include -I "" $2)
- $$(PREPROC) $$< charmap.txt | $$(CPP) -I include - | $$(AS) $$(ASFLAGS) -o $$@
-endef
-$(foreach src, $(REGULAR_DATA_ASM_SRCS), $(eval $(call DATA_ASM_DEP,$(patsubst $(DATA_ASM_SUBDIR)/%.s,$(DATA_ASM_BUILDDIR)/%.o, $(src)),$(src))))
-$(foreach src, $(C_ASM_SRCS), $(eval $(call DATA_ASM_DEP,$(patsubst $(C_SUBDIR)/%.s,$(C_BUILDDIR)/%.o, $(src)),$(src))))
+$(foreach src, $(REGULAR_DATA_ASM_SRCS), $(eval $(call SRC_ASM_DATA_DEP,$(patsubst $(DATA_ASM_SUBDIR)/%.s,$(DATA_ASM_BUILDDIR)/%.o, $(src)),$(src))))
+endif
endif
$(SONG_BUILDDIR)/%.o: $(SONG_SUBDIR)/%.s
@@ -367,7 +419,7 @@ $(ROM): $(ELF)
$(OBJCOPY) -O binary $< $@
$(FIX) $@ -p --silent
-modern: ; @$(MAKE) MODERN=1
+modern: all
berry_fix/berry_fix.gba: berry_fix
diff --git a/make_tools.mk b/make_tools.mk
new file mode 100644
index 000000000..697897a69
--- /dev/null
+++ b/make_tools.mk
@@ -0,0 +1,11 @@
+
+MAKEFLAGS += --no-print-directory
+
+TOOLDIRS := $(filter-out tools/agbcc tools/binutils,$(wildcard tools/*))
+
+.PHONY: all $(TOOLDIRS)
+
+all: $(TOOLDIRS)
+
+$(TOOLDIRS):
+ @$(MAKE) -C $@
diff --git a/tools/preproc/c_file.cpp b/tools/preproc/c_file.cpp
index b996a048c..17a08cc9f 100644
--- a/tools/preproc/c_file.cpp
+++ b/tools/preproc/c_file.cpp
@@ -23,32 +23,59 @@
#include <stdexcept>
#include <string>
#include <memory>
+#include <cstring>
+#include <cerrno>
#include "preproc.h"
#include "c_file.h"
#include "char_util.h"
#include "utf8.h"
#include "string_parser.h"
-CFile::CFile(std::string filename) : m_filename(filename)
+CFile::CFile(const char * filenameCStr, bool isStdin)
{
- FILE *fp = std::fopen(filename.c_str(), "rb");
+ FILE *fp;
+
+ if (isStdin) {
+ fp = stdin;
+ m_filename = std::string{"<stdin>/"}.append(filenameCStr);
+ } else {
+ fp = std::fopen(filenameCStr, "rb");
+ m_filename = std::string(filenameCStr);
+ }
+
+ std::string& filename = m_filename;
if (fp == NULL)
FATAL_ERROR("Failed to open \"%s\" for reading.\n", filename.c_str());
- std::fseek(fp, 0, SEEK_END);
-
- m_size = std::ftell(fp);
+ m_size = 0;
+ m_buffer = (char *)malloc(CHUNK_SIZE + 1);
+ if (m_buffer == NULL) {
+ FATAL_ERROR("Failed to allocate memory to process file \"%s\"!", filename.c_str());
+ }
- if (m_size < 0)
- FATAL_ERROR("File size of \"%s\" is less than zero.\n", filename.c_str());
+ std::size_t numAllocatedBytes = CHUNK_SIZE + 1;
+ std::size_t bufferOffset = 0;
+ std::size_t count;
- m_buffer = new char[m_size + 1];
+ while ((count = std::fread(m_buffer + bufferOffset, 1, CHUNK_SIZE, fp)) != 0) {
+ if (!std::ferror(fp)) {
+ m_size += count;
- std::rewind(fp);
+ if (std::feof(fp)) {
+ break;
+ }
- if (std::fread(m_buffer, m_size, 1, fp) != 1)
- FATAL_ERROR("Failed to read \"%s\".\n", filename.c_str());
+ numAllocatedBytes += CHUNK_SIZE;
+ bufferOffset += CHUNK_SIZE;
+ m_buffer = (char *)realloc(m_buffer, numAllocatedBytes);
+ if (m_buffer == NULL) {
+ FATAL_ERROR("Failed to allocate memory to process file \"%s\"!", filename.c_str());
+ }
+ } else {
+ FATAL_ERROR("Failed to read \"%s\". (error: %s)", filename.c_str(), std::strerror(errno));
+ }
+ }
m_buffer[m_size] = 0;
@@ -56,6 +83,7 @@ CFile::CFile(std::string filename) : m_filename(filename)
m_pos = 0;
m_lineNum = 1;
+ m_isStdin = isStdin;
}
CFile::CFile(CFile&& other) : m_filename(std::move(other.m_filename))
@@ -64,13 +92,14 @@ CFile::CFile(CFile&& other) : m_filename(std::move(other.m_filename))
m_pos = other.m_pos;
m_size = other.m_size;
m_lineNum = other.m_lineNum;
+ m_isStdin = other.m_isStdin;
- other.m_buffer = nullptr;
+ other.m_buffer = NULL;
}
CFile::~CFile()
{
- delete[] m_buffer;
+ free(m_buffer);
}
void CFile::Preproc()
diff --git a/tools/preproc/c_file.h b/tools/preproc/c_file.h
index 7369aba85..49e633a18 100644
--- a/tools/preproc/c_file.h
+++ b/tools/preproc/c_file.h
@@ -30,7 +30,7 @@
class CFile
{
public:
- CFile(std::string filename);
+ CFile(const char * filenameCStr, bool isStdin);
CFile(CFile&& other);
CFile(const CFile&) = delete;
~CFile();
@@ -42,6 +42,7 @@ private:
long m_size;
long m_lineNum;
std::string m_filename;
+ bool m_isStdin;
bool ConsumeHorizontalWhitespace();
bool ConsumeNewline();
@@ -55,4 +56,6 @@ private:
void RaiseWarning(const char* format, ...);
};
+#define CHUNK_SIZE 4096
+
#endif // C_FILE_H
diff --git a/tools/preproc/preproc.cpp b/tools/preproc/preproc.cpp
index c9c6042df..eb2d4c8a2 100644
--- a/tools/preproc/preproc.cpp
+++ b/tools/preproc/preproc.cpp
@@ -103,9 +103,9 @@ void PreprocAsmFile(std::string filename)
}
}
-void PreprocCFile(std::string filename)
+void PreprocCFile(const char * filename, bool isStdin)
{
- CFile cFile(filename);
+ CFile cFile(filename, isStdin);
cFile.Preproc();
}
@@ -132,9 +132,9 @@ char* GetFileExtension(char* filename)
int main(int argc, char **argv)
{
- if (argc != 3)
+ if (argc < 3 || argc > 4)
{
- std::fprintf(stderr, "Usage: %s SRC_FILE CHARMAP_FILE", argv[0]);
+ std::fprintf(stderr, "Usage: %s SRC_FILE CHARMAP_FILE [-i]\nwhere -i denotes if input is from stdin\n", argv[0]);
return 1;
}
@@ -147,9 +147,17 @@ int main(int argc, char **argv)
if ((extension[0] == 's') && extension[1] == 0)
PreprocAsmFile(argv[1]);
- else if ((extension[0] == 'c' || extension[0] == 'i') && extension[1] == 0)
- PreprocCFile(argv[1]);
- else
+ else if ((extension[0] == 'c' || extension[0] == 'i') && extension[1] == 0) {
+ if (argc == 4) {
+ if (argv[3][0] == '-' && argv[3][1] == 'i' && argv[3][2] == '\0') {
+ PreprocCFile(argv[1], true);
+ } else {
+ FATAL_ERROR("unknown argument flag \"%s\".\n", argv[3]);
+ }
+ } else {
+ PreprocCFile(argv[1], false);
+ }
+ } else
FATAL_ERROR("\"%s\" has an unknown file extension of \"%s\".\n", argv[1], extension);
return 0;