diff --git a/spec/code_libultra_gc.inc b/spec/code_libultra_gc.inc index 25839bc9177..dbe2a20442b 100644 --- a/spec/code_libultra_gc.inc +++ b/spec/code_libultra_gc.inc @@ -92,4 +92,3 @@ include "$(BUILD_DIR)/src/libultra/libc/llcvt.o" include "$(BUILD_DIR)/src/libultra/io/vigetcurrframebuf.o" include "$(BUILD_DIR)/src/libultra/io/spsetpc.o" - include "$(BUILD_DIR)/src/libc/sqrt.o" diff --git a/spec/code_libultra_ique.inc b/spec/code_libultra_ique.inc index e99152cf989..317d56baeed 100644 --- a/spec/code_libultra_ique.inc +++ b/spec/code_libultra_ique.inc @@ -101,7 +101,7 @@ include "$(BUILD_DIR)/src/libultra/gu/rotate.o" include "$(BUILD_DIR)/src/libultra/os/getcurrfaultedthread.o" include "$(BUILD_DIR)/src/libultra/bb/sk/skapi.o" -#ifndef COMPILER_GCC +#if !(defined(NON_MATCHING) && defined(COMPILER_GCC)) include "$(BUILD_DIR)/src/libultra/bb/sa/common.o" #endif include "$(BUILD_DIR)/src/libultra/io/motor.o" diff --git a/spec/code_libultra_n64.inc b/spec/code_libultra_n64.inc index 7535025d1ee..12046e00ab8 100644 --- a/spec/code_libultra_n64.inc +++ b/spec/code_libultra_n64.inc @@ -69,4 +69,3 @@ #endif include "$(BUILD_DIR)/src/libultra/io/vigetcurrframebuf.o" include "$(BUILD_DIR)/src/libultra/io/spsetpc.o" - include "$(BUILD_DIR)/src/libc/sqrt.o" diff --git a/spec/spec b/spec/spec index 766d1cbfa23..c7bad158122 100644 --- a/spec/spec +++ b/spec/spec @@ -4,6 +4,49 @@ #include "include/versions.h" +#ifdef NON_MATCHING +// For non-matching builds we allow some includes to be repeated, +// for simplicity compared to cluttering the matching parts of the spec. +// Note this doesn't mean there ends up being several copies in the ROM, +// instead only the first include of a file is considered and any subsequent one is skipped. +#if DEBUG_FEATURES +// boot +skip_duplicate_include "$(BUILD_DIR)/src/libu64/debug.o" +skip_duplicate_include "$(BUILD_DIR)/src/libultra/io/epiwrite.o" +skip_duplicate_include "$(BUILD_DIR)/src/libultra/io/vimodefpallan1.o" +skip_duplicate_include "$(BUILD_DIR)/src/libultra/libc/ldiv.o" +skip_duplicate_include "$(BUILD_DIR)/src/libultra/libc/string.o" +skip_duplicate_include "$(BUILD_DIR)/src/libultra/libc/xldtob.o" +skip_duplicate_include "$(BUILD_DIR)/src/libultra/libc/xlitob.o" +skip_duplicate_include "$(BUILD_DIR)/src/libultra/libc/xprintf.o" +// code +skip_duplicate_include "$(BUILD_DIR)/src/libu64/mtxuty-cvt.o" +skip_duplicate_include "$(BUILD_DIR)/src/libultra/io/contpfs.o" +skip_duplicate_include "$(BUILD_DIR)/src/libultra/io/contramread.o" +skip_duplicate_include "$(BUILD_DIR)/src/libultra/io/contramwrite.o" +skip_duplicate_include "$(BUILD_DIR)/src/libultra/io/crc.o" +skip_duplicate_include "$(BUILD_DIR)/src/libultra/io/pfsallocatefile.o" +skip_duplicate_include "$(BUILD_DIR)/src/libultra/io/pfschecker.o" +skip_duplicate_include "$(BUILD_DIR)/src/libultra/io/pfsdeletefile.o" +skip_duplicate_include "$(BUILD_DIR)/src/libultra/io/pfsfilestate.o" +skip_duplicate_include "$(BUILD_DIR)/src/libultra/io/pfsfindfile.o" +skip_duplicate_include "$(BUILD_DIR)/src/libultra/io/pfsfreeblocks.o" +skip_duplicate_include "$(BUILD_DIR)/src/libultra/io/pfsgetstatus.o" +skip_duplicate_include "$(BUILD_DIR)/src/libultra/io/pfsinitpak.o" +skip_duplicate_include "$(BUILD_DIR)/src/libultra/io/pfsisplug.o" +skip_duplicate_include "$(BUILD_DIR)/src/libultra/io/pfsreadwritefile.o" +skip_duplicate_include "$(BUILD_DIR)/src/libultra/io/pfsselectbank.o" +#if PLATFORM_IQUE +skip_duplicate_include "$(BUILD_DIR)/src/libultra/mgu/mtxl2f.o" +#endif +#endif +#ifdef COMPILER_GCC +skip_duplicate_include "$(BUILD_DIR)/src/libultra/libc/string.o" +skip_duplicate_include "$(BUILD_DIR)/src/libc/memset.o" +skip_duplicate_include "$(BUILD_DIR)/src/libc/memmove.o" +#endif +#endif + beginseg name "boot" @@ -67,7 +110,7 @@ beginseg #endif // libgcc -#if PLATFORM_IQUE && !defined(COMPILER_GCC) +#if PLATFORM_IQUE && !(defined(NON_MATCHING) && defined(COMPILER_GCC)) include "$(BUILD_DIR)/src/libgcc/__divdi3.o" include "$(BUILD_DIR)/src/libgcc/__moddi3.o" include "$(BUILD_DIR)/src/libgcc/__udivdi3.o" @@ -93,7 +136,7 @@ beginseg include "$(BUILD_DIR)/data/cic6105.o" // Extra files for non-matching debug builds -#if DEBUG_FEATURES +#if defined(NON_MATCHING) && DEBUG_FEATURES include "$(BUILD_DIR)/src/libu64/debug.o" include "$(BUILD_DIR)/src/libultra/io/epiwrite.o" include "$(BUILD_DIR)/src/libultra/io/vimodefpallan1.o" @@ -109,7 +152,7 @@ beginseg #endif // Functions that GCC-compiled code may depend on, placed in boot so they will always be loaded -#ifdef COMPILER_GCC +#if defined(NON_MATCHING) && defined(COMPILER_GCC) include "$(BUILD_DIR)/src/libultra/libc/string.o" include "$(BUILD_DIR)/src/libc/memset.o" include "$(BUILD_DIR)/src/libc/memmove.o" @@ -824,7 +867,7 @@ beginseg include "$(BUILD_DIR)/data/njpgdspMain.o" // Extra files for non-matching debug builds -#if DEBUG_FEATURES +#if defined(NON_MATCHING) && DEBUG_FEATURES include "$(BUILD_DIR)/src/libu64/mtxuty-cvt.o" include "$(BUILD_DIR)/src/libultra/io/contpfs.o" include "$(BUILD_DIR)/src/libultra/io/contramread.o" diff --git a/tools/mkldscript.c b/tools/mkldscript.c index 3351298838a..c78ea7099f0 100644 --- a/tools/mkldscript.c +++ b/tools/mkldscript.c @@ -12,6 +12,35 @@ struct Segment *g_segments; int g_segmentsCount; +static void check_duplicate_includes(void) +{ + bool has_duplicate = false; + for (int i = 0; i < g_segmentsCount; i++) { + for (int j = 0; j < g_segments[i].includesCount; j++) { + for (int m = i; m < g_segmentsCount; m++) { + for (int n = j + 1; n < g_segments[m].includesCount; n++) { + if (strcmp(g_segments[i].includes[j].fpath, g_segments[m].includes[n].fpath) == 0) { + if (!has_duplicate) { + fprintf(stderr, "Duplicate includes found!\n"); + has_duplicate = true; + } + if (i == m) { + fprintf(stderr, "%s is included twice in %s\n", + g_segments[i].includes[j].fpath, g_segments[i].name); + } else { + fprintf(stderr, "%s is included in both %s and %s\n", + g_segments[i].includes[j].fpath, g_segments[i].name, g_segments[m].name); + } + } + } + } + } + } + if (has_duplicate) { + util_fatal_error("Duplicate includes found! (see above)\n"); + } +} + static void write_includes(const struct Segment *seg, FILE *fout, const char *segments_dir, const char *section) { // Note sections contain a suffix wildcard as compilers other than IDO such as GCC may emit sections titled @@ -302,6 +331,8 @@ int main(int argc, char **argv) spec = util_read_whole_file(argv[1], &size); parse_rom_spec(spec, &g_segments, &g_segmentsCount); + check_duplicate_includes(); + ldout = fopen(argv[2], "w"); if (ldout == NULL) util_fatal_error("failed to open file '%s' for writing", argv[2]); diff --git a/tools/spec.c b/tools/spec.c index 187549ead75..e1ca637564c 100644 --- a/tools/spec.c +++ b/tools/spec.c @@ -141,6 +141,7 @@ static const char *const stmtNames[] = [STMT_name] = "name", [STMT_number] = "number", [STMT_romalign] = "romalign", + [STMT_skip_duplicate_include] = "skip_duplicate_include", [STMT_stack] = "stack", [STMT_increment] = "increment", [STMT_pad_text] = "pad_text", @@ -157,7 +158,7 @@ STMTId get_stmt_id_by_stmt_name(const char *stmtName, int lineNum) { return -1; } -bool parse_segment_statement(struct Segment *currSeg, STMTId stmt, char* args, int lineNum, const struct Segment *segments, int segment_count) { +bool parse_segment_statement(struct Segment *currSeg, STMTId stmt, char* args, int lineNum, const struct Segment *segments, int segment_count, char **skipDuplicateIncludes, int skipDuplicateIncludesCount) { // ensure no duplicates (except for 'include' or 'pad_text') if (stmt != STMT_include && stmt != STMT_pad_text && (currSeg->fields & (1 << stmt))) @@ -226,7 +227,19 @@ bool parse_segment_statement(struct Segment *currSeg, STMTId stmt, char* args, i } } + bool skipInclude; if (!inc_is_dup) { + skipInclude = false; + } else { + skipInclude = false; + for (int i = 0; i < skipDuplicateIncludesCount; i++) { + if (strcmp(skipDuplicateIncludes[i], inc) == 0) { + skipInclude = true; + } + } + } + + if (!skipInclude) { currSeg->includesCount++; currSeg->includes = realloc(currSeg->includes, currSeg->includesCount * sizeof(*currSeg->includes)); currSeg->includes[currSeg->includesCount - 1].fpath = inc; @@ -262,6 +275,9 @@ void parse_rom_spec(char *spec, struct Segment **segments, int *segment_count) struct Segment *currSeg = NULL; + char** skipDuplicateIncludes = NULL; + int skipDuplicateIncludesCount = 0; + // iterate over lines while (line[0] != 0) { @@ -280,7 +296,7 @@ void parse_rom_spec(char *spec, struct Segment **segments, int *segment_count) if (currSeg != NULL) { - bool segmentEnded = parse_segment_statement(currSeg, stmt, args, lineNum, *segments, *segment_count); + bool segmentEnded = parse_segment_statement(currSeg, stmt, args, lineNum, *segments, *segment_count, skipDuplicateIncludes, skipDuplicateIncludesCount); if (segmentEnded) { currSeg = NULL; } @@ -297,6 +313,12 @@ void parse_rom_spec(char *spec, struct Segment **segments, int *segment_count) case STMT_endseg: util_fatal_error("line %i: '%s' outside of a segment definition", lineNum, stmtName); break; + case STMT_skip_duplicate_include: + skipDuplicateIncludesCount++; + skipDuplicateIncludes = realloc(skipDuplicateIncludes, skipDuplicateIncludesCount * sizeof(*skipDuplicateIncludes)); + if (!parse_quoted_string(args, &skipDuplicateIncludes[skipDuplicateIncludesCount - 1])) + util_fatal_error("line %i: invalid filename", lineNum); + break; default: fprintf(stderr, "warning: '%s' is not implemented\n", stmtName); break; diff --git a/tools/spec.h b/tools/spec.h index 96ca6c16f67..dbce19281f9 100644 --- a/tools/spec.h +++ b/tools/spec.h @@ -17,6 +17,7 @@ typedef enum { STMT_name, STMT_number, STMT_romalign, + STMT_skip_duplicate_include, STMT_stack, STMT_increment, STMT_pad_text,