[perl #90122] Make h2ph correctly search gcc include directories
authorNiko Tyni <ntyni@debian.org>
Thu, 19 May 2011 04:44:06 +0000 (21:44 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Thu, 19 May 2011 13:18:26 +0000 (06:18 -0700)
System header conversion with "h2ph -a" is currently broken on Ubuntu
Natty and Oneiric (unless the gcc-multilib package is installed for
backward compatibility), resulting in things like

 # perl -e 'require "syscall.ph"'
 Can't locate asm/unistd.ph in @INC [...]

This happens because Ubuntu has switched to a 'multiarch' setup, see
<https://wiki.ubuntu.com/MultiarchSpec> for details.

The asm subdirectory isn't in $Config{usrinc} anymore: /usr/include/asm
is now /usr/include/x86_64-linux-gnu/asm. (The third component of the
new path varies with the actual architecture.)

gcc --print-search-dirs doesn't really tell anything about where gcc
looks for the include directories, it was just used to find the gcc
internal directory prefix.

Parse the output of "gcc -v -E" instead, and append $Config{usrinc}
for safety. Duplicates shouldn't matter.

The h2ph "-a" switch isn't currently tested automatically, and that
seems nontrivial to do portably. Manual testing was done with

 # mkdir ttt
 # ./perl -Ilib ./utils/h2ph -a -d $(pwd)/ttt syscall.h

The gcc invocation has been tested to work with gcc 4.6, 4.1, and 3.3.

http://bugs.debian.org/625808
https://bugs.launchpad.net/bugs/777903

utils/h2ph.PL

index 87f3c7d..4545d6d 100644 (file)
@@ -761,16 +761,8 @@ sub queue_includes_from
 # non-GCC?) C compilers, but gcc uses additional include directories.
 sub inc_dirs
 {
-    my $from_gcc    = `LC_ALL=C $Config{cc} -v 2>&1`;
-    if( !( $from_gcc =~ s:^Reading specs from (.*?)/specs\b.*:$1/include:s ) )
-    { # gcc-4+ :
-       $from_gcc   = `LC_ALL=C $Config{cc} -print-search-dirs 2>&1`;
-       if ( !($from_gcc =~ s/^install:\s*([^\s]+[^\s\/])([\s\/]*).*$/$1\/include/s) )
-       {
-           $from_gcc = '';
-       };
-    };
-    length($from_gcc) ? ($from_gcc, $from_gcc . "-fixed", $Config{usrinc}) : ($Config{usrinc});
+    my $from_gcc   = `LC_ALL=C $Config{cc} -v -E - < /dev/null 2>&1 | awk '/^#include/, /^End of search list/' | grep '^ '`;
+    length($from_gcc) ? (split(' ', $from_gcc), $Config{usrinc}) : ($Config{usrinc});
 }