diff options
author | konablend <[email protected]> | 2012-01-04 09:41:11 +0000 |
---|---|---|
committer | konablend <[email protected]> | 2012-01-04 09:41:11 +0000 |
commit | 6d95ab81984cc44296438270aa792255f037c89a (patch) | |
tree | 842d42f935c31a5ec8c1529605cd0226d5d29197 /make | |
parent | aad50499b32c44d28a6bae7f353b579e24564e25 (diff) |
BuildSystem: Mac OS X - transition to Xcode4
- transition from Xcode3 to Xcode4
- overhaul HandBrake.xcodeproj file
- simplify down to 2 configurations: debug, release
- add xcconfig for useful variants: osx106.i386, osx106.x86_64, osx107.i386, osx107.x86_64
- add configure --xcode-config as preferred method to choose OSX minimum version and SDK
- overhaul Info.plist generation to use m4 instead of cpp
- remove use of direct static libraries on command line - Xcode4 now enables -search_paths_first by default
- reference external build static libraries project file - greatly simplifying project file maintenance
- update universal build targets to use --xcode-config
- update ffmpeg hack to build on i386 in both debug and optimized modes
- update ffmpeg build to show compile verbosity
- enable local yasm when yasm probe fails
- remove unused GCC.ldsysroot
- remove unused GCC.ldminver
- enhance xcodemake to use --sysroot, --minver
- update/regenerate docs accordingly
- add support for configure-time repo probe when svn repo is incompatible format to Xcode via .svn/HANDBRAKE_REPO_PROBE
- replaced make/test/build.matrix.darwin with make/test/build.matrix
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@4395 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'make')
-rw-r--r-- | make/configure.py | 123 | ||||
-rw-r--r-- | make/include/gcc.defs | 10 | ||||
-rw-r--r-- | make/include/main.rules | 19 | ||||
-rwxr-xr-x | make/test/build.matrix | 156 | ||||
-rwxr-xr-x | make/test/build.matrix.darwin | 59 | ||||
-rw-r--r-- | make/variant/darwin.defs | 25 | ||||
-rw-r--r-- | make/variant/darwin.rules | 12 | ||||
-rwxr-xr-x | make/xcodemake | 181 |
8 files changed, 394 insertions, 191 deletions
diff --git a/make/configure.py b/make/configure.py index 5e61b6e5a..3e6fb81b5 100644 --- a/make/configure.py +++ b/make/configure.py @@ -8,6 +8,7 @@ ############################################################################### import fnmatch +import glob import optparse import os import platform @@ -99,12 +100,6 @@ class Configure( object ): cfg.infof( 'compute: makevar BUILD/ = %s\n', self.build_final ) cfg.infof( 'compute: makevar PREFIX/ = %s\n', self.prefix_final ) - ## xcode does a chdir so we need appropriate values - macosx = os.path.join( self.src_dir, 'macosx' ) - self.xcode_x_src = self._final_dir( macosx, self.src_dir ) - self.xcode_x_build = self._final_dir( macosx, self.build_dir ) - self.xcode_x_prefix = self._final_dir( macosx, self.prefix_dir ) - ## perform chdir and enable log recording def chdir( self ): if os.path.abspath( self.build_dir ) == os.path.abspath( self.src_dir ): @@ -402,8 +397,10 @@ class LDProbe( Action ): ## ## example results from various platforms: ## -## i386-apple-darwin9.6.0 (Mac OS X 10.5.6 Intel) ## powerpc-apple-darwin9.6.0 (Mac OS X 10.5.6 PPC) +## i386-apple-darwin9.6.0 (Mac OS X 10.5.6 Intel) +## x86_64-apple-darwin10.8.0 (Mac OS X 10.6.8 Intel) +## x86_64-apple-darwin11.2.0 (Mac OS X 10.7.2 Intel) ## i686-pc-cygwin (Cygwin, Microsoft Vista) ## x86_64-unknown-linux-gnu (Linux, Fedora 10 x86_64) ## @@ -553,6 +550,9 @@ class ArchAction( Action ): ## some match on system should be made here; otherwise we signal a warning. if host.match( '*-*-cygwin*' ): pass + elif host.match( '*-*-darwin11.*' ): + self.mode['i386'] = 'i386-apple-darwin%s' % (host.release) + self.mode['x86_64'] = 'x86_64-apple-darwin%s' % (host.release) elif host.match( '*-*-darwin*' ): self.mode['i386'] = 'i386-apple-darwin%s' % (host.release) self.mode['x86_64'] = 'x86_64-apple-darwin%s' % (host.release) @@ -628,20 +628,24 @@ class CoreProbe( Action ): class SelectMode( dict ): def __init__( self, descr, *modes, **kwargs ): super( SelectMode, self ).__init__( modes ) - self.descr = descr - self.modes = modes - self.default = kwargs.get('default',modes[0][0]) - self.mode = self.default + self.descr = descr + self.modes = modes + self.what = kwargs.get('what',' mode') + if modes: + self.default = kwargs.get('default',modes[0][0]) + else: + self.default = None + self.mode = self.default def cli_add_option( self, parser, option ): parser.add_option( option, default=self.mode, metavar='MODE', - help='select %s mode: %s' % (self.descr,self.toString()), + help='select %s%s: %s' % (self.descr,self.what,self.toString()), action='callback', callback=self.cli_callback, type='str' ) def cli_callback( self, option, opt_str, value, parser, *args, **kwargs ): if value not in self: - raise optparse.OptionValueError( 'invalid %s mode: %s (choose from %s)' - % (self.descr,value,self.toString( True )) ) + raise optparse.OptionValueError( 'invalid %s%s: %s (choose from: %s)' + % (self.descr,self.what,value,self.toString( True )) ) self.mode = value def toString( self, nodefault=False ): @@ -671,7 +675,23 @@ class SelectMode( dict ): ## class RepoProbe( ShellProbe ): def __init__( self ): - super( RepoProbe, self ).__init__( 'svn info', 'svn info %s' % (cfg.src_dir) ) + svn = 'svn' + + ## Possible the repo was created using an incompatible version than what is + ## available in PATH when probe runs. Workaround by checking for file + ## .svn/HANDBRAKE_REPO_PROBE which points to a preferred svn executable. + try: + hrp = os.path.join( cfg.src_dir, '.svn', 'HANDBRAKE_REPO_PROBE' ) + if os.path.isfile( hrp ) and os.path.getsize( hrp ) > 0: + file = cfg.open( hrp, 'r' ) + line = file.readline().strip() + file.close() + if line: + svn = line + except: + pass + + super( RepoProbe, self ).__init__( 'svn info', '%s info %s' % (svn,cfg.src_dir) ) self.url = 'svn://nowhere.com/project/unknown' self.root = 'svn://nowhere.com/project' @@ -865,7 +885,7 @@ class SelectTool( Action ): self.run() break if not found: - raise optparse.OptionValueError( 'invalid %s mode: %s (choose from %s)' + raise optparse.OptionValueError( 'invalid %s mode: %s (choose from: %s)' % (self.name,value,self.toString( True )) ) def doc_add( self, doc ): @@ -1003,8 +1023,8 @@ class Option( optparse.Option ): conf_args = [] def _conf_record( self, opt, value ): - ## skip conf,force,launch - if re.match( '^--(conf|force|launch).*$', opt ): + ## filter out non-applicable options + if re.match( '^--(force|launch).*$', opt ): return ## remove duplicates (last duplicate wins) @@ -1030,13 +1050,13 @@ def createCLI(): cli.description += 'Configure %s build system.' % (project.name) ## add hidden options - cli.add_option( '--conf-method', default='terminal', action='store', help=optparse.SUPPRESS_HELP ) + cli.add_option( '--xcode-driver', default='bootstrap', action='store', help=optparse.SUPPRESS_HELP ) cli.add_option( '--force', default=False, action='store_true', help='overwrite existing build config' ) cli.add_option( '--verbose', default=False, action='store_true', help='increase verbosity' ) ## add install options grp = OptionGroup( cli, 'Directory Locations' ) - h = IfHost( 'specify sysroot (e.g. for Leopard builds from Snow Leapard)', '*-*-darwin*', none=optparse.SUPPRESS_HELP ).value + h = IfHost( 'specify sysroot of SDK for Xcode builds', '*-*-darwin*', none=optparse.SUPPRESS_HELP ).value grp.add_option( '--sysroot', default=None, action='store', metavar='DIR', help=h ) grp.add_option( '--src', default=cfg.src_dir, action='store', metavar='DIR', @@ -1064,9 +1084,6 @@ def createCLI(): h = IfHost( 'enable use of ffmpeg mpeg2 decoding', '*-*-*', none=optparse.SUPPRESS_HELP ).value grp.add_option( '--enable-ff-mpeg2', default=False, action='store_true', help=h ) - h = IfHost( 'disable Xcode', '*-*-darwin*', none=optparse.SUPPRESS_HELP ).value - grp.add_option( '--disable-xcode', default=False, action='store_true', help=h ) - cli.add_option_group( grp ) ## add launch options @@ -1088,7 +1105,7 @@ def createCLI(): arch.mode.cli_add_option( grp, '--arch' ) grp.add_option( '--cross', default=None, action='store', metavar='SPEC', help='specify GCC cross-compilation spec' ) - h = IfHost( 'Min OS X Version', '*-*-darwin*', none=optparse.SUPPRESS_HELP ).value + h = IfHost( 'specify Mac OS X deployment target for Xcode builds', '*-*-darwin*', none=optparse.SUPPRESS_HELP ).value grp.add_option( '--minver', default=None, action='store', metavar='VER', help=h ) @@ -1097,6 +1114,16 @@ def createCLI(): cli.add_option_group( grp ) + ## add Xcode options + if host.match( '*-*-darwin*' ): + grp = OptionGroup( cli, 'Xcode Options' ) + grp.add_option( '--disable-xcode', default=False, action='store_true', + help='disable Xcode' ) + grp.add_option( '--xcode-symroot', default='xroot', action='store', metavar='DIR', + help='specify root of the directory hierarchy that contains product files and intermediate build files' ) + xcconfigMode.cli_add_option( grp, '--xcode-config' ) + cli.add_option_group( grp ) + ## add tool locations grp = OptionGroup( cli, 'Tool Basenames and Locations' ) for tool in ToolProbe.tools: @@ -1266,6 +1293,19 @@ try: debugMode = SelectMode( 'debug', ('none','none'), ('min','min'), ('std','std'), ('max','max') ) optimizeMode = SelectMode( 'optimize', ('none','none'), ('speed','speed'), ('size','size'), default='speed' ) + ## find xcconfig values + xcconfigMode = SelectMode( 'xcconfig', ('none',None), what='' ) + if host.match( '*-*-darwin*' ): + for xc in glob.glob( os.path.join(cfg.dir, '../macosx/xcconfig/*.xcconfig') ): + bname = os.path.basename( xc ) + xname = os.path.splitext( bname ) + if xname and xname[0]: + xcconfigMode[xname[0]] = bname + if not 'native' in xcconfigMode: + raise Exception( 'native xcconfig not found' ) + xcconfigMode.default = 'native' + xcconfigMode.mode = xcconfigMode.default + ## create CLI and parse cli = createCLI() (options,args) = cli.parse_args() @@ -1294,6 +1334,10 @@ try: for action in Action.actions: action.run() + ## enable local yasm when yasm probe fails + if Tools.yasm.fail and not options.enable_local_yasm: + options.enable_local_yasm = True + if build.system == 'mingw': dlfcn_test = """ #include <dlfcn.h> @@ -1437,20 +1481,16 @@ int main () doc.add( 'BUILD.ncpu', core.count ) doc.add( 'BUILD.jobs', core.jobs ) - doc.add( 'BUILD.cross', int(options.cross != None or arch.mode.mode != arch.mode.default) ) + doc.add( 'BUILD.cross', int(options.cross != None or arch.mode.mode != arch.mode.default) ) if options.cross: doc.add( 'BUILD.cross.prefix', '%s-' % (options.cross) ) else: doc.add( 'BUILD.cross.prefix', '' ) - doc.add( 'BUILD.method', 'terminal' ) doc.add( 'BUILD.date', time.strftime('%c') ) doc.add( 'BUILD.arch', arch.mode.mode ) doc.addBlank() - doc.add( 'CONF.method', options.conf_method ) - - doc.addBlank() doc.add( 'SRC', cfg.src_final ) doc.add( 'SRC/', cfg.src_final + os.sep ) doc.add( 'BUILD', cfg.build_final ) @@ -1460,22 +1500,25 @@ int main () doc.addBlank() doc.add( 'FEATURE.local_yasm', int( options.enable_local_yasm ) ) - doc.add( 'FEATURE.asm', 'disabled' ) - doc.add( 'FEATURE.gtk', int( not options.disable_gtk )) - doc.add( 'FEATURE.gtk.update.checks', int( not options.disable_gtk_update_checks )) - doc.add( 'FEATURE.gtk.mingw', int( options.enable_gtk_mingw )) - doc.add( 'FEATURE.gst', int( not options.disable_gst )) + doc.add( 'FEATURE.asm', 'disabled' ) + doc.add( 'FEATURE.gtk', int( not options.disable_gtk )) + doc.add( 'FEATURE.gtk.update.checks', int( not options.disable_gtk_update_checks )) + doc.add( 'FEATURE.gtk.mingw', int( options.enable_gtk_mingw )) + doc.add( 'FEATURE.gst', int( not options.disable_gst )) doc.add( 'FEATURE.ff.mpeg2', int( options.enable_ff_mpeg2 )) - doc.add( 'FEATURE.xcode', int( not (Tools.xcodebuild.fail or options.disable_xcode or options.cross) )) + doc.add( 'FEATURE.xcode', int( not (Tools.xcodebuild.fail or options.disable_xcode or options.cross) )) if not Tools.xcodebuild.fail and not options.disable_xcode: doc.addBlank() - doc.add( 'XCODE.external.src', cfg.xcode_x_src ) - doc.add( 'XCODE.external.build', cfg.xcode_x_build ) - doc.add( 'XCODE.external.prefix', cfg.xcode_x_prefix ) + doc.add( 'XCODE.driver', options.xcode_driver ) + if os.path.isabs(options.xcode_symroot): + doc.add( 'XCODE.symroot', options.xcode_symroot ) + else: + doc.add( 'XCODE.symroot', os.path.abspath(os.path.join(cfg.build_dir,options.xcode_symroot)) ) + doc.add( 'XCODE.xcconfig', xcconfigMode[xcconfigMode.mode] ) - doc.addBlank() if build.system == 'mingw': + doc.addBlank() if not dlfcn.fail: doc.add( 'HAS.dlfcn', 1 ) if not pthread.fail: @@ -1513,8 +1556,6 @@ int main () doc.add( 'GCC.archs', '' ) doc.add( 'GCC.sysroot', '' ) doc.add( 'GCC.minver', '' ) - doc.add( 'GCC.ldsysroot', '$(GCC.sysroot)' ) - doc.add( 'GCC.ldminver', '$(GCC.minver)' ) if options.enable_asm and ( not Tools.yasm.fail or options.enable_local_yasm ): asm = '' diff --git a/make/include/gcc.defs b/make/include/gcc.defs index c93d0babd..50b31f100 100644 --- a/make/include/gcc.defs +++ b/make/include/gcc.defs @@ -1,5 +1,5 @@ GCC.gcc = gcc -GCC.gxx = $(dir $(GCC.gcc))$(subst gcc,g++,$(notdir $(GCC.gcc))) +GCC.gxx = $(dir $(GCC.gcc))$(subst clang,clang++,$(subst gcc,g++,$(notdir $(GCC.gcc)))) GCC.strip = $$(if $$(filter none,$$(GCC.g)),1) GCC.dylib = 1 @@ -9,9 +9,7 @@ GCC.H = 0 GCC.W = all GCC.archs = GCC.sysroot = -GCC.ldsysroot = GCC.minver = -GCC.ldminver= GCC.vis = 0 GCC.pic = 0 ifndef GCC.g @@ -49,9 +47,7 @@ GCC.args.H = -H GCC.args.W = -W$(1) GCC.args.archs = -arch $(1) GCC.args.sysroot = --sysroot=$(1) -GCC.args.ldsysroot = -syslibroot $(1) GCC.args.minver = -mmacosx-version-min=$(1) -GCC.args.ldminver = -macosx_version_min $(1) GCC.args.vis = -fvisibility=hidden GCC.args.pic = -fPIC GCC.args.g.none = -g0 @@ -95,9 +91,7 @@ define import.GCC $(1).GCC.W = $$(GCC.W) $(1).GCC.archs = $$(GCC.archs) $(1).GCC.sysroot = $$(GCC.sysroot) - $(1).GCC.ldsysroot = $$(GCC.ldsysroot) $(1).GCC.minver = $$(GCC.minver) - $(1).GCC.ldminver = $$(GCC.ldminver) $(1).GCC.vis = $$(GCC.vis) $(1).GCC.pic = $$(GCC.pic) $(1).GCC.g = $$(GCC.g) @@ -131,9 +125,7 @@ define import.GCC $(1).GCC.args.W = $$(GCC.args.W) $(1).GCC.args.archs = $$(GCC.args.archs) $(1).GCC.args.sysroot = $$(GCC.args.sysroot) - $(1).GCC.args.ldsysroot = $$(GCC.args.ldsysroot) $(1).GCC.args.minver = $$(GCC.args.minver) - $(1).GCC.args.ldminver = $$(GCC.args.ldminver) $(1).GCC.args.vis = $$(GCC.args.vis) $(1).GCC.args.pic = $$(GCC.args.pic) $(1).GCC.args.g.none = $$(GCC.args.g.none) diff --git a/make/include/main.rules b/make/include/main.rules index 5a8d8acfb..158f24a9c 100644 --- a/make/include/main.rules +++ b/make/include/main.rules @@ -3,10 +3,9 @@ ############################################################################### -## file-wide conditional to use xcode rules if xcode=1 method=terminal -## xcodemake will set BUILD.method != terminal to prevent infinite recursion -ifeq (1:terminal,$(FEATURE.xcode):$(BUILD.method)) - include $(SRC/)macosx/module.xcode +## shunt make through xcodebuild when FEATURE.xcode=1 and XCODE.driver is applicable +ifeq (1:shunt,$(FEATURE.xcode):$(if $(filter bootstrap terminal,$(XCODE.driver)),shunt)) + include $(SRC/)macosx/module.xcodebuild else ## only included using special report targets @@ -40,19 +39,15 @@ include $(MODULES:%=$(SRC/)%/module.rules) ############################################################################### -## target which causes re-configure if project-root is svn update'd -$(BUILD/)GNUmakefile: $(wildcard $(SRC/).svn/entries) - $(SRC/)configure --force --conf-method=$(CONF.method) $(CONF.args) - -## target useful to force reconfigure; only helpful for build-system development +## force reconfigure .PHONY: reconfigure reconfigure: - $(SRC/)configure --force --conf-method=$(CONF.method) $(CONF.args) + $(SRC/)configure --force $(CONF.args) ############################################################################### -## target to build all dependency dirs +## build all dependency dirs $(sort $(dir $(BUILD.out))): $(MKDIR.exe) -p $@ -endif ## xcode=1 method=terminal +endif ## FEATURE.xcode XCODE.driver diff --git a/make/test/build.matrix b/make/test/build.matrix new file mode 100755 index 000000000..70d07445b --- /dev/null +++ b/make/test/build.matrix @@ -0,0 +1,156 @@ +#!/usr/bin/env ruby1.9 + +## This script is used to launch a wide variety of builds for darwin. +## It is unsupported and is meant for use only with build-system testing. + +require 'pathname' +require 'thread' + +################################################################################ + +class Printer < Mutex + def p(*args) + synchronize { super } + end + + def puts(*args) + synchronize { super } + end +end + +$out = Printer.new + +################################################################################ + +class Build + def initialize(debug, xcconfig, method) + @debug = debug + @xcconfig = xcconfig + @method = method + if @xcconfig + @dir = '_matrix.%s.%s.%s' % [@debug[0], @xcconfig, @method] + else + @dir = '_matrix.%s.%s' % [@debug[0], @method] + end + @configure = [] + @make = [] + end + + def doit + p = Pathname.new(@dir) + return if p.exist? + p.mkdir + + @configure[0..0] += @debug[1].split + @configure[0..0] += ["--build=#{@dir}"] + @configure << ('--xcode-config=%s' % [@xcconfig]) if @xcconfig + + if [email protected]? + @make[0..0] += ['-C', @dir] + end + + if [email protected]? + return if !run(@configure) + end + if [email protected]? + return if !run(@make, true) + end + end + +private + def run(args, append=false) + s = args.join(' ') + $out.puts s + return Kernel.system('%s %s %s/matrix.log 2>&1' % [s, append ? '>>' : '>', @dir]) + end +end + +################################################################################ + +class BuildTerminal < Build + def initialize(debug, xcconfig) + super(debug, xcconfig, 'term_make') + @configure += './configure --force --disable-xcode'.split + @make += 'make BUILD.jobs=1'.split + end +end + +class BuildLaunch < Build + def initialize(debug, xcconfig) + super(debug, xcconfig, 'launch_make') + @configure += './configure --force --launch --launch-jobs=1 --disable-xcode'.split + end +end + +class BuildTerminalXcode < Build + def initialize(debug, xcconfig) + super(debug, xcconfig, 'term_xcode') + @configure += './configure --force'.split + @make += 'make BUILD.jobs=1'.split + end +end + +class BuildLaunchXcode < Build + def initialize(debug, xcconfig) + super(debug, xcconfig, 'launch_xcode') + @configure += './configure --force --launch --launch-jobs=1'.split + end +end + +################################################################################ + +## probe ncpu +begin + case + when RUBY_PLATFORM =~ /darwin/ + workload = `sysctl -n hw.activecpu 2>/dev/null`[0].to_i + end +rescue + workload = 1 +end + +## create work queue +queue = Queue.new + +## create xcconfig list +xclist = [] +case +when RUBY_PLATFORM =~ /darwin11/ + xclist += 'native osx106.i386 osx106.x86_64 osx107.i386 osx107.x86_64'.split +when RUBY_PLATFORM =~ /darwin10/ + xclist += 'native osx106.i386 osx106.x86_64'.split +end + +## fill queue +[['release',''],['debug','--debug=max --optimize=none']].each do |debug| + [BuildTerminal, BuildLaunch].each do |kind| + queue << kind.new(debug, nil) + end + [BuildTerminalXcode, BuildLaunchXcode].each do |kind| + xclist.each do |xcconfig| + queue << kind.new(debug, xcconfig) + end + end +end + +## process queue +workers = (1..workload).map do |i| + queue << :finish + Thread.new() do |worker| + loop do + item = queue.pop + break if item == :finish + + begin + item.doit + rescue SystemExit + break + rescue + puts 'whups' + end + end + end +end + +## wait for all workers to finish +workers.each(&:join) diff --git a/make/test/build.matrix.darwin b/make/test/build.matrix.darwin deleted file mode 100755 index 7620707b5..000000000 --- a/make/test/build.matrix.darwin +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash -# - -## This script is used to launch a wide variety of builds for darwin. -## It is unsupported and is meant for use only with build-system testing. - -if [ -z "$1" ]; then - echo "usage: $0 BUILDPREFIX" - exit 1 -fi - -set -e -buildprefix=$1 - -term_make() { - eval $1="make" - eval $2="'--disable-xcode'" -} - -term_xcode() { - eval $1="make" - eval $2="" -} - -launch_make() { - eval $1="launch" - eval $2="'--launch --launch-jobs=0 --launch-quiet --disable-xcode'" -} - -launch_xcode() { - eval $1="launch" - eval $2="'--launch --launch-jobs=0 --launch-quiet'" -} - -for debug in none max; do -for arch in i386 ppc ppc64 x86_64; do - for method in launch_make launch_xcode term_make term_xcode; do - dir=$buildprefix.$arch.$debug.$method - if [ -d $dir ]; then - echo "skipping $dir" - continue - fi - - $method mode args - - cmd="./configure --arch=$arch --debug=$debug --build=$dir $args" - echo $cmd | awk '{ \ - trail = ""; \ - for( i = 4; i <= NF; i++ ) \ - trail = trail " " $i; \ - printf("%-11s %-13s %-30s%s\n", $1, $2, $3, trail) }' - - $cmd - if [ "$mode" = "make" ]; then - (set -x; cd $dir && make -j8 >& log/build.txt) - fi - done -done -done diff --git a/make/variant/darwin.defs b/make/variant/darwin.defs index 4c9d06bb2..755bcb571 100644 --- a/make/variant/darwin.defs +++ b/make/variant/darwin.defs @@ -1,9 +1,10 @@ -UB.archs = i386 x86_64 ppc ppc64 -UB.builds = $(wildcard $(foreach n,$(UB.archs),$(SRC/)build.$n)) -UB.first = $(word 1,$(UB.archs)) -UB.other = $(wordlist 2,999,$(UB.archs)) +UB.xcconfigs = osx106.i386 osx106.x86_64 +UB.builds = $(wildcard $(foreach n,$(UB.xcconfigs),$(SRC/)build.$n)) +UB.first = $(word 1,$(UB.xcconfigs)) +UB.more = $(wordlist 2,999,$(UB.xcconfigs)) +UB.products/ = macosx/release/ -UB.BUILD = $(SRC/)configure --force --build=ub.$(1) --arch=$(1) --launch --launch-quiet +UB.BUILD = $(SRC/)configure --force --build=ub.$(1) --xcconfig=$(1) --launch --launch-quiet ## linefeed is important define UB.BUILD.item @@ -12,7 +13,7 @@ define UB.BUILD.item endef define UB.BUILD.SERIAL - $(foreach n,$(UB.archs),$(call UB.BUILD.item,$n)) + $(foreach n,$(UB.xcconfigs),$(call UB.BUILD.item,$n)) endef define UB.BUILD.PARALLEL @@ -22,16 +23,16 @@ endef define UB.COMBINE $(RM.exe) -fr ub.combine $(MKDIR.exe) -p ub.combine - $(CP.exe) ub.$(UB.first)/HandBrakeCLI ub.combine/. - $(LIPO.exe) $(foreach n,$(UB.archs),ub.$n/HandBrakeCLI) -create -output ub.combine/HandBrakeCLI - $(CP.exe) -R ub.$(UB.first)/HandBrake.app ub.combine/. - $(LIPO.exe) $(foreach n,$(UB.archs),ub.$n/$(1)) -create -output ub.combine/$(1) + $(CP.exe) ub.$(UB.first)/$(UB.products/)HandBrakeCLI ub.combine/. + $(LIPO.exe) $(foreach n,$(UB.xcconfigs),ub.$n/$(UB.products/)HandBrakeCLI) -create -output ub.combine/HandBrakeCLI + $(CP.exe) -R ub.$(UB.first)/$(UB.products/)HandBrake.app ub.combine/. + $(LIPO.exe) $(foreach n,$(UB.xcconfigs),ub.$n/$(UB.products/)$(1)) -create -output ub.combine/$(1) @lipo -info ub.combine/$(1) @sync @echo "" - @echo "$@: { $(UB.archs) } combined -> ub.combine/HandBrakeCLI" + @echo "$@: { $(UB.xcconfigs) } combined -> ub.combine/HandBrakeCLI" @echo "$@: UB executable size: `du -sh ub.combine/HandBrakeCLI | awk '{ print $$1 }'`" @echo "" - @echo "$@: { $(UB.archs) } combined -> ub.combine/HandBrake.app" + @echo "$@: { $(UB.xcconfigs) } combined -> ub.combine/HandBrake.app" @echo "$@: UB executable size: `du -sh ub.combine/$(1) | awk '{ print $$1 }'`" endef diff --git a/make/variant/darwin.rules b/make/variant/darwin.rules index d59a222b4..cd0d1ade9 100644 --- a/make/variant/darwin.rules +++ b/make/variant/darwin.rules @@ -1,14 +1,16 @@ .PHONY: ub.build ub.combine ub.clean +ub.build: ub.build.serial + ub.build.serial: @$(UB.BUILD.SERIAL) ub.build.parallel: @set -e; \ - for arch in $(UB.archs); do \ - $(call UB.BUILD.PARALLEL,$$arch) & \ + for xcconfig in $(UB.xcconfigs); do \ + $(call UB.BUILD.PARALLEL,$$xcconfig) & \ children="$$children $$!"; \ - echo "pid $$!: $(call UB.BUILD.PARALLEL,$$arch)"; \ + echo "pid $$!: $(call UB.BUILD.PARALLEL,$$xcconfig)"; \ done; \ echo "waiting for background jobs to complete:$$children"; \ wait @@ -16,5 +18,5 @@ ub.build.parallel: ub.combine: $(call UB.COMBINE,HandBrake.app/Contents/MacOS/HandBrake) -ub.clean: - $(RM.EXE) -fr $(foreach n,$(UB.archs.other),ub.$n) +#ub.clean: +# $(RM.exe) -fr $(foreach n,$(UB.archs.other),ub.$n) diff --git a/make/xcodemake b/make/xcodemake index 93c927c96..b4b6bad94 100755 --- a/make/xcodemake +++ b/make/xcodemake @@ -3,34 +3,95 @@ set -e -## This script is invoked by Xcode external targets. +## This script is initiated by either xcodebuild or Xcode.app. ## -## We must guarantee no jobserver is passed through since the file-descriptors -## have been clobbered by Xcode. If this is not done then make behaves as if -## it is allowed to run an infinite number of jobs. +## We must guarantee no jobserver is passed through since file-descriptors are +## clobbered by Xcode. If this is not done then make allows unlimited jobs. ## MAKEFLAGS= MFLAGS= -## sanity check - the build system only supports 1 arch at a time +## validate environment +case "$EXTERNAL_DRIVER" in +bootstrap) ;; ## bootstrapping from terminal +terminal) ;; ## building from terminal +xcode) ;; ## building from Xcode.app +*) + echo "ERROR: unexpected value for EXTERNAL_DRIVER: $EXTERNAL_DRIVER" + exit 1 + ;; +esac + +## validate environment +for name in EXTERNAL_BUILD EXTERNAL_JOBS EXTERNAL_SRC; do + eval v="\$$name" + if [ -z "$v" ]; then + echo "ERROR: missing value for $name" + exit 1 + fi +done + +## validate environment archcount=`echo $ARCHS | awk '{ print NF }'` if [ "$archcount" -ne 1 ]; then echo "*********************************************************************" echo "***" - echo "*** ERROR: invalid number of architectures: $ARCHS" - echo "*** This build system builds one (1) archtecture at a time." + echo "*** ERROR: multiple architectures: $ARCHS" + echo "***" + echo "*** This build system does not support more than one (1)" + echo "*** simultaneous architecture setting." echo "***" echo "*********************************************************************" exit 1 fi +exit_post_log=0 + +## compute goals; these correlate with TARGET_NAME and ACTION from Xcode +spec="$TARGET_NAME:$ACTION" +echo "target specification: $spec" +case "$spec" in + external:clean) + if [ "$EXTERNAL_DRIVER" == "xcode" ]; then + ## driving build from Xcode.app do pristine clean + if [ -z "$EXTERNAL_BUILD" ]; then + echo "ERROR: unsafe rm -fr would result because EXTERNAL_BUILD is not defined" + exit 1 + fi + if [ -d "$EXTERNAL_BUILD" ]; then + cmd="/bin/rm -fr $EXTERNAL_BUILD/*" + echo "$cmd" + $cmd + [ $? -ne 0 ] && exit 1 + exit_post_log=1 + else + echo "already clean" + fi + else + ## driving build from xcodebuild do xclean, preserving configuration + goals=xclean + fi + ;; + external:*) + if [ -z "$EXTERNAL_GOALS" ]; then + goals=build + else + goals="$EXTERNAL_GOALS" + fi + ;; + *) + echo "ERROR: unexpected env specification: $spec" + exit 1 + ;; +esac + ## compute if re/configure necessary -if [ $EXTERNAL_METHOD != 'xcode' ]; then - reconfigure="terminal -> Xcode" -elif [ ! -f $EXTERNAL_BUILD/GNUmakefile ]; then +if [ ! -f $EXTERNAL_BUILD/GNUmakefile ]; then reconfigure="no configuration present" elif [ $EXTERNAL_SRC/make/configure.py -nt $EXTERNAL_BUILD/GNUmakefile ]; then reconfigure="configure script was updated" +elif [ $EXTERNAL_DRIVER == "bootstrap" ]; then + reconfigure="driver bootstrap" else reconfigure= fi @@ -39,57 +100,60 @@ fi if [ -n "$reconfigure" ]; then echo "reconfiguring ($reconfigure)" + if [ "$EXTERNAL_DRIVER" == "bootstrap" ]; then + driver="--xcode-driver=terminal" + else + driver="--xcode-driver=$EXTERNAL_DRIVER" + fi + + case "$GCC_VERSION" in + com.apple.compilers.llvmgcc42) + gcc="--gcc=$DEVELOPER_BIN_DIR/llvm-gcc-4.2" + ;; + com.apple.compilers.llvm.clang.1_0) + gcc="--gcc=$DEVELOPER_BIN_DIR/clang" + ;; + *) + gcc= + ;; + esac + + if [ -n "$ARCHS" ]; then + arch="--arch=$ARCHS" + else + arch= + fi + case "$CONFIGURATION" in debug*) debug="--debug=max --optimize=none" ;; - standard*|*) + release*|*) debug= ;; esac - ## invoke configure with (hidden) option which indicates conf performed by xcode - (set -x; $EXTERNAL_SRC/configure --force $EXTERNAL_CONFARGS \ - --build=$EXTERNAL_BUILD --arch=$ARCHS $debug --conf-method=xcode PATH=$PATH ) -fi + if [ -n "$SDKROOT" ]; then + sysroot="--sysroot=$SDKROOT" + else + sysroot= + fi -## compute goals; these correlate with TARGET_NAME and ACTION from Xcode -spec="$TARGET_NAME:$ACTION" -echo "env specification: $spec" -case "$spec" in - contrib:clean) - goals=contrib.xclean - ;; - contrib:*) - goals=contrib.install - ;; - external:clean) - goals=clean - ;; - external:*) - if [ -z "$EXTERNAL_GOALS" ]; then - goals=build - else - goals="$EXTERNAL_GOALS" - fi - ;; - libhb:clean) - goals=libhb.clean - ;; - libhb:*) - goals=libhb.build - ;; - *) - echo "ERROR: invalid env specification: $spec" - exit 1 - ;; -esac + if [ -n "$MACOSX_DEPLOYMENT_TARGET" ]; then + minver="--minver=$MACOSX_DEPLOYMENT_TARGET" + else + minver= + fi -## safeguard against passing blank value which would result in unlimited jobs -if [ -z "$EXTERNAL_JOBS" ]; then - jobs= -else - jobs=--jobs=$EXTERNAL_JOBS + ## invoke configure with (hidden) option which indicates conf performed by xcode + (set -ex; $EXTERNAL_SRC/configure --force \ + $EXTERNAL_CONF_ARGS \ + --build="$EXTERNAL_BUILD" \ + $driver \ + --xcode-symroot="$SYMROOT" \ + --xcode-config="$EXTERNAL_XCCONFIG" \ + $gcc $arch $debug $sysroot $minver) + [ $? -ne 0 ] && exit 1 fi ## log environment as provided by Xcode @@ -99,7 +163,18 @@ if [ ! -d $logdir ]; then fi env | sort > $logdir/xcodemake.env.txt +[ $exit_post_log -ne 0 ] && exit 0 + +## safeguard against passing blank value which would result in unlimited jobs +if [ -z "$EXTERNAL_JOBS" ]; then + jobs= +elif [ "$EXTERNAL_JOBS" == "auto" ]; then + jobs=--jobs=`sysctl -n hw.activecpu` +else + jobs=--jobs=$EXTERNAL_JOBS +fi + ## pull the trigger -## must set BUILD.method != terminal to prevent inifinite recursion +## must set XCODE.driver to prevent inifinite recursion set -x -exec make -C $EXTERNAL_BUILD BUILD.method=xcode $jobs $goals $EXTERNAL_VARS +exec make -C $EXTERNAL_BUILD XCODE.driver=xcodemake $jobs $goals $EXTERNAL_VARS |