Changed generation of makefile dependencies:

* There are now two options, --create-dep and --create-full-dep. One
    will add system includes, the other not.
  * Both options require a file name. This is an incompatible change(!)
    but has the advantage that the user is in control of extension and
    path of the generated file.
  * Output will always include a phony target for the input files. This
    may not work with all make programs.


git-svn-id: svn://svn.cc65.org/cc65/trunk@4652 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz 2010-05-01 09:42:12 +00:00
parent 54740da820
commit 96cf7f6271
7 changed files with 263 additions and 179 deletions

View file

@ -53,6 +53,7 @@ Usage: cc65 [options] file
Short options: Short options:
-Cl Make local variables static -Cl Make local variables static
-Dsym[=defn] Define a symbol -Dsym[=defn] Define a symbol
-E Stop after the preprocessing stage
-I dir Set an include directory search path -I dir Set an include directory search path
-O Optimize code -O Optimize code
-Oi Optimize code, inline more code -Oi Optimize code, inline more code
@ -60,11 +61,12 @@ Short options:
-Os Inline some known functions -Os Inline some known functions
-T Include source as comment -T Include source as comment
-V Print the compiler version number -V Print the compiler version number
-W name[,name] Enable or disable warnings -W Suppress warnings
-d Debug mode -d Debug mode
-g Add debug info to object file -g Add debug info to object file
-h Help (this text) -h Help (this text)
-j Default characters are signed -j Default characters are signed
-mm model Set the memory model
-o name Name the output file -o name Name the output file
-r Enable register variables -r Enable register variables
-t sys Set the target system -t sys Set the target system
@ -76,15 +78,21 @@ Long options:
--check-stack Generate stack overflow checks --check-stack Generate stack overflow checks
--code-name seg Set the name of the CODE segment --code-name seg Set the name of the CODE segment
--codesize x Accept larger code by factor x --codesize x Accept larger code by factor x
--cpu type Set cpu type --cpu type Set cpu type (6502, 65c02)
--create-dep Create a make dependency file --create-dep name Create a make dependency file
--create-full-dep name Create a full make dependency file
--data-name seg Set the name of the DATA segment --data-name seg Set the name of the DATA segment
--debug Debug mode --debug Debug mode
--debug-info Add debug info to object file --debug-info Add debug info to object file
--debug-opt name Debug optimization steps
--disable-opt name Disable an optimization step
--enable-opt name Enable an optimization step
--forget-inc-paths Forget include search paths --forget-inc-paths Forget include search paths
--help Help (this text) --help Help (this text)
--include-dir dir Set an include directory search path --include-dir dir Set an include directory search path
--list-opt-steps List all optimizer steps and exit
--local-strings Emit string literals immediately --local-strings Emit string literals immediately
--memory-model model Set the memory model
--register-space b Set space available for register variables --register-space b Set space available for register variables
--register-vars Enable register variables --register-vars Enable register variables
--rodata-name seg Set the name of the RODATA segment --rodata-name seg Set the name of the RODATA segment
@ -139,20 +147,29 @@ Here is a description of all the command line options:
<label id="option-cpu"> <label id="option-cpu">
<tag><tt>--cpu CPU</tt></tag> <tag><tt>--cpu CPU</tt></tag>
A new, still experimental option. You may specify "6502" or "65C02" as A new, still experimental option. You may specify "6502" or "65C02" as the
the CPU. 6502 is the default, so this will not change anything. CPU. 6502 is the default, so this will not change anything. Specifying 65C02
Specifying 65C02 will use a few 65C02 instructions when generating code. will use a few 65C02 instructions when generating code. Don't expect too
Don't expect too much from this option: It is still new (and may have much from this option: It is still new (and may have bugs), and the
bugs), and the additional instructions for the 65C02 are not that additional instructions for the 65C02 are not that overwhelming.
overwhelming.
<label id="option-create-dep"> <label id="option-create-dep">
<tag><tt>--create-dep</tt></tag> <tag><tt>--create-dep name</tt></tag>
Tells the compiler to generate a file containing the dependency list for Tells the compiler to generate a file containing the dependency list for the
the compiled module in makefile syntax. The file is named as the C input compiled module in makefile syntax. The output is written to a file with the
file with the extension replaced by <tt/.u/. given name. The output does not include system include files (in angle
brackets).
<label id="option-create-full-dep">
<tag><tt>--create-full-dep name</tt></tag>
Tells the compiler to generate a file containing the dependency list for the
compiled module in makefile syntax. The output is written to a file with the
given name. The output does include system include files (in angle
brackets).
<label id="option-data-name"> <label id="option-data-name">

View file

@ -6,7 +6,7 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2009, Ullrich von Bassewitz */ /* (C) 1998-2010, Ullrich von Bassewitz */
/* Roemerstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
@ -45,7 +45,6 @@
unsigned char AddSource = 0; /* Add source lines as comments */ unsigned char AddSource = 0; /* Add source lines as comments */
unsigned char DebugInfo = 0; /* Add debug info to the obj */ unsigned char DebugInfo = 0; /* Add debug info to the obj */
unsigned char CreateDep = 0; /* Create a dependency file */
unsigned char PreprocessOnly = 0; /* Just preprocess the input */ unsigned char PreprocessOnly = 0; /* Just preprocess the input */
unsigned RegisterSpace = 6; /* Space available for register vars */ unsigned RegisterSpace = 6; /* Space available for register vars */
@ -62,4 +61,9 @@ IntStack CheckStack = INTSTACK(0); /* Generate stack overflow checks */
IntStack Optimize = INTSTACK(0); /* Optimize flag */ IntStack Optimize = INTSTACK(0); /* Optimize flag */
IntStack CodeSizeFactor = INTSTACK(100);/* Size factor for generated code */ IntStack CodeSizeFactor = INTSTACK(100);/* Size factor for generated code */
/* File names */
StrBuf DepName = STATIC_STRBUF_INITIALIZER; /* Name of dependencies file */
StrBuf FullDepName = STATIC_STRBUF_INITIALIZER; /* Name of full dependencies file */

View file

@ -6,7 +6,7 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2009, Ullrich von Bassewitz */ /* (C) 1998-2010, Ullrich von Bassewitz */
/* Roemerstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
@ -40,6 +40,7 @@
/* common */ /* common */
#include "intstack.h" #include "intstack.h"
#include "strbuf.h"
@ -52,7 +53,6 @@
/* Options */ /* Options */
extern unsigned char AddSource; /* Add source lines as comments */ extern unsigned char AddSource; /* Add source lines as comments */
extern unsigned char DebugInfo; /* Add debug info to the obj */ extern unsigned char DebugInfo; /* Add debug info to the obj */
extern unsigned char CreateDep; /* Create a dependency file */
extern unsigned char PreprocessOnly; /* Just preprocess the input */ extern unsigned char PreprocessOnly; /* Just preprocess the input */
extern unsigned RegisterSpace; /* Space available for register vars */ extern unsigned RegisterSpace; /* Space available for register vars */
@ -69,6 +69,10 @@ extern IntStack CheckStack; /* Generate stack overflow checks */
extern IntStack Optimize; /* Optimize flag */ extern IntStack Optimize; /* Optimize flag */
extern IntStack CodeSizeFactor; /* Size factor for generated code */ extern IntStack CodeSizeFactor; /* Size factor for generated code */
/* File names */
extern StrBuf DepName; /* Name of dependencies file */
extern StrBuf FullDepName; /* Name of full dependencies file */
/* End of global.h */ /* End of global.h */

View file

@ -43,14 +43,17 @@
#include "check.h" #include "check.h"
#include "coll.h" #include "coll.h"
#include "print.h" #include "print.h"
#include "strbuf.h"
#include "xmalloc.h" #include "xmalloc.h"
/* cc65 */ /* cc65 */
#include "codegen.h" #include "codegen.h"
#include "error.h" #include "error.h"
#include "global.h"
#include "incpath.h" #include "incpath.h"
#include "lineinfo.h"
#include "input.h" #include "input.h"
#include "lineinfo.h"
#include "output.h"
@ -60,6 +63,15 @@
/* An enum that describes different types of input files. The members are
* choosen so that it is possible to combine them to bitsets
*/
typedef enum {
IT_MAIN = 0x01, /* Main input file */
IT_SYSINC = 0x02, /* System include file (using <>) */
IT_USERINC = 0x04, /* User include file (using "") */
} InputType;
/* The current input line */ /* The current input line */
StrBuf* Line; StrBuf* Line;
@ -70,6 +82,17 @@ char NextC = '\0';
/* Maximum count of nested includes */ /* Maximum count of nested includes */
#define MAX_INC_NESTING 16 #define MAX_INC_NESTING 16
/* Struct that describes an input file */
typedef struct IFile IFile;
struct IFile {
unsigned Index; /* File index */
unsigned Usage; /* Usage counter */
unsigned long Size; /* File size */
unsigned long MTime; /* Time of last modification */
InputType Type; /* Type of input file */
char Name[1]; /* Name of file (dynamically allocated) */
};
/* Struct that describes an active input file */ /* Struct that describes an active input file */
typedef struct AFile AFile; typedef struct AFile AFile;
struct AFile { struct AFile {
@ -490,6 +513,14 @@ int NextLine (void)
const char* GetInputFile (const struct IFile* IF)
/* Return a filename from an IFile struct */
{
return IF->Name;
}
const char* GetCurrentFile (void) const char* GetCurrentFile (void)
/* Return the name of the current input file */ /* Return the name of the current input file */
{ {
@ -526,30 +557,77 @@ unsigned GetCurrentLine (void)
void WriteDependencies (FILE* F, const char* OutputFile) static void WriteDep (FILE* F, InputType Types)
/* Write a makefile dependency list to the given file */ /* Helper function. Writes all file names that match Types to the output */
{ {
unsigned I; unsigned I;
/* Get the number of input files */
unsigned IFileCount = CollCount (&IFiles);
/* Print the output file followed by a tab char */
fprintf (F, "%s:\t", OutputFile);
/* Loop over all files */ /* Loop over all files */
for (I = 0; I < IFileCount; ++I) { unsigned FileCount = CollCount (&IFiles);
for (I = 0; I < FileCount; ++I) {
/* Get the next input file */ /* Get the next input file */
const IFile* IF = (const IFile*) CollAt (&IFiles, I); const IFile* IF = (const IFile*) CollAt (&IFiles, I);
/* If this is not the first file, add a space */
const char* Format = (I == 0)? "%s" : " %s"; /* Ignore it if it is not of the correct type */
/* Print the dependency */ if ((IF->Type & Types) == 0) {
fprintf (F, Format, IF->Name); continue;
} }
/* End the line */ /* If this is not the first file, add a space */
fprintf (F, "\n\n"); if (I > 0) {
fputc (' ', F);
}
/* Print the dependency */
fputs (IF->Name, F);
}
} }
static void CreateDepFile (const char* Name, InputType Types)
/* Create a dependency file with the given name and place dependencies for
* all files with the given types there.
*/
{
/* Open the file */
FILE* F = fopen (Name, "w");
if (F == 0) {
Fatal ("Cannot open dependency file `%s': %s", Name, strerror (errno));
}
/* Print the output file followed by a tab char */
fprintf (F, "%s:\t", OutputFilename);
/* Write out the dependencies for the output file */
WriteDep (F, Types);
fputs ("\n\n", F);
/* Write out a phony dependency for the included files */
WriteDep (F, Types);
fputs (":\n\n", F);
/* Close the file, check for errors */
if (fclose (F) != 0) {
remove (Name);
Fatal ("Cannot write to dependeny file (disk full?)");
}
}
void CreateDependencies (void)
/* Create dependency files requested by the user */
{
if (SB_NotEmpty (&DepName)) {
CreateDepFile (SB_GetConstBuf (&DepName),
IT_MAIN | IT_USERINC);
}
if (SB_NotEmpty (&FullDepName)) {
CreateDepFile (SB_GetConstBuf (&FullDepName),
IT_MAIN | IT_SYSINC | IT_USERINC);
}
}

View file

@ -51,12 +51,8 @@
/* An enum that describes different types of input files */ /* Forward for an IFile structure */
typedef enum { struct IFile;
IT_MAIN, /* Main input file */
IT_SYSINC, /* System include file (using <>) */
IT_USERINC, /* User include file (using "") */
} InputType;
/* The current input line */ /* The current input line */
extern StrBuf* Line; extern StrBuf* Line;
@ -65,17 +61,6 @@ extern StrBuf* Line;
extern char CurC; extern char CurC;
extern char NextC; extern char NextC;
/* Struct that describes an input file */
typedef struct IFile IFile;
struct IFile {
unsigned Index; /* File index */
unsigned Usage; /* Usage counter */
unsigned long Size; /* File size */
unsigned long MTime; /* Time of last modification */
InputType Type; /* Type of input file */
char Name[1]; /* Name of file (dynamically allocated) */
};
/*****************************************************************************/ /*****************************************************************************/
@ -107,14 +92,17 @@ StrBuf* InitLine (StrBuf* Buf);
int NextLine (void); int NextLine (void);
/* Get a line from the current input. Returns 0 on end of file. */ /* Get a line from the current input. Returns 0 on end of file. */
const char* GetInputFile (const struct IFile* IF);
/* Return a filename from an IFile struct */
const char* GetCurrentFile (void); const char* GetCurrentFile (void);
/* Return the name of the current input file */ /* Return the name of the current input file */
unsigned GetCurrentLine (void); unsigned GetCurrentLine (void);
/* Return the line number in the current input file */ /* Return the line number in the current input file */
void WriteDependencies (FILE* F, const char* OutputFile); void CreateDependencies (void);
/* Write a makefile dependency list to the given file */ /* Create dependency files requested by the user */

View file

@ -181,7 +181,7 @@ const char* GetInputName (const LineInfo* LI)
/* Return the file name from a line info */ /* Return the file name from a line info */
{ {
PRECONDITION (LI != 0); PRECONDITION (LI != 0);
return LI->InputFile->Name; return GetInputFile (LI->InputFile);
} }

View file

@ -6,7 +6,7 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000-2009, Ullrich von Bassewitz */ /* (C) 2000-2010, Ullrich von Bassewitz */
/* Roemerstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
@ -82,57 +82,58 @@ static void Usage (void)
{ {
printf ("Usage: %s [options] file\n" printf ("Usage: %s [options] file\n"
"Short options:\n" "Short options:\n"
" -Cl\t\t\tMake local variables static\n" " -Cl\t\t\t\tMake local variables static\n"
" -Dsym[=defn]\t\tDefine a symbol\n" " -Dsym[=defn]\t\t\tDefine a symbol\n"
" -E\t\t\tStop after the preprocessing stage\n" " -E\t\t\t\tStop after the preprocessing stage\n"
" -I dir\t\tSet an include directory search path\n" " -I dir\t\t\tSet an include directory search path\n"
" -O\t\t\tOptimize code\n" " -O\t\t\t\tOptimize code\n"
" -Oi\t\t\tOptimize code, inline more code\n" " -Oi\t\t\t\tOptimize code, inline more code\n"
" -Or\t\t\tEnable register variables\n" " -Or\t\t\t\tEnable register variables\n"
" -Os\t\t\tInline some known functions\n" " -Os\t\t\t\tInline some known functions\n"
" -T\t\t\tInclude source as comment\n" " -T\t\t\t\tInclude source as comment\n"
" -V\t\t\tPrint the compiler version number\n" " -V\t\t\t\tPrint the compiler version number\n"
" -W\t\t\tSuppress warnings\n" " -W\t\t\t\tSuppress warnings\n"
" -d\t\t\tDebug mode\n" " -d\t\t\t\tDebug mode\n"
" -g\t\t\tAdd debug info to object file\n" " -g\t\t\t\tAdd debug info to object file\n"
" -h\t\t\tHelp (this text)\n" " -h\t\t\t\tHelp (this text)\n"
" -j\t\t\tDefault characters are signed\n" " -j\t\t\t\tDefault characters are signed\n"
" -mm model\t\tSet the memory model\n" " -mm model\t\t\tSet the memory model\n"
" -o name\t\tName the output file\n" " -o name\t\t\tName the output file\n"
" -r\t\t\tEnable register variables\n" " -r\t\t\t\tEnable register variables\n"
" -t sys\t\tSet the target system\n" " -t sys\t\t\tSet the target system\n"
" -v\t\t\tIncrease verbosity\n" " -v\t\t\t\tIncrease verbosity\n"
"\n" "\n"
"Long options:\n" "Long options:\n"
" --add-source\t\tInclude source as comment\n" " --add-source\t\t\tInclude source as comment\n"
" --bss-name seg\tSet the name of the BSS segment\n" " --bss-name seg\t\tSet the name of the BSS segment\n"
" --check-stack\t\tGenerate stack overflow checks\n" " --check-stack\t\t\tGenerate stack overflow checks\n"
" --code-name seg\tSet the name of the CODE segment\n" " --code-name seg\t\tSet the name of the CODE segment\n"
" --codesize x\t\tAccept larger code by factor x\n" " --codesize x\t\t\tAccept larger code by factor x\n"
" --cpu type\t\tSet cpu type (6502, 65c02)\n" " --cpu type\t\t\tSet cpu type (6502, 65c02)\n"
" --create-dep\t\tCreate a make dependency file\n" " --create-dep name\t\tCreate a make dependency file\n"
" --data-name seg\tSet the name of the DATA segment\n" " --create-full-dep name\tCreate a full make dependency file\n"
" --debug\t\tDebug mode\n" " --data-name seg\t\tSet the name of the DATA segment\n"
" --debug-info\t\tAdd debug info to object file\n" " --debug\t\t\tDebug mode\n"
" --debug-opt name\tDebug optimization steps\n" " --debug-info\t\t\tAdd debug info to object file\n"
" --disable-opt name\tDisable an optimization step\n" " --debug-opt name\t\tDebug optimization steps\n"
" --enable-opt name\tEnable an optimization step\n" " --disable-opt name\t\tDisable an optimization step\n"
" --forget-inc-paths\tForget include search paths\n" " --enable-opt name\t\tEnable an optimization step\n"
" --help\t\tHelp (this text)\n" " --forget-inc-paths\t\tForget include search paths\n"
" --include-dir dir\tSet an include directory search path\n" " --help\t\t\tHelp (this text)\n"
" --list-opt-steps\tList all optimizer steps and exit\n" " --include-dir dir\t\tSet an include directory search path\n"
" --local-strings\tEmit string literals immediately\n" " --list-opt-steps\t\tList all optimizer steps and exit\n"
" --memory-model model\tSet the memory model\n" " --local-strings\t\tEmit string literals immediately\n"
" --register-space b\tSet space available for register variables\n" " --memory-model model\t\tSet the memory model\n"
" --register-vars\tEnable register variables\n" " --register-space b\t\tSet space available for register variables\n"
" --rodata-name seg\tSet the name of the RODATA segment\n" " --register-vars\t\tEnable register variables\n"
" --signed-chars\tDefault characters are signed\n" " --rodata-name seg\t\tSet the name of the RODATA segment\n"
" --standard std\tLanguage standard (c89, c99, cc65)\n" " --signed-chars\t\tDefault characters are signed\n"
" --static-locals\tMake local variables static\n" " --standard std\t\tLanguage standard (c89, c99, cc65)\n"
" --target sys\t\tSet the target system\n" " --static-locals\t\tMake local variables static\n"
" --verbose\t\tIncrease verbosity\n" " --target sys\t\t\tSet the target system\n"
" --version\t\tPrint the compiler version number\n" " --verbose\t\t\tIncrease verbosity\n"
" --writable-strings\tMake string literals writable\n", " --version\t\t\tPrint the compiler version number\n"
" --writable-strings\t\tMake string literals writable\n",
ProgName); ProgName);
} }
@ -242,29 +243,16 @@ static void SetSys (const char* Sys)
static void DoCreateDep (const char* OutputName) static void FileNameOption (const char* Opt, const char* Arg, StrBuf* Name)
/* Create the dependency file */ /* Handle an option that remembers a file name for later */
{ {
/* Make the dependency file name from the output file name */ /* Cannot have the option twice */
char* DepName = MakeFilename (OutputName, ".u"); if (SB_NotEmpty (Name)) {
AbEnd ("Cannot use option `%s' twice", Opt);
/* Open the file */
FILE* F = fopen (DepName, "w");
if (F == 0) {
Fatal ("Cannot open dependency file `%s': %s", DepName, strerror (errno));
} }
/* Remember the file name for later */
/* Write the dependencies to the file */ SB_CopyStr (Name, Arg);
WriteDependencies (F, OutputName); SB_Terminate (Name);
/* Close the file, check for errors */
if (fclose (F) != 0) {
remove (DepName);
Fatal ("Cannot write to dependeny file (disk full?)");
}
/* Free the name */
xfree (DepName);
} }
@ -382,11 +370,19 @@ static void OptCodeSize (const char* Opt, const char* Arg)
static void OptCreateDep (const char* Opt attribute ((unused)), static void OptCreateDep (const char* Opt, const char* Arg)
const char* Arg attribute ((unused)))
/* Handle the --create-dep option */ /* Handle the --create-dep option */
{ {
CreateDep = 1; FileNameOption (Opt, Arg, &DepName);
}
static void OptCreateFullDep (const char* Opt attribute ((unused)),
const char* Arg)
/* Handle the --create-full-dep option */
{
FileNameOption (Opt, Arg, &FullDepName);
} }
@ -750,7 +746,8 @@ int main (int argc, char* argv[])
{ "--code-name", 1, OptCodeName }, { "--code-name", 1, OptCodeName },
{ "--codesize", 1, OptCodeSize }, { "--codesize", 1, OptCodeSize },
{ "--cpu", 1, OptCPU }, { "--cpu", 1, OptCPU },
{ "--create-dep", 0, OptCreateDep }, { "--create-dep", 1, OptCreateDep },
{ "--create-full-dep", 1, OptCreateFullDep },
{ "--data-name", 1, OptDataName }, { "--data-name", 1, OptDataName },
{ "--debug", 0, OptDebug }, { "--debug", 0, OptDebug },
{ "--debug-info", 0, OptDebugInfo }, { "--debug-info", 0, OptDebugInfo },
@ -963,11 +960,7 @@ int main (int argc, char* argv[])
CloseOutputFile (); CloseOutputFile ();
/* Create dependencies if requested */ /* Create dependencies if requested */
if (CreateDep) { CreateDependencies ();
DoCreateDep (OutputFilename);
Print (stdout, 1, "Creating dependeny file\n");
}
} }
/* Return an apropriate exit code */ /* Return an apropriate exit code */