Index: source/tools/pkgdata/pkgdata.cpp |
diff --git a/source/tools/pkgdata/pkgdata.cpp b/source/tools/pkgdata/pkgdata.cpp |
index 7d29ad6ffc3c8e3df1165140611ef3b14481cf02..03304ba74cc3eaf9a6e426ae5b093436223017c6 100644 |
--- a/source/tools/pkgdata/pkgdata.cpp |
+++ b/source/tools/pkgdata/pkgdata.cpp |
@@ -1,5 +1,5 @@ |
/****************************************************************************** |
- * Copyright (C) 2000-2014, International Business Machines |
+ * Copyright (C) 2000-2015, International Business Machines |
* Corporation and others. All Rights Reserved. |
******************************************************************************* |
* file name: pkgdata.cpp |
@@ -56,6 +56,13 @@ U_CDECL_BEGIN |
#include "pkgtypes.h" |
U_CDECL_END |
+#if U_HAVE_POPEN |
+ |
+using icu::LocalPointerBase; |
+ |
+U_DEFINE_LOCAL_OPEN_POINTER(LocalPipeFilePointer, FILE, pclose); |
+ |
+#endif |
static void loadLists(UPKGOptions *o, UErrorCode *status); |
@@ -73,6 +80,11 @@ static int32_t pkg_installCommonMode(const char *installDir, const char *fileNam |
static int32_t pkg_createWithoutAssemblyCode(UPKGOptions *o, const char *targetDir, const char mode); |
#endif |
+#ifdef CAN_WRITE_OBJ_CODE |
+static void pkg_createOptMatchArch(char *optMatchArch); |
+static void pkg_destroyOptMatchArch(char *optMatchArch); |
+#endif |
+ |
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, UBool specialHandling=FALSE); |
static int32_t pkg_archiveLibrary(const char *targetDir, const char *version, UBool reverseExt); |
@@ -730,7 +742,11 @@ static int32_t pkg_executeOptions(UPKGOptions *o) { |
#endif |
} else { |
#ifdef CAN_WRITE_OBJ_CODE |
- writeObjectCode(datFileNamePath, o->tmpDir, o->entryName, NULL, NULL, gencFilePath); |
+ /* Try to detect the arch type, use NULL if unsuccessful */ |
+ char optMatchArch[10] = { 0 }; |
+ pkg_createOptMatchArch(optMatchArch); |
+ writeObjectCode(datFileNamePath, o->tmpDir, o->entryName, (optMatchArch[0] == 0 ? NULL : optMatchArch), NULL, gencFilePath); |
+ pkg_destroyOptMatchArch(optMatchArch); |
#if U_PLATFORM_IS_LINUX_BASED |
result = pkg_generateLibraryFile(targetDir, mode, gencFilePath); |
#elif defined(WINDOWS_WITH_MSVC) |
@@ -816,6 +832,10 @@ static int32_t initializePkgDataFlags(UPKGOptions *o) { |
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 NULL */ |
+ for (int32_t n = i + 1; n < PKGDATA_FLAGS_SIZE; n++) { |
+ pkgDataFlags[n] = NULL; |
+ } |
return -1; |
} |
} |
@@ -837,7 +857,10 @@ static int32_t initializePkgDataFlags(UPKGOptions *o) { |
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]); |
+ if (pkgDataFlags[i]) { |
+ uprv_free(pkgDataFlags[i]); |
+ pkgDataFlags[i] = NULL; |
+ } |
} |
currentBufferSize = tmpResult; |
} else if (U_FAILURE(status)) { |
@@ -888,7 +911,8 @@ static void createFileNames(UPKGOptions *o, const char mode, const char *version |
} |
#if U_PLATFORM == U_PF_MINGW |
- sprintf(libFileNames[LIB_FILE_MINGW], "%s%s.lib", pkgDataFlags[LIBPREFIX], libName); |
+ // Name the import library lib*.dll.a |
+ sprintf(libFileNames[LIB_FILE_MINGW], "lib%s.dll.a", libName); |
#elif U_PLATFORM == U_PF_CYGWIN |
sprintf(libFileNames[LIB_FILE_CYGWIN], "cyg%s%s%s", |
libName, |
@@ -2078,7 +2102,7 @@ static void loadLists(UPKGOptions *o, UErrorCode *status) |
/* Try calling icu-config directly to get the option file. */ |
static int32_t pkg_getOptionsFromICUConfig(UBool verbose, UOption *option) { |
#if U_HAVE_POPEN |
- FILE *p = NULL; |
+ LocalPipeFilePointer p; |
size_t n; |
static char buf[512] = ""; |
icu::CharString cmdBuf; |
@@ -2097,24 +2121,21 @@ static void loadLists(UPKGOptions *o, UErrorCode *status) |
if(verbose) { |
fprintf(stdout, "# Calling icu-config: %s\n", cmdBuf.data()); |
} |
- p = popen(cmdBuf.data(), "r"); |
+ p.adoptInstead(popen(cmdBuf.data(), "r")); |
} |
- if(p == NULL || (n = fread(buf, 1, UPRV_LENGTHOF(buf)-1, p)) <= 0) { |
- if(verbose) { |
- fprintf(stdout, "# Calling icu-config: %s\n", cmd); |
- } |
- pclose(p); |
+ if(p.isNull() || (n = fread(buf, 1, UPRV_LENGTHOF(buf)-1, p.getAlias())) <= 0) { |
+ if(verbose) { |
+ fprintf(stdout, "# Calling icu-config: %s\n", cmd); |
+ } |
- p = popen(cmd, "r"); |
- if(p == NULL || (n = fread(buf, 1, UPRV_LENGTHOF(buf)-1, p)) <= 0) { |
- fprintf(stderr, "%s: icu-config: No icu-config found. (fix PATH or use -O option)\n", progname); |
- return -1; |
- } |
+ p.adoptInstead(popen(cmd, "r")); |
+ if(p.isNull() || (n = fread(buf, 1, UPRV_LENGTHOF(buf)-1, p.getAlias())) <= 0) { |
+ fprintf(stderr, "%s: icu-config: No icu-config found. (fix PATH or use -O option)\n", progname); |
+ return -1; |
+ } |
} |
- pclose(p); |
- |
for (int32_t length = strlen(buf) - 1; length >= 0; length--) { |
if (buf[length] == '\n' || buf[length] == ' ') { |
buf[length] = 0; |
@@ -2146,3 +2167,45 @@ static void loadLists(UPKGOptions *o, UErrorCode *status) |
return -1; |
#endif |
} |
+ |
+#ifdef CAN_WRITE_OBJ_CODE |
+ /* Create optMatchArch for genccode architecture detection */ |
+static void pkg_createOptMatchArch(char *optMatchArch) { |
+#if !defined(WINDOWS_WITH_MSVC) || defined(USING_CYGWIN) |
+ const char* code = "void oma(){}"; |
+ const char* source = "oma.c"; |
+ const char* obj = "oma.obj"; |
+ FileStream* stream = NULL; |
+ |
+ stream = T_FileStream_open(source,"w"); |
+ if (stream != NULL) { |
+ T_FileStream_writeLine(stream, code); |
+ T_FileStream_close(stream); |
+ |
+ char cmd[LARGE_BUFFER_MAX_SIZE]; |
+ sprintf(cmd, "%s %s -o %s", |
+ pkgDataFlags[COMPILER], |
+ source, |
+ obj); |
+ |
+ if (runCommand(cmd) == 0){ |
+ sprintf(optMatchArch, "%s", obj); |
+ } |
+ else { |
+ fprintf(stderr, "Failed to compile %s\n", source); |
+ } |
+ if(!T_FileStream_remove(source)){ |
+ fprintf(stderr, "T_FileStream_remove failed to delete %s\n", source); |
+ } |
+ } |
+ else { |
+ fprintf(stderr, "T_FileStream_open failed to open %s for writing\n", source); |
+ } |
+#endif |
+} |
+static void pkg_destroyOptMatchArch(char *optMatchArch) { |
+ if(T_FileStream_file_exists(optMatchArch) && !T_FileStream_remove(optMatchArch)){ |
+ fprintf(stderr, "T_FileStream_remove failed to delete %s\n", optMatchArch); |
+ } |
+} |
+#endif |