mirror of
https://github.com/apache/nuttx.git
synced 2026-05-30 05:16:47 +08:00
Extending tools/mkdeps.c
This commit is contained in:
+6
-2
@@ -49,13 +49,17 @@ HOSTCFLAGS ?= -O2 -Wall -Wstrict-prototypes -Wshadow -I. -DCONFIG_WINDOWS_NATIVE
|
|||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
# GCC is assumed in the POSIX environment.
|
# GCC is assumed in the POSIX environment (Linux or Cygwin).
|
||||||
# strtok_r is used in some tools, but does not seem to be available in
|
# strtok_r is used in some tools, but does not seem to be available in
|
||||||
# the MinGW environment.
|
# the MinGW environment.
|
||||||
|
|
||||||
HOSTCC ?= gcc
|
HOSTCC ?= gcc
|
||||||
HOSTCFLAGS ?= -O2 -Wall -Wstrict-prototypes -Wshadow -I. -DHAVE_STRTOK_C
|
HOSTCFLAGS ?= -O2 -Wall -Wstrict-prototypes -Wshadow -I.
|
||||||
|
HOSTCFLAGS += -DHAVE_STRTOK_C=1
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_WINDOWS_CYGWIN),y)
|
||||||
|
HOSTCFLAGS += -DHAVE_CYGWIN=1
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Targets
|
# Targets
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ static unsigned long g_lineno;
|
|||||||
static char g_line[MAX_LINE];
|
static char g_line[MAX_LINE];
|
||||||
static char g_dequoted[MAX_PATH];
|
static char g_dequoted[MAX_PATH];
|
||||||
static char g_posix[MAX_PATH];
|
static char g_posix[MAX_PATH];
|
||||||
static const char g_cygpath[] = "/usr/bin/cygpath";
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
|
|||||||
+190
-31
@@ -48,11 +48,17 @@
|
|||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_CYGWIN
|
||||||
|
# include <sys/cygwin.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#define MAX_BUFFER (4096)
|
#define MAX_BUFFER (4096)
|
||||||
|
#define MAX_EXPAND (2048)
|
||||||
|
#define MAX_PATH (512)
|
||||||
|
|
||||||
/* NAME_MAX is typically defined in limits.h */
|
/* NAME_MAX is typically defined in limits.h */
|
||||||
|
|
||||||
@@ -101,15 +107,19 @@ static char *g_objpath = NULL;
|
|||||||
static char *g_suffix = ".o";
|
static char *g_suffix = ".o";
|
||||||
static int g_debug = 0;
|
static int g_debug = 0;
|
||||||
static bool g_winnative = false;
|
static bool g_winnative = false;
|
||||||
|
|
||||||
#ifdef HAVE_WINPATH
|
#ifdef HAVE_WINPATH
|
||||||
static bool g_winpath = false;
|
static bool g_winpath = false;
|
||||||
static char *g_topdir = NULL;
|
static char *g_topdir = NULL;
|
||||||
#define DELIM "\\"
|
|
||||||
#else
|
|
||||||
#define DELIM "/"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static char g_command[MAX_BUFFER];
|
static char g_command[MAX_BUFFER];
|
||||||
|
static char g_expand[MAX_EXPAND];
|
||||||
|
|
||||||
|
#ifdef HAVE_CYGWIN
|
||||||
|
static char g_dequoted[MAX_PATH];
|
||||||
|
static char g_posixpath[MAX_PATH];
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
@@ -413,12 +423,144 @@ static void parse_args(int argc, char **argv)
|
|||||||
#ifdef HAVE_WINPATH
|
#ifdef HAVE_WINPATH
|
||||||
if (g_winnative && g_winpath)
|
if (g_winnative && g_winpath)
|
||||||
{
|
{
|
||||||
show_usage(argv[0], "ERROR: Both --winnative and --winpapth makes no sense", EXIT_FAILURE);
|
show_usage(argv[0], "ERROR: Both --winnative and --winpath makes no sense", EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_dependency(const char *file, char separator)
|
static const char *do_expand(const char *argument)
|
||||||
|
{
|
||||||
|
if (g_winnative)
|
||||||
|
{
|
||||||
|
const char *src;
|
||||||
|
char *dest;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
src = argument;
|
||||||
|
dest = g_expand;
|
||||||
|
len = 0;
|
||||||
|
|
||||||
|
while (*src && len < MAX_EXPAND)
|
||||||
|
{
|
||||||
|
if (*src == '\\')
|
||||||
|
{
|
||||||
|
*dest++ = '\\';
|
||||||
|
if (++len >= MAX_EXPAND)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*dest++ = *src++;
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*src)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: Truncated during expansion string is too long [%lu/%u]\n",
|
||||||
|
(unsigned long)strlen(argument), MAX_EXPAND);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
*dest = '\0';
|
||||||
|
return g_expand;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return argument;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_CYGWIN
|
||||||
|
static bool dequote_path(const char *winpath)
|
||||||
|
{
|
||||||
|
char *dest = g_dequoted;
|
||||||
|
const char *src = winpath;
|
||||||
|
int len = 0;
|
||||||
|
bool quoted = false;
|
||||||
|
|
||||||
|
while (*src && len < MAX_PATH)
|
||||||
|
{
|
||||||
|
if (src[0] != '\\' || (src[1] != ' ' && src[1] != '(' && src[1] != ')'))
|
||||||
|
{
|
||||||
|
*dest++ = *src;
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
quoted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*src || len >= MAX_PATH)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "# ERROR: Path truncated\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
*dest = '\0';
|
||||||
|
return quoted;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const char *convert_path(const char *path)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_CYGWIN
|
||||||
|
if (g_winnative)
|
||||||
|
{
|
||||||
|
const char *retptr;
|
||||||
|
ssize_t size;
|
||||||
|
ssize_t ret;
|
||||||
|
bool quoted;
|
||||||
|
|
||||||
|
quoted = dequote_path(path);
|
||||||
|
if (quoted)
|
||||||
|
{
|
||||||
|
retptr = g_posixpath;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retptr = &g_posixpath[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
size = cygwin_conv_path(CCP_POSIX_TO_WIN_A | CCP_RELATIVE, g_dequoted,
|
||||||
|
NULL, 0);
|
||||||
|
if (size > (MAX_PATH-3))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "# ERROR: POSIX path too long: %lu\n",
|
||||||
|
(unsigned long)size);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = cygwin_conv_path(CCP_POSIX_TO_WIN_A | CCP_RELATIVE, g_dequoted,
|
||||||
|
&g_posixpath[1], MAX_PATH-3);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "# ERROR: cygwin_conv_path '%s' failed: %s\n",
|
||||||
|
g_dequoted, strerror(errno));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (quoted)
|
||||||
|
{
|
||||||
|
size++;
|
||||||
|
g_posixpath[0] = '"';
|
||||||
|
g_posixpath[size] = '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
g_posixpath[size+1] = '\0';
|
||||||
|
return retptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_dependency(const char *file)
|
||||||
{
|
{
|
||||||
static const char moption[] = " -M ";
|
static const char moption[] = " -M ";
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
@@ -426,12 +568,17 @@ static void do_dependency(const char *file, char separator)
|
|||||||
char *altpath;
|
char *altpath;
|
||||||
char *path;
|
char *path;
|
||||||
char *lasts;
|
char *lasts;
|
||||||
|
char separator;
|
||||||
int cmdlen;
|
int cmdlen;
|
||||||
int pathlen;
|
int pathlen;
|
||||||
int filelen;
|
int filelen;
|
||||||
int totallen;
|
int totallen;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
/* Initialize the separator */
|
||||||
|
|
||||||
|
separator = g_winnative ? '\\' : '/';
|
||||||
|
|
||||||
/* Copy the compiler into the command buffer */
|
/* Copy the compiler into the command buffer */
|
||||||
|
|
||||||
cmdlen = strlen(g_cc);
|
cmdlen = strlen(g_cc);
|
||||||
@@ -444,16 +591,6 @@ static void do_dependency(const char *file, char separator)
|
|||||||
|
|
||||||
strcpy(g_command, g_cc);
|
strcpy(g_command, g_cc);
|
||||||
|
|
||||||
/* Copy " -M " */
|
|
||||||
|
|
||||||
cmdlen += strlen(moption);
|
|
||||||
if (cmdlen >= MAX_BUFFER)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "ERROR: Option string is too long [%d/%d]: %s\n",
|
|
||||||
cmdlen, MAX_BUFFER, moption);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy " -MT " */
|
/* Copy " -MT " */
|
||||||
|
|
||||||
if (g_objpath)
|
if (g_objpath)
|
||||||
@@ -462,6 +599,7 @@ static void do_dependency(const char *file, char separator)
|
|||||||
char *dupname;
|
char *dupname;
|
||||||
char *objname;
|
char *objname;
|
||||||
char *dotptr;
|
char *dotptr;
|
||||||
|
const char *expanded;
|
||||||
|
|
||||||
dupname = strdup(file);
|
dupname = strdup(file);
|
||||||
if (!dupname)
|
if (!dupname)
|
||||||
@@ -477,10 +615,11 @@ static void do_dependency(const char *file, char separator)
|
|||||||
*dotptr = '\0';
|
*dotptr = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(tmp, NAME_MAX+6, " -MT %s" DELIM "%s%s ",
|
snprintf(tmp, NAME_MAX+6, " -MT %s%c%s%s ",
|
||||||
g_objpath, objname, g_suffix);
|
g_objpath, separator, objname, g_suffix);
|
||||||
|
expanded = do_expand(tmp);
|
||||||
|
|
||||||
cmdlen += strlen(tmp);
|
cmdlen += strlen(expanded);
|
||||||
if (cmdlen >= MAX_BUFFER)
|
if (cmdlen >= MAX_BUFFER)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ERROR: Option string is too long [%d/%d]: %s\n",
|
fprintf(stderr, "ERROR: Option string is too long [%d/%d]: %s\n",
|
||||||
@@ -488,16 +627,28 @@ static void do_dependency(const char *file, char separator)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
strcat(g_command, tmp);
|
strcat(g_command, expanded);
|
||||||
free(dupname);
|
free(dupname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Copy " -M " */
|
||||||
|
|
||||||
|
cmdlen += strlen(moption);
|
||||||
|
if (cmdlen >= MAX_BUFFER)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: Option string is too long [%d/%d]: %s\n",
|
||||||
|
cmdlen, MAX_BUFFER, moption);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
strcat(g_command, moption);
|
strcat(g_command, moption);
|
||||||
|
|
||||||
/* Copy the CFLAGS into the command buffer */
|
/* Copy the CFLAGS into the command buffer */
|
||||||
|
|
||||||
if (g_cflags)
|
if (g_cflags)
|
||||||
{
|
{
|
||||||
|
const char *expanded;
|
||||||
|
|
||||||
cmdlen += strlen(g_cflags);
|
cmdlen += strlen(g_cflags);
|
||||||
if (cmdlen >= MAX_BUFFER)
|
if (cmdlen >= MAX_BUFFER)
|
||||||
{
|
{
|
||||||
@@ -506,7 +657,8 @@ static void do_dependency(const char *file, char separator)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
strcat(g_command, g_cflags);
|
expanded = do_expand(g_cflags);
|
||||||
|
strcat(g_command, expanded);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add a space */
|
/* Add a space */
|
||||||
@@ -534,9 +686,14 @@ static void do_dependency(const char *file, char separator)
|
|||||||
|
|
||||||
while ((path = strtok_r(altpath, " ", &lasts)) != NULL)
|
while ((path = strtok_r(altpath, " ", &lasts)) != NULL)
|
||||||
{
|
{
|
||||||
|
const char *expanded;
|
||||||
|
const char *converted;
|
||||||
|
|
||||||
/* Create a full path to the file */
|
/* Create a full path to the file */
|
||||||
|
|
||||||
pathlen = strlen(path);
|
expanded = do_expand(path);
|
||||||
|
pathlen = strlen(expanded);
|
||||||
|
|
||||||
totallen = cmdlen + pathlen;
|
totallen = cmdlen + pathlen;
|
||||||
if (totallen >= MAX_BUFFER)
|
if (totallen >= MAX_BUFFER)
|
||||||
{
|
{
|
||||||
@@ -545,7 +702,7 @@ static void do_dependency(const char *file, char separator)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(&g_command[cmdlen], path);
|
strcpy(&g_command[cmdlen], expanded);
|
||||||
|
|
||||||
if (g_command[totallen] != '\0')
|
if (g_command[totallen] != '\0')
|
||||||
{
|
{
|
||||||
@@ -553,7 +710,7 @@ static void do_dependency(const char *file, char separator)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_command[totallen-1] != separator)
|
if (g_command[totallen-1] != separator)
|
||||||
{
|
{
|
||||||
g_command[totallen] = separator;
|
g_command[totallen] = separator;
|
||||||
g_command[totallen+1] = '\0';
|
g_command[totallen+1] = '\0';
|
||||||
@@ -561,16 +718,17 @@ static void do_dependency(const char *file, char separator)
|
|||||||
totallen++;
|
totallen++;
|
||||||
}
|
}
|
||||||
|
|
||||||
filelen = strlen(file);
|
expanded = do_expand(file);
|
||||||
totallen += filelen;
|
filelen = strlen(expanded);
|
||||||
if (totallen >= MAX_BUFFER)
|
totallen += filelen;
|
||||||
{
|
if (totallen >= MAX_BUFFER)
|
||||||
|
{
|
||||||
fprintf(stderr, "ERROR: Path+file is too long [%d/%d]\n",
|
fprintf(stderr, "ERROR: Path+file is too long [%d/%d]\n",
|
||||||
totallen, MAX_BUFFER);
|
totallen, MAX_BUFFER);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
strcat(g_command, file);
|
strcat(g_command, expanded);
|
||||||
|
|
||||||
/* Check that a file actually exists at this path */
|
/* Check that a file actually exists at this path */
|
||||||
|
|
||||||
@@ -580,7 +738,8 @@ static void do_dependency(const char *file, char separator)
|
|||||||
path, file, &g_command[cmdlen]);
|
path, file, &g_command[cmdlen]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = stat(&g_command[cmdlen], &buf);
|
converted = convert_path(&g_command[cmdlen]);
|
||||||
|
ret = stat(converted, &buf);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
altpath = NULL;
|
altpath = NULL;
|
||||||
@@ -822,7 +981,7 @@ int main(int argc, char **argv, char **envp)
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
do_dependency(file, g_winnative ? '\\' : '/');
|
do_dependency(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
files = NULL;
|
files = NULL;
|
||||||
|
|||||||
+4
-4
@@ -39,7 +39,7 @@
|
|||||||
TOOLDIR=$(dirname $0)
|
TOOLDIR=$(dirname $0)
|
||||||
|
|
||||||
if [ ! -x ${TOOLDIR}/mkwindeps.sh ]; then
|
if [ ! -x ${TOOLDIR}/mkwindeps.sh ]; then
|
||||||
echo "ERROR: tools/ directory not found"
|
echo "# ERROR: tools/ directory not found"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -49,19 +49,19 @@ MKDEPS=${TOOLDIR}/mkdeps.exe
|
|||||||
CNVWINDEPS=${TOOLDIR}/cnvwindeps.exe
|
CNVWINDEPS=${TOOLDIR}/cnvwindeps.exe
|
||||||
|
|
||||||
if [ ! -x ${MKDEPS} ]; then
|
if [ ! -x ${MKDEPS} ]; then
|
||||||
echo "ERROR: tools/mkdeps.exe does not exist"
|
echo "# ERROR: tools/mkdeps.exe does not exist"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -x ${CNVWINDEPS} ]; then
|
if [ ! -x ${CNVWINDEPS} ]; then
|
||||||
echo "ERROR: tools/cnvwindeps.exe does not exist"
|
echo "# ERROR: tools/cnvwindeps.exe does not exist"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Run the mkdeps.exe program to generate a Windows dependency file
|
# Run the mkdeps.exe program to generate a Windows dependency file
|
||||||
|
|
||||||
TMPFILE=$(mktemp)
|
TMPFILE=$(mktemp)
|
||||||
${MKDEPS} $* > ${TMPFILE} || { echo "mkdeps.exe failed"; exit 1; }
|
${MKDEPS} --winnative $* > ${TMPFILE} || { echo "# ERROR: mkdeps.exe failed"; exit 1; }
|
||||||
|
|
||||||
# Then convert this to a POSIX dependency file (on stdout)
|
# Then convert this to a POSIX dependency file (on stdout)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user