From 5aae52d3ef316b3fd3c43b3f974a8032d279e6fc Mon Sep 17 00:00:00 2001 From: Hugh McMaster Date: Mon, 23 Dec 2019 22:11:05 +1100 Subject: [PATCH] ICU-20924 Use pkg-config to generate the path to pkgdata.inc --- icu4c/source/tools/pkgdata/pkgdata.cpp | 84 +++++++++++++------------- 1 file changed, 43 insertions(+), 41 deletions(-) diff --git a/icu4c/source/tools/pkgdata/pkgdata.cpp b/icu4c/source/tools/pkgdata/pkgdata.cpp index 7235a7f669d..6406fcc7a5b 100644 --- a/icu4c/source/tools/pkgdata/pkgdata.cpp +++ b/icu4c/source/tools/pkgdata/pkgdata.cpp @@ -95,7 +95,7 @@ static int32_t pkg_archiveLibrary(const char *targetDir, const char *version, UB 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 int32_t pkg_getPkgDataPath(UBool verbose, UOption *option); static int runCommand(const char* command, UBool specialHandling=FALSE); #define IN_COMMON_MODE(mode) (mode == 'a' || mode == 'c') @@ -309,7 +309,7 @@ main(int argc, char* argv[]) { #if !defined(WINDOWS_WITH_MSVC) || defined(USING_CYGWIN) if(!options[BLDOPT].doesOccur && uprv_strcmp(options[MODE].value, "common") != 0) { - if (pkg_getOptionsFromICUConfig(options[VERBOSE].doesOccur, &options[BLDOPT]) != 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; @@ -2158,41 +2158,46 @@ static void loadLists(UPKGOptions *o, UErrorCode *status) } /* for each file list file */ } -/* Try calling icu-config directly to get the option file. */ - static int32_t pkg_getOptionsFromICUConfig(UBool verbose, UOption *option) { +/* Helper for pkg_getPkgDataPath() */ #if U_HAVE_POPEN - LocalPipeFilePointer p; - size_t n; - static char buf[512] = ""; +static UBool getPkgDataPath(const char *cmd, UBool verbose, char *buf, size_t items) { icu::CharString cmdBuf; UErrorCode status = U_ZERO_ERROR; - const char cmd[] = "icu-config --incpkgdatafile"; - char dirBuf[1024] = ""; - /* #1 try the same path where pkgdata was called from. */ - findDirname(progname, dirBuf, UPRV_LENGTHOF(dirBuf), &status); - if(U_SUCCESS(status)) { - cmdBuf.append(dirBuf, status); - if (cmdBuf[0] != 0) { - cmdBuf.append( U_FILE_SEP_STRING, status ); - } - cmdBuf.append( cmd, status ); - - if(verbose) { - fprintf(stdout, "# Calling icu-config: %s\n", cmdBuf.data()); - } - p.adoptInstead(popen(cmdBuf.data(), "r")); - } - - if(p.isNull() || (n = fread(buf, 1, UPRV_LENGTHOF(buf)-1, p.getAlias())) <= 0) { - if(verbose) { - fprintf(stdout, "# Calling icu-config: %s\n", cmd); - } + LocalPipeFilePointer p; + size_t n; - 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); + cmdBuf.append(cmd, status); + if (verbose) { + fprintf(stdout, "# Calling: %s\n", cmdBuf.data()); + } + p.adoptInstead( popen(cmdBuf.data(), "r") ); + + if (p.isNull() || (n = fread(buf, 1, items-1, p.getAlias())) <= 0) { + fprintf(stderr, "%s: Error calling '%s'\n", progname, cmd); + *buf = 0; + return FALSE; + } + + return TRUE; +} +#endif + +/* Get path to pkgdata.inc. Try pkg-config first, falling back to icu-config. */ +static int32_t pkg_getPkgDataPath(UBool verbose, UOption *option) { +#if U_HAVE_POPEN + static char buf[512] = ""; + UBool pkgconfigIsValid = TRUE; + const char *pkgconfigCmd = "pkg-config --variable=pkglibdir icu-uc"; + const char *icuconfigCmd = "icu-config --incpkgdatafile"; + const char *pkgdata = "pkgdata.inc"; + + if (!getPkgDataPath(pkgconfigCmd, verbose, buf, UPRV_LENGTHOF(buf))) { + if (!getPkgDataPath(icuconfigCmd, verbose, buf, UPRV_LENGTHOF(buf))) { + fprintf(stderr, "%s: icu-config not found. Fix PATH or specify -O option\n", progname); return -1; } + + pkgconfigIsValid = FALSE; } for (int32_t length = strlen(buf) - 1; length >= 0; length--) { @@ -2203,21 +2208,18 @@ static void loadLists(UPKGOptions *o, UErrorCode *status) } } - if(buf[strlen(buf)-1]=='\n') - { - buf[strlen(buf)-1]=0; - } - - if(buf[0] == 0) - { - fprintf(stderr, "%s: icu-config: invalid response from icu-config (fix PATH or use -O option)\n", progname); + if (!*buf) { + fprintf(stderr, "%s: Unable to locate pkgdata.inc. Unable to parse the results of '%s'. Check paths or use the -O option to specify the path to pkgdata.inc.\n", progname, pkgconfigIsValid ? pkgconfigCmd : icuconfigCmd); return -1; } - if(verbose) { - fprintf(stdout, "# icu-config said: %s\n", buf); + if (pkgconfigIsValid) { + uprv_strcat(buf, U_FILE_SEP_STRING); + uprv_strcat(buf, pkgdata); } + buf[strlen(buf)] = 0; + option->value = buf; option->doesOccur = TRUE; -- 2.40.0