-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdarwin.sconstruct
180 lines (157 loc) · 6.26 KB
/
darwin.sconstruct
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# -*- python -*-
import json
import os
"""
Notes on some problems I encountered and the solutions I came up with.
PROBLEM: BSD getopt (mac version) behaves differently:
SOLUTION: Use gnu getopt
brew install gnu-getopt
PATH=/usr/local/opt/gnu-getopt/bin:$PATH
PROBLEM: BSD readlink (mac version) does not accept -m option:
SOLUTION: Use gnu readlink
brew install coreutils
PATH=/usr/local/opt/coreutils/libexec/gnubin:$PATH
PROBLEM: need tex executable
SOLUTION:
brew install mactex
PATH=/Library/TeX/texbin:$PATH
PROBLEM: ncurses: -no-cpp-precomp sould be --no-cpp-precomp in ./configure
SOLUTION: Download ncurses-6.0 in this script.
PROBLEM: expat: ldconfig not required or understood on darwin, but
chosen by .configure for some reason.
SOLUTION: Download expat-2.2.9 using this script.
"""
def str_to_file(string, executable=None):
"""Return a generator which writes the specified string to a file."""
def write_str_to_file(target, source, env, string=string): #pylint: disable=unused-argument
filename = str(target[0])
with open(filename, 'w') as fh:
fh.write(string)
if executable:
mode = os.stat(filename).st_mode
mode |= (mode & 0o444) >> 2 # copy R bits to X
os.chmod(filename, mode)
return write_str_to_file
def make_symlink(target, source, env):
"""Function for creating symlinks in a Command builder."""
os.symlink(os.path.abspath(str(source[0])), os.path.abspath(str(target[0])))
with open(File('config.json').abspath, 'r') as fh:
config = json.load(fh)
env = Environment()
topdir = Dir('work').abspath
sources = [] # Will store all the sources needed for the build
# Symlink work/b to the build_script_dir.
sources += [env.Command('work/b', config['build_script_dir'], make_symlink)]
# Copy over and edit the desired build scripts to the work dir.
build_scripts = (
'build.elf',
)
for build_script in build_scripts:
src = os.path.join(config['build_script_dir'], build_script)
sources += [env.Command(f'work/{build_script}', src, f"""\
sed -e "s,TOPDIR=/directory,TOPDIR={topdir}," \
-e "s,# HOSTTRIPLE,HOSTTRIPLE," \
-e "s,--jobs=3,--jobs=8," \
$SOURCE > $TARGET
chmod a+x $TARGET
""")]
# Download all the desired components into our workdir.
components = (
('binutils', None),
('gdb', None),
('newlib', None),
('uclibc', None),
('gcc', None),
('glibc', None),
('smallclib', None),
('gold', None),
('qemu', None),
('packages', None),
('python', None),
('ncurses', 'ftp://ftp.invisible-island.net/ncurses/ncurses-6.0.tar.gz'),
('expat', 'https://github.com/libexpat/libexpat/releases/download/R_2_2_9/expat-2.2.9.tar.gz'),
)
for component, src in components:
if src is None:
version = config['version']
src = f"http://codescape.mips.com/components/toolchain/{version}/src/{component}-{version}.src.tar.gz"
dirname = os.path.join(topdir, 'src', component)
sources += [env.Command(f'work/src/{component}/.fetch', None, f"""\
mkdir -p {dirname}
curl -L {src} | tar zxf - -C {dirname} --strip-components 1
touch $TARGET
""")];
# Call gcc contrib/download_prerequisites to get gcc prerequisites.
sources += [env.Command(
'work/src/gcc/.download_prerequisites',
'work/src/gcc/.fetch',
f"(cd work/src/gcc; contrib/download_prerequisites) && touch $TARGET")]
# Hack gcc inclhack.def to work around a gcc issue building on OSX Catelina.
# This bug will probably be fixed in the gcc sources in the future
env.Command(f'work/src/gcc/.inclhack.txt', f'work/src/gcc/.fetch',
str_to_file("""
/*
* macOS 10.15 <Availability.h> does not define __OSX_AVAILABLE_STARTING on
* non-clang compilers.
*/
fix = {
hackname = darwin_availability;
mach = "*-*-darwin*";
files = Availability.h;
select = "#endif /\\* __OSX_AVAILABLE_STARTING \\*/";
c_fix = format;
c_fix_arg = <<- _EOFix_
#endif /* __OSX_AVAILABLE_STARTING */
#ifndef __OSX_AVAILABLE_STARTING
#define __OSX_AVAILABLE_STARTING(_osx, _ios)
#define __OSX_AVAILABLE_BUT_DEPRECATED(_osxIntro, _osxDep, _iosIntro, _iosDep)
#define __OSX_AVAILABLE_BUT_DEPRECATED_MSG(_osxIntro, _osxDep, _iosIntro, _iosDep, _msg)
#endif
_EOFix_;
test_text = "#endif /* __OSX_AVAILABLE_STARTING */";
};
"""))
sources += [env.Command(f'work/src/gcc/.inclhack.ok', f'work/src/gcc/.inclhack.txt', f"cat $SOURCE >> work/src/gcc/fixincludes/inclhack.def && touch $TARGET")]
# Make gcc exe 'x86_64-pc-linux-gnu-gcc', used to build some components.
# Note that this is a link to a specific homebrew gcc, which might
# change in the future.
sources += [env.Command('work/x86_64-pc-linux-gnu-gcc',
'/usr/local/Cellar/gcc/9.2.0_3/bin/gcc-9',
make_symlink)]
for tool in ('ar', 'ranlib'):
sources += [env.Command(f'work/x86_64-pc-linux-gnu-{tool}',
f'/usr/local/Cellar/gcc/9.2.0_3/bin/gcc-{tool}-9',
make_symlink)]
# Make 'invoke' script which calls other scripts with the required environment.
sources += [env.Command(f'work/invoke', None, str_to_file(f"""\
#! /bin/sh
PATH=/usr/local/opt/coreutils/libexec/gnubin:$PATH
PATH=/usr/local/opt/gnu-getopt/bin:$PATH
PATH=/usr/local/opt/gnu-sed/libexec/gnubin:$PATH
PATH=/Library/TeX/texbin:$PATH
PATH={topdir}:$PATH
export PATH
exec "$@"
""", executable=True))]
# Check existance/versions of certain executables when called with 'invoke'.
# (We could add further checks here that the versions are really the ones
# we need).
sources += [env.Command('.versions',
['work/invoke',
'work/x86_64-pc-linux-gnu-gcc',
'work/x86_64-pc-linux-gnu-ar',
'work/x86_64-pc-linux-gnu-ranlib',
],
f"""\
echo "# Command versions" > $TARGET
$SOURCE which getopt >> $TARGET
$SOURCE which readlink >> $TARGET
$SOURCE which tex >> $TARGET
$SOURCE which x86_64-pc-linux-gnu-gcc >> $TARGET
$SOURCE which x86_64-pc-linux-gnu-ar >> $TARGET
$SOURCE which x86_64-pc-linux-gnu-ranlib >> $TARGET
""")]
# An alias for setup up all the source files, but not actually building.
env.Alias('sources', sources)
# Target to do the actual build.
env.Command('elf', sources, 'cd work; ./invoke ./build.elf')