Skip to contentSkip to conversation

Proper gcc header dir handling in sparse.

PATCH In review Alexey zaytsev 3 participants 7 messages Dec 8, 2008 – Dec 15, 2008

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover Proper gcc header dir handling in sparse.

[Resending with correct ml address. Sorry.]

Hello.

People have convinced me that sparse should take gcc base directory as a run-time parameter, so it could be used with gcc versions differing from the one sparse was compiled with.
So here it goes, along with some related fixes.

The patches may also be pulled from

git://git.zaytsev.su/git/sparse.git git-base-dir

Also, the first two patches should fix the Debian bug 505177:

       http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=505177

---

Alexey zaytsev (4):
Set gcc include path at runtime.
Let cgcc pass -gcc-base-dir to sparse. Document -gcc-base-dir in sparse.1 Rename dirafter to idirafter.

 Makefile      |    7 ++--
 cgcc          |   14 ++++++++
 lib.c         |   30 ++++++++++++-----
 pre-process.c |   98 +++++++++++++++++++++++++++++++++++++++++++++------------
 sparse.1      |    5 +++
 5 files changed, 119 insertions(+), 35 deletions(-)
#1 lore raw

PATCH 1/4 Set gcc include path at runtime.

You can now tell sparse where to look for the compiler headers with -gcc-base-dir <dir>. Otherwise sparse will look for headers used to build it.

Also adds $GCC_BASE/include-fixed used by newer gcc versions.

---
 Makefile      |    7 ++--
 lib.c         |   23 ++++++++++++--
 pre-process.c |   96 +++++++++++++++++++++++++++++++++++++++++++++------------
 3 files changed, 99 insertions(+), 27 deletions(-)
Makefile +3 -4
index 3eab17e..78c2ce7 100644
@@ -15,6 +15,8 @@ HAVE_LIBXML=$(shell pkg-config --exists libxml-2.0 && echo 'yes')
 #
 CFLAGS += -DDEBUG
 
+CFLAGS += -DGCC_BASE=\"$(shell $(CC) --print-file-name=)\"
+
 DESTDIR=
 PREFIX=$(HOME)
 BINDIR=$(PREFIX)/bin
@@ -145,7 +147,7 @@ lib.o: $(LIB_H)
 allocate.o: $(LIB_H)
 ptrlist.o: $(LIB_H)
 parse.o: $(LIB_H)
-pre-process.o: $(LIB_H) pre-process.h
+pre-process.o: $(LIB_H)
 scope.o: $(LIB_H)
 show-parse.o: $(LIB_H)
 symbol.o: $(LIB_H)
@@ -184,9 +186,6 @@ compat-solaris.o: compat/mmap-blob.c $(LIB_H)
 compat-mingw.o: $(LIB_H)
 compat-cygwin.o: $(LIB_H)
 
-pre-process.h:
-	$(QUIET_GEN)echo "#define GCC_INTERNAL_INCLUDE \"`$(CC) -print-file-name=include`\"" > pre-process.h
-
 .c.o:
 	$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $<
 
lib.c +20 -3
index 0abcc9a..b579834 100644
@@ -41,6 +41,8 @@ int gcc_major = __GNUC__;
 int gcc_minor = __GNUC_MINOR__;
 int gcc_patchlevel = __GNUC_PATCHLEVEL__;
 
+static const char *gcc_base_dir = GCC_BASE;
+
 struct token *skip_to(struct token *token, int op)
 {
 	while (!match_op(token, op) && !eof_token(token))
@@ -580,6 +582,14 @@ static char **handle_dirafter(char *arg, char **next)
 	return next;
 }
 
+static char **handle_base_dir(char *arg, char **next)
+{
+	gcc_base_dir = *++next;
+	if (!gcc_base_dir)
+		die("missing argument for -gcc-base-dir option");
+	return next;
+}
+
 struct switches {
 	const char *name;
 	char **(*fn)(char *, char **);
@@ -590,6 +600,7 @@ char **handle_switch(char *arg, char **next)
 	static struct switches cmd[] = {
 		{ "nostdinc", handle_nostdinc },
 		{ "dirafter", handle_dirafter },
+		{ "gcc-base-dir", handle_base_dir},
 		{ NULL, NULL }
 	};
 	struct switches *s;
@@ -633,8 +644,8 @@ void declare_builtin_functions(void)
 	/* Gaah. gcc knows tons of builtin <string.h> functions */
 	add_pre_buffer("extern void *__builtin_memcpy(void *, const void *, __SIZE_TYPE__);\n");
 	add_pre_buffer("extern void *__builtin_mempcpy(void *, const void *, __SIZE_TYPE__);\n");
-	add_pre_buffer("extern void *__builtin_memset(void *, int, __SIZE_TYPE__);\n");	
-	add_pre_buffer("extern int __builtin_memcmp(const void *, const void *, __SIZE_TYPE__);\n");	
+	add_pre_buffer("extern void *__builtin_memset(void *, int, __SIZE_TYPE__);\n");
+	add_pre_buffer("extern int __builtin_memcmp(const void *, const void *, __SIZE_TYPE__);\n");
 	add_pre_buffer("extern char *__builtin_strcat(char *, const char *);\n");
 	add_pre_buffer("extern char *__builtin_strncat(char *, const char *, __SIZE_TYPE__);\n");
 	add_pre_buffer("extern int __builtin_strcmp(const char *, const char *);\n");
@@ -687,6 +698,12 @@ void create_builtin_stream(void)
 	add_pre_buffer("#weak_define __GNUC__ %d\n", gcc_major);
 	add_pre_buffer("#weak_define __GNUC_MINOR__ %d\n", gcc_minor);
 	add_pre_buffer("#weak_define __GNUC_PATCHLEVEL__ %d\n", gcc_patchlevel);
+
+	/* We add compiler headers path here because we have to parse
+	 * the arguments to get it, falling back to default. */
+	add_pre_buffer("#add_system \"%s/include\"\n", gcc_base_dir);
+	add_pre_buffer("#add_system \"%s/include-fixed\"\n", gcc_base_dir);
+
 	add_pre_buffer("#define __extension__\n");
 	add_pre_buffer("#define __pragma__\n");
 
@@ -769,7 +786,7 @@ static struct symbol_list *sparse_tokenstream(struct token *token)
 		putchar('\n');
 
 		return NULL;
-	} 
+	}
 
 	// Parse the resulting C code
 	while (!eof_token(token))
pre-process.c +76 -20

172 lines not on this page · raw message

#2 lore raw

Re: [PATCH 1/4] Set gcc include path at runtime.

Quoted 6 lines · Alexey zaytsev

You can now tell sparse where to look for the compiler headers with -gcc-base-dir <dir>. Otherwise sparse will look for headers used to build it.

Also adds $GCC_BASE/include-fixed used by newer gcc versions.

Thanks, that fixes the limits.h warnings for me.

#3 lore raw

PATCH 2/4 Let cgcc pass -gcc-base-dir to sparse.

In reply to Alexey zaytsev
---
 cgcc |   14 +++++++++++++-
 1 files changed, 13 insertions(+), 1 deletions(-)
cgcc +13 -1
index 89adbed..b59f7d6 100755
@@ -10,9 +10,11 @@ my $has_specs = 0;
 my $gendeps = 0;
 my $do_check = 0;
 my $do_compile = 1;
+my $gcc_base_dir;
 my $verbose = 0;
 
-foreach (@ARGV) {
+while (@ARGV) {
+    $_ = shift(@ARGV);
     # Look for a .c file.  We don't want to run the checker on .o or .so files
     # in the link run.  (This simplistic check knows nothing about options
     # with arguments, but it seems to do the job.)
@@ -36,6 +38,12 @@ foreach (@ARGV) {
 	next;
     }
 
+    if (/^-gcc-base-dir$/) {
+        $gcc_base_dir = shift @ARGV;
+        die ("$0: missing argument for -gcc-base-dir option") if !$gcc_base_dir;
+        next;
+    }
+
     # If someone adds "-E", don't pre-process twice.
     $do_compile = 0 if $_ eq '-E';
 
@@ -56,6 +64,10 @@ if ($do_check) {
 	$check .= &add_specs ('host_arch_specs');
 	$check .= &add_specs ('host_os_specs');
     }
+
+    $gcc_base_dir = qx($cc -print-file-name=) if !$gcc_base_dir;
+    $check .= " -gcc-base-dir " . $gcc_base_dir if $gcc_base_dir;
+
     print "$check\n" if $verbose;
     if ($do_compile) {
 	system ($check);
#4 lore raw

PATCH 3/4 Document -gcc-base-dir in sparse.1

In reply to Alexey zaytsev
---
 sparse.1 |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)
sparse.1 +5 -0
index d242dc7..92a1cae 100644
@@ -287,6 +287,11 @@ However, this behavior can lead to subtle errors.
 
 Sparse does not issue these warnings by default.
 .
+.SH MISC OPTIONS
+.TP
+.B \-gcc-base-dir \fIdir\fR
+Look for compiler-provided system headers in \fIdir\fR/include/ and \fIdir\fR/include-fixed/.
+.
 .SH SEE ALSO
 .BR cgcc (1)
 .
#5 lore raw

PATCH 4/4 Rename dirafter to idirafter.

In reply to Alexey zaytsev

Dirafter was probably just a mistake.
Gcc uses -idirafter.

---
 lib.c         |   15 +++++----------
 pre-process.c |    4 ++--
 2 files changed, 7 insertions(+), 12 deletions(-)
lib.c +5 -10
index b579834..7adff2d 100644
@@ -313,6 +313,11 @@ static char **handle_switch_i(char *arg, char **next)
 		if (!path)
 			die("missing argument for -isystem option");
 		add_pre_buffer("#add_isystem \"%s/\"\n", path);
+	} else if (*next && !strcmp(arg, "idirafter")) {
+		char *path = *++next;
+		if (!path)
+			die("missing argument for -idirafter option");
+		add_pre_buffer("#add_dirafter \"%s/\"\n", path);
 	}
 	return next;
 }
@@ -573,15 +578,6 @@ static char **handle_nostdinc(char *arg, char **next)
 	return next;
 }
 
-static char **handle_dirafter(char *arg, char **next)
-{
-	char *path = *++next;
-	if (!path)
-		die("missing argument for -dirafter option");
-	add_pre_buffer("#add_dirafter \"%s/\"\n", path);
-	return next;
-}
-
 static char **handle_base_dir(char *arg, char **next)
 {
 	gcc_base_dir = *++next;
@@ -599,7 +595,6 @@ char **handle_switch(char *arg, char **next)
 {
 	static struct switches cmd[] = {
 		{ "nostdinc", handle_nostdinc },
-		{ "dirafter", handle_dirafter },
 		{ "gcc-base-dir", handle_base_dir},
 		{ NULL, NULL }
 	};
pre-process.c +2 -2
index 9c6ef5b..cf53893 100644
@@ -682,10 +682,10 @@ static int already_tokenized(const char *path)
  *   angle_includepath is set equal to isys_includepath.
  * -nostdinc removes all sys dirs by storing NULL in entry pointed
  *   to by * sys_includepath. Note that this will reset all dirs built-in
- *   and added before -nostdinc by -isystem and -dirafter.
+ *   and added before -nostdinc by -isystem and -idirafter.
  * -isystem dir adds dir where isys_includepath points adding this dir as
  *   first systemdir
- * -dirafter dir adds dir to the end of the list
+ * -idirafter dir adds dir to the end of the list
  */
 
 static void set_stream_include_path(struct stream *stream)