/* This sets the modes that are available */ staticstruct { constchar *name, *alt_name; constchar *desc;
} modes[] = {
{ "files", nullptr, "Uses raw data files (no effect). Installation copies all files to the target location." }, #if U_PLATFORM_HAS_WIN32_API
{ "dll", "library", "Generates one common data file and one shared library, .dll"},
{ "common", "archive", "Generates just the common file, .dat"},
{ "static", "static", "Generates one statically linked library, " LIB_PREFIX "" UDATA_LIB_SUFFIX } #else #ifdef UDATA_SO_SUFFIX
{ "dll", "library", "Generates one shared library, " UDATA_SO_SUFFIX }, #endif
{ "common", "archive", "Generates one common data file, .dat" },
{ "static", "static", "Generates one statically linked library, " LIB_PREFIX "" UDATA_LIB_SUFFIX } #endif
};
constchar options_help[][320]={ "Set the data name", #ifdef U_MAKE_IS_NMAKE "The directory where the ICU is located (e.g. which contains the bin directory)", #else "Specify options for the builder.", #endif "Specify the mode of building (see below; default: common)", "This usage text", "This usage text", "Make the output verbose", "Use the standard ICU copyright", "Use a custom comment (instead of the copyright)", "Specify the destination directory for files", "Force rebuilding of all data", "Specify temporary dir (default: output dir)", "Install the data (specify target)", "Specify a custom source directory", "Specify a custom entrypoint name (default: short name)", "Specify a version when packaging in dll or static mode", "Add package to all file names if not present", "Library name to build (if different than package name)", "Quiet mode. (e.g. Do not output a readme file for static libraries)", "Build the data without assembly code", "Build PDS dataset (zOS build only)", "Build for Universal Windows Platform (Windows build only)", "Specify the DLL machine architecture for LINK.exe (Windows build only)", "Ignored. Enable DYNAMICBASE on the DLL. This is now the default. (Windows build only)",
};
constchar *progname = "PKGDATA";
int
main(int argc, char* argv[]) { int result = 0; /* FileStream *out; */
UPKGOptions o;
CharList *tail;
UBool needsHelp = false;
UErrorCode status = U_ZERO_ERROR; /* char tmp[1024]; */
uint32_t i;
int32_t n;
U_MAIN_INIT_ARGS(argc, argv);
progname = argv[0];
options[MODE].value = "common";
/* read command line options */
argc=u_parseArgs(argc, argv, UPRV_LENGTHOF(options), options);
/* error handling, printing usage message */ /* I've decided to simply print an error and quit. This tool has too
many options to just display them all of the time. */
#if !defined(WINDOWS_WITH_MSVC) || defined(USING_CYGWIN) if(!options[BLDOPT].doesOccur && uprv_strcmp(options[MODE].value, "common") != 0) { if (pkg_getPkgDataPath(options[VERBOSE].doesOccur, &options[BLDOPT]) != 0) {
fprintf(stderr, " required parameter is missing: -O is required for static and shared builds.\n");
fprintf(stderr, "Run '%s --help' for help.\n", progname); return 1;
}
} #else if(options[BLDOPT].doesOccur) {
fprintf(stdout, "Warning: You are using the -O option which is not needed for MSVC build on Windows.\n");
} #endif
if(!options[NAME].doesOccur) /* -O we already have - don't report it. */
{
fprintf(stderr, " required parameter -p is missing \n");
fprintf(stderr, "Run '%s --help' for help.\n", progname); return 1;
}
if(argc == 1) {
fprintf(stderr, "No input files specified.\n" "Run '%s --help' for help.\n", progname); return 1;
}
} /* end !needsHelp */
if(argc<0 || needsHelp ) {
fprintf(stderr, "usage: %s [-options] [-] [packageFile] \n" "\tProduce packaged ICU data from the given list(s) of files.\n" "\t'-' by itself means to read from stdin.\n" "\tpackageFile is a text file containing the list of files to package.\n",
progname);
if(options[PDS_BUILD].doesOccur) { #if U_PLATFORM == U_PF_OS390
o.pdsbuild = true; #else
o.pdsbuild = false;
fprintf(stdout, "Warning: You are using the -z option which only works on z/OS.\n");
#endif
} else {
o.pdsbuild = false;
}
o.verbose = options[VERBOSE].doesOccur;
#if !defined(WINDOWS_WITH_MSVC) || defined(USING_CYGWIN) /* on UNIX, we'll just include the file... */ if (options[BLDOPT].doesOccur) {
o.options = options[BLDOPT].value;
} else {
o.options = nullptr;
} #endif if(options[COPYRIGHT].doesOccur) {
o.comment = U_COPYRIGHT_STRING;
} elseif (options[COMMENT].doesOccur) {
o.comment = options[COMMENT].value;
}
o.withoutAssembly = false; if (options[WITHOUT_ASSEMBLY].doesOccur) { #ifndef BUILD_DATA_WITHOUT_ASSEMBLY
fprintf(stdout, "Warning: You are using the option to build without assembly code which is not supported on this platform.\n");
fprintf(stdout, "Warning: This option will be ignored.\n"); #else
o.withoutAssembly = true; #endif
}
if (options[WIN_DYNAMICBASE].doesOccur) {
fprintf(stdout, "Note: Ignoring option -b (windows-dynamicbase).\n");
}
/* OK options are set up. Now the file lists. */
tail = nullptr; for( n=1; n<argc; n++) {
o.fileListFiles = pkg_appendToList(o.fileListFiles, &tail, uprv_strdup(argv[n]));
}
printf("pkgdata: %s\n", cmd); int result = system(cmd); if (result != 0) {
fprintf(stderr, "-- return status = %d\n", result);
result = 1; // system() result code is platform specific.
}
if (IN_FILES_MODE(mode)) { /* Copy the raw data to the installation directory. */ if (o->install != nullptr) {
uprv_strcpy(targetDir, o->install); if (o->shortName != nullptr) {
uprv_strcat(targetDir, PKGDATA_FILE_SEP_STRING);
uprv_strcat(targetDir, o->shortName);
}
/* Move the dat file created to the target directory. */ if (uprv_strcmp(datFileNamePath, targetFileNamePath) != 0) { if (T_FileStream_file_exists(targetFileNamePath)) { if ((result = remove(targetFileNamePath)) != 0) {
fprintf(stderr, "Unable to remove old dat file: %s\n",
targetFileNamePath); return result;
}
}
result = rename(datFileNamePath, targetFileNamePath);
if (o->verbose) {
fprintf(stdout, "# Moving package file to %s ..\n",
targetFileNamePath);
} if (result != 0) {
fprintf(
stderr, "Unable to move dat file (%s) to target location (%s).\n",
datFileNamePath, targetFileNamePath); return result;
}
}
if (o->install != nullptr) {
result = pkg_installCommonMode(o->install, targetFileNamePath);
}
#if !defined(WINDOWS_WITH_MSVC) || defined(USING_CYGWIN) /* Get the version major number. */ if (o->version != nullptr) { for (uint32_t i = 0;i < sizeof(version_major);i++) { if (o->version[i] == '.') {
version_major[i] = 0; break;
}
version_major[i] = o->version[i];
}
} else {
noVersion = true; if (IN_DLL_MODE(mode)) {
fprintf(stdout, "Warning: Providing a revision number with the -r option is recommended when packaging data in the current mode.\n");
}
}
#if U_PLATFORM != U_PF_OS400 /* Certain platforms have different library extension ordering. (e.g. libicudata.##.so vs libicudata.so.##) * reverseExt is false if the suffix should be the version number.
*/ if (pkgDataFlags[LIB_EXT_ORDER][uprv_strlen(pkgDataFlags[LIB_EXT_ORDER])-1] == pkgDataFlags[SO_EXT][uprv_strlen(pkgDataFlags[SO_EXT])-1]) {
reverseExt = true;
} #endif /* Using the base libName and version number, generate the library file names. */
createFileNames(o, mode, version_major, o->version == nullptr ? "" : o->version, o->libName, reverseExt, noVersion);
if ((o->version!=nullptr || IN_STATIC_MODE(mode)) && o->rebuild == false && o->pdsbuild == false) { /* Check to see if a previous built data library file exists and check if it is the latest. */
snprintf(checkLibFile, sizeof(checkLibFile), "%s%s", targetDir, libFileNames[LIB_FILE_VERSION]); if (T_FileStream_file_exists(checkLibFile)) { if (isFileModTimeLater(checkLibFile, o->srcDir, true) && isFileModTimeLater(checkLibFile, o->options)) { if (o->install != nullptr) { if(o->verbose) {
fprintf(stdout, "# Installing already-built library into %s\n", o->install);
}
result = pkg_installLibrary(o->install, targetDir, noVersion);
} else { if(o->verbose) {
printf("# Not rebuilding %s - up to date.\n", checkLibFile);
}
} return result;
} elseif (o->verbose && (o->install!=nullptr)) {
fprintf(stdout, "# Not installing up-to-date library %s into %s\n", checkLibFile, o->install);
}
} elseif(o->verbose && (o->install!=nullptr)) {
fprintf(stdout, "# Not installing missing %s into %s\n", checkLibFile, o->install);
}
}
/* If we run out of space, allocate more */ #if !defined(WINDOWS_WITH_MSVC) || defined(USING_CYGWIN) do { #endif if (pkgDataFlags != nullptr) { for (int32_t i = 0; i < PKGDATA_FLAGS_SIZE; i++) {
pkgDataFlags[i] = static_cast<char*>(uprv_malloc(sizeof(char) * currentBufferSize)); if (pkgDataFlags[i] != nullptr) {
pkgDataFlags[i][0] = 0;
} else {
fprintf(stderr,"Error allocating memory for pkgDataFlags.\n"); /* If an error occurs, ensure that the rest of the array is nullptr */ for (int32_t n = i + 1; n < PKGDATA_FLAGS_SIZE; n++) {
pkgDataFlags[n] = nullptr;
} return -1;
}
}
} else {
fprintf(stderr,"Error allocating memory for pkgDataFlags.\n"); return -1;
}
if (o->options == nullptr) { return result;
}
#if !defined(WINDOWS_WITH_MSVC) || defined(USING_CYGWIN) /* Read in options file. */ if(o->verbose) {
fprintf(stdout, "# Reading options file %s\n", o->options);
}
status = U_ZERO_ERROR;
tmpResult = parseFlagsFile(o->options, pkgDataFlags, currentBufferSize, FLAG_NAMES, static_cast<int32_t>(PKGDATA_FLAGS_SIZE), &status); if (status == U_BUFFER_OVERFLOW_ERROR) { for (int32_t i = 0; i < PKGDATA_FLAGS_SIZE; i++) { if (pkgDataFlags[i]) {
uprv_free(pkgDataFlags[i]);
pkgDataFlags[i] = nullptr;
}
}
currentBufferSize = tmpResult;
} elseif (U_FAILURE(status)) {
fprintf(stderr,"Unable to open or read \"%s\" option file. status = %s\n", o->options, u_errorName(status)); return -1;
} #endif if(o->verbose) {
fprintf(stdout, "# pkgDataFlags=\n"); for(int32_t i=0;i<PKGDATA_FLAGS_SIZE;i++) {
fprintf(stdout, " [%d] %s: %s\n", i, FLAG_NAMES[i], pkgDataFlags[i]);
}
fprintf(stdout, "\n");
} #if !defined(WINDOWS_WITH_MSVC) || defined(USING_CYGWIN)
} while (status == U_BUFFER_OVERFLOW_ERROR); #endif
return result;
}
/* * Given the base libName and version numbers, generate the library file names and store it in libFileNames. * Depending on the configuration, the library name may either end with version number or shared object suffix.
*/ staticvoid createFileNames(UPKGOptions *o, constchar mode, constchar *version_major, constchar *version, constchar *libName, UBool reverseExt, UBool noVersion) { constchar* FILE_EXTENSION_SEP = uprv_strlen(pkgDataFlags[SO_EXT]) == 0 ? "" : "."; constchar* FILE_SUFFIX = pkgDataFlags[LIB_EXT_ORDER][0] == '.' ? "." : ""; #ifdefined(__GNUC__) && !defined(__clang__)
_Pragma("GCC diagnostic push")
_Pragma("GCC diagnostic ignored \"-Wformat-truncation\"") #endif
#if U_PLATFORM == U_PF_MINGW /* MinGW does not need the library prefix when building in dll mode. */ if (IN_DLL_MODE(mode)) {
snprintf(libFileNames[LIB_FILE], sizeof(libFileNames[LIB_FILE]), "%s", libName);
} else {
snprintf(libFileNames[LIB_FILE], sizeof(libFileNames[LIB_FILE]), "%s%s%s",
(strstr(libName, "icudt") ? "lib" : ""),
pkgDataFlags[LIBPREFIX],
libName);
} #else
snprintf(libFileNames[LIB_FILE], sizeof(libFileNames[LIB_FILE]), "%s%s",
pkgDataFlags[LIBPREFIX],
libName); #endif
#if U_PF_MINGW <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN /* Cygwin and MinGW only deals with the version major number. */
uprv_strcpy(libFileNames[LIB_FILE_VERSION_TMP], libFileNames[LIB_FILE_VERSION_MAJOR]); #endif
FileStream *f = T_FileStream_open(fileListName, "r"); if (f != nullptr) { for(;;) { if (T_FileStream_readLine(f, buffer, SMALL_BUFFER_MAX_SIZE) != nullptr) {
bufferLength = static_cast<int32_t>(uprv_strlen(buffer)); /* Remove new line character. */ if (bufferLength > 0) {
buffer[bufferLength-1] = 0;
}
auto ret = snprintf(cmd, sizeof(cmd), "%s %s%s%s %s%s%s",
pkgDataFlags[INSTALL_CMD],
srcDir, PKGDATA_FILE_SEP_STRING, buffer,
installDir, PKGDATA_FILE_SEP_STRING, buffer);
(void)ret;
U_ASSERT(0 <= ret && ret < SMALL_BUFFER_MAX_SIZE);
result = runCommand(cmd); if (result != 0) {
fprintf(stderr, "Failed to install data file with command: %s\n", cmd); break;
}
} else { if (!T_FileStream_eof(f)) {
fprintf(stderr, "Failed to read line from file: %s\n", fileListName);
result = -1;
} break;
}
}
T_FileStream_close(f);
} else {
result = -1;
fprintf(stderr, "Unable to open list file: %s\n", fileListName);
} #else
snprintf(cmd, sizeof(cmd), "%s %s %s %s", WIN_INSTALL_CMD, srcDir, installDir, WIN_INSTALL_CMD_FLAGS);
result = runCommand(cmd); if (result != 0) {
fprintf(stderr, "Failed to install data file with command: %s\n", cmd);
} #endif
return result;
}
/* Archiving of the library file may be needed depending on the platform and options given. * If archiving is not needed, copy over the library file name.
*/ static int32_t pkg_archiveLibrary(constchar *targetDir, constchar *version, UBool reverseExt) {
int32_t result = 0; char cmd[LARGE_BUFFER_MAX_SIZE];
/* If the shared object suffix and the final object suffix is different and the final object suffix and the * archive file suffix is the same, then the final library needs to be archived.
*/ if (uprv_strcmp(pkgDataFlags[SOBJ_EXT], pkgDataFlags[SO_EXT]) != 0 && uprv_strcmp(pkgDataFlags[A_EXT], pkgDataFlags[SO_EXT]) == 0) { #ifdefined(__GNUC__) && !defined(__clang__)
_Pragma("GCC diagnostic push")
_Pragma("GCC diagnostic ignored \"-Wformat-truncation\"") #endif
/* * Using the compiler information from the configuration file set by -O option, generate the library file. * command may be given to allow for a larger buffer for cmd.
*/ static int32_t pkg_generateLibraryFile(constchar *targetDir, constchar mode, constchar*objectFile, char *command, UBool specialHandling) {
int32_t result = 0; char *cmd = nullptr;
UBool freeCmd = false;
int32_t length = 0;
(void)specialHandling; // Suppress unused variable compiler warnings on platforms where all usage // of this parameter is #ifdefed out.
/* This is necessary because if packaging is done without assembly code, objectFile might be extremely large * containing many object files and so the calling function should supply a command buffer that is large * enough to handle this. Otherwise, use the default size.
*/ if (command != nullptr) {
cmd = command;
}
/* Remove the ending .s and replace it with .o for the new object file. */
uprv_strcpy(tempObjectFile, gencFilePath);
tempObjectFile[uprv_strlen(tempObjectFile)-1] = 'o';
#ifdef BUILD_DATA_WITHOUT_ASSEMBLY /* * Generation of the data library without assembly code needs to compile each data file * individually and then link it all together. * Note: Any update to the directory structure of the data needs to be reflected here.
*/ enum {
DATA_PREFIX_BRKITR,
DATA_PREFIX_COLL,
DATA_PREFIX_CURR,
DATA_PREFIX_LANG,
DATA_PREFIX_RBNF,
DATA_PREFIX_REGION,
DATA_PREFIX_TRANSLIT,
DATA_PREFIX_ZONE,
DATA_PREFIX_UNIT,
DATA_PREFIX_LENGTH
};
if((icudtAllFile = T_FileStream_open(icudtAll, "w"))==nullptr) {
fprintf(stderr, "Unable to write to icudtall file: %s\n", icudtAll); return result;
} #endif
if (list == nullptr || listNames == nullptr) { /* list and listNames should never be nullptr since we are looping through the CharList with * the given size.
*/ return -1;
}
if ((cmd = static_cast<char*>(uprv_malloc((listSize + 2) * SMALL_BUFFER_MAX_SIZE))) == nullptr) {
fprintf(stderr, "Unable to allocate memory for cmd.\n"); return -1;
} elseif ((buffer = static_cast<char*>(uprv_malloc((listSize + 1) * SMALL_BUFFER_MAX_SIZE))) == nullptr) {
fprintf(stderr, "Unable to allocate memory for buffer.\n");
uprv_free(cmd); return -1;
}
for (int32_t i = 0; i < (listSize + 1); i++) { constchar *file ; constchar *name;
if (i == 0) { /* The first iteration calls the gencmn function and initializes the buffer. */
createCommonDataFile(o->tmpDir, o->shortName, o->entryName, nullptr, o->srcDir, o->comment, o->fileListFiles->str, 0, true, o->verbose, gencmnFile);
buffer[0] = 0; #ifdef USE_SINGLE_CCODE_FILE
uprv_strcpy(tempObjectFile, gencmnFile);
tempObjectFile[uprv_strlen(tempObjectFile) - 1] = 'o';
newName[0] = dataName[0] = 0; for (int32_t n = 0; n < DATA_PREFIX_LENGTH; n++) {
dataDirName[0] = 0;
sprintf(dataDirName, "%s%s", DATA_PREFIX[n], PKGDATA_FILE_SEP_STRING); /* If the name contains a prefix (indicating directory), alter the new name accordingly. */
pSubstring = uprv_strstr(name, dataDirName); if (pSubstring != nullptr) { char newNameTmp[SMALL_BUFFER_MAX_SIZE] = ""; constchar *p = name + uprv_strlen(dataDirName); for (int32_t i = 0;;i++) { if (p[i] == '.') {
newNameTmp[i] = '_'; continue;
}
newNameTmp[i] = p[i]; if (p[i] == 0) { break;
}
} auto ret = snprintf(newName, sizeof(newName), "%s_%s",
DATA_PREFIX[n],
newNameTmp);
(void)ret;
U_ASSERT(0 <= ret && ret < SMALL_BUFFER_MAX_SIZE);
ret = snprintf(dataName, sizeof(dataName), "%s_%s",
o->shortName,
DATA_PREFIX[n]);
(void)ret;
U_ASSERT(0 <= ret && ret < SMALL_BUFFER_MAX_SIZE);
} if (newName[0] != 0) { break;
}
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.26Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.