mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-01-19 04:49:25 +08:00
b55e3f1916
ccwrap massages the compiler's standard include directories to remove '/usr/include/w32api', with the intent of allowing it to be overriden by '--with-windows-headers' (See 4c36016b). I'm not 100% convinced that this is always working as desired, since in some places w32api includes are done using <w32api/something.h>, which will find them via the path /usr/include. If this does turn out to be needed, this could also be implemented by constructing the appropriate compiler flags once, rather than on every compiler invocation.
104 lines
3.2 KiB
Perl
Executable File
104 lines
3.2 KiB
Perl
Executable File
#!/usr/bin/perl -s
|
|
#
|
|
# This file is part of Cygwin.
|
|
#
|
|
# This software is a copyrighted work licensed under the terms of the
|
|
# Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
|
# details.
|
|
#
|
|
my $tls = shift;
|
|
my $tls_out = shift;
|
|
my $tgt = shift;
|
|
# FIXME? This method obviously requires a 64 bit OS to build tlsoffsets64.h
|
|
# Another method which doesn't requires to run an executable would be to
|
|
# generate assembler code accessing the various struct members and analyzing
|
|
# it, but that's arguably a lot more effort.
|
|
my $tgt_opt = $tgt eq 'x86_64' ? '-m64' : '-m32';
|
|
open TLS, '<', $tls or die "$0: couldn't open tls file \"$tls\" - $!\n";
|
|
my $struct = '';
|
|
my @fields = ();
|
|
my $def = '';
|
|
$tls = join('', <TLS>);
|
|
$tls =~ s/\A.*\n#pragma once\n//os;
|
|
$tls =~ s/\n[^\n]*gentls_offsets[^\n]*\n(.+)\Z/$1/os;
|
|
my $pre = $`;
|
|
substr($tls, 0, length($pre)) = '';
|
|
$pre .= "\n//*/";
|
|
$tls =~ s%/\*\s*gentls_offsets.*?/\*\s*gentls_offsets\s*\*/%%ogs;
|
|
foreach ($tls =~ /^.*\n/mg) {
|
|
/^}|\s*(?:typedef|const)/ and do {
|
|
$def .= $_ ;
|
|
next;
|
|
};
|
|
$def .= $_ if $struct;
|
|
if (!s/;.*$//) {
|
|
if (!$struct && /^\s*(?:struct|class)\s*([a-z_0-9]+)/) {
|
|
$def .= $_;
|
|
$struct = $1
|
|
}
|
|
next;
|
|
}
|
|
s/(?:\[[^\]]*\]|struct|class)//;
|
|
s/^\s+\S+\s+//;
|
|
s/[\*\s()]+//g;
|
|
for my $f (split(/,/)) {
|
|
push(@fields, $f);
|
|
}
|
|
}
|
|
close TLS;
|
|
open TMP, '>', "/tmp/$$.cc" or die "$0: couldn't open temporary index file \"/tmp/$$.c\" - $!\n";
|
|
print TMP <<EOF;
|
|
#define __INSIDE_CYGWIN__
|
|
#ifndef __x86_64__
|
|
#define __attribute__(X)
|
|
#endif
|
|
#define __reg1
|
|
#define __reg2
|
|
#define __reg3
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <signal.h>
|
|
#include <windows.h>
|
|
$pre
|
|
$def
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
$struct *foo;
|
|
# define foo_beg ((char *) foo)
|
|
# define offset(f) ((unsigned)((int) (((char *) &(foo->f)) - foo_beg) - CYGTLS_PADSIZE))
|
|
# define poffset(f) ((unsigned)(((char *) &(foo->f)) - ((char *) foo)))
|
|
EOF
|
|
print TMP 'puts ("//;# autogenerated: Do not edit.\n");', "\n\n";
|
|
print TMP "printf (\"//; \$tls::start_offset = -%d;\\n\", CYGTLS_PADSIZE);\n";
|
|
for my $f (@fields) {
|
|
print TMP ' printf ("//; $tls::', $f, ' = %d;\n", ', "offset($f));\n";
|
|
print TMP ' printf ("//; $tls::p', $f, ' = %d;\n", ', "poffset($f));\n";
|
|
}
|
|
print TMP ' puts ("//; __DATA__\n");', "\n";
|
|
for my $f (@fields) {
|
|
print TMP ' printf ("#define tls_', $f, ' (%d)\n", ', "offset($f));\n";
|
|
print TMP ' printf ("#define tls_p', $f, ' (%d)\n", ', "poffset($f));\n";
|
|
}
|
|
|
|
print TMP <<EOF;
|
|
|
|
exit (0);
|
|
}
|
|
EOF
|
|
close TMP;
|
|
my @avoid_headers = qw'-D_XMMINTRIN_H_INCLUDED -D_ADXINTRIN_H_INCLUDED -D_EMMINTRIN_H_INCLUDED -D_X86INTRIN_H_INCLUDED';
|
|
my @cmd = (@ARGV, @avoid_headers, '-o', "/tmp/$$-1.cc", '-E', "/tmp/$$.cc");
|
|
|
|
system @cmd;
|
|
system 'g++', "$tgt_opt", '-o', "/tmp/$$.a.out", "/tmp/$$-1.cc" and
|
|
($? == 127 && system 'c++', "$tgt_opt", '-o', "/tmp/$$.a.out", "/tmp/$$-1.cc") and
|
|
die "$0: couldn't generate executable for offset calculation \"/tmp/$$.a.out\" - $!\n";
|
|
open TLS_OUT, '>', $tls_out or die "$0: couldn't open tls index file \"$tls_out\" - $!\n";
|
|
open OFFS, '-|', "/tmp/$$.a.out" or die "$0: couldn't run \"/tmp/$$.a.out\" - $!\n";
|
|
print TLS_OUT <OFFS>;
|
|
close OFFS;
|
|
close TLS_OUT;
|
|
unlink "/tmp/$$.cc", "/tmp/$$-1.cc", "/tmp/$$-1.d", "/tmp/$$.a.out";
|
|
exit(0);
|