| /* --COPYRIGHT--,EPL |
| * Copyright (c) 2008-2019 Texas Instruments Incorporated |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Texas Instruments - initial implementation |
| * |
| * --/COPYRIGHT--*/ |
| /* |
| * ======== xdc.c ======== |
| * XDC Build Tool |
| * |
| * usage: xdc [-n] <goal> ... [-P package ...] |
| * |
| * Options: |
| * -h, -?, --help - display this message |
| * --help-make - display GNU make command options |
| * -k - don't stop on the first error (keep going for as |
| * long as possible) |
| * -n - don't do build just echo build commands |
| * -r[a] - use .xdcenv.mak to define XDCROOT, XDCPATH ... |
| * -P pkg ... - add package(s) to list of packages to build |
| * -PR dir ... - add all packages located under dir to the list |
| * of packages to build |
| * -Pr dir ... - add all packages whose repository is dir to the list |
| * of packages to build |
| * -PD pkg ... - add package(s) pkg and all packages that it |
| * (recursively)requires to the list of packages to build |
| */ |
| |
| #define xdc__deprecated_types |
| #include <xdc/std.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| |
| #include <xdc/services/host/lib/xutl.h> |
| #include <sys/stat.h> |
| |
| #define MAXNAME 512 |
| #define MAXARG (2 * MAXNAME) |
| #define MAXARGS 128 |
| #define MAXNEW 16 |
| |
| #if defined(xdc_target__os_Linux) |
| #include <unistd.h> |
| #define HOSTOS "HOSTOS=Linux" |
| #define LMAKE "../bin/gmake.x86U" |
| #endif |
| |
| #if defined(xdc_target__os_MacOS) |
| #include <unistd.h> |
| #define HOSTOS "HOSTOS=MacOS" |
| #define LMAKE "../bin/gmake.x86_64M" |
| #endif |
| |
| #if defined(xdc_target__os_Windows) |
| #define HOSTOS "HOSTOS=Windows" |
| #define LMAKE "..\\bin\\release\\gmake.exe" |
| #define DIRSTR "\\" |
| #define PATHSTR ";" |
| #define MAKE "bin" DIRSTR "gmake.exe" |
| |
| #include <windows.h> /* GetModuleFileName */ |
| #include <io.h> |
| |
| #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) |
| |
| #else /* Unix */ |
| |
| #define DIRSTR "/" |
| #define PATHSTR ":" |
| #define MAKE "bin" DIRSTR "gmake" |
| #endif |
| |
| #define PACKPREFIX "PACKAGES=" |
| #define PACKSUFFIX "" |
| |
| #define XDCREPO "packages" /* repo name under XDCROOT */ |
| #define XDCTOPMAKE (DIRSTR "xdc" DIRSTR "bld" DIRSTR "xdc_top.mak") |
| #define XDCMAKE (DIRSTR "xdc" DIRSTR "bld" DIRSTR "xdc.mak") |
| |
| static Bool rflag = FALSE; |
| static Bool nflag = FALSE; |
| static Int verbose = 0; |
| |
| static String root; /* root path; i.e., $(XDCROOT) */ |
| static Char rootDef[MAXARG]; /* XDCROOT=$(XDCROOT) */ |
| |
| static String repoName = XDCREPO; /* repository containing xdc packages */ |
| static Char repoDef[MAXARG]; /* XDCREPO=$(XDCREPO) */ |
| |
| #if 0 |
| static Char hostName[MAXARG]; /* HOSTNAME=<host-name> */ |
| #endif |
| |
| static Char makeCmd[MAXARG]; /* full path to make command */ |
| static Char makeFile[MAXARG]; /* $(XDCROOT)/$(XDCREPO)/XDCTOPMAKE if |
| * '-P[...]' option is supplied; otherwise |
| * $(XDCROOT)/$(XDCREPO)/XDCMAKE |
| */ |
| static String pkgsDef; /* PACKAGES="..." */ |
| static String xdcPathDef = NULL; /* XDCPATH= definition on command line */ |
| |
| static String makeArgv[MAXARGS]; |
| static Int makeArgc = 0; |
| |
| static String progName; |
| static String usage = \ |
| "usage: %s [-h?|--help] [--help-make] [-k] [-n] [-r[a]] [def ...] [goal ...]\n"\ |
| " [@opt-file] [-P[rRD] package-dir ...]\n\n" \ |
| " -h, -?, --help - display this message and exit\n" \ |
| " --help-make - display GNU make command options\n" \ |
| " -k - don't stop on first build error (keep going)\n" \ |
| " -n - show the make command but don't execute it\n" \ |
| " -r[a] - (rebuild) use existing .xdcenv.mak to define XDC\n" \ |
| " environment variables XDCROOT and XDCPATH. If -ra\n" \ |
| " is specified, XDCARGS and XDCTARGETS are also read\n"\ |
| " from this file rather than from the environment.\n" \ |
| " --xdcpath=path - set the XDCPATH to path. This is identical to\n" \ |
| " passing the definition XDCPATH=path on the \n" \ |
| " command line.\n" \ |
| " [def ...] - def is a name=value pair that overrides the value\n"\ |
| " of the environment variable named name within this\n"\ |
| " invocation of xdc\n" \ |
| " [goal ...] - goal is any valid GNU make command option or goal.\n"\ |
| " Common options and goals include:\n" \ |
| " .help - display package-specific goals\n" \ |
| " all - build all files\n" \ |
| " clean - delete all generated files\n" \ |
| " test - build and run all tests\n" \ |
| " release - build all package release archives\n"\ |
| " @opt-file - treat all options contained in the file opt-file\n"\ |
| " as though they were directly inserted at the \n"\ |
| " location of this @ option. This option may be \n"\ |
| " repeated anywhere on the command line. Each option\n"\ |
| " in opt-files must appear on a separate line and\n"\ |
| " contain only characters that should be part of \n"\ |
| " the option; no quote processing is done and all\n"\ |
| " space or tab characters are part of the option.\n"\ |
| " -P[rRD] dir .. - build specified goal(s) in all directories\n" \ |
| " named after -P that contain a build script.\n" \ |
| " If -PD is specified, build the package based at\n" \ |
| " dir and (recursively) all other prerequisites of\n"\ |
| " this package.\n" \ |
| " If -Pr is specified, build all packages whose\n" \ |
| " repository is dir.\n" \ |
| " If -PR is specified, recursively descend into\n" \ |
| " specified directories and build every package that\n"\ |
| " contains a build script.\n"; |
| |
| static String optsUsage = \ |
| " XDCOPTIONS options that affect output messages but never the\n" |
| " package bits actually generated include:\n" |
| " -d debug makefile generation\n" |
| " -q don't display any banners in recursive builds\n" |
| " -t don't display date timestamps in banners\n" |
| " -v show complete commands as they're executed\n" |
| " XDCPATH the user settable portion of the package path\n" |
| " XDCARGS arguments that are passed to the package's build \n" |
| " script, package.bld. The package's build script\n" |
| " references the arguments from the global array \n" |
| " arguments.\n" |
| " XDCBUILDCFG if defined and the file './config.bld' does not exist,\n" |
| " this variable names a file that will be used in-lieu of\n" |
| " the config.bld file found along the package path.\n" |
| " XDCTARGETS a string of white space separated target names that \n" |
| " name the set of targets to build for, if the set is not\n" |
| " already specified by the config.bld file\n"; |
| |
| static void checkXdcOptions(String arg); |
| static Void d2u(String buf); |
| static String findFile(String file, String path); |
| static Void findMake(Char *buffer, Uns max); |
| static char **genEnvp(String root, char *envp[]); |
| static String getRoot(String progName); |
| static Bool isFile(String name); |
| static Void printSetEnv(String env); |
| static Void printVers(String progName); |
| |
| /* |
| * ======== main ======== |
| */ |
| int main(int argc, char *argv[], char *envp[]) |
| { |
| Int status = 0; |
| Int i, j; |
| SizeT len; |
| String vs, err; |
| |
| progName = argv[0]; |
| |
| XUTL_init(); |
| argv = XUTL_expandArgv(argc, argv, &argc, &err); |
| if (argv == NULL) { |
| fprintf(stderr, "%s: unable to expand command line arguments: %s\n", |
| progName, err); |
| exit(1); |
| } |
| |
| if ((vs = getenv("XDC_VERBOSE")) != NULL) { |
| verbose = atoi(vs); |
| } |
| |
| root = getRoot(progName); |
| |
| sprintf(makeCmd, "%s%s", root, DIRSTR MAKE); |
| makeArgv[makeArgc++] = makeCmd; |
| makeArgv[makeArgc++] = "-r"; |
| makeArgv[makeArgc++] = "-R"; |
| makeArgv[makeArgc++] = HOSTOS; |
| #if 0 |
| sprintf(hostName, "HOSTNAME=%s", getHostName()); |
| makeArgv[makeArgc++] = hostName; |
| #endif |
| sprintf(rootDef, "XDCROOT=%s", root); |
| d2u(rootDef); |
| makeArgv[makeArgc++] = rootDef; |
| |
| /* we're in a non-standard repository, define XDCREPO */ |
| if (strcmp(repoName, XDCREPO) != 0) { |
| sprintf(repoDef, "XDCREPO=%s", repoName); |
| makeArgv[makeArgc++] = repoDef; |
| } |
| |
| sprintf(makeFile, "%s" DIRSTR "%s%s", root, repoName, XDCMAKE); |
| makeArgv[makeArgc++] = "-f"; |
| makeArgv[makeArgc++] = makeFile; |
| |
| /* parse options */ |
| for (i = 1; i < argc; i++) { |
| if (makeArgc >= MAXARGS) { |
| fprintf(stderr, "%s: out of memory.\n", progName); |
| exit(1); |
| } |
| if (argv[i][0] == '-') { |
| switch (argv[i][1]) { |
| case 'r': { |
| /* add "_USEXDCENV_=path" to make's argument list */ |
| if (rflag == FALSE) { |
| if (argv[i][2] == 'a') { |
| makeArgv[makeArgc++] = "_USEXDCENV_=path+args"; |
| } |
| else { |
| makeArgv[makeArgc++] = "_USEXDCENV_=path"; |
| } |
| } |
| rflag = TRUE; |
| break; |
| } |
| |
| case 'n': { |
| nflag = TRUE; |
| break; |
| } |
| |
| case 'P': { |
| Int n; |
| |
| /* this is a "big" make, so re-define the makefile */ |
| sprintf(makeFile, "%s" DIRSTR "%s%s", |
| root, repoName, XDCTOPMAKE); |
| |
| /* construct "PACKAGES=..." definition for make */ |
| len = 32; /* enough for PACKAGES="" + null-termination */ |
| for (j = i; j < argc; j++) { |
| len += strlen(argv[j]) + 1; |
| } |
| if ((pkgsDef = (String)malloc(len)) == NULL) { |
| fprintf(stderr, "%s: out of memory.\n", progName); |
| exit(1); |
| } |
| pkgsDef[0] = '\0'; |
| |
| switch (argv[i][2]) { |
| case '\0': { |
| break; |
| } |
| case 'r': |
| case 'D': |
| case 'R': { |
| if (argv[i][3] == '\0') { |
| pkgsDef[0] = argv[i][2]; |
| pkgsDef[1] = '\0'; |
| break; |
| } |
| /* intensionally fall into default case */ |
| } |
| default: { |
| /* unregognized -P[...] option */ |
| fprintf(stderr, usage, progName); |
| exit(1); |
| } |
| } |
| strcat(pkgsDef, PACKPREFIX); |
| for (n = 0, i++; i < argc; i++) { |
| strcat(pkgsDef, argv[i]); |
| if ((argc - i) > 1) { |
| /* delimit by semi to preserve spaces */ |
| strcat(pkgsDef, ";"); |
| } |
| n++; |
| } |
| strcat(pkgsDef, PACKSUFFIX); |
| |
| /* -P[...] requires at least one additional argument */ |
| if (n <= 0) { |
| fprintf(stderr, usage, progName); |
| exit(1); |
| } |
| |
| /* add "PACKAGES= ..." to make's argument list */ |
| makeArgv[makeArgc++] = pkgsDef; |
| break; |
| } |
| |
| case 'h': |
| case '?': { |
| fprintf(stderr, usage, progName); |
| fprintf(stderr, "\nEnvironment Variables\n"); |
| fprintf(stderr, optsUsage); |
| exit(0); |
| break; |
| } |
| |
| case '-': { |
| if (strncmp("help-make", argv[i] + 2, 9) == 0) { |
| makeArgv[makeArgc++] = "-h"; |
| /* set up args for call to gmake */ |
| break; |
| } |
| |
| if (strncmp("help", argv[i] + 2, 4) == 0) { |
| fprintf(stderr, usage, progName); |
| fprintf(stderr, "\nEnvironment Variables\n"); |
| fprintf(stderr, optsUsage); |
| exit(0); |
| break; |
| } |
| |
| if (strncmp("xdcpath", argv[i] + 2, 7) == 0) { |
| String src; |
| if (argv[i][9] == '\0') { |
| i++; |
| if (i >= argc) { |
| fprintf(stderr, usage, progName); |
| exit(1); |
| } |
| src = argv[i]; |
| } |
| else { |
| src = argv[i] + 10; |
| } |
| |
| xdcPathDef = (String)malloc(strlen(src) + 32); |
| if (xdcPathDef == NULL) { |
| fprintf(stderr, "%s: out of memory\n", progName); |
| exit(1); |
| } |
| sprintf(xdcPathDef, "XDCPATH=%s", src); |
| makeArgv[makeArgc++] = xdcPathDef; |
| break; |
| } |
| |
| if (strncmp("xdc", argv[i] + 2, 3) == 0) { |
| /* unknown --xdc* option */ |
| fprintf(stderr, usage, progName); |
| exit(1); |
| } |
| |
| if (strncmp("ver", argv[i] + 2, 3) == 0) { |
| printVers(progName); |
| printf("\n"); |
| } |
| |
| /* FALL THROUGH */ |
| } |
| default: { |
| makeArgv[makeArgc++] = argv[i]; |
| break; |
| } |
| } |
| } |
| else { |
| if (strncmp("XDCPATH=", argv[i], 8) == 0) { |
| xdcPathDef = argv[i]; |
| } |
| checkXdcOptions(argv[i]); |
| makeArgv[makeArgc++] = argv[i]; |
| } |
| } |
| |
| /* replace consecutive semicolons in XDCPATH by single semicolon */ |
| if (xdcPathDef != NULL) { |
| for (i = 0, j = 0; xdcPathDef[i] != '\0'; i++) { |
| if (!((xdcPathDef[i] == ';') && (xdcPathDef[i + 1] == ';'))) { |
| xdcPathDef[j] = xdcPathDef[i]; |
| j++; |
| } |
| } |
| xdcPathDef[j] = '\0'; |
| } |
| |
| /* now "range check" the environment settings */ |
| checkXdcOptions(NULL); |
| |
| /* if we can't find make in XDCROOT/bin, try alternatives */ |
| if (access(makeArgv[0], 00) != 0) { |
| findMake(makeArgv[0], MAXNAME); |
| } |
| |
| /* set PATH in environment before executing or displaying command */ |
| envp = genEnvp(root, envp); |
| |
| /* if verbose flag is set, display the commands to be executed */ |
| if (nflag == TRUE || verbose >= 1) { |
| if (verbose >= 2) { |
| for (i = 0; envp[i] != NULL; i++) { |
| printf("%s\n", envp[i]); |
| } |
| printf("\n"); |
| } |
| |
| /* display the make command */ |
| for (i = 0; i < makeArgc; i++) { |
| if (i > 0 && strpbrk(makeArgv[i], " \t;") != NULL) { |
| printf("\"%s\" ", makeArgv[i]); |
| } |
| else { |
| printf("%s ", makeArgv[i]); |
| } |
| } |
| printf("\n"); |
| fflush(stdout); |
| } |
| |
| if (nflag == FALSE) { |
| /* execute make command */ |
| if ((status = XUTL_run(makeArgv[0], makeArgv, envp))) { |
| fprintf(stderr, "%s: can't execute '%s' ", progName, makeArgv[0]); |
| perror("because"); |
| } |
| } |
| |
| /* if the exec failed, return its error status */ |
| return (status); |
| } |
| |
| /* |
| * ======== checkXdcOptions ======== |
| */ |
| static void checkXdcOptions(String arg) |
| { |
| String opts = NULL; |
| static Bool checked = FALSE; |
| |
| if (checked) { |
| return; |
| } |
| |
| if (arg == NULL) { |
| opts = getenv("XDCOPTIONS"); |
| } |
| else if (strncmp("XDCOPTIONS=", arg, 11) == 0) { |
| opts = arg + 11; |
| checked = TRUE; |
| } |
| |
| if (opts != NULL) { |
| Char *tok = strtok(opts, "-tdgvq \t\n\r"); |
| if (tok != NULL) { |
| fprintf(stderr, |
| "%s: Warning: unknown setting for XDCOPTIONS (='%s')\n", |
| progName, opts); |
| fprintf(stderr, optsUsage); |
| } |
| } |
| } |
| |
| /* |
| * ======== d2u ======== |
| * Convert DOS path string into unix path string |
| */ |
| static Void d2u(String buf) |
| { |
| Char *cp; |
| |
| for (cp = buf; *cp != '\0'; cp++) { |
| if (*cp == '\\') { |
| *cp = '/'; |
| } |
| } |
| } |
| |
| /* |
| * ======== findMake ======== |
| */ |
| static Void findMake(Char *buffer, Uns max) |
| { |
| String path, tmp; |
| String tools, mach; |
| Int n; |
| |
| String names[] = { |
| #if defined(xdc_target__os_Windows) |
| "gmake.exe", "gnumake.exe", "make.exe" |
| #else |
| "gmake", "gnumake", "make" |
| #endif |
| }; |
| # define MAXEXE 16 /* MAXEXE > max string len in names[] */ |
| |
| /* look in XDCROOT first (to support alternative installations) */ |
| if ((strlen(root) + MAXEXE) > max) { |
| return; |
| } |
| for (n = 0; n < (sizeof(names) / sizeof(String)); n++) { |
| sprintf(buffer, "%s" DIRSTR "%s", root, names[n]); |
| if (access(buffer, 00) == 0) { |
| return; |
| } |
| } |
| |
| /* if TOOLS is defined, try iliad tree and the tools */ |
| if ((tools = getenv("TOOLS")) != NULL && (mach = getenv("_M")) != NULL) { |
| sprintf(buffer, "%s" DIRSTR "%s", root, LMAKE); |
| if (access(buffer, 00) == 0) { |
| return; |
| } |
| else { |
| if ((strlen(tools) + strlen(mach) + MAXEXE + 8) > max) { |
| return; |
| } |
| for (n = 0; n < (sizeof(names) / sizeof(String)); n++) { |
| sprintf(buffer, "%s" DIRSTR "bin%s" DIRSTR "%s", |
| tools, mach, names[n]); |
| if (access(buffer, 00) == 0) { |
| return; |
| } |
| } |
| } |
| } |
| |
| /* if we still can't find it, try the user's path */ |
| if ((path = getenv("PATH")) != NULL |
| || (path = getenv("Path")) != NULL) { |
| for (n = 0; n < (sizeof(names) / sizeof(String)); n++) { |
| if ((tmp = findFile(names[n], path)) != NULL) { |
| strcpy(buffer, tmp); |
| return; |
| } |
| } |
| } |
| |
| /* last ditch effort: let OS try to find gnumake */ |
| strcpy(buffer, "gnumake"); |
| } |
| |
| /* |
| * ======== findFile ======== |
| */ |
| static String findFile(String file, String path) |
| { |
| static Char nameBuf[MAXNAME + 1]; |
| String pathBuf = NULL; |
| String tmp; |
| SizeT len; |
| |
| /* if the nameBuf is too small we fail */ |
| if (file == NULL || (len = strlen(file)) > MAXNAME) { |
| return (NULL); |
| } |
| |
| /* if file is a full path name, test it unadorned */ |
| if (file[0] == DIRSTR[0] || file[1] == ':') { |
| if (isFile(nameBuf)) { |
| strcpy(nameBuf, file); |
| return (nameBuf); |
| } |
| } |
| |
| if (path == NULL) { |
| return (NULL); |
| } |
| |
| /* otherwise, try every prefix in path */ |
| if ((pathBuf = (Char *)malloc(strlen(path) + 1)) != NULL) { |
| strcpy(pathBuf, path); |
| |
| tmp = strtok(pathBuf, PATHSTR); |
| for (; tmp != NULL; tmp = strtok(NULL, PATHSTR)) { |
| if ((len + 1 + strlen(tmp)) <= MAXNAME) { |
| sprintf(nameBuf, "%s%s%s", tmp, DIRSTR, file); |
| if (isFile(nameBuf)) { |
| free(pathBuf); |
| return (nameBuf); |
| } |
| } |
| } |
| free(pathBuf); |
| } |
| |
| return (NULL); |
| } |
| |
| /* |
| * ======== genEnvp ======== |
| * Generates environment for build tools: |
| * o redefine XDCROOT and XDCPATH as necessary |
| * o Add root to the beginning of PATH environment variable to ensure |
| * that our build tools are used within make. |
| * o remove CLASSPATH from environment to avoid in appropriate |
| * versions of Java or Java classes. |
| * o remove ENV to prevent shell from executing commands in the |
| * file named by $ENV for every shell use by gmake. It is for |
| * performance purposes only. |
| * o remove MAKEFLAGS to prevent xdc's make from reading make options |
| * set by a make calling xdc; e.g., the silent flag will prevent |
| * XDCOPTIONS=v from doing what is expected. |
| * o remove MAKELEVEL to prevent xdc's make from getting confused |
| * by a make calling xdc; e.g., a non-zero MAKELEVEL triggers |
| * the "print directories" feature (unless explicitly disabled) |
| */ |
| static char **genEnvp(String root, char *envp[]) |
| { |
| Int i, j; |
| Int envc; |
| char **newEnvp = NULL; |
| String tmp; |
| |
| /* clone envp so we don't mess with the C runtime's copy */ |
| for (envc = i = 0; envp[i] != NULL; i++) { |
| envc++; |
| } |
| if ((newEnvp = malloc((envc + MAXNEW + 1) * sizeof(String))) == NULL) { |
| fprintf(stderr, "%s: out of memory\n", progName); |
| exit(1); |
| } |
| memcpy(newEnvp, envp, envc * sizeof(String)); |
| newEnvp[envc] = NULL; |
| envp = newEnvp; |
| |
| /* re-define selected environment variables */ |
| for (i = 0; envp[i] != NULL; i++) { |
| /* redefine XDCROOT (if necessary) */ |
| if (strncmp("XDCROOT=", envp[i], 8) == 0) { |
| envp[i] = rootDef; |
| if (nflag) { |
| printSetEnv(envp[i]); |
| } |
| } |
| else if (xdcPathDef != NULL && strncmp("XDCPATH=", envp[i], 8) == 0) { |
| /* we need to put XDCPATH in the environment because GNU make |
| * does not set the environment for commands run via $(shell ...) |
| * and we want all such commands to see the path specified on |
| * the command line |
| */ |
| envp[i] = xdcPathDef; |
| xdcPathDef = NULL; |
| if (nflag) { |
| printSetEnv(envp[i]); |
| } |
| } |
| else { |
| /* redefine PATH */ |
| String prefix[] = {"PATH=", "Path=", "path="}; |
| for (j = 0; j < (sizeof(prefix) / sizeof(String)); j++) { |
| if (strncmp(prefix[j], envp[i], strlen(prefix[j])) == 0) { |
| String path; |
| String mach; |
| SizeT len = strlen(envp[i]) + strlen(root) + 32; |
| |
| if ((path = (String)malloc(len)) == NULL) { |
| fprintf(stderr, "%s: out of memory\n", progName); |
| exit(1); |
| } |
| if ((mach = getenv("_M")) != NULL) { |
| sprintf(path, "%s" DIRSTR "bin%s", root, mach); |
| if (access(path, 00) != 0) { |
| mach = ""; |
| } |
| } |
| else { |
| mach = ""; |
| } |
| |
| /* add $XDCROOT/bin$_M to end of existing path */ |
| sprintf(path, "%s" PATHSTR "%s" DIRSTR "bin%s", |
| envp[i], root, mach); |
| envp[i] = path; |
| if (nflag) { |
| printSetEnv(envp[i]); |
| } |
| } |
| } |
| } |
| } |
| |
| /* remove undesirable environment variables */ |
| for (envc = i = 0; envp[i] != NULL; i++) { |
| String removeTab[] = { |
| "CLASSPATH=", |
| "ENV=", |
| "MAKELEVEL=", "MAKEFLAGS=" |
| }; |
| for (j = 0; j < (sizeof(removeTab) / sizeof(String)); j++) { |
| if (strncmp(removeTab[j], envp[i], strlen(removeTab[j])) == 0) { |
| if (nflag) { |
| printSetEnv(removeTab[j]); |
| } |
| break; |
| } |
| } |
| |
| /* if envp[i] is not in the undesirable list, add it to the env */ |
| if (j >= (sizeof(removeTab) / sizeof(String))) { |
| envp[envc++] = envp[i]; |
| } |
| } |
| |
| /* add XDCPATH,xdc definition */ |
| tmp = getenv("XDCPATH"); |
| if (tmp != NULL) { |
| String envDef; |
| if ((envDef = malloc(strlen(tmp) * sizeof (char) + 80)) == NULL) { |
| fprintf(stderr, "%s: out of memory\n", progName); |
| exit(1); |
| } |
| sprintf(envDef, "XDCPATH,xdc=%s", tmp); |
| d2u(envDef); |
| newEnvp[envc++] = envDef; |
| if (nflag) { |
| printSetEnv(envDef); |
| } |
| } |
| |
| /* add XDCPATH definition, if it's not already in the environment */ |
| if (xdcPathDef != NULL) { |
| /* we need to put XDCPATH in the environment because GNU make |
| * does not set the environment for commands run via $(shell ...) |
| */ |
| newEnvp[envc++] = xdcPathDef; |
| if (nflag) { |
| printSetEnv(xdcPathDef); |
| } |
| } |
| |
| /* NULL terminate and return new environment array */ |
| newEnvp[envc] = NULL; |
| |
| return (newEnvp); |
| } |
| |
| #if 0 |
| /* |
| * ======== getHostName ======== |
| */ |
| static String getHostName(Void) |
| { |
| static Char name[MAXNAME + 1]; |
| #if defined(xdc_target__os_Windows) |
| static Bool init = FALSE; |
| if (init == FALSE) { |
| WSADATA wsaData; |
| init = TRUE; |
| if ( WSAStartup( MAKEWORD( 1, 1 ), &wsaData) != 0 ) { |
| /* we could not find a usable WinSock DLL. */ |
| return(""); |
| } |
| } |
| #endif |
| |
| if (gethostname(name, MAXNAME) != 0) { |
| return(""); |
| } |
| name[MAXNAME] = '\0'; |
| |
| return (name); |
| } |
| #endif |
| |
| /* |
| * ======== getRepo ======== |
| * Update root by stripping the package directories from the end. |
| * |
| * Returns a pointer to the first character of the last directory |
| * containing the package; e.g., |
| */ |
| static String getRepo(String root, String pname) |
| { |
| Char *cp; |
| String token; |
| |
| cp = root + strlen(root) - 1; |
| |
| do { |
| /* get next package token to match */ |
| token = strrchr(pname, '.'); |
| if (token == NULL) { |
| token = pname; |
| } |
| else { |
| token++; |
| } |
| |
| /* strip trailing directory characters */ |
| while (cp > root && (*cp == '/' || *cp == '\\')) { |
| *cp-- = '\0'; |
| } |
| |
| /* find the start of the last directory in root */ |
| while (cp > root && (*cp != '/' && *cp != '\\')) { |
| cp--; |
| } |
| |
| if (strcmp(cp + 1, token) != 0) { |
| return (NULL); /* package name and directory names don't match */ |
| } |
| |
| /* remove token from root and pname */ |
| *cp = '\0'; |
| if (token != pname) { |
| token[-1] = '\0'; /* -1 needed to remove leading '.' */ |
| } |
| } while (token != pname); |
| |
| /* strip trailing directory characters */ |
| while (cp > root && (*cp == '/' || *cp == '\\')) { |
| *cp-- = '\0'; |
| } |
| /* find the start of the repository in root */ |
| while (cp > root && (*cp != '/' && *cp != '\\')) { |
| cp--; |
| } |
| |
| return (cp); |
| } |
| |
| /* |
| * ======== getRoot ======== |
| * Return the installation directory of the XDCtools |
| * |
| * This executable can be run from one of two places: |
| * 1. XDCROOT |
| * 2. XDCROOT/<some_repository>/<some_package> |
| * |
| * To determine the XDCROOT we first locate the directory containing |
| * this executable. If this directory is the package providing this |
| * executable (e.g., xdc.services.host.bin), XDCROOT is the directory |
| * containing this package's repository; otherwise, XDCROOT is the |
| * directory containing this executable. |
| * |
| * Warning: this function uses rootDef as a scratch buffer. |
| */ |
| static String getRoot(String progName) |
| { |
| String pname; |
| String root; |
| |
| /* find where this executable lives */ |
| if ((root = XUTL_getProgPath(progName)) == NULL) { |
| fprintf(stderr, |
| "%s: can't determine XDCROOT: %s\n", progName, |
| XUTL_getLastErrorString()); |
| exit(1); |
| } |
| |
| /* as an optimization, first check for default root/$(XDCREPO) */ |
| sprintf(rootDef, "%s%c" XDCREPO, root, DIRSTR[0]); |
| if (XUTL_isDir(rootDef)) { |
| return (root); |
| } |
| |
| /* check to see if root is the base of a package */ |
| if ((pname = XUTL_getPackageName(root, FALSE)) != NULL) { |
| Char *cp; |
| |
| /* make a copy of root; so getRepo can modify it */ |
| rootDef[strlen(root)] = '\0'; |
| |
| /* strip <some_repository>/<some_package> from the copy of root */ |
| if ((cp = getRepo(rootDef, pname)) != NULL) { |
| |
| /* if getRepo succeeds, apply the changes to root */ |
| root[strlen(rootDef)] = '\0'; |
| |
| /* extract non-default repository name; redefine repoName */ |
| repoName = root + (cp - rootDef); |
| *repoName++ = '\0'; |
| } |
| } |
| |
| if (pname != NULL) { |
| #if 0 |
| printf("xdc: pkg name %s, root = %s, repo = %s\n", |
| pname, root, repoName); |
| #endif |
| free(pname); |
| } |
| |
| return (root); |
| } |
| |
| /* |
| * ======== isFile ======== |
| * Return TRUE iff name exists and is not a directory |
| */ |
| static Bool isFile(String name) |
| { |
| struct stat buf; |
| |
| if (stat(name, &buf) == 0 && !S_ISDIR(buf.st_mode)) { |
| return (TRUE); |
| } |
| |
| return (FALSE); |
| } |
| |
| /* |
| * ======== printSetEnv ======== |
| */ |
| static Void printSetEnv(String env) |
| { |
| printf("set %s\n", env); |
| } |
| |
| /* |
| * ======== printVers ======== |
| */ |
| #define _NAME_ "xdc" |
| #define _DATE_ __DATE__ |
| #define _CSUM_ "0" |
| |
| #include "../ident.c" |
| |
| static Void printVers(String progName) |
| { |
| fprintf(stderr, "%s: version %s, %s\n", progName, |
| __VERS + 8, __DATE); /* "used" to prevent compiler warnings */ |
| } |