ICU-1568 static mode

X-SVN-Rev: 7847
This commit is contained in:
Steven R. Loomis 2002-03-01 22:43:48 +00:00
parent 73325772ff
commit df88d97213
8 changed files with 249 additions and 8 deletions

View File

@ -32,7 +32,7 @@ CLEANFILES = *~ $(DEPS) $(RES_FILES) $(TEST_FILES) mkmap.tmp $(ALL_MAN_FILES)
TARGET = pkgdata
DEFS = @DEFS@
CPPFLAGS = @CPPFLAGS@ -I$(top_builddir)/common -I$(top_srcdir)/common -I$(srcdir)/../toolutil -DUDATA_SO_SUFFIX=\".$(SO)\"
CPPFLAGS = @CPPFLAGS@ -I$(top_builddir)/common -I$(top_srcdir)/common -I$(srcdir)/../toolutil -DUDATA_SO_SUFFIX=\".$(SO)\" -DSTATIC_O=\"$(STATIC_O)\"
CFLAGS = @CFLAGS@
CXXFLAGS = @CXXFLAGS@
ifeq ($(ENABLE_RPATH),YES)
@ -41,7 +41,7 @@ endif
LDFLAGS = @LDFLAGS@ $(RPATHLDFLAGS)
LIBS = $(LIBICUTOOLUTIL) $(LIBICUUC) @LIBS@ @LIB_M@
OBJECTS = pkgdata.o pkgtypes.o gmake.o dllmode.o cmnmode.o filemode.o
OBJECTS = pkgdata.o pkgtypes.o gmake.o dllmode.o cmnmode.o filemode.o staticmode.o
DEPS = $(OBJECTS:.o=.d)

View File

@ -25,7 +25,7 @@ char linebuf[2048];
void
pkg_mak_writeHeader(FileStream *f, const UPKGOptions *o)
{
sprintf(linebuf, "## Makefile for %s created by pkgtool\n"
sprintf(linebuf, "## Makefile for %s created by pkgdata\n"
"## from ICU Version %s\n"
"\n",
o->shortName,

View File

@ -46,6 +46,7 @@ extern void pkg_mode_windows(UPKGOptions *o, FileStream *makefile, UErrorCode *s
#else /*#ifdef WIN32*/
#ifdef UDATA_SO_SUFFIX
extern void pkg_mode_dll(UPKGOptions* o, FileStream *stream, UErrorCode *status);
extern void pkg_mode_static(UPKGOptions* o, FileStream *stream, UErrorCode *status);
#endif /*#ifdef UDATA_SO_SUFFIX*/
extern void pkg_mode_common(UPKGOptions* o, FileStream *stream, UErrorCode *status);
#endif /*#ifdef WIN32*/

View File

@ -25,7 +25,7 @@ char linebuf[2048];
void
pkg_mak_writeHeader(FileStream *f, const UPKGOptions *o)
{
sprintf(linebuf, "## Makefile for %s created by pkgtool\n"
sprintf(linebuf, "## Makefile for %s created by pkgdata\n"
"## from ICU Version %s\n"
"\n",
o->shortName,

View File

@ -2,11 +2,12 @@
.\"
.\" pkgdata.8: manual page for the pkgdata utility
.\"
.\" Copyright (C) 2000 IBM, Inc. and others.
.\" Copyright (C) 2000-2002 IBM, Inc. and others.
.\"
.\" Manual page by Yves Arrouye <yves@realnames.com>.
.\" Modified by Steven R. Loomis <srl@jtcsv.com>
.\"
.TH PKGDATA 8 "20 December 2001" "ICU MANPAGE" "ICU @VERSION@ Manual"
.TH PKGDATA 8 "1 March 2002" "ICU MANPAGE" "ICU @VERSION@ Manual"
.SH NAME
.B pkgdata
\- package data for use by ICU
@ -98,6 +99,23 @@ linked to the application that uses them. Such resource bundles can
then be placed anywhere where the system's dynamic linker will be
looking for shared libraries, instead of being forced to live inside
the ICU data directory.
.PP
The
.BR static
packaging mode is similar to dll or library, however it produces a
static library. Note that many platforms are not able to dynamically load
symbols from static object files, so for this reason
.BR udata_setAppData()
must be called
to install this data. As a convenience, pkgdata will build a C source file
and a header file. Given a data package named "\fIname\fP", in the output
directory will be created \fIname\fR.c and \fIname\fR.h with the single
function \fBudata_install_\fIname\fB(UErrorCode *err)\fR. Call this function
once early in the program. The error code returned is that of \fBudata_setAppData()\fP.
Subsequently, the application can access this data by passing "\fIname\fP" for the "path"
argument to functions such as \fBures_open()\fP.
.PP
Finally,
.B pkgdata

View File

@ -1,6 +1,6 @@
/******************************************************************************
*
* Copyright (C) 2000-2001, International Business Machines
* Copyright (C) 2000-2002, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
@ -51,7 +51,8 @@ static struct
#ifdef UDATA_SO_SUFFIX
{ "dll", "library", pkg_mode_dll, "Generates one shared library, <package>" UDATA_SO_SUFFIX },
#endif
{ "common", "archive", pkg_mode_common, "Generates one common data file, <package>.dat" }
{ "common", "archive", pkg_mode_common, "Generates one common data file, <package>.dat" },
{ "static", "static", pkg_mode_static, "Generates one statically linked library, " LIB_PREFIX "<package>" UDATA_LIB_SUFFIX }
#endif /*#ifdef WIN32*/
};

View File

@ -127,6 +127,7 @@ typedef struct UPKGOptions_
#else /* POSIX? */
# define LIB_PREFIX "lib"
# define OBJ_SUFFIX ".o"
# define UDATA_LIB_SUFFIX ".a"
#endif

View File

@ -0,0 +1,220 @@
/******************************************************************************
*
* Copyright (C) 2002, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
* file name: staticmode.c
* encoding: ANSI X3.4 (1968)
* tab size: 8 (not used)
* indentation:4
*
* created on: 2000may15
* created by: Steven \u24C7 Loomis
*
* This program packages the ICU data into different forms
* (DLL, common data, etc.)
*/
#include <stdio.h>
#include <stdlib.h>
#include "unicode/utypes.h"
#include "cmemory.h"
#include "cstring.h"
#include "filestrm.h"
#include "toolutil.h"
#include "unewdata.h"
#include "uoptions.h"
#include "pkgtypes.h"
#include "makefile.h"
static void
writeObjRules(UPKGOptions *o, FileStream *makefile, CharList **objects)
{
const char *p, *baseName;
char tmp[1024];
char stanza[1024];
char cfile[1024];
CharList *oTail = NULL;
CharList *infiles;
CharList *parents = NULL, *commands = NULL;
infiles = o->filePaths;
for(;infiles;infiles = infiles->next) {
baseName = findBasename(infiles->str);
p = uprv_strrchr(baseName, '.');
if( (p == NULL) || (*p == '\0' ) ) {
continue;
}
uprv_strncpy(tmp, baseName, p-baseName);
p++;
uprv_strcpy(tmp+(p-1-baseName), "_"); /* to append */
uprv_strcat(tmp, p);
uprv_strcat(tmp, ".");
uprv_strcat(tmp, STATIC_O);
*objects = pkg_appendToList(*objects, &oTail, uprv_strdup(tmp));
/* write source list */
strcpy(cfile,tmp);
strcpy(cfile+strlen(cfile)-strlen("." STATIC_O), ".c" );
/* Make up parents.. */
parents = pkg_appendToList(parents, NULL, uprv_strdup(infiles->str));
/* make up commands.. */
sprintf(stanza, "$(INVOKE) $(GENCCODE) -n %s -d $(TEMP_DIR) $<", o->shortName);
commands = pkg_appendToList(commands, NULL, uprv_strdup(stanza));
sprintf(stanza, "$(COMPILE.c) -o $@ $(TEMP_DIR)/%s", cfile);
commands = pkg_appendToList(commands, NULL, uprv_strdup(stanza));
sprintf(stanza, "$(TEMP_DIR)/%s", tmp);
pkg_mak_writeStanza(makefile, o, stanza, parents, commands);
pkg_deleteList(parents);
pkg_deleteList(commands);
parents = NULL;
commands = NULL;
}
}
void pkg_mode_static(UPKGOptions *o, FileStream *makefile, UErrorCode *status)
{
char tmp[1024];
CharList *tail = NULL;
CharList *objects = NULL;
if(U_FAILURE(*status)) {
return;
}
uprv_strcpy(tmp, LIB_PREFIX);
uprv_strcat(tmp, o->shortName);
uprv_strcat(tmp, UDATA_LIB_SUFFIX);
o->outFiles = pkg_appendToList(o->outFiles, &tail, uprv_strdup(tmp));
if(o->nooutput || o->verbose) {
fprintf(stdout, "# Output file: %s%s%s\n", o->targetDir, U_FILE_SEP_STRING, tmp);
}
if(o->nooutput) {
*status = U_ZERO_ERROR;
return;
}
/* begin writing makefile ========================= */
T_FileStream_writeLine(makefile, "# Version numbers:\nVERSIONED=");
if (o->version) {
sprintf(tmp, ".%s", o->version);
if (!uprv_strchr(o->version, '.')) {
uprv_strcat(tmp, ".0");
}
T_FileStream_writeLine(makefile, tmp);
T_FileStream_writeLine(makefile, "\nDLL_LDFLAGS=$(LD_SONAME) $(RPATH_LDFLAGS)\n");
} else {
T_FileStream_writeLine(makefile, "\nDLL_LDFLAGS=$(BIR_LDFLAGS)\n");
}
T_FileStream_writeLine(makefile, "\n");
sprintf(tmp, "# File to make:\nTARGET=%s\n\n", o->outFiles->str);
T_FileStream_writeLine(makefile, tmp);
T_FileStream_writeLine(makefile, "LIB_TARGET=$(TARGET)\n"
"HEADER=$(TARGETDIR)/$(NAME).h\n");
uprv_strcpy(tmp, "all: $(TARGETDIR)/$(LIB_TARGET) $(HEADER)");
uprv_strcat(tmp, "\n\n");
T_FileStream_writeLine(makefile, tmp);
/* Write compile rules */
writeObjRules(o, makefile, &objects);
sprintf(tmp, "# List file for gencmn:\n"
"CMNLIST=%s%s%s_static.lst\n\n",
o->tmpDir,
U_FILE_SEP_STRING,
o->shortName);
T_FileStream_writeLine(makefile, tmp);
if(o->hadStdin == FALSE) { /* shortcut */
T_FileStream_writeLine(makefile, "$(CMNLIST): $(LISTFILES)\n"
"\tcat $(LISTFILES) > $(CMNLIST)\n\n");
} else {
T_FileStream_writeLine(makefile, "$(CMNLIST): \n"
"\t@echo \"generating $@ (list of data files)\"\n"
"\t@-$(RMV) $@\n"
"\t@for file in $(DATAFILEPATHS); do \\\n"
"\t echo $$file >> $@; \\\n"
"\tdone;\n\n");
}
sprintf(tmp,"$(TEMP_DIR)/%s_dat.$(STATIC_O) : $(TEMP_DIR)/%s_dat.c\n"
"\t$(COMPILE.c) -o $@ $<\n\n",
o->shortName,
o->shortName);
T_FileStream_writeLine(makefile, tmp);
T_FileStream_writeLine(makefile, "# 'TOCOBJ' contains C Table of Contents objects [if any]\n");
sprintf(tmp, "$(TEMP_DIR)/%s_dat.c: $(CMNLIST)\n"
"\t$(INVOKE) $(GENCMN) -e %s -n %s -S -d $(TEMP_DIR) 0 $(CMNLIST)\n\n", o->shortName, o->entryName, o->shortName);
T_FileStream_writeLine(makefile, tmp);
sprintf(tmp, "TOCOBJ= %s_dat%s \n\n", o->shortName,OBJ_SUFFIX);
T_FileStream_writeLine(makefile, tmp);
sprintf(tmp, "TOCSYM= %s_dat \n\n", o->entryName); /* entrypoint not always shortname! */
T_FileStream_writeLine(makefile, tmp);
T_FileStream_writeLine(makefile, "BASE_OBJECTS= $(TOCOBJ) $(NAME).$(STATIC_O) ");
pkg_writeCharListWrap(makefile, objects, " ", " \\\n",0);
T_FileStream_writeLine(makefile, "\n\n");
T_FileStream_writeLine(makefile, "OBJECTS=$(BASE_OBJECTS:%=$(TEMP_DIR)/%)\n\n");
T_FileStream_writeLine(makefile,"$(TEMP_DIR)/%.$(STATIC_O): $(TEMP_DIR)/%.c\n\t $(COMPILE.c) -o $@ $<\n\n");
T_FileStream_writeLine(makefile, "$(TARGETDIR)/$(LIB_TARGET):$(TARGETDIR)/$(LIB_TARGET)($(OBJECTS)) $(HPUX_JUNK_OBJ) $(LISTFILES)\n"
"\t$(RANLIB) $@\n\n");
T_FileStream_writeLine(makefile, "CLEANFILES= $(CMNLIST) $(OBJECTS) $(HPUX_JUNK_OBJ) $(TARGETDIR)/$(LIB_TARGET) $(TARGETDIR)/$(MIDDLE_STATIC_LIB_TARGET) $(TARGETDIR)/$(TARGET)\n\nclean:\n\t-$(RMV) $(CLEANFILES) $(MAKEFILE)");
T_FileStream_writeLine(makefile, "\n\n");
T_FileStream_writeLine(makefile, "# static mode shouldn't need to be installed, but we will install the header and static library for them.\n");
T_FileStream_writeLine(makefile, "install: $(TARGETDIR)/$(LIB_TARGET) $(HEADER)\n"
"\t$(INSTALL-L) $(TARGETDIR)/$(LIB_TARGET) $(INSTALLTO)/$(LIB_TARGET)\n"
"\t$(INSTALL_DATA) $(HEADER) $(INSTALLTO)/$(includedir)/unicode\n");
if (o->version) {
T_FileStream_writeLine(makefile, "\tcd $(INSTALLTO) && $(RM) $(MIDDLE_STATIC_LIB_TARGET) && ln -s $(LIB_TARGET) $(MIDDLE_STATIC_LIB_TARGET)\n\tcd $(INSTALLTO) && $(RM) $(STATIC_LIB_TARGET) && ln -s $(LIB_TARGET) $(STATIC_LIB_TARGET)\n");
}
T_FileStream_writeLine(makefile, "\n");
T_FileStream_writeLine(makefile, "# We generate the following files from the Makefile, so that they don't get needlessly recompiled.\n");
T_FileStream_writeLine(makefile, "\n");
T_FileStream_writeLine(makefile, "$(TARGETDIR)/$(NAME).h:\n"
"\techo '#include \"unicode/utypes.h\"' > $@\n"
"\techo >> $@\n"
"\techo '/* Call this function to install Application data */' >> $@\n"
"\techo \"U_CAPI void udata_install_$(NAME)(UErrorCode* err);\" >> $@\n\n");
T_FileStream_writeLine(makefile, "$(TARGETDIR)/$(NAME).c:\n"
"\techo '#include \"unicode/udata.h\"' > $@\n"
"\techo \"extern char $(NAME)_dat[];\" >> $@\n"
"\techo \"extern void udata_install_$(NAME)(UErrorCode* err){udata_setAppData(\"'\"'\"$(NAME)\"'\"'\", (const void*) $(NAME)_dat, err);}\" >> $@\n"
"\n");
*status = U_ZERO_ERROR;
}