41ca4f63ee
X-SVN-Rev: 17296
445 lines
14 KiB
C
445 lines
14 KiB
C
/**************************************************************************
|
|
*
|
|
* Copyright (C) 2000-2005, International Business Machines
|
|
* Corporation and others. All Rights Reserved.
|
|
*
|
|
***************************************************************************
|
|
* file name: make.c
|
|
* encoding: ANSI X3.4 (1968)
|
|
* tab size: 8 (not used)
|
|
* indentation:4
|
|
*
|
|
* created on: 2000jul18
|
|
* created by: Vladimir Weinstein
|
|
* created on: 2000may17
|
|
* created by: Steven \u24C7 Loomis
|
|
* merged on: 2003sep14
|
|
* merged by: George Rhoten
|
|
* merged from nmake.c and gmake.c
|
|
*
|
|
* Emit a NMAKE or GNU makefile
|
|
*/
|
|
|
|
#include "unicode/utypes.h"
|
|
#include "unicode/putil.h"
|
|
#include "makefile.h"
|
|
#include "cstring.h"
|
|
#include <stdio.h>
|
|
|
|
#ifdef U_MAKE_IS_NMAKE
|
|
|
|
char linebuf[2048];
|
|
|
|
/* Write any setup/initialization stuff */
|
|
void
|
|
pkg_mak_writeHeader(FileStream *f, const UPKGOptions *o)
|
|
{
|
|
const char *appendVersion = NULL;
|
|
if(o->version && !uprv_strstr(o->shortName,o->version)) { /* do not append version if
|
|
already contained in the name */
|
|
appendVersion = o->version;
|
|
}
|
|
|
|
sprintf(linebuf, "## Makefile for %s (%s) created by pkgdata\n"
|
|
"## from ICU Version %s\n"
|
|
"\n",
|
|
o->shortName,
|
|
o->libName,
|
|
U_ICU_VERSION);
|
|
T_FileStream_writeLine(f, linebuf);
|
|
|
|
sprintf(linebuf, "NAME=%s%s\n"
|
|
"CNAME=%s\n"
|
|
"LIBNAME=%s\n"
|
|
"SRCDIR=%s\n"
|
|
"TARGETDIR=%s\n"
|
|
"TEMP_DIR=%s\n"
|
|
"MODE=%s\n"
|
|
"MAKEFILE=%s\n"
|
|
"ENTRYPOINT=%s\n"
|
|
"TARGET_VERSION=%s\n"
|
|
"MKINSTALLDIRS=mkdir\n"
|
|
"\n\n\n",
|
|
o->shortName,
|
|
(appendVersion ? appendVersion : ""),
|
|
o->cShortName,
|
|
o->libName,
|
|
o->srcDir,
|
|
o->targetDir,
|
|
o->tmpDir,
|
|
o->mode,
|
|
o->makeFile,
|
|
o->entryName,
|
|
o->version);
|
|
T_FileStream_writeLine(f, linebuf);
|
|
|
|
sprintf(linebuf, "## List files [%d] containing data files to process (note: - means stdin)\n"
|
|
"LISTFILES= ",
|
|
pkg_countCharList(o->fileListFiles));
|
|
T_FileStream_writeLine(f, linebuf);
|
|
|
|
pkg_writeCharListWrap(f, o->fileListFiles, " ", " \\\n", 0);
|
|
|
|
T_FileStream_writeLine(f, "\n\n\n");
|
|
|
|
sprintf(linebuf, "## Data Files [%d]\n"
|
|
"DATAFILES= ",
|
|
pkg_countCharList(o->files));
|
|
|
|
T_FileStream_writeLine(f, linebuf);
|
|
|
|
pkg_writeCharListWrap(f, o->files, " ", " \\\n", -1);
|
|
|
|
T_FileStream_writeLine(f, "\n\n\n");
|
|
|
|
sprintf(linebuf, "## Data File Paths [%d]\n"
|
|
"DATAFILEPATHS= ",
|
|
pkg_countCharList(o->filePaths));
|
|
|
|
T_FileStream_writeLine(f, linebuf);
|
|
|
|
pkg_writeCharListWrap(f, o->filePaths, " ", " \\\n", 1);
|
|
|
|
T_FileStream_writeLine(f, "\n\n\n");
|
|
|
|
}
|
|
|
|
/* Write a stanza in the makefile, with specified "target: parents... \n\n\tcommands" [etc] */
|
|
void
|
|
pkg_mak_writeStanza(FileStream *f, const UPKGOptions *o,
|
|
const char *target,
|
|
CharList* parents,
|
|
CharList* commands )
|
|
{
|
|
T_FileStream_write(f, target, (int32_t)uprv_strlen(target));
|
|
T_FileStream_write(f, " : ", 3);
|
|
pkg_writeCharList(f, parents, " ",1);
|
|
T_FileStream_write(f, "\n", 1);
|
|
|
|
if(commands)
|
|
{
|
|
T_FileStream_write(f, "\t", 1);
|
|
pkg_writeCharList(f, commands, "\n\t",0);
|
|
}
|
|
T_FileStream_write(f, "\n\n", 2);
|
|
}
|
|
|
|
/* write any cleanup/post stuff */
|
|
void
|
|
pkg_mak_writeFooter(FileStream *f, const UPKGOptions *o)
|
|
{
|
|
char buf[256];
|
|
sprintf(buf, "\n\n# End of makefile for %s [%s mode]\n\n", o->shortName, o->mode);
|
|
T_FileStream_write(f, buf, (int32_t)uprv_strlen(buf));
|
|
}
|
|
|
|
#else /* #ifdef U_MAKE_IS_NMAKE */
|
|
|
|
#include "cmemory.h"
|
|
#include "filestrm.h"
|
|
#include "toolutil.h"
|
|
#include "unewdata.h"
|
|
#include "uoptions.h"
|
|
#include "pkgtypes.h"
|
|
#include <string.h>
|
|
|
|
char linebuf[2048];
|
|
|
|
/* Write any setup/initialization stuff */
|
|
void
|
|
pkg_mak_writeHeader(FileStream *f, const UPKGOptions *o)
|
|
{
|
|
sprintf(linebuf, "## Makefile for %s created by pkgdata\n"
|
|
"## from ICU Version %s\n"
|
|
"\n",
|
|
o->shortName,
|
|
U_ICU_VERSION);
|
|
T_FileStream_writeLine(f, linebuf);
|
|
|
|
sprintf(linebuf, "NAME=%s\n"
|
|
"LIBNAME=%s\n"
|
|
"CNAME=%s\n"
|
|
"TARGETDIR=%s\n"
|
|
"TEMP_DIR=%s\n"
|
|
"srcdir=$(TEMP_DIR)\n"
|
|
"SRCDIR=%s\n"
|
|
"MODE=%s\n"
|
|
"MAKEFILE=%s\n"
|
|
"ENTRYPOINT=%s\n"
|
|
"include %s\n"
|
|
"\n\n\n",
|
|
o->shortName,
|
|
o->libName,
|
|
o->cShortName,
|
|
o->targetDir,
|
|
o->tmpDir,
|
|
o->srcDir,
|
|
o->mode,
|
|
o->makeFile,
|
|
o->entryName,
|
|
o->options);
|
|
T_FileStream_writeLine(f, linebuf);
|
|
|
|
/* TEMP_PATH and TARG_PATH will be empty if the respective dir is . */
|
|
/* Avoid //'s and .'s which confuse make ! */
|
|
if(!strcmp(o->tmpDir,"."))
|
|
{
|
|
T_FileStream_writeLine(f, "TEMP_PATH=\n");
|
|
}
|
|
else
|
|
{
|
|
T_FileStream_writeLine(f, "TEMP_PATH=$(TEMP_DIR)/\n");
|
|
}
|
|
|
|
if(!strcmp(o->targetDir,"."))
|
|
{
|
|
T_FileStream_writeLine(f, "TARG_PATH=\n");
|
|
}
|
|
else
|
|
{
|
|
T_FileStream_writeLine(f, "TARG_PATH=$(TARGETDIR)/\n");
|
|
}
|
|
|
|
sprintf(linebuf, "## List files [%u] containing data files to process (note: - means stdin)\n"
|
|
"LISTFILES= ",
|
|
(int)pkg_countCharList(o->fileListFiles));
|
|
T_FileStream_writeLine(f, linebuf);
|
|
|
|
pkg_writeCharListWrap(f, o->fileListFiles, " ", " \\\n",0);
|
|
|
|
T_FileStream_writeLine(f, "\n\n\n");
|
|
|
|
sprintf(linebuf, "## Data Files [%u]\n"
|
|
"DATAFILES= ",
|
|
(int)pkg_countCharList(o->files));
|
|
|
|
T_FileStream_writeLine(f, linebuf);
|
|
|
|
pkg_writeCharListWrap(f, o->files, " ", " \\\n",-1);
|
|
|
|
T_FileStream_writeLine(f, "\n\n\n");
|
|
|
|
sprintf(linebuf, "## Data File Paths [%u]\n"
|
|
"DATAFILEPATHS= ",
|
|
(int)pkg_countCharList(o->filePaths));
|
|
|
|
T_FileStream_writeLine(f, linebuf);
|
|
|
|
pkg_writeCharListWrap(f, o->filePaths, " ", " \\\n",0);
|
|
|
|
T_FileStream_writeLine(f, "\n\n\n");
|
|
|
|
}
|
|
|
|
/* Write a stanza in the makefile, with specified "target: parents... \n\n\tcommands" [etc] */
|
|
void
|
|
pkg_mak_writeStanza(FileStream *f, const UPKGOptions *o,
|
|
const char *target,
|
|
CharList* parents,
|
|
CharList* commands)
|
|
{
|
|
T_FileStream_write(f, target, uprv_strlen(target));
|
|
T_FileStream_write(f, " : ", 3);
|
|
pkg_writeCharList(f, parents, " ",0);
|
|
T_FileStream_write(f, "\n", 1);
|
|
|
|
if(commands)
|
|
{
|
|
T_FileStream_write(f, "\t", 1);
|
|
pkg_writeCharList(f, commands, "\n\t",0);
|
|
}
|
|
T_FileStream_write(f, "\n\n", 2);
|
|
}
|
|
|
|
/* write any cleanup/post stuff */
|
|
void
|
|
pkg_mak_writeFooter(FileStream *f, const UPKGOptions *o)
|
|
{
|
|
T_FileStream_writeLine(f, "\nrebuild: clean all\n");
|
|
}
|
|
|
|
|
|
void
|
|
pkg_mak_writeObjRules(UPKGOptions *o, FileStream *makefile, CharList **objects, const char* objSuffix)
|
|
{
|
|
const char *p, *baseName;
|
|
char *tmpPtr;
|
|
char tmp[1024];
|
|
char stanza[1024];
|
|
char cfile[1024];
|
|
CharList *oTail = NULL;
|
|
CharList *infiles;
|
|
CharList *parents = NULL, *commands = NULL;
|
|
int32_t genFileOffset = 0; /* offset from beginning of .c and .o file name, use to chop off package name for AS/400 */
|
|
static int serNo = 0; /* counter for numeric file names */
|
|
char serName[100];
|
|
|
|
if(o->embed) {
|
|
infiles = o->filePaths;
|
|
} else {
|
|
infiles = o->files; /* raw files - no paths other than tree paths */
|
|
}
|
|
|
|
#if defined (OS400)
|
|
if(infiles != NULL) {
|
|
baseName = findBasename(infiles->str);
|
|
p = uprv_strchr(baseName, '_');
|
|
if(p != NULL) {
|
|
genFileOffset = (p-baseName)+1; /* "package_" - name + underscore */
|
|
}
|
|
}
|
|
#endif
|
|
|
|
for(;infiles;infiles = infiles->next) {
|
|
if(o->embed) {
|
|
baseName = findBasename(infiles->str);
|
|
} else {
|
|
baseName = infiles->str; /* skip the icudt28b/ part */
|
|
}
|
|
p = uprv_strrchr(baseName, '.');
|
|
if( (p == NULL) || (*p == '\0' ) ) {
|
|
continue;
|
|
}
|
|
|
|
if(o->numeric) {
|
|
sprintf(serName, "t%04x", serNo++);
|
|
uprv_strcpy(tmp,serName);
|
|
uprv_strcat(tmp, objSuffix);
|
|
} else {
|
|
uprv_strncpy(tmp, baseName, p-baseName);
|
|
p++;
|
|
|
|
uprv_strcpy(tmp+(p-1-baseName), "_"); /* to append */
|
|
uprv_strcat(tmp, p);
|
|
uprv_strcat(tmp, objSuffix );
|
|
|
|
/* iSeries cannot have '-' in the .o objects. */
|
|
for( tmpPtr = tmp; *tmpPtr; tmpPtr++ ) {
|
|
if ( *tmpPtr == U_FILE_SEP_CHAR ) { /* map tree names with underscores */
|
|
*tmpPtr = '_';
|
|
}
|
|
if ( *tmpPtr == '-' ) {
|
|
*tmpPtr = '_';
|
|
}
|
|
}
|
|
}
|
|
|
|
*objects = pkg_appendToList(*objects, &oTail, uprv_strdup(tmp + genFileOffset)); /* Offset for AS/400 */
|
|
|
|
/* write source list */
|
|
uprv_strcpy(cfile,tmp);
|
|
uprv_strcpy(cfile+uprv_strlen(cfile)-uprv_strlen(objSuffix), ".c" ); /* replace .o with .c */
|
|
|
|
/* Make up parents.. */
|
|
if(!o->embed) {
|
|
char *parentPath;
|
|
parentPath = uprv_malloc(1+uprv_strlen(baseName) + uprv_strlen("$(SRCDIR)/"));
|
|
sprintf(parentPath, "$(SRCDIR)/%s", baseName);
|
|
parents = pkg_appendToList(parents, NULL, parentPath);
|
|
} else {
|
|
parents = pkg_appendToList(parents, NULL, uprv_strdup(infiles->str));
|
|
}
|
|
|
|
/* make up commands.. */
|
|
if(!o->embed) {
|
|
/* search for tree.. */
|
|
const char *tchar;
|
|
char tree[1024];
|
|
if((tchar=uprv_strchr(baseName, '/'))) {
|
|
tree[0]='_';
|
|
strncpy(tree+1,baseName,tchar-baseName);
|
|
tree[tchar-baseName+1]=0;
|
|
} else {
|
|
tree[0] = 0;
|
|
}
|
|
#ifdef OS400
|
|
sprintf(stanza, "$(INVOKE) $(GENCCODE) -n $(CNAME)%s -d $(TEMP_DIR) $(SRCDIR)/%s", tree, infiles->str);
|
|
#else
|
|
sprintf(stanza, "$(INVOKE) $(GENCCODE) -n $(CNAME)%s -d $(TEMP_DIR) $<", tree);
|
|
#endif
|
|
} else {
|
|
#ifdef OS400
|
|
sprintf(stanza, "$(INVOKE) $(GENCCODE) -d $(TEMP_DIR) %s", infiles->str);
|
|
#else
|
|
sprintf(stanza, "$(INVOKE) $(GENCCODE) -d $(TEMP_DIR) $<");
|
|
#endif
|
|
}
|
|
|
|
if(o->numeric) {
|
|
strcat(stanza, " -f ");
|
|
strcat(stanza,serName);
|
|
} else if(!o->embed && uprv_strchr(baseName, '/')) {
|
|
/* append actual file - ex: coll_en_res otherwise the tree name will be lost */
|
|
strcat(stanza, " -f ");
|
|
strncat(stanza, tmp, (strlen(tmp)-strlen(objSuffix)));
|
|
}
|
|
|
|
commands = pkg_appendToList(commands, NULL, uprv_strdup(stanza));
|
|
|
|
#ifdef OS400
|
|
/* This builds the file into one .c file */
|
|
sprintf(stanza, "@cat $(TEMP_PATH)%s >> $(TEMP_PATH)/$(NAME)all.c", cfile);
|
|
commands = pkg_appendToList(commands, NULL, uprv_strdup(stanza));
|
|
|
|
sprintf(stanza, "@$(RMV) $(TEMP_DIR)/%s", cfile);
|
|
commands = pkg_appendToList(commands, NULL, uprv_strdup(stanza));
|
|
|
|
T_FileStream_write(makefile, "\t", 1);
|
|
pkg_writeCharList(makefile, commands, "\n\t",0);
|
|
T_FileStream_write(makefile, "\n\n", 2);
|
|
#else
|
|
if(genFileOffset > 0) { /* for AS/400 */
|
|
sprintf(stanza, "@mv $(TEMP_PATH)%s $(TEMP_PATH)%s", cfile, cfile+genFileOffset);
|
|
commands = pkg_appendToList(commands, NULL, uprv_strdup(stanza));
|
|
}
|
|
|
|
sprintf(stanza, "@$(COMPILE.c) -o $@ $(TEMP_DIR)/%s", cfile+genFileOffset); /* for AS/400 */
|
|
commands = pkg_appendToList(commands, NULL, uprv_strdup(stanza));
|
|
|
|
sprintf(stanza, "@$(RMV) $(TEMP_DIR)/%s", cfile+genFileOffset);
|
|
commands = pkg_appendToList(commands, NULL, uprv_strdup(stanza));
|
|
|
|
sprintf(stanza, "$(TEMP_PATH)%s", tmp+genFileOffset); /* for AS/400 */
|
|
pkg_mak_writeStanza(makefile, o, stanza, parents, commands);
|
|
#endif
|
|
|
|
pkg_deleteList(parents);
|
|
pkg_deleteList(commands);
|
|
parents = NULL;
|
|
commands = NULL;
|
|
}
|
|
}
|
|
|
|
#endif /* #ifdef U_MAKE_IS_NMAKE */
|
|
|
|
void
|
|
pkg_mak_writeAssemblyHeader(FileStream *f, const UPKGOptions *o)
|
|
{
|
|
T_FileStream_writeLine(f, "\n");
|
|
T_FileStream_writeLine(f, "ifneq ($(GENCCODE_ASSEMBLY),)\n");
|
|
T_FileStream_writeLine(f, "\n");
|
|
T_FileStream_writeLine(f, "BASE_OBJECTS=$(NAME)_dat.o\n");
|
|
T_FileStream_writeLine(f, "\n");
|
|
T_FileStream_writeLine(f, "$(TEMP_DIR)/$(NAME).dat: $(CMNLIST) $(DATAFILEPATHS)\n");
|
|
if(!o->embed) {
|
|
T_FileStream_writeLine(f, "\t$(INVOKE) $(GENCMN) -c -e $(ENTRYPOINT) -n $(NAME) -s $(SRCDIR) -t dat -d $(TEMP_DIR) 0 $(CMNLIST)\n");
|
|
} else {
|
|
T_FileStream_writeLine(f, "\t$(INVOKE) $(GENCMN) -c -e $(ENTRYPOINT) -n $(NAME) -E -t dat -d $(TEMP_DIR) 0 $(CMNLIST)\n");
|
|
}
|
|
T_FileStream_writeLine(f, "\n");
|
|
T_FileStream_writeLine(f, "$(TEMP_DIR)/$(NAME)_dat.o : $(TEMP_DIR)/$(NAME).dat\n");
|
|
T_FileStream_writeLine(f, "\t$(INVOKE) $(GENCCODE) $(GENCCODE_ASSEMBLY) -n $(NAME) -e $(ENTRYPOINT) -d $(TEMP_DIR) $<\n");
|
|
T_FileStream_writeLine(f, "\t$(COMPILE.c) $(DYNAMICCPPFLAGS) $(DYNAMICCXXFLAGS) -o $@ $(TEMP_DIR)/$(NAME)_dat"ASM_SUFFIX"\n");
|
|
T_FileStream_writeLine(f, "\t$(RMV) $(TEMP_DIR)/$(NAME)_dat"ASM_SUFFIX"\n");
|
|
T_FileStream_writeLine(f, "\n");
|
|
T_FileStream_writeLine(f, "else\n");
|
|
T_FileStream_writeLine(f, "\n");
|
|
}
|
|
|
|
void
|
|
pkg_mak_writeAssemblyFooter(FileStream *f, const UPKGOptions *o)
|
|
{
|
|
T_FileStream_writeLine(f, "\nendif\n");
|
|
}
|
|
|