1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-23 19:29:37 +00:00

Added dependency file generation to the assembler. This includes two new

options, --create-dep and --create-full-dep. The latter will include files
that are passed via debug info to the assembler.


git-svn-id: svn://svn.cc65.org/cc65/trunk@4653 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz 2010-05-01 11:59:55 +00:00
parent 96cf7f6271
commit 3fd52eb57f
9 changed files with 290 additions and 98 deletions

View File

@ -87,40 +87,42 @@ The assembler accepts the following options:
---------------------------------------------------------------------------
Usage: ca65 [options] file
Short options:
-D name[=value] Define a symbol
-I dir Set an include directory search path
-U Mark unresolved symbols as import
-V Print the assembler version
-W n Set warning level n
-g Add debug info to object file
-h Help (this text)
-i Ignore case of symbols
-l Create a listing if assembly was ok
-mm model Set the memory model
-o name Name the output file
-s Enable smart mode
-t sys Set the target system
-v Increase verbosity
-D name[=value] Define a symbol
-I dir Set an include directory search path
-U Mark unresolved symbols as import
-V Print the assembler version
-W n Set warning level n
-g Add debug info to object file
-h Help (this text)
-i Ignore case of symbols
-l Create a listing if assembly was ok
-mm model Set the memory model
-o name Name the output file
-s Enable smart mode
-t sys Set the target system
-v Increase verbosity
Long options:
--auto-import Mark unresolved symbols as import
--bin-include-dir dir Set a search path for binary includes
--cpu type Set cpu type
--debug-info Add debug info to object file
--feature name Set an emulation feature
--forget-inc-paths Forget include search paths
--help Help (this text)
--ignore-case Ignore case of symbols
--include-dir dir Set an include directory search path
--listing Create a listing if assembly was ok
--list-bytes n Maximum number of bytes per listing line
--macpack-dir dir Set a macro package directory
--memory-model model Set the memory model
--pagelength n Set the page length for the listing
--smart Enable smart mode
--target sys Set the target system
--verbose Increase verbosity
--version Print the assembler version
--auto-import Mark unresolved symbols as import
--bin-include-dir dir Set a search path for binary includes
--cpu type Set cpu type
--create-dep name Create a make dependency file
--create-full-dep name Create a full make dependency file
--debug-info Add debug info to object file
--feature name Set an emulation feature
--forget-inc-paths Forget include search paths
--help Help (this text)
--ignore-case Ignore case of symbols
--include-dir dir Set an include directory search path
--listing Create a listing if assembly was ok
--list-bytes n Maximum number of bytes per listing line
--macpack-dir dir Set a macro package directory
--memory-model model Set the memory model
--pagelength n Set the page length for the listing
--smart Enable smart mode
--target sys Set the target system
--verbose Increase verbosity
--version Print the assembler version
---------------------------------------------------------------------------
</verb></tscreen>
@ -153,6 +155,24 @@ Here is a description of all the command line options:
instruction set is "proprietary and confidential".
<label id="option-create-dep">
<tag><tt>--create-dep name</tt></tag>
Tells the assembler to generate a file containing the dependency list for
the assembled module in makefile syntax. The output is written to a file
with the given name. The output does not include files passed via debug
information to the assembler.
<label id="option-create-full-dep">
<tag><tt>--create-full-dep name</tt></tag>
Tells the assembler to generate a file containing the dependency list for
the assembled module in makefile syntax. The output is written to a file
with the given name. The output does include files passed via debug
information to the assembler.
<label id="option--feature">
<tag><tt>--feature name</tt></tag>

View File

@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 2000-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* (C) 2000-2010, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
@ -85,7 +85,7 @@ void DbgInfoFile (void)
MTime = ConstExpression ();
/* Insert the file into the table */
AddFile (&Name, Size, MTime);
AddFile (&Name, FT_DBGINFO, Size, MTime);
/* Free memory used for Name */
SB_Done (&Name);

View File

@ -33,7 +33,9 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
/* common */
#include "check.h"
@ -44,6 +46,7 @@
/* ca65 */
#include "error.h"
#include "filetab.h"
#include "global.h"
#include "objfile.h"
#include "spool.h"
@ -88,6 +91,7 @@ struct FileEntry {
HashNode Node;
unsigned Name; /* File name */
unsigned Index; /* Index of entry */
FileType Type; /* Type of file */
unsigned long Size; /* Size of file */
unsigned long MTime; /* Time of last modification */
};
@ -155,7 +159,8 @@ static int HT_Compare (const void* Key1, const void* Key2)
static FileEntry* NewFileEntry (unsigned Name, unsigned long Size, unsigned long MTime)
static FileEntry* NewFileEntry (unsigned Name, FileType Type,
unsigned long Size, unsigned long MTime)
/* Create a new FileEntry, insert it into the tables and return it */
{
/* Allocate memory for the entry */
@ -165,6 +170,7 @@ static FileEntry* NewFileEntry (unsigned Name, unsigned long Size, unsigned long
InitHashNode (&F->Node, F);
F->Name = Name;
F->Index = CollCount (&FileTab) + 1; /* First file has index #1 */
F->Type = Type;
F->Size = Size;
F->MTime = MTime;
@ -183,7 +189,7 @@ static FileEntry* NewFileEntry (unsigned Name, unsigned long Size, unsigned long
const StrBuf* GetFileName (unsigned Name)
/* Get the name of a file where the name index is known */
{
static StrBuf ErrorMsg = LIT_STRBUF_INITIALIZER ("(outside file scope)");
static const StrBuf ErrorMsg = LIT_STRBUF_INITIALIZER ("(outside file scope)");
const FileEntry* F;
@ -226,13 +232,14 @@ unsigned GetFileIndex (const StrBuf* Name)
unsigned AddFile (const StrBuf* Name, unsigned long Size, unsigned long MTime)
unsigned AddFile (const StrBuf* Name, FileType Type,
unsigned long Size, unsigned long MTime)
/* Add a new file to the list of input files. Return the index of the file in
* the table.
*/
{
/* Create a new file entry and insert it into the tables */
FileEntry* F = NewFileEntry (GetStrBufId (Name), Size, MTime);
FileEntry* F = NewFileEntry (GetStrBufId (Name), Type, Size, MTime);
/* Return the index */
return F->Index;
@ -267,4 +274,79 @@ void WriteFiles (void)
static void WriteDep (FILE* F, FileType Types)
/* Helper function. Writes all file names that match Types to the output */
{
unsigned I;
/* Loop over all files */
for (I = 0; I < CollCount (&FileTab); ++I) {
const StrBuf* Filename;
/* Get the next input file */
const FileEntry* E = (const FileEntry*) CollAt (&FileTab, I);
/* Ignore it if it is not of the correct type */
if ((E->Type & Types) == 0) {
continue;
}
/* If this is not the first file, add a space */
if (I > 0) {
fputc (' ', F);
}
/* Print the dependency */
Filename = GetStrBuf (E->Name);
fprintf (F, "%*s", SB_GetLen (Filename), SB_GetConstBuf (Filename));
}
}
static void CreateDepFile (const char* Name, FileType 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", OutFile);
/* 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),
FT_MAIN | FT_INCLUDE | FT_BINARY);
}
if (SB_NotEmpty (&FullDepName)) {
CreateDepFile (SB_GetConstBuf (&FullDepName),
FT_MAIN | FT_INCLUDE | FT_BINARY | FT_DBGINFO);
}
}

View File

@ -43,6 +43,24 @@
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* 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 {
FT_MAIN = 0x01, /* Main input file */
FT_INCLUDE = 0x02, /* Normal include file */
FT_BINARY = 0x04, /* Binary include file */
FT_DBGINFO = 0x08, /* File from debug info */
} FileType;
/*****************************************************************************/
/* Code */
/*****************************************************************************/
@ -55,7 +73,8 @@ const StrBuf* GetFileName (unsigned Name);
unsigned GetFileIndex (const StrBuf* Name);
/* Return the file index for the given file name. */
unsigned AddFile (const StrBuf* Name, unsigned long Size, unsigned long MTime);
unsigned AddFile (const StrBuf* Name, FileType Type,
unsigned long Size, unsigned long MTime);
/* Add a new file to the list of input files. Return the index of the file in
* the table.
*/
@ -63,6 +82,8 @@ unsigned AddFile (const StrBuf* Name, unsigned long Size, unsigned long MTime);
void WriteFiles (void);
/* Write the list of input files to the object file */
void CreateDependencies (void);
/* Create dependency files requested by the user */

View File

@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 1998-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* (C) 1998-2010, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
@ -51,6 +51,8 @@
const char* InFile = 0; /* Name of input file */
const char* OutFile = 0; /* Name of output file */
const char* ListFile = 0; /* Name of listing file */
StrBuf DepName = STATIC_STRBUF_INITIALIZER; /* Dependency file */
StrBuf FullDepName = STATIC_STRBUF_INITIALIZER; /* Full dependency file */
/* Default extensions */
const char ObjExt[] = ".o";/* Default object extension */

View File

@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 1998-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* (C) 1998-2010, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
@ -38,6 +38,11 @@
/* common */
#include "strbuf.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
@ -48,6 +53,8 @@
extern const char* InFile; /* Name of input file */
extern const char* OutFile; /* Name of output file */
extern const char* ListFile; /* Name of listing file */
extern StrBuf DepName; /* Name of dependencies file */
extern StrBuf FullDepName; /* Name of full dependencies file */
/* Default extensions */
extern const char ObjExt[]; /* Default object extension */

View File

@ -89,40 +89,42 @@ static void Usage (void)
{
printf ("Usage: %s [options] file\n"
"Short options:\n"
" -D name[=value]\tDefine a symbol\n"
" -I dir\t\tSet an include directory search path\n"
" -U\t\t\tMark unresolved symbols as import\n"
" -V\t\t\tPrint the assembler version\n"
" -W n\t\t\tSet warning level n\n"
" -g\t\t\tAdd debug info to object file\n"
" -h\t\t\tHelp (this text)\n"
" -i\t\t\tIgnore case of symbols\n"
" -l\t\t\tCreate a listing if assembly was ok\n"
" -mm model\t\tSet the memory model\n"
" -o name\t\tName the output file\n"
" -s\t\t\tEnable smart mode\n"
" -t sys\t\tSet the target system\n"
" -v\t\t\tIncrease verbosity\n"
" -D name[=value]\t\tDefine a symbol\n"
" -I dir\t\t\tSet an include directory search path\n"
" -U\t\t\t\tMark unresolved symbols as import\n"
" -V\t\t\t\tPrint the assembler version\n"
" -W n\t\t\t\tSet warning level n\n"
" -g\t\t\t\tAdd debug info to object file\n"
" -h\t\t\t\tHelp (this text)\n"
" -i\t\t\t\tIgnore case of symbols\n"
" -l\t\t\t\tCreate a listing if assembly was ok\n"
" -mm model\t\t\tSet the memory model\n"
" -o name\t\t\tName the output file\n"
" -s\t\t\t\tEnable smart mode\n"
" -t sys\t\t\tSet the target system\n"
" -v\t\t\t\tIncrease verbosity\n"
"\n"
"Long options:\n"
" --auto-import\t\tMark unresolved symbols as import\n"
" --bin-include-dir dir\tSet a search path for binary includes\n"
" --cpu type\t\tSet cpu type\n"
" --debug-info\t\tAdd debug info to object file\n"
" --feature name\tSet an emulation feature\n"
" --forget-inc-paths\tForget include search paths\n"
" --help\t\tHelp (this text)\n"
" --ignore-case\t\tIgnore case of symbols\n"
" --include-dir dir\tSet an include directory search path\n"
" --listing\t\tCreate a listing if assembly was ok\n"
" --list-bytes n\tMaximum number of bytes per listing line\n"
" --macpack-dir dir\tSet a macro package directory\n"
" --memory-model model\tSet the memory model\n"
" --pagelength n\tSet the page length for the listing\n"
" --smart\t\tEnable smart mode\n"
" --target sys\t\tSet the target system\n"
" --verbose\t\tIncrease verbosity\n"
" --version\t\tPrint the assembler version\n",
" --auto-import\t\t\tMark unresolved symbols as import\n"
" --bin-include-dir dir\t\tSet a search path for binary includes\n"
" --cpu type\t\t\tSet cpu type\n"
" --create-dep name\t\tCreate a make dependency file\n"
" --create-full-dep name\tCreate a full make dependency file\n"
" --debug-info\t\t\tAdd debug info to object file\n"
" --feature name\t\tSet an emulation feature\n"
" --forget-inc-paths\t\tForget include search paths\n"
" --help\t\t\tHelp (this text)\n"
" --ignore-case\t\t\tIgnore case of symbols\n"
" --include-dir dir\t\tSet an include directory search path\n"
" --listing\t\t\tCreate a listing if assembly was ok\n"
" --list-bytes n\t\tMaximum number of bytes per listing line\n"
" --macpack-dir dir\t\tSet a macro package directory\n"
" --memory-model model\t\tSet the memory model\n"
" --pagelength n\t\tSet the page length for the listing\n"
" --smart\t\t\tEnable smart mode\n"
" --target sys\t\t\tSet the target system\n"
" --verbose\t\t\tIncrease verbosity\n"
" --version\t\t\tPrint the assembler version\n",
ProgName);
}
@ -281,6 +283,20 @@ static void SetSys (const char* Sys)
static void FileNameOption (const char* Opt, const char* Arg, StrBuf* Name)
/* Handle an option that remembers a file name for later */
{
/* Cannot have the option twice */
if (SB_NotEmpty (Name)) {
AbEnd ("Cannot use option `%s' twice", Opt);
}
/* Remember the file name for later */
SB_CopyStr (Name, Arg);
SB_Terminate (Name);
}
static void DefineSymbol (const char* Def)
/* Define a symbol from the command line */
{
@ -363,6 +379,23 @@ static void OptCPU (const char* Opt attribute ((unused)), const char* Arg)
static void OptCreateDep (const char* Opt, const char* Arg)
/* Handle the --create-dep option */
{
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);
}
static void OptDebugInfo (const char* Opt attribute ((unused)),
const char* Arg attribute ((unused)))
/* Add debug info to the object file */
@ -796,6 +829,8 @@ int main (int argc, char* argv [])
{ "--auto-import", 0, OptAutoImport },
{ "--bin-include-dir", 1, OptBinIncludeDir },
{ "--cpu", 1, OptCPU },
{ "--create-dep", 1, OptCreateDep },
{ "--create-full-dep", 1, OptCreateFullDep },
{ "--debug-info", 0, OptDebugInfo },
{ "--feature", 1, OptFeature },
{ "--forget-inc-paths", 0, OptForgetIncPaths },
@ -958,7 +993,7 @@ int main (int argc, char* argv [])
/* If we didn't have any errors, check the pseudo insn stacks */
if (ErrorCount == 0) {
CheckPseudo ();
CheckPseudo ();
}
/* If we didn't have any errors, check the unnamed labels */
@ -990,12 +1025,15 @@ int main (int argc, char* argv [])
SegDump ();
}
/* If we didn't have any errors, create the object and listing files */
/* If we didn't have any errors, create the object, listing and
* dependency files
*/
if (ErrorCount == 0) {
CreateObjFile ();
if (Listing) {
CreateListing ();
}
CreateObjFile ();
if (Listing) {
CreateListing ();
}
CreateDependencies ();
}
/* Close the input file */

View File

@ -38,6 +38,8 @@
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <sys/types.h> /* EMX needs this */
#include <sys/stat.h>
/* common */
#include "assertion.h"
@ -58,6 +60,7 @@
#include "error.h"
#include "expr.h"
#include "feature.h"
#include "filetab.h"
#include "global.h"
#include "incpath.h"
#include "instr.h"
@ -1086,6 +1089,7 @@ static void DoIncBin (void)
/* Include a binary file */
{
StrBuf Name = STATIC_STRBUF_INITIALIZER;
struct stat StatBuf;
long Start = 0L;
long Count = -1L;
long Size;
@ -1122,26 +1126,42 @@ static void DoIncBin (void)
if (PathName == 0 || (F = fopen (PathName, "rb")) == 0) {
/* Not found or cannot open, print an error and bail out */
ErrorSkip ("Cannot open include file `%m%p': %s", &Name, strerror (errno));
xfree (PathName);
goto ExitPoint;
}
/* Remember the new file name */
SB_CopyStr (&Name, PathName);
/* Free the allocated memory */
xfree (PathName);
/* If we had an error before, bail out now */
if (F == 0) {
goto ExitPoint;
}
}
/* Get the size of the file */
fseek (F, 0, SEEK_END);
Size = ftell (F);
/* Stat the file and remember the values. There a race condition here,
* since we cannot use fileno() (non standard identifier in standard
* header file), and therefore not fstat. When using stat with the
* file name, there's a risk that the file was deleted and recreated
* while it was open. Since mtime and size are only used to check
* if a file has changed in the debugger, we will ignore this problem
* here.
*/
SB_Terminate (&Name);
if (stat (SB_GetConstBuf (&Name), &StatBuf) != 0) {
Fatal ("Cannot stat input file `%m%p': %s", &Name, strerror (errno));
}
/* Add the file to the input file table */
AddFile (&Name, FT_BINARY, Size, StatBuf.st_mtime);
/* If a count was not given, calculate it now */
if (Count < 0) {
Count = Size - Start;
if (Count < 0) {
/* Nothing to read - flag this as a range error */
Count = Size - Start;
if (Count < 0) {
/* Nothing to read - flag this as a range error */
ErrorSkip ("Range error");
goto Done;
}

View File

@ -347,7 +347,7 @@ static void DoneCharSource (void)
/*****************************************************************************/
/* InputFile functions */
/*****************************************************************************/
static void IFMarkStart (CharSource* S)
@ -488,7 +488,9 @@ int NewInputFile (const char* Name)
}
/* Add the file to the input file table and remember the index */
FileIdx = AddFile (SB_InitFromString (&NameBuf, Name), Buf.st_size, Buf.st_mtime);
FileIdx = AddFile (SB_InitFromString (&NameBuf, Name),
(FCount == 0)? FT_MAIN : FT_INCLUDE,
Buf.st_size, Buf.st_mtime);
/* Create a new input source variable and initialize it */
S = xmalloc (sizeof (*S));