mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Merge pull request #424 from ISSOtm/better_deps
Improve dependency generation
This commit is contained in:
@@ -35,6 +35,10 @@ extern struct sOptions DefaultOptions;
|
|||||||
extern struct sOptions CurrentOptions;
|
extern struct sOptions CurrentOptions;
|
||||||
|
|
||||||
extern FILE *dependfile;
|
extern FILE *dependfile;
|
||||||
|
extern char *tzTargetFileName;
|
||||||
|
extern bool oGeneratedMissingIncludes;
|
||||||
|
extern bool oFailedOnMissingInclude;
|
||||||
|
extern bool oGeneratePhonyDeps;
|
||||||
|
|
||||||
void opt_Push(void);
|
void opt_Push(void);
|
||||||
void opt_Pop(void);
|
void opt_Pop(void);
|
||||||
|
|||||||
@@ -1004,16 +1004,22 @@ set : T_LABEL T_POP_SET const
|
|||||||
include : T_POP_INCLUDE string
|
include : T_POP_INCLUDE string
|
||||||
{
|
{
|
||||||
fstk_RunInclude($2);
|
fstk_RunInclude($2);
|
||||||
|
if (oFailedOnMissingInclude)
|
||||||
|
YYACCEPT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
incbin : T_POP_INCBIN string
|
incbin : T_POP_INCBIN string
|
||||||
{
|
{
|
||||||
out_BinaryFile($2);
|
out_BinaryFile($2);
|
||||||
|
if (oFailedOnMissingInclude)
|
||||||
|
YYACCEPT;
|
||||||
}
|
}
|
||||||
| T_POP_INCBIN string comma uconst comma uconst
|
| T_POP_INCBIN string comma uconst comma uconst
|
||||||
{
|
{
|
||||||
out_BinaryFileSlice($2, $4, $6);
|
out_BinaryFileSlice($2, $4, $6);
|
||||||
|
if (oFailedOnMissingInclude)
|
||||||
|
YYACCEPT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@@ -325,6 +325,15 @@ void fstk_AddIncludePath(char *s)
|
|||||||
fatalerror("Include path too long '%s'", s);
|
fatalerror("Include path too long '%s'", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void printdep(const char *fileName)
|
||||||
|
{
|
||||||
|
if (dependfile) {
|
||||||
|
fprintf(dependfile, "%s: %s\n", tzTargetFileName, fileName);
|
||||||
|
if (oGeneratePhonyDeps)
|
||||||
|
fprintf(dependfile, "%s:\n", fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FILE *fstk_FindFile(char *fname, char **incPathUsed)
|
FILE *fstk_FindFile(char *fname, char **incPathUsed)
|
||||||
{
|
{
|
||||||
char path[_MAX_PATH];
|
char path[_MAX_PATH];
|
||||||
@@ -337,9 +346,7 @@ FILE *fstk_FindFile(char *fname, char **incPathUsed)
|
|||||||
f = fopen(fname, "rb");
|
f = fopen(fname, "rb");
|
||||||
|
|
||||||
if (f != NULL || errno != ENOENT) {
|
if (f != NULL || errno != ENOENT) {
|
||||||
if (dependfile)
|
printdep(fname);
|
||||||
fprintf(dependfile, "%s: %s\n", tzObjectname, fname);
|
|
||||||
|
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,10 +369,8 @@ FILE *fstk_FindFile(char *fname, char **incPathUsed)
|
|||||||
f = fopen(path, "rb");
|
f = fopen(path, "rb");
|
||||||
|
|
||||||
if (f != NULL || errno != ENOENT) {
|
if (f != NULL || errno != ENOENT) {
|
||||||
if (dependfile) {
|
printdep(path);
|
||||||
fprintf(dependfile, "%s: %s\n", tzObjectname,
|
|
||||||
path);
|
|
||||||
}
|
|
||||||
if (incPathUsed)
|
if (incPathUsed)
|
||||||
*incPathUsed = IncludePaths[i];
|
*incPathUsed = IncludePaths[i];
|
||||||
return f;
|
return f;
|
||||||
@@ -373,6 +378,8 @@ FILE *fstk_FindFile(char *fname, char **incPathUsed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
|
if (oGeneratedMissingIncludes)
|
||||||
|
printdep(fname);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,8 +391,13 @@ void fstk_RunInclude(char *tzFileName)
|
|||||||
char *incPathUsed = "";
|
char *incPathUsed = "";
|
||||||
FILE *f = fstk_FindFile(tzFileName, &incPathUsed);
|
FILE *f = fstk_FindFile(tzFileName, &incPathUsed);
|
||||||
|
|
||||||
if (f == NULL)
|
if (f == NULL) {
|
||||||
|
if (oGeneratedMissingIncludes) {
|
||||||
|
oFailedOnMissingInclude = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
err(1, "Unable to open included file '%s'", tzFileName);
|
err(1, "Unable to open included file '%s'", tzFileName);
|
||||||
|
}
|
||||||
|
|
||||||
pushcontext();
|
pushcontext();
|
||||||
nLineNo = 1;
|
nLineNo = 1;
|
||||||
|
|||||||
133
src/asm/main.c
133
src/asm/main.c
@@ -14,6 +14,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include "asm/symbol.h"
|
#include "asm/symbol.h"
|
||||||
#include "asm/fstack.h"
|
#include "asm/fstack.h"
|
||||||
@@ -46,6 +47,10 @@ uint32_t unionStart[128], unionSize[128];
|
|||||||
/* extern int yydebug; */
|
/* extern int yydebug; */
|
||||||
|
|
||||||
FILE *dependfile;
|
FILE *dependfile;
|
||||||
|
bool oGeneratedMissingIncludes;
|
||||||
|
bool oFailedOnMissingInclude;
|
||||||
|
bool oGeneratePhonyDeps;
|
||||||
|
char *tzTargetFileName;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Option stack
|
* Option stack
|
||||||
@@ -235,9 +240,32 @@ static void opt_ParseDefines(void)
|
|||||||
sym_AddString(cldefines[i], cldefines[i + 1]);
|
sym_AddString(cldefines[i], cldefines[i + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Escapes Make-special chars from a string */
|
||||||
|
static char *make_escape(const char *str)
|
||||||
|
{
|
||||||
|
char * const escaped_str = malloc(strlen(str) * 2 + 1);
|
||||||
|
char *dest = escaped_str;
|
||||||
|
|
||||||
|
if (escaped_str == NULL)
|
||||||
|
err(1, "%s: Failed to allocate memory", __func__);
|
||||||
|
|
||||||
|
while (*str) {
|
||||||
|
/* All dollars needs to be doubled */
|
||||||
|
if (*str == '$')
|
||||||
|
*dest++ = '$';
|
||||||
|
*dest++ = *str++;
|
||||||
|
}
|
||||||
|
*dest = '\0';
|
||||||
|
|
||||||
|
return escaped_str;
|
||||||
|
}
|
||||||
|
|
||||||
/* Short options */
|
/* Short options */
|
||||||
static char const *optstring = "b:D:Eg:hi:LM:o:p:r:VvW:w";
|
static char const *optstring = "b:D:Eg:hi:LM:o:p:r:VvW:w";
|
||||||
|
|
||||||
|
/* Variables for the long-only options */
|
||||||
|
static int depType; /* Variants of `-M` */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Equivalent long options
|
* Equivalent long options
|
||||||
* Please keep in the same order as short opts
|
* Please keep in the same order as short opts
|
||||||
@@ -249,29 +277,33 @@ static char const *optstring = "b:D:Eg:hi:LM:o:p:r:VvW:w";
|
|||||||
* over short opt matching
|
* over short opt matching
|
||||||
*/
|
*/
|
||||||
static struct option const longopts[] = {
|
static struct option const longopts[] = {
|
||||||
{ "binary-digits", required_argument, NULL, 'b' },
|
{ "binary-digits", required_argument, NULL, 'b' },
|
||||||
{ "define", required_argument, NULL, 'D' },
|
{ "define", required_argument, NULL, 'D' },
|
||||||
{ "export-all", no_argument, NULL, 'E' },
|
{ "export-all", no_argument, NULL, 'E' },
|
||||||
{ "gfx-chars", required_argument, NULL, 'g' },
|
{ "gfx-chars", required_argument, NULL, 'g' },
|
||||||
{ "halt-without-nop", no_argument, NULL, 'h' },
|
{ "halt-without-nop", no_argument, NULL, 'h' },
|
||||||
{ "include", required_argument, NULL, 'i' },
|
{ "include", required_argument, NULL, 'i' },
|
||||||
{ "preserve-ld", no_argument, NULL, 'L' },
|
{ "preserve-ld", no_argument, NULL, 'L' },
|
||||||
{ "dependfile", required_argument, NULL, 'M' },
|
{ "dependfile", required_argument, NULL, 'M' },
|
||||||
{ "output", required_argument, NULL, 'o' },
|
{ "MG", no_argument, &depType, 'G' },
|
||||||
{ "pad-value", required_argument, NULL, 'p' },
|
{ "MP", no_argument, &depType, 'P' },
|
||||||
{ "recursion-depth", required_argument, NULL, 'r' },
|
{ "MT", required_argument, &depType, 'T' },
|
||||||
{ "version", no_argument, NULL, 'V' },
|
{ "MQ", required_argument, &depType, 'Q' },
|
||||||
{ "verbose", no_argument, NULL, 'v' },
|
{ "output", required_argument, NULL, 'o' },
|
||||||
{ "warning", required_argument, NULL, 'W' },
|
{ "pad-value", required_argument, NULL, 'p' },
|
||||||
{ NULL, no_argument, NULL, 0 }
|
{ "recursion-depth", required_argument, NULL, 'r' },
|
||||||
|
{ "version", no_argument, NULL, 'V' },
|
||||||
|
{ "verbose", no_argument, NULL, 'v' },
|
||||||
|
{ "warning", required_argument, NULL, 'W' },
|
||||||
|
{ NULL, no_argument, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static void print_usage(void)
|
static void print_usage(void)
|
||||||
{
|
{
|
||||||
fputs(
|
fputs(
|
||||||
"Usage: rgbasm [-EhLVvw] [-b chars] [-D name[=value]] [-g chars] [-i path]\n"
|
"Usage: rgbasm [-EhLVvw] [-b chars] [-D name[=value]] [-g chars] [-i path]\n"
|
||||||
" [-M depend_file] [-o out_file] [-p pad_value] [-r depth]\n"
|
" [-M depend_file] [-MG] [-MP] [-MT target_file] [-MQ target_file]\n"
|
||||||
" [-W warning] <file> ...\n"
|
" [-o out_file] [-p pad_value] [-r depth] [-W warning] <file> ...\n"
|
||||||
"Useful options:\n"
|
"Useful options:\n"
|
||||||
" -E, --export-all export all labels\n"
|
" -E, --export-all export all labels\n"
|
||||||
" -M, --dependfile <path> set the output dependency file\n"
|
" -M, --dependfile <path> set the output dependency file\n"
|
||||||
@@ -306,6 +338,11 @@ int main(int argc, char *argv[])
|
|||||||
/* yydebug=1; */
|
/* yydebug=1; */
|
||||||
|
|
||||||
nMaxRecursionDepth = 64;
|
nMaxRecursionDepth = 64;
|
||||||
|
oGeneratePhonyDeps = false;
|
||||||
|
oGeneratedMissingIncludes = false;
|
||||||
|
oFailedOnMissingInclude = false;
|
||||||
|
tzTargetFileName = NULL;
|
||||||
|
size_t nTargetFileNameLen = 0;
|
||||||
|
|
||||||
DefaultOptions.gbgfx[0] = '0';
|
DefaultOptions.gbgfx[0] = '0';
|
||||||
DefaultOptions.gbgfx[1] = '1';
|
DefaultOptions.gbgfx[1] = '1';
|
||||||
@@ -361,10 +398,13 @@ int main(int argc, char *argv[])
|
|||||||
newopt.optimizeloads = false;
|
newopt.optimizeloads = false;
|
||||||
break;
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
dependfile = fopen(optarg, "w");
|
if (!strcmp("-", optarg))
|
||||||
|
dependfile = stdout;
|
||||||
|
else
|
||||||
|
dependfile = fopen(optarg, "w");
|
||||||
if (dependfile == NULL)
|
if (dependfile == NULL)
|
||||||
err(1, "Could not open dependfile %s", optarg);
|
err(1, "Could not open dependfile %s",
|
||||||
|
optarg);
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
out_SetFileName(optarg);
|
out_SetFileName(optarg);
|
||||||
@@ -397,6 +437,45 @@ int main(int argc, char *argv[])
|
|||||||
case 'w':
|
case 'w':
|
||||||
newopt.warnings = false;
|
newopt.warnings = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* Long-only options */
|
||||||
|
case 0:
|
||||||
|
if (depType) {
|
||||||
|
switch (depType) {
|
||||||
|
case 'G':
|
||||||
|
oGeneratedMissingIncludes = true;
|
||||||
|
break;
|
||||||
|
case 'P':
|
||||||
|
oGeneratePhonyDeps = true;
|
||||||
|
break;
|
||||||
|
case 'Q':
|
||||||
|
case 'T':
|
||||||
|
if (optind == argc)
|
||||||
|
errx(1, "-M%c takes a target file name argument",
|
||||||
|
depType);
|
||||||
|
ep = optarg;
|
||||||
|
if (depType == 'Q')
|
||||||
|
ep = make_escape(ep);
|
||||||
|
|
||||||
|
nTargetFileNameLen += strlen(ep) + 1;
|
||||||
|
tzTargetFileName =
|
||||||
|
realloc(tzTargetFileName,
|
||||||
|
nTargetFileNameLen + 1);
|
||||||
|
if (tzTargetFileName == NULL)
|
||||||
|
err(1, "Cannot append new file to target file list");
|
||||||
|
strcat(tzTargetFileName, ep);
|
||||||
|
if (depType == 'Q')
|
||||||
|
free(ep);
|
||||||
|
char *ptr = tzTargetFileName +
|
||||||
|
strlen(tzTargetFileName);
|
||||||
|
*ptr++ = ' ';
|
||||||
|
*ptr = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Unrecognized options */
|
||||||
default:
|
default:
|
||||||
print_usage();
|
print_usage();
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
@@ -405,6 +484,9 @@ int main(int argc, char *argv[])
|
|||||||
argc -= optind;
|
argc -= optind;
|
||||||
argv += optind;
|
argv += optind;
|
||||||
|
|
||||||
|
if (tzTargetFileName == NULL)
|
||||||
|
tzTargetFileName = tzObjectname;
|
||||||
|
|
||||||
opt_SetCurrentOptions(&newopt);
|
opt_SetCurrentOptions(&newopt);
|
||||||
|
|
||||||
DefaultOptions = CurrentOptions;
|
DefaultOptions = CurrentOptions;
|
||||||
@@ -422,10 +504,10 @@ int main(int argc, char *argv[])
|
|||||||
printf("Assembling %s\n", tzMainfile);
|
printf("Assembling %s\n", tzMainfile);
|
||||||
|
|
||||||
if (dependfile) {
|
if (dependfile) {
|
||||||
if (!tzObjectname)
|
if (!tzTargetFileName)
|
||||||
errx(1, "Dependency files can only be created if an output object file is specified.\n");
|
errx(1, "Dependency files can only be created if a target file is specified with either -o, -MQ or -MT.\n");
|
||||||
|
|
||||||
fprintf(dependfile, "%s: %s\n", tzObjectname, tzMainfile);
|
fprintf(dependfile, "%s: %s\n", tzTargetFileName, tzMainfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
nStartClock = clock();
|
nStartClock = clock();
|
||||||
@@ -447,6 +529,8 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (yyparse() != 0 || nbErrors != 0)
|
if (yyparse() != 0 || nbErrors != 0)
|
||||||
errx(1, "Assembly aborted (%ld errors)!", nbErrors);
|
errx(1, "Assembly aborted (%ld errors)!", nbErrors);
|
||||||
|
if (dependfile)
|
||||||
|
fclose(dependfile);
|
||||||
|
|
||||||
if (nIFDepth != 0)
|
if (nIFDepth != 0)
|
||||||
errx(1, "Unterminated IF construct (%ld levels)!", nIFDepth);
|
errx(1, "Unterminated IF construct (%ld levels)!", nIFDepth);
|
||||||
@@ -471,6 +555,9 @@ int main(int argc, char *argv[])
|
|||||||
(int)(60 / timespent * nTotalLines));
|
(int)(60 / timespent * nTotalLines));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (oFailedOnMissingInclude)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* If no path specified, don't write file */
|
/* If no path specified, don't write file */
|
||||||
if (tzObjectname != NULL)
|
if (tzObjectname != NULL)
|
||||||
out_WriteObject();
|
out_WriteObject();
|
||||||
|
|||||||
@@ -880,8 +880,13 @@ void out_BinaryFile(char *s)
|
|||||||
FILE *f;
|
FILE *f;
|
||||||
|
|
||||||
f = fstk_FindFile(s, NULL);
|
f = fstk_FindFile(s, NULL);
|
||||||
if (f == NULL)
|
if (f == NULL) {
|
||||||
|
if (oGeneratedMissingIncludes) {
|
||||||
|
oFailedOnMissingInclude = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
err(1, "Unable to open incbin file '%s'", s);
|
err(1, "Unable to open incbin file '%s'", s);
|
||||||
|
}
|
||||||
|
|
||||||
int32_t fsize;
|
int32_t fsize;
|
||||||
|
|
||||||
@@ -915,8 +920,13 @@ void out_BinaryFileSlice(char *s, int32_t start_pos, int32_t length)
|
|||||||
fatalerror("Number of bytes to read must be greater than zero");
|
fatalerror("Number of bytes to read must be greater than zero");
|
||||||
|
|
||||||
f = fstk_FindFile(s, NULL);
|
f = fstk_FindFile(s, NULL);
|
||||||
if (f == NULL)
|
if (f == NULL) {
|
||||||
|
if (oGeneratedMissingIncludes) {
|
||||||
|
oFailedOnMissingInclude = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
err(1, "Unable to open included file '%s'", s);
|
err(1, "Unable to open included file '%s'", s);
|
||||||
|
}
|
||||||
|
|
||||||
int32_t fsize;
|
int32_t fsize;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user