/******************************************************************************
- * Copyright (C) 2000-2011, International Business Machines
+ * Copyright (C) 2000-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*******************************************************************************
- * file name: pkgdata.c
+ * file name: pkgdata.cpp
* encoding: ANSI X3.4 (1968)
* tab size: 8 (not used)
* indentation:4
* (DLL, common data, etc.)
*/
-/*
- * We define _XOPEN_SOURCE so that we can get popen and pclose.
- */
-#if !defined(_XOPEN_SOURCE)
-#if __STDC_VERSION__ >= 199901L
-/* It is invalid to compile an XPG3, XPG4, XPG4v2 or XPG5 application using c99 on Solaris */
-#define _XOPEN_SOURCE 600
-#else
-#define _XOPEN_SOURCE 4
-#endif
-#endif
-
+// Defines _XOPEN_SOURCE for access to POSIX functions.
+// Must be before any other #includes.
+#include "uposixdefs.h"
#include "unicode/utypes.h"
+#include "unicode/putil.h"
+#include "putilimp.h"
+
#if U_HAVE_POPEN
-#if defined(U_CYGWIN) && defined(__STRICT_ANSI__)
-/* popen/pclose aren't defined in strict ANSI on Cygwin */
+#if (U_PF_MINGW <= U_PLATFORM || U_PLATFORM <= U_PF_CYGWIN) && defined(__STRICT_ANSI__)
+/* popen/pclose aren't defined in strict ANSI on Cygwin and MinGW */
#undef __STRICT_ANSI__
#endif
#endif
-#include "unicode/putil.h"
#include "cmemory.h"
#include "cstring.h"
#include "filestrm.h"
#include "unicode/uclean.h"
#include "unewdata.h"
#include "uoptions.h"
-#include "putilimp.h"
#include "package.h"
#include "pkg_icu.h"
#include "pkg_genc.h"
#include "flagparser.h"
#include "filetools.h"
-
#if U_HAVE_POPEN
# include <unistd.h>
#endif
+
#include <stdio.h>
#include <stdlib.h>
#include "pkgtypes.h"
U_CDECL_END
-#ifdef U_WINDOWS
-#ifdef __GNUC__
-#define WINDOWS_WITH_GNUC
-#else
-#define WINDOWS_WITH_MSVC
-#endif
-#endif
-#if !defined(WINDOWS_WITH_MSVC) && !defined(U_LINUX)
-#define BUILD_DATA_WITHOUT_ASSEMBLY
-#endif
-#if defined(WINDOWS_WITH_MSVC) || defined(U_LINUX)
-#define CAN_WRITE_OBJ_CODE
-#endif
-#if defined(U_CYGWIN) || defined(CYGWINMSVC)
-#define USING_CYGWIN
-#endif
-
-/*
- * When building the data library without assembly,
- * some platforms use a single c code file for all of
- * the data to generate the final data library. This can
- * increase the performance of the pkdata tool.
- */
-#if defined(OS400)
-#define USE_SINGLE_CCODE_FILE
-#endif
-
-/* Need to fix the file seperator character when using MinGW. */
-#if defined(WINDOWS_WITH_GNUC) || defined(USING_CYGWIN)
-#define PKGDATA_FILE_SEP_STRING "/"
-#else
-#define PKGDATA_FILE_SEP_STRING U_FILE_SEP_STRING
-#endif
-
-#define LARGE_BUFFER_MAX_SIZE 2048
-#define SMALL_BUFFER_MAX_SIZE 512
-#define BUFFER_PADDING_SIZE 20
static void loadLists(UPKGOptions *o, UErrorCode *status);
static int32_t pkg_createWindowsDLL(const char mode, const char *gencFilePath, UPKGOptions *o);
#endif
static int32_t pkg_createSymLinks(const char *targetDir, UBool specialHandling=FALSE);
-static int32_t pkg_installLibrary(const char *installDir, const char *dir);
+static int32_t pkg_installLibrary(const char *installDir, const char *dir, UBool noVersion);
static int32_t pkg_installFileMode(const char *installDir, const char *srcDir, const char *fileListName);
static int32_t pkg_installCommonMode(const char *installDir, const char *fileName);
static int32_t pkg_createWithAssemblyCode(const char *targetDir, const char mode, const char *gencFilePath);
static int32_t pkg_generateLibraryFile(const char *targetDir, const char mode, const char *objectFile, char *command = NULL);
static int32_t pkg_archiveLibrary(const char *targetDir, const char *version, UBool reverseExt);
-static void createFileNames(UPKGOptions *o, const char mode, const char *version_major, const char *version, const char *libName, const UBool reverseExt);
+static void createFileNames(UPKGOptions *o, const char mode, const char *version_major, const char *version, const char *libName, const UBool reverseExt, UBool noVersion);
static int32_t initializePkgDataFlags(UPKGOptions *o);
static int32_t pkg_getOptionsFromICUConfig(UBool verbose, UOption *option);
static int runCommand(const char* command, UBool specialHandling=FALSE);
+#define IN_COMMON_MODE(mode) (mode == 'a' || mode == 'c')
+#define IN_DLL_MODE(mode) (mode == 'd' || mode == 'l')
+#define IN_STATIC_MODE(mode) (mode == 's')
+#define IN_FILES_MODE(mode) (mode == 'f')
+
enum {
NAME,
BLDOPT,
REVISION,
FORCE_PREFIX,
LIBNAME,
- QUIET
+ QUIET,
+ WITHOUT_ASSEMBLY,
+ PDS_BUILD
};
/* This sets the modes that are available */
const char *desc;
} modes[] = {
{ "files", 0, "Uses raw data files (no effect). Installation copies all files to the target location." },
-#ifdef U_WINDOWS
+#if U_PLATFORM_HAS_WIN32_API
{ "dll", "library", "Generates one common data file and one shared library, <package>.dll"},
{ "common", "archive", "Generates just the common file, <package>.dat"},
{ "static", "static", "Generates one statically linked library, " LIB_PREFIX "<package>" UDATA_LIB_SUFFIX }
/*16*/ UOPTION_DEF( "revision", 'r', UOPT_REQUIRES_ARG),
/*17*/ UOPTION_DEF( "force-prefix", 'f', UOPT_NO_ARG),
/*18*/ UOPTION_DEF( "libname", 'L', UOPT_REQUIRES_ARG),
- /*19*/ UOPTION_DEF( "quiet", 'q', UOPT_NO_ARG)
+ /*19*/ UOPTION_DEF( "quiet", 'q', UOPT_NO_ARG),
+ /*20*/ UOPTION_DEF( "without-assembly", 'w', UOPT_NO_ARG),
+ /*21*/ UOPTION_DEF( "zos-pds-build", 'z', UOPT_NO_ARG)
};
+/* This enum and the following char array should be kept in sync. */
enum {
GENCCODE_ASSEMBLY_TYPE,
SO_EXT,
INSTALL_CMD,
PKGDATA_FLAGS_SIZE
};
+static const char* FLAG_NAMES[PKGDATA_FLAGS_SIZE] = {
+ "GENCCODE_ASSEMBLY_TYPE",
+ "SO",
+ "SOBJ",
+ "A",
+ "LIBPREFIX",
+ "LIB_EXT_ORDER",
+ "COMPILE",
+ "LIBFLAGS",
+ "GENLIB",
+ "LDICUDTFLAGS",
+ "LD_SONAME",
+ "RPATH_FLAGS",
+ "BIR_LDFLAGS",
+ "AR",
+ "ARFLAGS",
+ "RANLIB",
+ "INSTALL_CMD"
+};
static char **pkgDataFlags = NULL;
enum {
LIB_FILE_VERSION_MAJOR,
LIB_FILE_VERSION,
LIB_FILE_VERSION_TMP,
-#ifdef U_CYGWIN
+#if U_PLATFORM == U_PF_CYGWIN
LIB_FILE_CYGWIN,
- LIB_FILE_CYGWIN_VERSION,
+ LIB_FILE_CYGWIN_VERSION,
+#elif U_PLATFORM == U_PF_MINGW
+ LIB_FILE_MINGW,
#endif
LIB_FILENAMES_SIZE
};
"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)",
- "Quite mode. (e.g. Do not output a readme file for static libraries)"
+ "Quite mode. (e.g. Do not output a readme file for static libraries)",
+ "Build the data without assembly code"
};
const char *progname = "PKGDATA";
o.quiet = FALSE;
}
+ if(options[PDS_BUILD].doesOccur) {
+ o.pdsbuild = TRUE;
+ } else {
+ o.pdsbuild = FALSE;
+ }
+
o.verbose = options[VERBOSE].doesOccur;
o.entryName = o.cShortName;
}
+ 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
+ }
+
/* OK options are set up. Now the file lists. */
tail = NULL;
for( n=1; n<argc; n++) {
}
if (!specialHandling) {
-#if defined(USING_CYGWIN) || defined(OS400)
+#if defined(USING_CYGWIN) || U_PLATFORM == U_PF_MINGW || U_PLATFORM == U_PF_OS400
if ((len + BUFFER_PADDING_SIZE) >= SMALL_BUFFER_MAX_SIZE) {
cmd = (char *)uprv_malloc(len + BUFFER_PADDING_SIZE);
} else {
cmd = cmdBuffer;
}
-#ifdef USING_CYGWIN
+#if defined(USING_CYGWIN) || U_PLATFORM == U_PF_MINGW
sprintf(cmd, "bash -c \"%s\"", command);
-#elif defined(OS400)
+#elif U_PLATFORM == U_PF_OS400
sprintf(cmd, "QSH CMD('%s')", command);
#endif
#else
goto normal_command_mode;
#endif
} else {
+#if !(defined(USING_CYGWIN) || U_PLATFORM == U_PF_MINGW || U_PLATFORM == U_PF_OS400)
normal_command_mode:
+#endif
cmd = (char *)command;
}
printf("pkgdata: %s\n", cmd);
int result = system(cmd);
if (result != 0) {
- printf("-- return status = %d\n", result);
+ fprintf(stderr, "-- return status = %d\n", result);
}
if (cmd != cmdBuffer && cmd != command) {
#define LN_CMD "ln -s"
#define RM_CMD "rm -f"
-#define MODE_COMMON 'c'
-#define MODE_STATIC 's'
-#define MODE_DLL 'd'
-#define MODE_FILES 'f'
-
static int32_t pkg_executeOptions(UPKGOptions *o) {
int32_t result = 0;
initializePkgDataFlags(o);
- if (mode == MODE_FILES) {
+ if (IN_FILES_MODE(mode)) {
/* Copy the raw data to the installation directory. */
if (o->install != NULL) {
uprv_strcpy(targetDir, o->install);
result = pkg_installFileMode(targetDir, o->srcDir, o->fileListFiles->str);
}
return result;
- } else /* if (mode == MODE_COMMON || mode == MODE_STATIC || mode == MODE_DLL) */ {
+ } else /* if (IN_COMMON_MODE(mode) || IN_DLL_MODE(mode) || IN_STATIC_MODE(mode)) */ {
+ UBool noVersion = FALSE;
+
uprv_strcpy(targetDir, o->targetDir);
uprv_strcat(targetDir, PKGDATA_FILE_SEP_STRING);
return result;
}
- if (mode == MODE_COMMON) {
+ if (IN_COMMON_MODE(mode)) {
char targetFileNamePath[LARGE_BUFFER_MAX_SIZE] = "";
uprv_strcpy(targetFileNamePath, targetDir);
uprv_strcat(targetFileNamePath, datFileName);
- if (T_FileStream_file_exists(targetFileNamePath)) {
- if ((result = remove(targetFileNamePath)) != 0) {
- fprintf(stderr, "Unable to remove old dat file: %s\n", targetFileNamePath);
- return result;
+ /* 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;
+ }
}
- }
- /* Move the dat file created to the target directory. */
- result = rename(datFileNamePath, targetFileNamePath);
+ 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);
+ 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 != NULL) {
}
return result;
- } else /* if (mode[0] == MODE_STATIC || mode[0] == MODE_DLL) */ {
+ } else /* if (IN_STATIC_MODE(mode) || IN_DLL_MODE(mode)) */ {
char gencFilePath[SMALL_BUFFER_MAX_SIZE] = "";
char version_major[10] = "";
UBool reverseExt = FALSE;
}
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");
+ }
}
-#ifndef OS400
+#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.
*/
}
#endif
/* Using the base libName and version number, generate the library file names. */
- createFileNames(o, mode, version_major, o->version, o->libName, reverseExt);
+ createFileNames(o, mode, version_major, o->version == NULL ? "" : o->version, o->libName, reverseExt, noVersion);
- if ((o->version!=NULL || (mode==MODE_STATIC)) && o->rebuild == FALSE) {
+ if ((o->version!=NULL || IN_STATIC_MODE(mode)) && o->rebuild == FALSE) {
/* Check to see if a previous built data library file exists and check if it is the latest. */
sprintf(checkLibFile, "%s%s", targetDir, libFileNames[LIB_FILE_VERSION]);
if (T_FileStream_file_exists(checkLibFile)) {
if(o->verbose) {
fprintf(stdout, "# Installing already-built library into %s\n", o->install);
}
- result = pkg_installLibrary(o->install, targetDir);
+ result = pkg_installLibrary(o->install, targetDir, noVersion);
} else {
if(o->verbose) {
printf("# Not rebuilding %s - up to date.\n", checkLibFile);
}
}
- pkg_checkFlag(o);
+ if (pkg_checkFlag(o) == NULL) {
+ /* Error occurred. */
+ return result;
+ }
#endif
- if (pkgDataFlags[GENCCODE_ASSEMBLY_TYPE][0] != 0) {
+ if (!o->withoutAssembly && pkgDataFlags[GENCCODE_ASSEMBLY_TYPE][0] != 0) {
const char* genccodeAssembly = pkgDataFlags[GENCCODE_ASSEMBLY_TYPE];
if(o->verbose) {
if (result != 0) {
fprintf(stderr, "Error generating assembly code for data.\n");
return result;
- } else if (mode == MODE_STATIC) {
+ } else if (IN_STATIC_MODE(mode)) {
if(o->install != NULL) {
if(o->verbose) {
fprintf(stdout, "# Installing static library into %s\n", o->install);
}
- result = pkg_installLibrary(o->install, targetDir);
+ result = pkg_installLibrary(o->install, targetDir, noVersion);
}
return result;
}
if(o->verbose) {
fprintf(stdout, "# Writing object code to %s ..\n", gencFilePath);
}
+ if (o->withoutAssembly) {
+#ifdef BUILD_DATA_WITHOUT_ASSEMBLY
+ result = pkg_createWithoutAssemblyCode(o, targetDir, mode);
+#else
+ /* This error should not occur. */
+ fprintf(stderr, "Error- BUILD_DATA_WITHOUT_ASSEMBLY is not defined. Internal error.\n");
+#endif
+ } else {
#ifdef CAN_WRITE_OBJ_CODE
- writeObjectCode(datFileNamePath, o->tmpDir, o->entryName, NULL, NULL, gencFilePath);
-#ifdef U_LINUX
- result = pkg_generateLibraryFile(targetDir, mode, gencFilePath);
+ writeObjectCode(datFileNamePath, o->tmpDir, o->entryName, NULL, NULL, gencFilePath);
+#if U_PLATFORM_IS_LINUX_BASED
+ result = pkg_generateLibraryFile(targetDir, mode, gencFilePath);
#elif defined(WINDOWS_WITH_MSVC)
- result = pkg_createWindowsDLL(mode, gencFilePath, o);
+ result = pkg_createWindowsDLL(mode, gencFilePath, o);
#endif
#elif defined(BUILD_DATA_WITHOUT_ASSEMBLY)
- result = pkg_createWithoutAssemblyCode(o, targetDir, mode);
+ result = pkg_createWithoutAssemblyCode(o, targetDir, mode);
+#else
+ fprintf(stderr, "Error- neither CAN_WRITE_OBJ_CODE nor BUILD_DATA_WITHOUT_ASSEMBLY are defined. Internal error.\n");
+ return 1;
#endif
+ }
+
if (result != 0) {
fprintf(stderr, "Error generating package data.\n");
return result;
}
}
-#ifndef U_WINDOWS
- if(mode != MODE_STATIC) {
+#if !U_PLATFORM_USES_ONLY_WIN32_API
+ if(!IN_STATIC_MODE(mode)) {
/* Certain platforms uses archive library. (e.g. AIX) */
if(o->verbose) {
fprintf(stdout, "# Creating data archive library file ..\n");
fprintf(stderr, "Error creating data archive library file.\n");
return result;
}
-#ifndef OS400
- /* Create symbolic links for the final library file. */
- result = pkg_createSymLinks(targetDir);
- if (result != 0) {
- fprintf(stderr, "Error creating symbolic links of the data library file.\n");
- return result;
+#if U_PLATFORM != U_PF_OS400
+ if (!noVersion) {
+ /* Create symbolic links for the final library file. */
+#if U_PLATFORM == U_PF_OS390
+ if (!o->pdsbuild) {
+ result = pkg_createSymLinks(targetDir, noVersion);
+ }
+#else
+ result = pkg_createSymLinks(targetDir, noVersion);
+#endif
+ if (result != 0) {
+ fprintf(stderr, "Error creating symbolic links of the data library file.\n");
+ return result;
+ }
}
#endif
- } /* !MODE_STATIC */
+ } /* !IN_STATIC_MODE */
#endif
-#if !defined(U_WINDOWS) || defined(USING_CYGWIN)
+#if !U_PLATFORM_USES_ONLY_WIN32_API
/* Install the libraries if option was set. */
if (o->install != NULL) {
if(o->verbose) {
fprintf(stdout, "# Installing library file to %s ..\n", o->install);
}
- result = pkg_installLibrary(o->install, targetDir);
+ result = pkg_installLibrary(o->install, targetDir, noVersion);
if (result != 0) {
fprintf(stderr, "Error installing the data library.\n");
return result;
fprintf(stdout, "# Reading options file %s\n", o->options);
}
status = U_ZERO_ERROR;
- tmpResult = parseFlagsFile(o->options, pkgDataFlags, currentBufferSize, (int32_t)PKGDATA_FLAGS_SIZE, &status);
+ tmpResult = parseFlagsFile(o->options, pkgDataFlags, currentBufferSize, FLAG_NAMES, (int32_t)PKGDATA_FLAGS_SIZE, &status);
if (status == U_BUFFER_OVERFLOW_ERROR) {
for (int32_t i = 0; i < PKGDATA_FLAGS_SIZE; i++) {
uprv_free(pkgDataFlags[i]);
}
#endif
if(o->verbose) {
- fprintf(stdout, "# pkgDataFlags=");
- for(int32_t i=0;i<PKGDATA_FLAGS_SIZE && pkgDataFlags[i][0];i++) {
- fprintf(stdout, "%c \"%s\"", (i>0)?',':' ',pkgDataFlags[i]);
+ 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");
}
* Given the base libName and version numbers, generate the libary file names and store it in libFileNames.
* Depending on the configuration, the library name may either end with version number or shared object suffix.
*/
-static void createFileNames(UPKGOptions *o, const char mode, const char *version_major, const char *version, const char *libName, UBool reverseExt) {
+static void createFileNames(UPKGOptions *o, const char mode, const char *version_major, const char *version, const char *libName, UBool reverseExt, UBool noVersion) {
+#if U_PLATFORM == U_PF_MINGW
+ /* MinGW does not need the library prefix when building in dll mode. */
+ if (IN_DLL_MODE(mode)) {
+ sprintf(libFileNames[LIB_FILE], "%s", libName);
+ } else {
+ sprintf(libFileNames[LIB_FILE], "%s%s",
+ pkgDataFlags[LIBPREFIX],
+ libName);
+ }
+#else
sprintf(libFileNames[LIB_FILE], "%s%s",
pkgDataFlags[LIBPREFIX],
libName);
+#endif
if(o->verbose) {
fprintf(stdout, "# libFileName[LIB_FILE] = %s\n", libFileNames[LIB_FILE]);
}
- if (version != NULL) {
-#ifdef U_CYGWIN
- sprintf(libFileNames[LIB_FILE_CYGWIN], "cyg%s.%s",
- libName,
- pkgDataFlags[SO_EXT]);
- sprintf(libFileNames[LIB_FILE_CYGWIN_VERSION], "cyg%s%s.%s",
- libName,
- version_major,
- pkgDataFlags[SO_EXT]);
-
- uprv_strcat(pkgDataFlags[SO_EXT], ".");
- uprv_strcat(pkgDataFlags[SO_EXT], pkgDataFlags[A_EXT]);
-
-#elif defined(OS400) || defined(_AIX)
- sprintf(libFileNames[LIB_FILE_VERSION_TMP], "%s.%s",
+#if U_PLATFORM == U_PF_MINGW
+ sprintf(libFileNames[LIB_FILE_MINGW], "%s%s.lib", pkgDataFlags[LIBPREFIX], libName);
+#elif U_PLATFORM == U_PF_CYGWIN
+ sprintf(libFileNames[LIB_FILE_CYGWIN], "cyg%s.%s",
+ libName,
+ pkgDataFlags[SO_EXT]);
+ sprintf(libFileNames[LIB_FILE_CYGWIN_VERSION], "cyg%s%s.%s",
+ libName,
+ version_major,
+ pkgDataFlags[SO_EXT]);
+
+ uprv_strcat(pkgDataFlags[SO_EXT], ".");
+ uprv_strcat(pkgDataFlags[SO_EXT], pkgDataFlags[A_EXT]);
+#elif U_PLATFORM == U_PF_OS400 || defined(_AIX)
+ sprintf(libFileNames[LIB_FILE_VERSION_TMP], "%s.%s",
+ libFileNames[LIB_FILE],
+ pkgDataFlags[SOBJ_EXT]);
+#elif U_PLATFROM == U_PF_OS390
+ if (o->pdsbuild) {
+ sprintf(libFileNames[LIB_FILE], "%s",
+ libName);
+ sprintf(libFileNames[LIB_FILE_VERSION_TMP], "\"%s\"",
+ libFileNames[LIB_FILE]);
+ } else {
+ sprintf(libFileNames[LIB_FILE_VERSION_TMP], "%s%s%s.%s",
+ libFileNames[LIB_FILE],
+ pkgDataFlags[LIB_EXT_ORDER][0] == '.' ? "." : "",
+ reverseExt ? version : pkgDataFlags[SOBJ_EXT],
+ reverseExt ? pkgDataFlags[SOBJ_EXT] : version);
+ }
+#else
+ if (noVersion && !reverseExt) {
+ sprintf(libFileNames[LIB_FILE_VERSION_TMP], "%s%s%s",
libFileNames[LIB_FILE],
+ pkgDataFlags[LIB_EXT_ORDER][0] == '.' ? "." : "",
pkgDataFlags[SOBJ_EXT]);
-#else
+ } else {
sprintf(libFileNames[LIB_FILE_VERSION_TMP], "%s%s%s.%s",
libFileNames[LIB_FILE],
pkgDataFlags[LIB_EXT_ORDER][0] == '.' ? "." : "",
reverseExt ? version : pkgDataFlags[SOBJ_EXT],
reverseExt ? pkgDataFlags[SOBJ_EXT] : version);
+ }
#endif
+ if (noVersion && !reverseExt) {
+ sprintf(libFileNames[LIB_FILE_VERSION_MAJOR], "%s%s%s",
+ libFileNames[LIB_FILE],
+ pkgDataFlags[LIB_EXT_ORDER][0] == '.' ? "." : "",
+ pkgDataFlags[SO_EXT]);
+
+ sprintf(libFileNames[LIB_FILE_VERSION], "%s%s%s",
+ libFileNames[LIB_FILE],
+ pkgDataFlags[LIB_EXT_ORDER][0] == '.' ? "." : "",
+ pkgDataFlags[SO_EXT]);
+ } else {
sprintf(libFileNames[LIB_FILE_VERSION_MAJOR], "%s%s%s.%s",
libFileNames[LIB_FILE],
pkgDataFlags[LIB_EXT_ORDER][0] == '.' ? "." : "",
pkgDataFlags[LIB_EXT_ORDER][0] == '.' ? "." : "",
reverseExt ? version : pkgDataFlags[SO_EXT],
reverseExt ? pkgDataFlags[SO_EXT] : version);
+ }
- if(o->verbose) {
- fprintf(stdout, "# libFileName[LIB_FILE_VERSION] = %s\n", libFileNames[LIB_FILE_VERSION]);
- }
+ if(o->verbose) {
+ fprintf(stdout, "# libFileName[LIB_FILE_VERSION] = %s\n", libFileNames[LIB_FILE_VERSION]);
+ }
-#ifdef U_CYGWIN
- /* Cygwin only deals with the version major number. */
- uprv_strcpy(libFileNames[LIB_FILE_VERSION_TMP], libFileNames[LIB_FILE_VERSION_MAJOR]);
+#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
- }
- if(mode == MODE_STATIC) {
+
+ if(IN_STATIC_MODE(mode)) {
sprintf(libFileNames[LIB_FILE_VERSION], "%s.%s", libFileNames[LIB_FILE], pkgDataFlags[A_EXT]);
libFileNames[LIB_FILE_VERSION_MAJOR][0]=0;
if(o->verbose) {
char name1[SMALL_BUFFER_MAX_SIZE]; /* symlink file name */
char name2[SMALL_BUFFER_MAX_SIZE]; /* file name to symlink */
-#ifndef USING_CYGWIN
+#if !defined(USING_CYGWIN) && U_PLATFORM != U_PF_MINGW
/* No symbolic link to make. */
if (uprv_strlen(libFileNames[LIB_FILE_VERSION]) == 0 || uprv_strlen(libFileNames[LIB_FILE_VERSION_MAJOR]) == 0 ||
uprv_strcmp(libFileNames[LIB_FILE_VERSION], libFileNames[LIB_FILE_VERSION_MAJOR]) == 0) {
libFileNames[LIB_FILE_VERSION_MAJOR]);
result = runCommand(cmd);
if (result != 0) {
+ fprintf(stderr, "Error creating symbolic links. Failed command: %s\n", cmd);
return result;
}
#endif
if (specialHandling) {
-#ifdef U_CYGWIN
+#if U_PLATFORM == U_PF_CYGWIN
sprintf(name1, "%s", libFileNames[LIB_FILE_CYGWIN]);
sprintf(name2, "%s", libFileNames[LIB_FILE_CYGWIN_VERSION]);
#else
goto normal_symlink_mode;
#endif
} else {
+#if U_PLATFORM != U_PF_CYGWIN
normal_symlink_mode:
+#endif
sprintf(name1, "%s.%s", libFileNames[LIB_FILE], pkgDataFlags[SO_EXT]);
sprintf(name2, "%s", libFileNames[LIB_FILE_VERSION]);
}
return result;
}
-static int32_t pkg_installLibrary(const char *installDir, const char *targetDir) {
+static int32_t pkg_installLibrary(const char *installDir, const char *targetDir, UBool noVersion) {
int32_t result = 0;
char cmd[SMALL_BUFFER_MAX_SIZE];
result = runCommand(cmd);
if (result != 0) {
+ fprintf(stderr, "Error installing library. Failed command: %s\n", cmd);
return result;
}
result = runCommand(cmd);
if (result != 0) {
+ fprintf(stderr, "Error installing library. Failed command: %s\n", cmd);
return result;
}
-#elif defined (U_CYGWIN)
+#elif U_PLATFORM == U_PF_CYGWIN
sprintf(cmd, "cd %s && %s %s %s",
targetDir,
pkgDataFlags[INSTALL_CMD],
result = runCommand(cmd);
if (result != 0) {
+ fprintf(stderr, "Error installing library. Failed command: %s\n", cmd);
return result;
}
#endif
- return pkg_createSymLinks(installDir, TRUE);
+ if (noVersion) {
+ return result;
+ } else {
+ return pkg_createSymLinks(installDir, TRUE);
+ }
}
static int32_t pkg_installCommonMode(const char *installDir, const char *fileName) {
}
#ifndef U_WINDOWS_WITH_MSVC
char buffer[SMALL_BUFFER_MAX_SIZE] = "";
+ int32_t bufferLength = 0;
FileStream *f = T_FileStream_open(fileListName, "r");
if (f != NULL) {
for(;;) {
if (T_FileStream_readLine(f, buffer, SMALL_BUFFER_MAX_SIZE) != NULL) {
+ bufferLength = uprv_strlen(buffer);
/* Remove new line character. */
- buffer[uprv_strlen(buffer)-1] = 0;
+ if (bufferLength > 0) {
+ buffer[bufferLength-1] = 0;
+ }
sprintf(cmd, "%s %s%s%s %s%s%s",
pkgDataFlags[INSTALL_CMD],
result = runCommand(cmd);
if (result != 0) {
+ fprintf(stderr, "Error creating archive library. Failed command: %s\n", cmd);
return result;
}
result = runCommand(cmd);
if (result != 0) {
+ fprintf(stderr, "Error creating archive library. Failed command: %s\n", cmd);
return result;
}
result = runCommand(cmd);
if (result != 0) {
+ fprintf(stderr, "Error creating archive library. Failed command: %s\n", cmd);
return result;
}
cmd = command;
}
- if (mode == MODE_STATIC) {
+ if (IN_STATIC_MODE(mode)) {
if (cmd == NULL) {
length = uprv_strlen(pkgDataFlags[AR]) + uprv_strlen(pkgDataFlags[ARFLAGS]) + uprv_strlen(targetDir) +
uprv_strlen(libFileNames[LIB_FILE_VERSION]) + uprv_strlen(objectFile) + uprv_strlen(pkgDataFlags[RANLIB]) + BUFFER_PADDING_SIZE;
result = runCommand(cmd);
}
- } else /* if (mode == MODE_DLL) */ {
+ } else /* if (IN_DLL_MODE(mode)) */ {
if (cmd == NULL) {
length = uprv_strlen(pkgDataFlags[GENLIB]) + uprv_strlen(pkgDataFlags[LDICUDTFLAGS]) +
- uprv_strlen(targetDir) + uprv_strlen(libFileNames[LIB_FILE_VERSION_TMP]) +
+ ((uprv_strlen(targetDir) + uprv_strlen(libFileNames[LIB_FILE_VERSION_TMP])) * 2) +
uprv_strlen(objectFile) + uprv_strlen(pkgDataFlags[LD_SONAME]) +
uprv_strlen(pkgDataFlags[LD_SONAME][0] == 0 ? "" : libFileNames[LIB_FILE_VERSION_MAJOR]) +
uprv_strlen(pkgDataFlags[RPATH_FLAGS]) + uprv_strlen(pkgDataFlags[BIR_FLAGS]) + BUFFER_PADDING_SIZE;
-#ifdef U_CYGWIN
+#if U_PLATFORM == U_PF_CYGWIN
length += uprv_strlen(targetDir) + uprv_strlen(libFileNames[LIB_FILE_CYGWIN_VERSION]);
+#elif U_PLATFORM == U_PF_MINGW
+ length += uprv_strlen(targetDir) + uprv_strlen(libFileNames[LIB_FILE_MINGW]);
#endif
if ((cmd = (char *)uprv_malloc(sizeof(char) * length)) == NULL) {
fprintf(stderr, "Unable to allocate memory for command.\n");
}
freeCmd = TRUE;
}
-#ifdef U_CYGWIN
+#if U_PLATFORM == U_PF_MINGW
+ sprintf(cmd, "%s%s%s %s -o %s%s %s %s%s %s %s",
+ pkgDataFlags[GENLIB],
+ targetDir,
+ libFileNames[LIB_FILE_MINGW],
+ pkgDataFlags[LDICUDTFLAGS],
+ targetDir,
+ libFileNames[LIB_FILE_VERSION_TMP],
+#elif U_PLATFORM == U_PF_CYGWIN
sprintf(cmd, "%s%s%s %s -o %s%s %s %s%s %s %s",
pkgDataFlags[GENLIB],
targetDir,
libFileNames[LIB_FILE_VERSION_TMP],
pkgDataFlags[LDICUDTFLAGS],
- targetDir, libFileNames[LIB_FILE_CYGWIN_VERSION],
+ targetDir,
+ libFileNames[LIB_FILE_CYGWIN_VERSION],
+#elif U_PLATFORM == U_PF_AIX
+ sprintf(cmd, "%s %s%s;%s %s -o %s%s %s %s%s %s %s",
+ RM_CMD,
+ targetDir,
+ libFileNames[LIB_FILE_VERSION_TMP],
+ pkgDataFlags[GENLIB],
+ pkgDataFlags[LDICUDTFLAGS],
+ targetDir,
+ libFileNames[LIB_FILE_VERSION_TMP],
#else
sprintf(cmd, "%s %s -o %s%s %s %s%s %s %s",
pkgDataFlags[GENLIB],
result = runCommand(cmd);
}
+ if (result != 0) {
+ fprintf(stderr, "Error generating library file. Failed command: %s\n", cmd);
+ }
+
if (freeCmd) {
uprv_free(cmd);
}
result = runCommand(cmd);
uprv_free(cmd);
if (result != 0) {
+ fprintf(stderr, "Error creating with assembly code. Failed command: %s\n", cmd);
return result;
}
char tempObjectFile[SMALL_BUFFER_MAX_SIZE] = "";
#ifdef USE_SINGLE_CCODE_FILE
char icudtAll[SMALL_BUFFER_MAX_SIZE] = "";
+ FileStream *icudtAllFile = NULL;
sprintf(icudtAll, "%s%s%sall.c",
o->tmpDir,
fprintf(stderr, "Unable to remove old icudtall file: %s\n", icudtAll);
return result;
}
+
+ if((icudtAllFile = T_FileStream_open(icudtAll, "w"))==NULL) {
+ fprintf(stderr, "Unable to write to icudtall file: %s\n", icudtAll);
+ return result;
+ }
#endif
if (list == NULL || listNames == NULL) {
uprv_strcpy(tempObjectFile, gencmnFile);
tempObjectFile[uprv_strlen(tempObjectFile) - 1] = 'o';
- sprintf(cmd, "%s %s -o %s %s"
+ sprintf(cmd, "%s %s -o %s %s",
pkgDataFlags[COMPILER],
pkgDataFlags[LIBFLAGS],
tempObjectFile,
}
}
+ if(o->verbose) {
+ printf("# Generating %s \n", gencmnFile);
+ }
+
writeCCode(file, o->tmpDir, dataName[0] != 0 ? dataName : o->shortName, newName[0] != 0 ? newName : NULL, gencmnFile);
+
#ifdef USE_SINGLE_CCODE_FILE
- sprintf(cmd, "cat %s >> %s", gencmnFile, icudtAll);
-
- result = runCommand(cmd);
- if (result != 0) {
- break;
- } else {
- /* Remove the c code file after concatenating it to icudtall.c file. */
- if ((result = remove(gencmnFile)) != 0) {
- fprintf(stderr, "Unable to remove c code file: %s\n", gencmnFile);
- return result;
- }
- }
+ sprintf(cmd, "#include \"%s\"\n", gencmnFile);
+ T_FileStream_writeLine(icudtAllFile, cmd);
+ /* don't delete the file */
#endif
}
gencmnFile);
result = runCommand(cmd);
if (result != 0) {
+ fprintf(stderr, "Error creating library without assembly code. Failed command: %s\n", cmd);
break;
}
}
#ifdef USE_SINGLE_CCODE_FILE
+ T_FileStream_close(icudtAllFile);
uprv_strcpy(tempObjectFile, icudtAll);
tempObjectFile[uprv_strlen(tempObjectFile) - 1] = 'o';
- sprintf(cmd, "%s %s -o %s %s",
+ sprintf(cmd, "%s %s -I. -o %s %s",
pkgDataFlags[COMPILER],
pkgDataFlags[LIBFLAGS],
tempObjectFile,
if (result == 0) {
uprv_strcat(buffer, " ");
uprv_strcat(buffer, tempObjectFile);
+ } else {
+ fprintf(stderr, "Error creating library without assembly code. Failed command: %s\n", cmd);
}
#endif
if (result == 0) {
/* Generate the library file. */
- result = pkg_generateLibraryFile(targetDir, mode, buffer, cmd);
+#if U_PLATFORM == U_PF_OS390
+ if (o->pdsbuild && IN_DLL_MODE(mode)) {
+ result = pkg_generateLibraryFile("",mode, buffer, cmd);
+ } else {
+ result = pkg_generateLibraryFile(targetDir,mode, buffer, cmd);
+ }
+#else
+ result = pkg_generateLibraryFile(targetDir,mode, buffer, cmd);
+#endif
}
uprv_free(buffer);
#define DLL_EXT UDATA_SO_SUFFIX
static int32_t pkg_createWindowsDLL(const char mode, const char *gencFilePath, UPKGOptions *o) {
+ int32_t result = 0;
char cmd[LARGE_BUFFER_MAX_SIZE];
- if (mode == MODE_STATIC) {
+ if (IN_STATIC_MODE(mode)) {
char staticLibFilePath[SMALL_BUFFER_MAX_SIZE] = "";
- uprv_strcpy(staticLibFilePath, o->tmpDir);
- uprv_strcat(staticLibFilePath, PKGDATA_FILE_SEP_STRING);
-
- uprv_strcat(staticLibFilePath, o->entryName);
- uprv_strcat(staticLibFilePath, LIB_EXT);
+#ifdef CYGWINMSVC
+ sprintf(staticLibFilePath, "%s%s%s%s%s",
+ o->targetDir,
+ PKGDATA_FILE_SEP_STRING,
+ pkgDataFlags[LIBPREFIX],
+ o->libName,
+ LIB_EXT);
+#else
+ sprintf(staticLibFilePath, "%s%s%s%s%s",
+ o->targetDir,
+ PKGDATA_FILE_SEP_STRING,
+ (strstr(o->libName, "icudt") ? "s" : ""),
+ o->libName,
+ LIB_EXT);
+#endif
sprintf(cmd, "%s\"%s\" \"%s\"",
LIB_CMD,
staticLibFilePath,
gencFilePath);
- } else if (mode == MODE_DLL) {
+ } else if (IN_DLL_MODE(mode)) {
char dllFilePath[SMALL_BUFFER_MAX_SIZE] = "";
char libFilePath[SMALL_BUFFER_MAX_SIZE] = "";
char resFilePath[SMALL_BUFFER_MAX_SIZE] = "";
);
}
- return runCommand(cmd, TRUE);
+ result = runCommand(cmd, TRUE);
+ if (result != 0) {
+ fprintf(stderr, "Error creating Windows DLL library. Failed command: %s\n", cmd);
+ }
+
+ return result;
}
#endif
static UPKGOptions *pkg_checkFlag(UPKGOptions *o) {
-#ifdef U_AIX
+#if U_PLATFORM == U_PF_AIX
/* AIX needs a map file. */
char *flag = NULL;
int32_t length = 0;
FileStream *f = NULL;
char mapFile[SMALL_BUFFER_MAX_SIZE] = "";
int32_t start = -1;
- int32_t count = 0;
+ uint32_t count = 0;
+ const char rm_cmd[] = "rm -f all ;";
+
+ flag = pkgDataFlags[GENLIB];
+
+ /* This portion of the code removes 'rm -f all' in the GENLIB.
+ * Only occurs in AIX.
+ */
+ if (uprv_strstr(flag, rm_cmd) != NULL) {
+ char *tmpGenlibFlagBuffer = NULL;
+ int32_t i, offset;
+
+ length = uprv_strlen(flag) + 1;
+ tmpGenlibFlagBuffer = (char *)uprv_malloc(length);
+ if (tmpGenlibFlagBuffer == NULL) {
+ /* Memory allocation error */
+ fprintf(stderr,"Unable to allocate buffer of size: %d.\n", length);
+ return NULL;
+ }
+
+ uprv_strcpy(tmpGenlibFlagBuffer, flag);
+
+ offset = uprv_strlen(rm_cmd);
+
+ for (i = 0; i < (length - offset); i++) {
+ flag[i] = tmpGenlibFlagBuffer[offset + i];
+ }
+
+ /* Zero terminate the string */
+ flag[i] = 0;
+
+ uprv_free(tmpGenlibFlagBuffer);
+ }
flag = pkgDataFlags[BIR_FLAGS];
length = uprv_strlen(pkgDataFlags[BIR_FLAGS]);
f = T_FileStream_open(mapFile, "w");
if (f == NULL) {
fprintf(stderr,"Unable to create map file: %s.\n", mapFile);
+ return NULL;
} else {
sprintf(tmpbuffer, "%s%s ", o->entryName, UDATA_CMN_INTERMEDIATE_SUFFIX);
T_FileStream_close(f);
}
}
-#elif defined(U_CYGWIN)
+#elif U_PLATFORM == U_PF_CYGWIN || U_PLATFORM == U_PF_MINGW
/* Cygwin needs to change flag options. */
char *flag = NULL;
int32_t length = 0;
}
uprv_memset(flag + position, 0, length - position);
-#elif defined(OS400)
- /* OS400 needs to fix the ld options (swap single quote with double quote) */
+#elif U_PLATFORM == U_PF_OS400
+ /* OS/400 needs to fix the ld options (swap single quote with double quote) */
char *flag = NULL;
int32_t length = 0;
char line[16384];
char *linePtr, *lineNext;
const uint32_t lineMax = 16300;
- char tmp[1024];
+ char *tmp;
+ int32_t tmpLength = 0;
char *s;
int32_t ln=0; /* line number */
}
/* remove spaces at the beginning */
linePtr = line;
+ /* On z/OS, disable call to isspace (#9996). Investigate using uprv_isspace instead (#9999) */
+#if U_PLATFORM != U_PF_OS390
while(isspace(*linePtr)) {
linePtr++;
}
+#endif
s=linePtr;
/* remove trailing newline characters */
while(*s!=0) {
/* normal mode.. o->files is just the bare list without package names */
o->files = pkg_appendToList(o->files, &tail, uprv_strdup(linePtr));
- if(uprv_pathIsAbsolute(s)) {
+ if(uprv_pathIsAbsolute(s) || s[0] == '.') {
fprintf(stderr, "pkgdata: Error: absolute path encountered. Old style paths are not supported. Use relative paths such as 'fur.res' or 'translit%cfur.res'.\n\tBad path: '%s'\n", U_FILE_SEP_CHAR, s);
exit(U_ILLEGAL_ARGUMENT_ERROR);
}
+ tmpLength = uprv_strlen(o->srcDir) +
+ uprv_strlen(s) + 5; /* 5 is to add a little extra space for, among other things, PKGDATA_FILE_SEP_STRING */
+ if((tmp = (char *)uprv_malloc(tmpLength)) == NULL) {
+ fprintf(stderr, "pkgdata: Error: Unable to allocate tmp buffer size: %d\n", tmpLength);
+ exit(U_MEMORY_ALLOCATION_ERROR);
+ }
uprv_strcpy(tmp, o->srcDir);
- uprv_strcat(tmp, o->srcDir[uprv_strlen(o->srcDir)-1] == U_FILE_SEP_CHAR ? "" :PKGDATA_FILE_SEP_STRING);
+ uprv_strcat(tmp, o->srcDir[uprv_strlen(o->srcDir)-1] == U_FILE_SEP_CHAR ? "" : PKGDATA_FILE_SEP_STRING);
uprv_strcat(tmp, s);
- o->filePaths = pkg_appendToList(o->filePaths, &tail2, uprv_strdup(tmp));
+ o->filePaths = pkg_appendToList(o->filePaths, &tail2, tmp);
linePtr = lineNext;
} /* for each entry on line */
} /* for each line */
/* #1 try the same path where pkgdata was called from. */
findDirname(progname, cmdBuf, 1024, &status);
if(U_SUCCESS(status)) {
- uprv_strncat(cmdBuf, U_FILE_SEP_STRING, 1024);
+ if (cmdBuf[0] != 0) {
+ uprv_strncat(cmdBuf, U_FILE_SEP_STRING, 1024);
+ }
uprv_strncat(cmdBuf, cmd, 1024);
if(verbose) {
p = popen(cmdBuf, "r");
}
- if(p == NULL) {
+ if(p == NULL || (n = fread(buf, 1, 511, p)) <= 0) {
if(verbose) {
fprintf(stdout, "# Calling icu-config: %s\n", cmd);
}
- p = popen(cmd, "r");
- }
+ pclose(p);
- if(p == NULL)
- {
- fprintf(stderr, "%s: icu-config: No icu-config found. (fix PATH or use -O option)\n", progname);
- return -1;
+ p = popen(cmd, "r");
+ if(p == NULL || (n = fread(buf, 1, 511, p)) <= 0) {
+ fprintf(stderr, "%s: icu-config: No icu-config found. (fix PATH or use -O option)\n", progname);
+ return -1;
+ }
}
- n = fread(buf, 1, 511, p);
-
pclose(p);
- if(n<=0)
- {
- fprintf(stderr,"%s: icu-config: Could not read from icu-config. (fix PATH or use -O option)\n", progname);
- return -1;
- }
-
for (int32_t length = strlen(buf) - 1; length >= 0; length--) {
if (buf[length] == '\n' || buf[length] == ' ') {
buf[length] = 0;
option->doesOccur = TRUE;
return 0;
-#endif
+#else
return -1;
+#endif
}