-
Notifications
You must be signed in to change notification settings - Fork 58
/
generate-config-h.py
126 lines (113 loc) · 4.85 KB
/
generate-config-h.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# Copyright 2012 David Malcolm <[email protected]>
# Copyright 2012 Red Hat, Inc.
#
# This is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see
# <http://www.gnu.org/licenses/>.
import os
import sys
from configbuilder import ConfigBuilder, CheckFor
class GccPythonPluginConfigBuilder(ConfigBuilder):
def __init__(self, argv):
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--gcc')
parser.add_argument('--plugindir')
args, argv = parser.parse_known_args(argv)
ConfigBuilder.__init__(self, argv)
self.gcc = args.gcc
self.plugindir = args.plugindir
self.extra_compilation_args = []
def main(self):
prefix = 'GCC_PYTHON_PLUGIN_CONFIG_'
if self.plugindir:
plugindir = self.plugindir
else:
plugindir = self.capture_shell_output('locating plugin directory for %s' % self.gcc,
'%s --print-file-name=plugin' % self.gcc).strip()
extraargs = ['-I%s' % os.path.join(plugindir, 'include')]
self.test_whether_built_with_cplusplus()
extraargs += self.extra_compilation_args
# In GCC 4.9 onwards, this header file uses C++ syntax, so we
# must already have determined C vs C++ at this point
self.test_for_mandatory_c_header('gcc-plugin.h', extraargs)
self.test_c_compilation(initmsg='checking whether plugin.def defines PLUGIN_FINISH_DECL',
src='''
#include <gcc-plugin.h>
int i[PLUGIN_FINISH_DECL];
''',
extraargs=extraargs,
description='Does plugin.def define PLUGIN_FINISH_DECL?',
defn=prefix+'has_PLUGIN_FINISH_DECL')
self.test_rtti()
self.write_outcome()
self.write_EXTRA_CFLAGS()
def test_whether_built_with_cplusplus(self):
"""
Determine if the GCC was built with C++ or C
"""
# According to http://gcc.gnu.org/ml/gcc/2012-03/msg00411.html
# we should look in $(gcc -print-file-name=plugin)/include/auto-host.h
# where we'll see either:
#
# Old 4.6, built with C:
# /* Define if building with C++. */
# #ifndef USED_FOR_TARGET
# /* #undef ENABLE_BUILD_WITH_CXX */
# #endif
#
# New 4.7, built with C++:
# /* Define if building with C++. */
# #ifndef USED_FOR_TARGET
# #define ENABLE_BUILD_WITH_CXX 1
# #endif
#
# 4.8, built with C++ doesn't have this (always built with C++)
with CheckFor('Checking whether %s was built with C or C++' % self.gcc,
True) as check:
def with_cplusplus():
check.okmsg = 'C++'
self.extra_compilation_args += ['-x', 'c++']
def with_c():
check.okmsg = 'C'
auto_host_h = os.path.join(self.plugindir, 'include', 'auto-host.h')
with open(auto_host_h, 'r') as f:
content = f.read()
if '/* #undef ENABLE_BUILD_WITH_CXX */' in content:
with_c()
elif '#define ENABLE_BUILD_WITH_CXX 1' in content:
with_cplusplus()
else:
# Not found, assume C++:
with_cplusplus()
def test_rtti(self):
# Only need to do this check for C++ compilation
if 'c++' in self.extra_compilation_args:
with CheckFor('checking whether passes are C++ classes', True) as check:
tree_pass_h = os.path.join(self.plugindir, 'include', 'tree-pass.h')
with open(tree_pass_h, 'r') as f:
content = f.read()
if 'class opt_pass' in content:
# Passes are C++ classes (GCC 4.9 onwards); we need
# -fno-rtti
self.extra_compilation_args += ['-fno-rtti']
check.okmsg = 'yes'
else:
check.okmsg = 'no'
def write_EXTRA_CFLAGS(self):
filename = 'autogenerated-EXTRA_CFLAGS.txt'
sys.stdout.write('writing %s\n' % filename)
with open(filename, 'w') as f:
f.write(' '.join(self.extra_compilation_args))
ch = GccPythonPluginConfigBuilder(sys.argv)
ch.main()