]>
Commit | Line | Data |
---|---|---|
3b2c81c7 RD |
1 | #!/usr/bin/env python |
2 | ||
3 | ################################### | |
4 | # Author: Kevin Ollivier | |
526954c5 | 5 | # Licence: wxWindows licence |
3b2c81c7 RD |
6 | ################################### |
7 | ||
8 | import os | |
9 | import re | |
10 | import sys | |
11 | import builder | |
3b2c81c7 RD |
12 | import glob |
13 | import optparse | |
14 | import platform | |
15 | import shutil | |
16 | import types | |
b4f28d1e | 17 | import subprocess |
3b2c81c7 RD |
18 | |
19 | # builder object | |
20 | wxBuilder = None | |
21 | ||
22 | # other globals | |
23 | scriptDir = None | |
24 | wxRootDir = None | |
25 | contribDir = None | |
26 | options = None | |
27 | configure_opts = None | |
28 | exitWithException = True | |
317bc825 | 29 | nmakeCommand = 'nmake.exe' |
3b2c81c7 | 30 | |
6d6f2e7c RD |
31 | verbose = False |
32 | ||
33 | ||
34 | def numCPUs(): | |
e2db04f8 RD |
35 | """ |
36 | Detects the number of CPUs on a system. | |
37 | This approach is from detectCPUs here: http://www.artima.com/weblogs/viewpost.jsp?thread=230001 | |
38 | """ | |
39 | # Linux, Unix and MacOS: | |
40 | if hasattr(os, "sysconf"): | |
016a3d4c | 41 | if "SC_NPROCESSORS_ONLN" in os.sysconf_names: |
e2db04f8 RD |
42 | # Linux & Unix: |
43 | ncpus = os.sysconf("SC_NPROCESSORS_ONLN") | |
44 | if isinstance(ncpus, int) and ncpus > 0: | |
45 | return ncpus | |
46 | else: # OSX: | |
b4f28d1e RD |
47 | p = subprocess.Popen("sysctl -n hw.ncpu", shell=True, stdout=subprocess.PIPE) |
48 | return p.stdout.read() | |
49 | ||
e2db04f8 | 50 | # Windows: |
016a3d4c | 51 | if "NUMBER_OF_PROCESSORS" in os.environ: |
e2db04f8 RD |
52 | ncpus = int(os.environ["NUMBER_OF_PROCESSORS"]); |
53 | if ncpus > 0: | |
54 | return ncpus | |
55 | return 1 # Default | |
6d6f2e7c | 56 | |
3b2c81c7 | 57 | |
9ad2035a RD |
58 | def getXcodePaths(): |
59 | base = getoutput("xcode-select -print-path") | |
60 | return [base, base+"/Platforms/MacOSX.platform/Developer"] | |
1ffe914a RD |
61 | |
62 | ||
5208671f RD |
63 | def getVisCVersion(): |
64 | text = getoutput("cl.exe") | |
12c6bfab RD |
65 | if 'Version 13' in text: |
66 | return '71' | |
5208671f RD |
67 | if 'Version 15' in text: |
68 | return '90' | |
2e59a53a RD |
69 | if 'Version 16' in text: |
70 | return '100' | |
5208671f RD |
71 | # TODO: Add more tests to get the other versions... |
72 | else: | |
73 | return 'FIXME' | |
74 | ||
75 | ||
3b2c81c7 RD |
76 | def exitIfError(code, msg): |
77 | if code != 0: | |
016a3d4c | 78 | print(msg) |
3b2c81c7 | 79 | if exitWithException: |
016a3d4c | 80 | raise builder.BuildError(msg) |
3b2c81c7 RD |
81 | else: |
82 | sys.exit(1) | |
83 | ||
84 | ||
e2db04f8 RD |
85 | def getWxRelease(wxRoot=None): |
86 | if not wxRoot: | |
87 | global wxRootDir | |
88 | wxRoot = wxRootDir | |
89 | ||
90 | configureText = open(os.path.join(wxRoot, "configure.in"), "r").read() | |
3b2c81c7 RD |
91 | majorVersion = re.search("wx_major_version_number=(\d+)", configureText).group(1) |
92 | minorVersion = re.search("wx_minor_version_number=(\d+)", configureText).group(1) | |
93 | ||
6d6f2e7c | 94 | versionText = "%s.%s" % (majorVersion, minorVersion) |
3b2c81c7 | 95 | |
6d6f2e7c RD |
96 | if int(minorVersion) % 2: |
97 | releaseVersion = re.search("wx_release_number=(\d+)", configureText).group(1) | |
98 | versionText += ".%s" % (releaseVersion) | |
3b2c81c7 | 99 | |
6d6f2e7c | 100 | return versionText |
3b2c81c7 RD |
101 | |
102 | ||
e2db04f8 RD |
103 | def getFrameworkName(options): |
104 | # the name of the framework is based on the wx port being built | |
105 | name = "wxOSX" | |
106 | if options.osx_cocoa: | |
107 | name += "Cocoa" | |
108 | else: | |
109 | name += "Carbon" | |
110 | return name | |
111 | ||
112 | ||
113 | def getPrefixInFramework(options, wxRoot=None): | |
114 | # the path inside the framework that is the wx --prefix | |
115 | fwPrefix = os.path.join( | |
116 | os.path.abspath(options.mac_framework_prefix), | |
117 | "%s.framework/Versions/%s" % (getFrameworkName(options), getWxRelease(wxRoot))) | |
118 | return fwPrefix | |
119 | ||
120 | ||
e5ad1e9d | 121 | def macFixupInstallNames(destdir, prefix, buildDir=None): |
3b2c81c7 RD |
122 | # When an installdir is used then the install_names embedded in |
123 | # the dylibs are not correct. Reset the IDs and the dependencies | |
124 | # to use just the prefix. | |
016a3d4c | 125 | print("**** macFixupInstallNames(%s, %s, %s)" % (destdir, prefix, buildDir)) |
3b2c81c7 RD |
126 | pwd = os.getcwd() |
127 | os.chdir(destdir+prefix+'/lib') | |
128 | dylibs = glob.glob('*.dylib') # ('*[0-9].[0-9].[0-9].[0-9]*.dylib') | |
129 | for lib in dylibs: | |
130 | cmd = 'install_name_tool -id %s/lib/%s %s/lib/%s' % \ | |
131 | (prefix,lib, destdir+prefix,lib) | |
016a3d4c | 132 | print(cmd) |
6d6f2e7c | 133 | run(cmd) |
3b2c81c7 | 134 | for dep in dylibs: |
e5ad1e9d RD |
135 | if buildDir is not None: |
136 | cmd = 'install_name_tool -change %s/lib/%s %s/lib/%s %s/lib/%s' % \ | |
137 | (buildDir,dep, prefix,dep, destdir+prefix,lib) | |
138 | else: | |
139 | cmd = 'install_name_tool -change %s/lib/%s %s/lib/%s %s/lib/%s' % \ | |
140 | (destdir+prefix,dep, prefix,dep, destdir+prefix,lib) | |
016a3d4c | 141 | print(cmd) |
6d6f2e7c | 142 | run(cmd) |
3b2c81c7 RD |
143 | os.chdir(pwd) |
144 | ||
145 | ||
6d6f2e7c RD |
146 | def run(cmd): |
147 | global verbose | |
148 | if verbose: | |
016a3d4c | 149 | print("Running %s" % cmd) |
6d6f2e7c | 150 | return exitIfError(os.system(cmd), "Error running %s" % cmd) |
3b2c81c7 | 151 | |
e2db04f8 | 152 | |
016a3d4c RD |
153 | def getoutput(cmd): |
154 | sp = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) | |
155 | output = None | |
156 | output = sp.stdout.read() | |
157 | if sys.version_info > (3,): | |
158 | output = output.decode('utf-8') # TODO: is utf-8 okay here? | |
159 | output = output.rstrip() | |
160 | rval = sp.wait() | |
161 | if rval: | |
162 | # Failed! | |
163 | print("Command '%s' failed with exit code %d." % (cmd, rval)) | |
164 | sys.exit(rval) | |
165 | return output | |
166 | ||
167 | ||
3b2c81c7 RD |
168 | def main(scriptName, args): |
169 | global scriptDir | |
170 | global wxRootDir | |
171 | global contribDir | |
172 | global options | |
173 | global configure_opts | |
174 | global wxBuilder | |
317bc825 | 175 | global nmakeCommand |
3b2c81c7 RD |
176 | |
177 | scriptDir = os.path.dirname(os.path.abspath(scriptName)) | |
178 | wxRootDir = os.path.abspath(os.path.join(scriptDir, "..", "..")) | |
179 | ||
180 | contribDir = os.path.join("contrib", "src") | |
181 | installDir = None | |
182 | ||
6d6f2e7c | 183 | VERSION = tuple([int(i) for i in getWxRelease().split('.')[:2]]) |
3b2c81c7 RD |
184 | |
185 | if sys.platform.startswith("win"): | |
186 | contribDir = os.path.join(wxRootDir, "contrib", "build") | |
187 | ||
188 | if sys.platform.startswith("win"): | |
189 | toolkit = "msvc" | |
190 | else: | |
191 | toolkit = "autoconf" | |
192 | ||
e2db04f8 RD |
193 | defJobs = str(numCPUs()) |
194 | defFwPrefix = '/Library/Frameworks' | |
195 | ||
3b2c81c7 | 196 | option_dict = { |
e2db04f8 RD |
197 | "clean" : (False, "Clean all files from the build directory"), |
198 | "debug" : (False, "Build the library in debug symbols"), | |
199 | "builddir" : ("", "Directory where the build will be performed for autoconf builds."), | |
200 | "prefix" : ("", "Configured prefix to use for autoconf builds. Defaults to installdir if set. Ignored for framework builds."), | |
201 | "jobs" : (defJobs, "Number of jobs to run at one time in make. Default: %s" % defJobs), | |
202 | "install" : (False, "Install the toolkit to the installdir directory, or the default dir."), | |
203 | "installdir" : ("", "Directory where built wxWidgets will be installed"), | |
204 | "mac_distdir" : (None, "If set on Mac, will create an installer package in the specified dir."), | |
205 | "mac_universal_binary" | |
508c5afe | 206 | : ("", "Comma separated list of architectures to include in the Mac universal binary"), |
3b2c81c7 | 207 | "mac_framework" : (False, "Install the Mac build as a framework"), |
e2db04f8 RD |
208 | "mac_framework_prefix" |
209 | : (defFwPrefix, "Prefix where the framework should be installed. Default: %s" % defFwPrefix), | |
932d0768 | 210 | "cairo" : (False, "Enable dynamicly loading the Cairo lib for wxGraphicsContext on MSW"), |
e2db04f8 RD |
211 | "no_config" : (False, "Turn off configure step on autoconf builds"), |
212 | "config_only" : (False, "Only run the configure step and then exit"), | |
213 | "rebake" : (False, "Regenerate Bakefile and autoconf files"), | |
214 | "unicode" : (False, "Build the library with unicode support"), | |
215 | "wxpython" : (False, "Build the wxWidgets library with all options needed by wxPython"), | |
216 | "cocoa" : (False, "Build the old Mac Cooca port."), | |
217 | "osx_cocoa" : (False, "Build the new Cocoa port"), | |
218 | "shared" : (False, "Build wx as a dynamic library"), | |
e2db04f8 RD |
219 | "extra_make" : ("", "Extra args to pass on [n]make's command line."), |
220 | "features" : ("", "A comma-separated list of wxUSE_XYZ defines on Win, or a list of configure flags on unix."), | |
b4f28d1e | 221 | "verbose" : (False, "Print commands as they are run, (to aid with debugging this script)"), |
317bc825 | 222 | "jom" : (False, "Use jom.exe instead of nmake for MSW builds."), |
3b2c81c7 RD |
223 | } |
224 | ||
225 | parser = optparse.OptionParser(usage="usage: %prog [options]", version="%prog 1.0") | |
e2db04f8 RD |
226 | |
227 | keys = option_dict.keys() | |
016a3d4c | 228 | for opt in sorted(keys): |
3b2c81c7 | 229 | default = option_dict[opt][0] |
3b2c81c7 | 230 | action = "store" |
016a3d4c | 231 | if type(default) == bool: |
3b2c81c7 | 232 | action = "store_true" |
e2db04f8 RD |
233 | parser.add_option("--" + opt, default=default, action=action, dest=opt, |
234 | help=option_dict[opt][1]) | |
3b2c81c7 RD |
235 | |
236 | options, arguments = parser.parse_args(args=args) | |
b4f28d1e RD |
237 | |
238 | global verbose | |
239 | if options.verbose: | |
240 | verbose = True | |
241 | ||
3b2c81c7 RD |
242 | # compiler / build system specific args |
243 | buildDir = options.builddir | |
6d6f2e7c | 244 | args = [] |
3b2c81c7 RD |
245 | installDir = options.installdir |
246 | prefixDir = options.prefix | |
247 | ||
248 | if toolkit == "autoconf": | |
e5ad1e9d RD |
249 | if not buildDir: |
250 | buildDir = os.getcwd() | |
3b2c81c7 RD |
251 | configure_opts = [] |
252 | if options.features != "": | |
253 | configure_opts.extend(options.features.split(" ")) | |
254 | ||
255 | if options.unicode: | |
256 | configure_opts.append("--enable-unicode") | |
257 | ||
258 | if options.debug: | |
259 | configure_opts.append("--enable-debug") | |
260 | ||
3b2c81c7 | 261 | if options.cocoa: |
e5ad1e9d | 262 | configure_opts.append("--with-old_cocoa") |
3b2c81c7 RD |
263 | |
264 | if options.osx_cocoa: | |
265 | configure_opts.append("--with-osx_cocoa") | |
e5ad1e9d | 266 | |
3b2c81c7 RD |
267 | wxpy_configure_opts = [ |
268 | "--with-opengl", | |
269 | "--enable-sound", | |
270 | "--enable-graphics_ctx", | |
271 | "--enable-mediactrl", | |
272 | "--enable-display", | |
273 | "--enable-geometry", | |
274 | "--enable-debug_flag", | |
275 | "--enable-optimise", | |
276 | "--disable-debugreport", | |
277 | "--enable-uiactionsim", | |
278 | ] | |
279 | ||
280 | if sys.platform.startswith("darwin"): | |
281 | wxpy_configure_opts.append("--enable-monolithic") | |
282 | else: | |
283 | wxpy_configure_opts.append("--with-sdl") | |
284 | wxpy_configure_opts.append("--with-gnomeprint") | |
285 | ||
119d50a8 RD |
286 | # Try to use use lowest available SDK back to 10.5. Both Carbon and |
287 | # Cocoa builds require at least the 10.5 SDK now. We only add it to | |
288 | # the wxpy options because this is a hard-requirement for wxPython, | |
289 | # but other cases it is optional and is left up to the developer. | |
290 | # TODO: there should be a command line option to set the SDK... | |
be7a5775 | 291 | if sys.platform.startswith("darwin"): |
9ad2035a RD |
292 | for xcodePath in getXcodePaths(): |
293 | sdks = [ | |
294 | xcodePath+"/SDKs/MacOSX10.5.sdk", | |
295 | xcodePath+"/SDKs/MacOSX10.6.sdk", | |
296 | xcodePath+"/SDKs/MacOSX10.7.sdk", | |
297 | xcodePath+"/SDKs/MacOSX10.8.sdk", | |
298 | ] | |
68a1c7d3 | 299 | |
9ad2035a RD |
300 | # use the lowest available sdk |
301 | for sdk in sdks: | |
302 | if os.path.exists(sdk): | |
303 | wxpy_configure_opts.append( | |
304 | "--with-macosx-sdk=%s" % sdk) | |
305 | break | |
be7a5775 | 306 | |
3b2c81c7 RD |
307 | if not options.mac_framework: |
308 | if installDir and not prefixDir: | |
309 | prefixDir = installDir | |
310 | if prefixDir: | |
e2db04f8 | 311 | prefixDir = os.path.abspath(prefixDir) |
3b2c81c7 | 312 | configure_opts.append("--prefix=" + prefixDir) |
e2db04f8 RD |
313 | |
314 | ||
3b2c81c7 RD |
315 | if options.wxpython: |
316 | configure_opts.extend(wxpy_configure_opts) | |
317 | if options.debug: | |
318 | # wxPython likes adding these debug options too | |
319 | configure_opts.append("--enable-debug_gdb") | |
320 | configure_opts.append("--disable-optimise") | |
e2db04f8 RD |
321 | configure_opts.remove("--enable-optimise") |
322 | ||
3b2c81c7 RD |
323 | |
324 | if options.rebake: | |
6d6f2e7c | 325 | retval = run("make -f autogen.mk") |
3b2c81c7 RD |
326 | exitIfError(retval, "Error running autogen.mk") |
327 | ||
328 | if options.mac_framework: | |
e2db04f8 RD |
329 | # TODO: Should options.install be automatically turned on if the |
330 | # mac_framework flag is given? | |
331 | ||
3b2c81c7 RD |
332 | # framework builds always need to be monolithic |
333 | if not "--enable-monolithic" in configure_opts: | |
334 | configure_opts.append("--enable-monolithic") | |
6d6f2e7c | 335 | |
e2db04f8 RD |
336 | # The --prefix given to configure will be the framework prefix |
337 | # plus the framework specific dir structure. | |
338 | prefixDir = getPrefixInFramework(options) | |
6d6f2e7c | 339 | configure_opts.append("--prefix=" + prefixDir) |
5be89298 RD |
340 | |
341 | # the framework build adds symlinks above the installDir + prefixDir folder | |
342 | # so we need to wipe from the framework root instead of inside the prefixDir. | |
343 | frameworkRootDir = os.path.abspath(os.path.join(installDir + prefixDir, "..", "..")) | |
344 | if os.path.exists(frameworkRootDir): | |
345 | if os.path.exists(frameworkRootDir): | |
346 | shutil.rmtree(frameworkRootDir) | |
6d6f2e7c RD |
347 | |
348 | if options.mac_universal_binary: | |
403c71da RD |
349 | if options.mac_universal_binary == 'default': |
350 | if options.osx_cocoa: | |
351 | configure_opts.append("--enable-universal_binary=i386,x86_64") | |
352 | else: | |
353 | configure_opts.append("--enable-universal_binary") | |
354 | else: | |
355 | configure_opts.append("--enable-universal_binary=%s" % options.mac_universal_binary) | |
e2db04f8 | 356 | |
3b2c81c7 | 357 | |
016a3d4c | 358 | print("Configure options: " + repr(configure_opts)) |
3b2c81c7 | 359 | wxBuilder = builder.AutoconfBuilder() |
6d6f2e7c | 360 | if not options.no_config and not options.clean: |
3b2c81c7 RD |
361 | olddir = os.getcwd() |
362 | if buildDir: | |
363 | os.chdir(buildDir) | |
364 | exitIfError(wxBuilder.configure(dir=wxRootDir, options=configure_opts), | |
365 | "Error running configure") | |
366 | os.chdir(olddir) | |
e5ad1e9d RD |
367 | |
368 | if options.config_only: | |
016a3d4c | 369 | print("Exiting after configure") |
e5ad1e9d | 370 | return |
3b2c81c7 RD |
371 | |
372 | elif toolkit in ["msvc", "msvcProject"]: | |
373 | flags = {} | |
374 | buildDir = os.path.abspath(os.path.join(scriptDir, "..", "msw")) | |
e5ad1e9d | 375 | |
016a3d4c | 376 | print("creating wx/msw/setup.h from setup0.h") |
3b2c81c7 RD |
377 | if options.unicode: |
378 | flags["wxUSE_UNICODE"] = "1" | |
379 | if VERSION < (2,9): | |
380 | flags["wxUSE_UNICODE_MSLU"] = "1" | |
381 | ||
382 | if options.cairo: | |
932d0768 | 383 | if not os.environ.get("CAIRO_ROOT"): |
016a3d4c | 384 | print("WARNING: Expected CAIRO_ROOT set in the environment!") |
3b2c81c7 RD |
385 | flags["wxUSE_CAIRO"] = "1" |
386 | ||
387 | if options.wxpython: | |
388 | flags["wxDIALOG_UNIT_COMPATIBILITY "] = "0" | |
e5ad1e9d | 389 | flags["wxUSE_DEBUGREPORT"] = "0" |
3b2c81c7 | 390 | flags["wxUSE_DIALUP_MANAGER"] = "0" |
e5ad1e9d RD |
391 | flags["wxUSE_GRAPHICS_CONTEXT"] = "1" |
392 | flags["wxUSE_DISPLAY"] = "1" | |
3b2c81c7 RD |
393 | flags["wxUSE_GLCANVAS"] = "1" |
394 | flags["wxUSE_POSTSCRIPT"] = "1" | |
395 | flags["wxUSE_AFM_FOR_POSTSCRIPT"] = "0" | |
3b2c81c7 | 396 | flags["wxUSE_DATEPICKCTRL_GENERIC"] = "1" |
e5ad1e9d | 397 | |
3b2c81c7 RD |
398 | if VERSION < (2,9): |
399 | flags["wxUSE_DIB_FOR_BITMAP"] = "1" | |
400 | ||
401 | if VERSION >= (2,9): | |
402 | flags["wxUSE_UIACTIONSIMULATOR"] = "1" | |
932d0768 | 403 | |
3b2c81c7 RD |
404 | |
405 | mswIncludeDir = os.path.join(wxRootDir, "include", "wx", "msw") | |
406 | setup0File = os.path.join(mswIncludeDir, "setup0.h") | |
407 | setupText = open(setup0File, "rb").read() | |
408 | ||
409 | for flag in flags: | |
410 | setupText, subsMade = re.subn(flag + "\s+?\d", "%s %s" % (flag, flags[flag]), setupText) | |
411 | if subsMade == 0: | |
016a3d4c | 412 | print("Flag %s wasn't found in setup0.h!" % flag) |
3b2c81c7 RD |
413 | sys.exit(1) |
414 | ||
415 | setupFile = open(os.path.join(mswIncludeDir, "setup.h"), "wb") | |
416 | setupFile.write(setupText) | |
417 | setupFile.close() | |
418 | args = [] | |
419 | if toolkit == "msvc": | |
016a3d4c | 420 | print("setting build options...") |
3b2c81c7 RD |
421 | args.append("-f makefile.vc") |
422 | if options.unicode: | |
423 | args.append("UNICODE=1") | |
424 | if VERSION < (2,9): | |
425 | args.append("MSLU=1") | |
426 | ||
427 | if options.wxpython: | |
428 | args.append("OFFICIAL_BUILD=1") | |
5208671f | 429 | args.append("COMPILER_VERSION=%s" % getVisCVersion()) |
3b2c81c7 RD |
430 | args.append("SHARED=1") |
431 | args.append("MONOLITHIC=0") | |
432 | args.append("USE_OPENGL=1") | |
433 | args.append("USE_GDIPLUS=1") | |
3b2c81c7 RD |
434 | |
435 | if not options.debug: | |
3b2c81c7 RD |
436 | args.append("BUILD=release") |
437 | else: | |
438 | args.append("BUILD=debug") | |
9f2b6b31 RD |
439 | |
440 | if options.shared: | |
441 | args.append("SHARED=1") | |
932d0768 | 442 | |
9f2b6b31 | 443 | if options.cairo: |
932d0768 RD |
444 | args.append( |
445 | "CPPFLAGS=/I%s" % | |
446 | os.path.join(os.environ.get("CAIRO_ROOT", ""), 'include\\cairo')) | |
317bc825 RD |
447 | |
448 | if options.jom: | |
449 | nmakeCommand = 'jom.exe' | |
3b2c81c7 | 450 | |
317bc825 | 451 | wxBuilder = builder.MSVCBuilder(commandName=nmakeCommand) |
3b2c81c7 RD |
452 | |
453 | if toolkit == "msvcProject": | |
454 | args = [] | |
455 | if options.shared or options.wxpython: | |
456 | args.append("wx_dll.dsw") | |
457 | else: | |
458 | args.append("wx.dsw") | |
459 | ||
460 | # TODO: | |
461 | wxBuilder = builder.MSVCProjectBuilder() | |
462 | ||
e2db04f8 | 463 | |
3b2c81c7 | 464 | if not wxBuilder: |
016a3d4c | 465 | print("Builder not available for your specified platform/compiler.") |
3b2c81c7 RD |
466 | sys.exit(1) |
467 | ||
468 | if options.clean: | |
016a3d4c | 469 | print("Performing cleanup.") |
9f2b6b31 | 470 | wxBuilder.clean(dir=buildDir, options=args) |
3b2c81c7 RD |
471 | |
472 | sys.exit(0) | |
6d6f2e7c RD |
473 | |
474 | if options.extra_make: | |
475 | args.append(options.extra_make) | |
e2db04f8 | 476 | |
5be89298 RD |
477 | if not sys.platform.startswith("win"): |
478 | args.append("--jobs=" + options.jobs) | |
6d6f2e7c | 479 | exitIfError(wxBuilder.build(dir=buildDir, options=args), "Error building") |
6d6f2e7c RD |
480 | |
481 | if options.install: | |
482 | extra=None | |
483 | if installDir: | |
484 | extra = ['DESTDIR='+installDir] | |
9f2b6b31 | 485 | wxBuilder.install(dir=buildDir, options=extra) |
e2db04f8 RD |
486 | |
487 | if options.install and options.mac_framework: | |
3b2c81c7 RD |
488 | |
489 | def renameLibrary(libname, frameworkname): | |
490 | reallib = libname | |
491 | links = [] | |
492 | while os.path.islink(reallib): | |
493 | links.append(reallib) | |
494 | reallib = "lib/" + os.readlink(reallib) | |
495 | ||
016a3d4c | 496 | #print("reallib is %s" % reallib) |
6d6f2e7c | 497 | run("mv -f %s lib/%s.dylib" % (reallib, frameworkname)) |
3b2c81c7 RD |
498 | |
499 | for link in links: | |
6d6f2e7c | 500 | run("ln -s -f %s.dylib %s" % (frameworkname, link)) |
3b2c81c7 | 501 | |
6d6f2e7c RD |
502 | frameworkRootDir = prefixDir |
503 | if installDir: | |
016a3d4c | 504 | print("installDir = %s" % installDir) |
6d6f2e7c RD |
505 | frameworkRootDir = installDir + prefixDir |
506 | os.chdir(frameworkRootDir) | |
3b2c81c7 RD |
507 | build_string = "" |
508 | if options.debug: | |
509 | build_string = "d" | |
6d6f2e7c | 510 | |
b4f28d1e | 511 | fwname = getFrameworkName(options) |
016a3d4c RD |
512 | version = getoutput("bin/wx-config --release") |
513 | version_full = getoutput("bin/wx-config --version") | |
514 | basename = getoutput("bin/wx-config --basename") | |
515 | configname = getoutput("bin/wx-config --selected-config") | |
5be89298 RD |
516 | |
517 | os.makedirs("Resources") | |
518 | wxplist = dict( | |
519 | CFBundleDevelopmentRegion="English", | |
520 | CFBundleIdentifier='org.wxwidgets.wxosxcocoa', | |
521 | CFBundleName=fwname, | |
522 | CFBundleVersion=version_full, | |
523 | CFBundleExecutable=fwname, | |
524 | CFBundleGetInfoString="%s %s" % (fwname, version_full), | |
525 | CFBundlePackageType="FMWK", | |
526 | CFBundleSignature="WXCO", | |
527 | CFBundleShortVersionString=version_full, | |
528 | CFBundleInfoDictionaryVersion="6.0", | |
529 | ) | |
530 | ||
531 | import plistlib | |
532 | plistlib.writePlist(wxplist, os.path.join(frameworkRootDir, "Resources", "Info.plist")) | |
3b2c81c7 RD |
533 | |
534 | # we make wx the "actual" library file and link to it from libwhatever.dylib | |
535 | # so that things can link to wx and survive minor version changes | |
b4f28d1e RD |
536 | renameLibrary("lib/lib%s-%s.dylib" % (basename, version), fwname) |
537 | run("ln -s -f lib/%s.dylib %s" % (fwname, fwname)) | |
3b2c81c7 | 538 | |
5be89298 | 539 | run("ln -s -f include Headers") |
3b2c81c7 RD |
540 | |
541 | for lib in ["GL", "STC", "Gizmos", "Gizmos_xrc"]: | |
542 | libfile = "lib/lib%s_%s-%s.dylib" % (basename, lib.lower(), version) | |
543 | if os.path.exists(libfile): | |
544 | frameworkDir = "framework/wx%s/%s" % (lib, version) | |
545 | if not os.path.exists(frameworkDir): | |
546 | os.makedirs(frameworkDir) | |
547 | renameLibrary(libfile, "wx" + lib) | |
6d6f2e7c | 548 | run("ln -s -f ../../../%s %s/wx%s" % (libfile, frameworkDir, lib)) |
3b2c81c7 RD |
549 | |
550 | for lib in glob.glob("lib/*.dylib"): | |
551 | if not os.path.islink(lib): | |
552 | corelibname = "lib/lib%s-%s.0.dylib" % (basename, version) | |
6d6f2e7c RD |
553 | run("install_name_tool -id %s %s" % (os.path.join(prefixDir, lib), lib)) |
554 | run("install_name_tool -change %s %s %s" % (os.path.join(frameworkRootDir, corelibname), os.path.join(prefixDir, corelibname), lib)) | |
b4f28d1e | 555 | |
3b2c81c7 RD |
556 | os.chdir("include") |
557 | ||
e2db04f8 | 558 | header_template = """ |
3b2c81c7 RD |
559 | #ifndef __WX_FRAMEWORK_HEADER__ |
560 | #define __WX_FRAMEWORK_HEADER__ | |
561 | ||
562 | %s | |
563 | ||
564 | #endif // __WX_FRAMEWORK_HEADER__ | |
565 | """ | |
566 | headers = "" | |
567 | header_dir = "wx-%s/wx" % version | |
568 | for include in glob.glob(header_dir + "/*.h"): | |
5be89298 | 569 | headers += "#include <wx/" + os.path.basename(include) + ">\n" |
3b2c81c7 | 570 | |
5be89298 | 571 | framework_header = open("%s.h" % fwname, "w") |
3b2c81c7 RD |
572 | framework_header.write(header_template % headers) |
573 | framework_header.close() | |
574 | ||
6d6f2e7c | 575 | run("ln -s -f %s wx" % header_dir) |
5be89298 RD |
576 | os.chdir("wx-%s/wx" % version) |
577 | run("ln -s -f ../../../lib/wx/include/%s/wx/setup.h setup.h" % configname) | |
3b2c81c7 | 578 | |
5be89298 RD |
579 | os.chdir(os.path.join(frameworkRootDir, "..")) |
580 | run("ln -s -f %s Current" % getWxRelease()) | |
581 | os.chdir("..") | |
6d6f2e7c RD |
582 | run("ln -s -f Versions/Current/Headers Headers") |
583 | run("ln -s -f Versions/Current/Resources Resources") | |
b4f28d1e | 584 | run("ln -s -f Versions/Current/%s %s" % (fwname, fwname)) |
3b2c81c7 | 585 | |
6d6f2e7c | 586 | # sanity check to ensure the symlink works |
e2db04f8 | 587 | os.chdir("Versions/Current") |
b4f28d1e RD |
588 | |
589 | # put info about the framework into wx-config | |
590 | os.chdir(frameworkRootDir) | |
591 | text = file('lib/wx/config/%s' % configname).read() | |
592 | text = text.replace("MAC_FRAMEWORK=", "MAC_FRAMEWORK=%s" % getFrameworkName(options)) | |
593 | if options.mac_framework_prefix not in ['/Library/Frameworks', | |
594 | '/System/Library/Frameworks']: | |
595 | text = text.replace("MAC_FRAMEWORK_PREFIX=", | |
596 | "MAC_FRAMEWORK_PREFIX=%s" % options.mac_framework_prefix) | |
597 | file('lib/wx/config/%s' % configname, 'w').write(text) | |
598 | ||
599 | # The framework is finished! | |
016a3d4c | 600 | print("wxWidgets framework created at: " + |
e2db04f8 RD |
601 | os.path.join( installDir, |
602 | options.mac_framework_prefix, | |
016a3d4c | 603 | '%s.framework' % fwname)) |
e2db04f8 RD |
604 | |
605 | ||
606 | # adjust the install_name if needed | |
3b2c81c7 RD |
607 | if sys.platform.startswith("darwin") and \ |
608 | options.install and \ | |
609 | options.installdir and \ | |
e2db04f8 | 610 | not options.mac_framework and \ |
3b2c81c7 | 611 | not options.wxpython: # wxPython's build will do this later if needed |
6d6f2e7c RD |
612 | if not prefixDir: |
613 | prefixDir = '/usr/local' | |
614 | macFixupInstallNames(options.installdir, prefixDir)#, buildDir) | |
615 | ||
616 | # make a package if a destdir was set. | |
617 | if options.mac_framework and \ | |
e2db04f8 | 618 | options.install and \ |
6d6f2e7c RD |
619 | options.installdir and \ |
620 | options.mac_distdir: | |
3b2c81c7 | 621 | |
6d6f2e7c RD |
622 | if os.path.exists(options.mac_distdir): |
623 | shutil.rmtree(options.mac_distdir) | |
624 | ||
625 | packagedir = os.path.join(options.mac_distdir, "packages") | |
626 | os.makedirs(packagedir) | |
627 | basename = os.path.basename(prefixDir.split(".")[0]) | |
628 | packageName = basename + "-" + getWxRelease() | |
9ad2035a | 629 | packageMakerPath = getXcodePaths()[0]+"/usr/bin/packagemaker " |
6d6f2e7c RD |
630 | args = [] |
631 | args.append("--root %s" % options.installdir) | |
632 | args.append("--id org.wxwidgets.%s" % basename.lower()) | |
633 | args.append("--title %s" % packageName) | |
634 | args.append("--version %s" % getWxRelease()) | |
635 | args.append("--out %s" % os.path.join(packagedir, packageName + ".pkg")) | |
636 | cmd = packageMakerPath + ' '.join(args) | |
016a3d4c | 637 | print("cmd = %s" % cmd) |
6d6f2e7c RD |
638 | run(cmd) |
639 | ||
640 | os.chdir(options.mac_distdir) | |
641 | ||
642 | run('hdiutil create -srcfolder %s -volname "%s" -imagekey zlib-level=9 %s.dmg' % (packagedir, packageName, packageName)) | |
3b2c81c7 | 643 | |
6d6f2e7c | 644 | shutil.rmtree(packagedir) |
3b2c81c7 RD |
645 | |
646 | if __name__ == '__main__': | |
647 | exitWithException = False # use sys.exit instead | |
648 | main(sys.argv[0], sys.argv[1:]) | |
649 |