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