Skip to contentSkip to conversation

Add support for multiarch system header files

PATCH In review Ramsay Jones 2 participants 5 messages Aug 4, 2014 – Oct 7, 2014

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

PATCH 7/10 Add support for multiarch system header files

---
 Makefile |  3 +++
 cgcc     | 10 ++++++++++
 lib.c    | 18 +++++++++++++++++-
 sparse.1 |  6 ++++++
 4 files changed, 36 insertions(+), 1 deletion(-)
Makefile +3 -0
index 1795905..36061e3 100644
@@ -36,6 +36,9 @@ HAVE_LLVM:=$(shell $(LLVM_CONFIG) --version >/dev/null 2>&1 && echo 'yes')
 GCC_BASE = $(shell $(CC) --print-file-name=)
 BASIC_CFLAGS = -DGCC_BASE=\"$(GCC_BASE)\"
 
+MULTIARCH_TRIPLET = $(shell $(CC) -print-multiarch 2>/dev/null)
+BASIC_CFLAGS += -DMULTIARCH_TRIPLET=\"$(MULTIARCH_TRIPLET)\"
+
 ifeq ($(HAVE_GCC_DEP),yes)
 BASIC_CFLAGS += -Wp,-MD,$(@D)/.$(@F).d
 endif
cgcc +10 -0
index c075e5f..ed35e39 100755
@@ -11,6 +11,7 @@ my $gendeps = 0;
 my $do_check = 0;
 my $do_compile = 1;
 my $gcc_base_dir;
+my $multiarch_dir;
 my $verbose = 0;
 
 while (@ARGV) {
@@ -44,6 +45,12 @@ while (@ARGV) {
         next;
     }
 
+    if (/^-multiarch-dir$/) {
+        $multiarch_dir = shift @ARGV;
+        die ("$0: missing argument for -multiarch-dir option") if !$multiarch_dir;
+        next;
+    }
+
     # If someone adds "-E", don't pre-process twice.
     $do_compile = 0 if $_ eq '-E';
 
@@ -66,8 +73,11 @@ if ($do_check) {
     }
 
     $gcc_base_dir = qx($cc -print-file-name=) if !$gcc_base_dir;
+    chomp($gcc_base_dir);  # possibly remove '\n' from compiler
     $check .= " -gcc-base-dir " . $gcc_base_dir if $gcc_base_dir;
 
+    $check .= " -multiarch-dir " . $multiarch_dir if $multiarch_dir;
+
     print "$check\n" if $verbose;
     if ($do_compile) {
 	system ($check);
lib.c +17 -1
index 9c7767e..0b62dcb 100644
@@ -59,6 +59,7 @@ int gcc_minor = __GNUC_MINOR__;
 int gcc_patchlevel = __GNUC_PATCHLEVEL__;
 
 static const char *gcc_base_dir = GCC_BASE;
+static const char *multiarch_dir = MULTIARCH_TRIPLET;
 
 struct token *skip_to(struct token *token, int op)
 {
@@ -363,6 +364,14 @@ static char **handle_switch_M(char *arg, char **next)
 	return next;
 }
 
+static char **handle_multiarch_dir(char *arg, char **next)
+{
+	multiarch_dir = *++next;
+	if (!multiarch_dir)
+		die("missing argument for -multiarch-dir option");
+	return next;
+}
+
 static char **handle_switch_m(char *arg, char **next)
 {
 	if (!strcmp(arg, "m64")) {
@@ -371,7 +380,8 @@ static char **handle_switch_m(char *arg, char **next)
 		arch_m64 = 0;
 	} else if (!strcmp(arg, "msize-long")) {
 		arch_msize_long = 1;
-	}
+	} else if (!strcmp(arg, "multiarch-dir"))
+		return handle_multiarch_dir(arg, next);
 	return next;
 }
 
@@ -881,6 +891,12 @@ void create_builtin_stream(void)
 	add_pre_buffer("#weak_define __GNUC_MINOR__ %d\n", gcc_minor);
 	add_pre_buffer("#weak_define __GNUC_PATCHLEVEL__ %d\n", gcc_patchlevel);
 
+	/* add the multiarch include directories, if any */
+	if (multiarch_dir && *multiarch_dir) {
+		add_pre_buffer("#add_system \"/usr/include/%s\"\n", multiarch_dir);
+		add_pre_buffer("#add_system \"/usr/local/include/%s\"\n", multiarch_dir);
+	}
+
 	/* 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);
sparse.1 +6 -0
index 54da09b..a305a21 100644
@@ -335,6 +335,12 @@ Sparse does not issue these warnings by default.
 .B \-gcc-base-dir \fIdir\fR
 Look for compiler-provided system headers in \fIdir\fR/include/ and \fIdir\fR/include-fixed/.
 .
+.TP
+.B \-multiarch-dir \fIdir\fR
+Look for system headers in the multiarch subdirectory \fIdir\fR.
+The \fIdir\fR name would normally take the form of the target's
+normalized GNU triplet. (e.g. i386-linux-gnu).
+.
 .SH OTHER OPTIONS
 .TP
 .B \-ftabstop=WIDTH
Signature · 1 line
2.0.0
maintainer
#1 lore raw
Quoted 2 lines · Ramsay Jones

May I have a more descriptive change log why is multiarch option useful?

Makefile HAVE_LLVM:=$(shell $(LLVM_CONFIG) --version >/dev/null 2>&1 && echo 'yes') · line 40

Quoted 6 lines
Makefile +2 -0
@@ -36,6 +36,9 @@ HAVE_LLVM:=$(shell $(LLVM_CONFIG) --version >/dev/null 2>&1 && echo 'yes')
 GCC_BASE = $(shell $(CC) --print-file-name=)
 BASIC_CFLAGS = -DGCC_BASE=\"$(GCC_BASE)\"
 
+MULTIARCH_TRIPLET = $(shell $(CC) -print-multiarch 2>/dev/null)
+BASIC_CFLAGS += -DMULTIARCH_TRIPLET=\"$(MULTIARCH_TRIPLET)\"

My gcc(4.8, FC20) does not support "-print-multiarch".
So the patch need to handle that case.
As far as I can tell, this patch is not ready for empty MULTIARCH_TRIPLET.

lib.c void create_builtin_stream(void) · line 898

Quoted 4 lines
lib.c +4 -0
+       if (multiarch_dir && *multiarch_dir) {
+               add_pre_buffer("#add_system \"/usr/include/%s\"\n", multiarch_dir);
+               add_pre_buffer("#add_system \"/usr/local/include/%s\"\n", multiarch_dir);
+       }

Not sure empty multiarch_dir works here.

Chris

#2 lore raw
Quoted 6 lines · Christopher Li
Quoted 2 lines · Ramsay Jones

May I have a more descriptive change log why is multiarch option useful?

Quoted 8 lines

Makefile HAVE_LLVM:=$(shell $(LLVM_CONFIG) --version >/dev/null 2>&1 && echo 'yes') · line 40

Quoted 6 lines
Makefile +2 -0
@@ -36,6 +36,9 @@ HAVE_LLVM:=$(shell $(LLVM_CONFIG) --version >/dev/null 2>&1 && echo 'yes')
 GCC_BASE = $(shell $(CC) --print-file-name=)
 BASIC_CFLAGS = -DGCC_BASE=\"$(GCC_BASE)\"
 
+MULTIARCH_TRIPLET = $(shell $(CC) -print-multiarch 2>/dev/null)
+BASIC_CFLAGS += -DMULTIARCH_TRIPLET=\"$(MULTIARCH_TRIPLET)\"

My gcc(4.8, FC20) does not support "-print-multiarch".

Yep, same is true for cygwin.

Quoted 2 lines

So the patch need to handle that case.
As far as I can tell, this patch is not ready for empty MULTIARCH_TRIPLET.

Hmm, works for me! Could you describe the failure you are seeing.

Quoted 7 lines

lib.c void create_builtin_stream(void) · line 898

Quoted 5 lines
lib.c +4 -0
+       if (multiarch_dir && *multiarch_dir) {
+               add_pre_buffer("#add_system \"/usr/include/%s\"\n", multiarch_dir);
+               add_pre_buffer("#add_system \"/usr/local/include/%s\"\n", multiarch_dir);
+       }

Not sure empty multiarch_dir works here.

Again, it works for me. :-D

ATB,
Ramsay Jones

maintainer
#3 lore raw
Quoted 4 lines · Ramsay Jones
Quoted 1 line · Christopher Li

My gcc(4.8, FC20) does not support "-print-multiarch".

Yep, same is true for cygwin.

I see, I thought your patch is expecting some thing from gcc. Then how to you test this code path?

Quoted 7 lines
Quoted 6 lines

lib.c void create_builtin_stream(void) · line 898

Quoted 5 lines
lib.c +4 -0
+       if (multiarch_dir && *multiarch_dir) {
+               add_pre_buffer("#add_system \"/usr/include/%s\"\n", multiarch_dir);
+               add_pre_buffer("#add_system \"/usr/local/include/%s\"\n", multiarch_dir);
+       }

Again, it works for me. :-D

So I guess multiarch_dir can be empty here. I just did not expect that.

Is it always prefix with "/usr/include/" and "/usr/local/include" for different distributions?

Chris

#4 lore raw
Quoted 8 lines · Christopher Li
Quoted 4 lines · Ramsay Jones
Quoted 1 line · Christopher Li

My gcc(4.8, FC20) does not support "-print-multiarch".

Yep, same is true for cygwin.

I see, I thought your patch is expecting some thing from gcc. Then how to you test this code path?

Well, I slightly mis-spoke. Of the two cygwin installations I have, one has a version of gcc which supports '-print-multiarch' and one doesn't (i.e. it isn't really the version of cygwin, but gcc that seems to matter). In any case, cygwin is not a "multiarch" system, so on my 64-bit cygwin installation 'gcc -print-multiarch' prints a blank line (ie an empty string) and exits with 0 status. On my old 32-bit cygwin installation (if memory serves me correctly) then gcc prints an error message and exits with non-zero status.

This patch is old enough that it was originally tested on my old cygwin installation (this patch was developed on my old laptop), so I haven't tested there for some time. However, before sending this series I distinctly remember simulating this on 64-bit cygwin by editing the Makefile and changing the '-print-multiarch' option to '-print-junk', which _should_ have the same effect.

[ie the $(MULTIARCH_TRIPLET) make variable should be set to the empty string on your FC20 system.]

Quoted 11 lines
Quoted 8 lines
Quoted 7 lines

lib.c void create_builtin_stream(void) · line 898

Quoted 6 lines
lib.c +4 -0
+       if (multiarch_dir && *multiarch_dir) {
+               add_pre_buffer("#add_system \"/usr/include/%s\"\n", multiarch_dir);
+               add_pre_buffer("#add_system \"/usr/local/include/%s\"\n", multiarch_dir);
+       }

Again, it works for me. :-D

So I guess multiarch_dir can be empty here. I just did not expect that.

Yes, indeed this _must_ be empty on non-multiarch systems.

[This was developed on Ubuntu, which is a multiarch system (and I'm now on Linux Mint 17, which is also). Until now, I didn't know that Fedora was not! :-D ]

Quoted 3 lines

Is it always prefix with "/usr/include/" and "/usr/local/include" for different distributions?

I can't quite remember how I came up with this list (it was a while ago), but I think I had a look at the gcc source code. (Hmm, don't quote me on that! ;-) ).

ATB,
Ramsay Jones