2
0
Эх сурвалжийг харах

Added macOS universal apps.

woollybah 5 жил өмнө
parent
commit
c2d4614a98
5 өөрчлөгдсөн 108 нэмэгдсэн , 63 устгасан
  1. 1 0
      CHANGELOG
  2. 43 51
      bmk.bmx
  3. 5 1
      bmk_config.bmx
  4. 53 6
      bmk_ng.bmx
  5. 6 5
      bmk_util.bmx

+ 1 - 0
CHANGELOG

@@ -2,6 +2,7 @@
 ### Added
  - macOS "arm64" build option.
  - Custom macOS toolchain configuration.
+ - macOS universal apps (requires xcode 12+).
 ### Fixed
  - obj-C sources now built in correct order.
 

+ 43 - 51
bmk.bmx

@@ -29,12 +29,20 @@ CreateDir BlitzMaxPath()+"/tmp"
 
 Select cmd.ToLower()
 Case "makeapp"
+	If opt_universal And processor.Platform() = "macos" And Float(processor.XCodeVersion()) < 12 Then
+		Throw "XCode 12+ required for universal macOS build"
+	End If
+
 	SetConfigMung
 	MakeApplication args,False
 Case "makelib"
 	SetConfigMung
 	MakeApplication args,True
 Case "makemods"
+	If opt_universal And processor.Platform() = "macos" And Float(processor.XCodeVersion()) < 12 Then
+		Throw "XCode 12+ required for universal macOS build"
+	End If
+
 	opt_quickscan = False
 	If opt_debug Or opt_release
 		SetConfigMung
@@ -105,7 +113,7 @@ Case "unzapmod"
 Case "ranlibdir"
 	RanlibDir args
 Case "-v"
-	VersionInfo(processor.GCCVersion(), GetCoreCount())
+	VersionInfo(processor.GCCVersion(), GetCoreCount(), processor.XCodeVersion())
 Default
 	CmdError "Unknown operation '" + cmd.ToLower() + "'"
 End Select
@@ -270,6 +278,11 @@ Function MakeApplication( args$[],makelib:Int,compileOnly:Int = False )
 		opt_outfile = RealPath(opt_outfile)
 	End If
 
+	If opt_universal And processor.Platform() = "macos" Then
+		opt_outfile :+ "." + processor.CPU()
+	End If
+
+
 	' set some useful global variables
 	globals.SetVar("BUILDPATH", ExtractDir(opt_infile))
 	globals.SetVar("EXEPATH", ExtractDir(opt_outfile))
@@ -279,15 +292,25 @@ Function MakeApplication( args$[],makelib:Int,compileOnly:Int = False )
 	' some more useful globals
 	If processor.Platform() = "macos" And opt_apptype="gui" And Not compileOnly Then
 		Local appId$=StripDir( opt_outfile )
+		
+		If opt_universal Then
+			appId = StripExt(appId)
+		End If
 
 		globals.SetVar("APPID", appId)
 		' modify for bundle
 		globals.SetVar("EXEPATH", ExtractDir(opt_outfile+".app/Contents/MacOS/"+appId))
 
 
-		' make bundle dirs
-		Local exeDir$=opt_outfile+".app",d$
+		Local baseDir:String = opt_outfile
+		If opt_universal Then
+			baseDir = StripExt(baseDir)
+		End If
 
+		' make bundle dirs
+		Local exeDir:String = baseDir + ".app"
+		Local d:String
+		
 		d=exeDir+"/Contents/MacOS"
 		Select FileType( d )
 		Case FILETYPE_NONE
@@ -346,32 +369,13 @@ Function MakeApplication( args$[],makelib:Int,compileOnly:Int = False )
 			'Local appId$=StripDir( opt_outfile )
 			Local appId$ = globals.Get("APPID")
 
-			Local exeDir$=opt_outfile+".app",d$,t:TStream
-	Rem
-			d=exeDir+"/Contents/MacOS"
-			Select FileType( d )
-			Case FILETYPE_NONE
-				CreateDir d,True
-				If FileType( d )<>FILETYPE_DIR
-					Throw "Unable to create application directory"
-				EndIf
-			Case FILETYPE_FILE
-				Throw "Unable to create application directory"
-			Case FILETYPE_DIR
-			End Select
+			Local baseDir:String = opt_outfile
+			If opt_universal Then
+				baseDir = StripExt(baseDir)
+			End If
+			Local exeDir:String = baseDir+".app"
+			Local t:TStream
 
-			d=exeDir+"/Contents/Resources"
-			Select FileType( d )
-			Case FILETYPE_NONE
-				CreateDir d
-				If FileType( d )<>FILETYPE_DIR
-					Throw "Unable to create resources directory"
-				EndIf
-			Case FILETYPE_FILE
-				Throw "Unable to create resources directory"
-			Case FILETYPE_DIR
-			End Select
-	End Rem
 			t=WriteStream( exeDir+"/Contents/Info.plist" )
 			If Not t Throw "Unable to create Info.plist"
 			t.WriteLine "<?xml version=~q1.0~q encoding=~qUTF-8~q?>"
@@ -404,9 +408,9 @@ Function MakeApplication( args$[],makelib:Int,compileOnly:Int = False )
 
 			opt_outfile=exeDir+"/Contents/MacOS/"+appId
 
-			' Mac GUI exepath is in the bundle...
-			'globals.SetVar("EXEPATH", ExtractDir(opt_outfile))
-			'globals.SetVar("APPID", appId)
+			If opt_universal Then
+				opt_outfile :+ "." + processor.CPU()
+			End If
 
 		EndIf
 	End If
@@ -434,10 +438,14 @@ Function MakeApplication( args$[],makelib:Int,compileOnly:Int = False )
 	buildManager.MakeApp(Main, makelib, compileOnly)
 	buildManager.DoBuild(makelib, Not compileOnly)
 
-	If opt_universal And processor.Platform() = "ios" Then
+	If opt_universal And processor.Platform() = "macos" Then
+
+		Local original:String = opt_outfile
 
 		processor.ToggleCPU()
-		LoadOptions(True) ' reload options for PPC
+		LoadOptions(True) ' reload options for other arch
+
+		opt_outfile  = StripExt(opt_outfile) + "." + processor.CPU()
 
 		BeginMake
 
@@ -447,26 +455,10 @@ Function MakeApplication( args$[],makelib:Int,compileOnly:Int = False )
 
 		processor.ToggleCPU()
 		LoadOptions(True)
+		
+		MergeApp original, opt_outfile, StripExt(opt_outfile)
 	End If
 
-Rem
-	If opt_universal
-
-		Local previousOutfile:String = opt_outfile
-		processor.ToggleCPU()
-		LoadOptions(True) ' reload options for PPC
-		opt_outfile :+ "." + processor.CPU()
-		BeginMake
-		MakeApp Main,makelib
-		processor.ToggleCPU()
-		LoadOptions(True)
-
-		MergeApp opt_outfile, previousOutfile
-
-		opt_outfile = previousOutfile
-	End If
-End Rem
-
 	If processor.Platform() = "nx" And Not compileOnly Then
 		BuildNxDependencies()
 	End If

+ 5 - 1
bmk_config.bmx

@@ -462,7 +462,7 @@ Function Usage:String(fullUsage:Int = False)
 	Return s
 End Function
 
-Function VersionInfo(gcc:String, cores:Int)
+Function VersionInfo(gcc:String, cores:Int, xcode:String)
 	Local s:String = "bmk "
 	s:+ BMK_VERSION + " "
 ?threaded
@@ -506,6 +506,10 @@ Function VersionInfo(gcc:String, cores:Int)
 	s:+ "js"
 ?
 	s:+ " / " + gcc
+	
+	If xcode Then
+		s:+ " / xcode " + xcode
+	End If
 
 	s:+ " (cpu x" + cores + ")"
 

+ 53 - 6
bmk_ng.bmx

@@ -358,11 +358,16 @@ Type TBMK
 		If opt_universal Then
 			Select Platform()
 				Case "macos"
-					If opt_arch = "ppc" Then
-						opt_arch = "x86"
-					Else
-						opt_arch = "ppc"
-					End If
+					Select CPU()
+						Case "ppc"
+							opt_arch = "x86"
+						Case "x86"
+							opt_arch = "ppc"
+						Case "x64"
+							opt_arch = "arm64"
+						Case "arm64"
+							opt_arch = "x64"
+					End Select
 				Case "ios"
 					Select CPU()
 						Case "x86"
@@ -553,7 +558,49 @@ Type TBMK
 		Return compiler + " " + version
 '?
 	End Method
-	
+
+	Method XCodeVersion:String()
+?macos
+		Global xcode:String
+		Global version:String
+		
+		If xcode Then
+			Return version
+		End If
+
+		Local process:TProcess
+		process = CreateProcess(Option(BuildName("xcodebuild"), "xcodebuild") + " -version")
+
+		Local s:String
+		
+		If Not process Then
+			Throw "Cannot find xcodebuild. Please check your paths and environment."
+		End If
+		
+		While True
+			Delay 10
+			
+			Local line:String = process.pipe.ReadLine()
+
+			If Not process.Status() And Not line Then
+				Exit
+			End If
+			
+			If line.startswith("Xcode") Then
+				xcode = line
+				Local parts:String[] = line.split(" ")
+				
+				version =parts[1].Trim()
+			End If
+			
+		Wend
+		
+		Return version
+?Not macos
+		Return Null
+?
+	End Method
+
 	Global _target:String
 	
 	Method HasTarget:Int(find:String)

+ 6 - 5
bmk_util.bmx

@@ -604,15 +604,16 @@ Function LinkApp( path$,lnk_files:TList,makelib:Int,opts$ )
 	End If
 End Function
 
-Function MergeApp(fromFile:String, toFile:String)
+Function MergeApp(file1:String, file2:String, outputFile:String)
 
-	If Not opt_quiet Print "Merging:"+StripDir(fromFile) + " + " + StripDir(toFile)
+	If Not opt_quiet Print "[100%] Merging:"+StripDir(file1) + " + " + StripDir(file2) + " > " + StripDir(outputFile)
 
-	Local cmd:String = "lipo -create ~q" + fromFile + "~q ~q" + toFile + "~q -output ~q" + toFile + "~q"
+	Local cmd:String = "lipo -create ~q" + file1 + "~q ~q" + file2 + "~q -output ~q" + outputFile + "~q"
 	
-	If processor.Sys( cmd ) Throw "Merge Error: Failed to merge " + toFile
+	If processor.Sys( cmd ) Throw "Merge Error: Failed to merge " + file1 + " and " + file2 + " into " + outputFile
 	
-	DeleteFile fromFile
+	DeleteFile file1
+	DeleteFile file2
 
 End Function