فهرست منبع

WIP x64 support for windows.

Mark Sibly 7 سال پیش
والد
کامیت
599d4ae1b3
4فایلهای تغییر یافته به همراه257 افزوده شده و 102 حذف شده
  1. 27 32
      src/mx2cc/builder.monkey2
  2. 137 57
      src/mx2cc/buildproduct.monkey2
  3. 1 1
      src/mx2cc/mx2.monkey2
  4. 92 12
      src/mx2cc/mx2cc.monkey2

+ 27 - 32
src/mx2cc/builder.monkey2

@@ -9,6 +9,8 @@ Class BuildOpts
 	
 	Field productType:String	'"app" or "module"
 	
+	Field toolchain:String		'"msvc" or "gcc"
+	
 	Field target:String
 	
 	Field config:String
@@ -19,6 +21,8 @@ Class BuildOpts
 
 	Field appType:String
 	
+	Field arch:String
+	
 	Field verbose:Int
 	
 	Field fast:Bool
@@ -78,41 +82,25 @@ Class BuilderInstance
 		Self.opts=opts
 		
 		Builder=self
-
-		If Int( GetEnv( "MX2_WHOLE_ARCHIVE" ) ) opts.wholeArchive=True
-		
-		If opts.target="desktop"
-		
-			opts.target=HostOS
-			
-			If Not opts.appType opts.appType="gui"
-			
-		Else If HostOS="windows" And opts.target="raspbian"
-		
-			SetEnv( "PATH",GetEnv( "MX2_RASPBIAN_TOOLS" )+";"+GetEnv( "PATH" ) )
-		
-			If Not opts.appType opts.appType="gui"
-			
-		Else If opts.target="emscripten"
-		
-			If Not opts.appType opts.appType="wasm"
-			
-		Endif
 		
 		ppsyms["__HOST__"]="~q"+HostOS+"~q"
 		ppsyms["__HOSTOS__"]="~q"+HostOS+"~q"
 		ppsyms["__TARGET__"]="~q"+opts.target+"~q"
 		ppsyms["__CONFIG__"]="~q"+opts.config+"~q"
+		ppsyms["__ARCH__"]="~q"+opts.arch+"~q"
 		
 		Select opts.target
 		Case "windows","macos","linux","raspbian"
+			
 			ppsyms["__DESKTOP_TARGET__"]="true"
 			ppsyms["__MOBILE_TARGET__"]="false"
 			ppsyms["__WEB_TARGET__"]="false"
+			
 		Case "android","ios"
 			ppsyms["__DESKTOP_TARGET__"]="false"
 			ppsyms["__MOBILE_TARGET__"]="true"
 			ppsyms["__WEB_TARGET__"]="false"
+			
 		Case "emscripten"
 			ppsyms["__DESKTOP_TARGET__"]="false"
 			ppsyms["__MOBILE_TARGET__"]="false"
@@ -131,7 +119,14 @@ Class BuilderInstance
 		ppsyms["__MAKEDOCS__"]=opts.makedocs ? "true" Else "false"
 
 		profileName=opts.target+"_"+opts.config
-		If opts.target="windows" And Int( GetEnv( "MX2_USE_MSVC" ) ) profileName+="_msvc"
+		
+		If opts.target="windows"
+			
+			If opts.toolchain="msvc" profileName+="_msvc"
+				
+			If opts.arch="x64" profileName+="_x64"
+				
+		Endif
 		
 		If opts.productType="app" APP_DIR=ExtractDir( opts.mainSource )
 		
@@ -650,7 +645,7 @@ Class BuilderInstance
 				
 				name=name.Slice( 3 )
 				
-				If product.toolchain="msvc"
+				If opts.toolchain="msvc"
 					product.LIB_FILES.Push( name+".lib" )
 				Else
 					product.LIB_FILES.Push( "-l"+name )
@@ -663,7 +658,7 @@ Class BuilderInstance
 			
 		Case ".lib"
 			
-			If product.toolchain="msvc"
+			If opts.toolchain="msvc"
 				product.LIB_FILES.Push( name )
 			Else
 				product.LIB_FILES.Push( "-l"+name )
@@ -671,13 +666,13 @@ Class BuilderInstance
 			
 		Case ".dylib"
 			
-			If product.toolchain="gcc"
+			If opts.toolchain="gcc"
 				product.LIB_FILES.Push( "-l"+name )
 			Endif
 			
 		Case ".framework"
 			
-			If product.toolchain="gcc"
+			If opts.toolchain="gcc"
 				product.LIB_FILES.Push( "-framework "+name )
 			Endif
 			
@@ -742,7 +737,7 @@ Class BuilderInstance
 				
 			Case ".a",".lib"
 				
-				If product.toolchain="msvc"
+				If opts.toolchain="msvc"
 					product.LD_OPTS+=" -LIBPATH:"+qdir
 				Else
 					product.LD_OPTS+=" -L"+qdir
@@ -750,13 +745,13 @@ Class BuilderInstance
 				
 			Case ".dylib"
 				
-				If product.toolchain="gcc"
+				If opts.toolchain="gcc"
 					product.LD_OPTS+=" -L"+qdir
 				Endif
 				
 			Case ".framework"
 				
-				If product.toolchain="gcc"
+				If opts.toolchain="gcc"
 					product.LD_OPTS+=" -F"+qdir
 				Endif
 				
@@ -772,7 +767,7 @@ Class BuilderInstance
 		
 		If ext=".framework"
 			
-			If product.toolchain="gcc"
+			If opts.toolchain="gcc"
 				If GetFileType( path )<>FileType.Directory
 					If Not opts.geninfo New BuildEx( "Framework not found "+qpath )
 				Endif
@@ -828,13 +823,13 @@ Class BuilderInstance
 		
 		Case ".a"
 			
-			If product.toolchain="gcc"
+			If opts.toolchain="gcc"
 				product.LIB_FILES.Push( qpath )
 			Endif
 			
 		Case ".so",".dylib"
 			
-			If product.toolchain="gcc"
+			If opts.toolchain="gcc"
 				product.LIB_FILES.Push( qpath )
 				product.DLL_FILES.Push( path )
 			Endif
@@ -847,7 +842,7 @@ Class BuilderInstance
 			
 		Case ".framework"
 			
-			If product.toolchain="gcc"
+			If opts.toolchain="gcc"
 				'OK, this is ugly...
 				ImportLocalFile( ExtractDir( path )+"*.framework" )
 				ImportSystemFile( StripDir( path ) )

+ 137 - 57
src/mx2cc/buildproduct.monkey2

@@ -8,8 +8,6 @@ Class BuildProduct
 	Field imports:=New Stack<Module>
 	Field outputFile:String
 	
-	Field toolchain:String
-
 	Field CC_OPTS:String
 	Field CPP_OPTS:String
 	Field AS_OPTS:String
@@ -29,8 +27,6 @@ Class BuildProduct
 		Self.module=module
 		Self.opts=opts
 		
-		toolchain=opts.target="windows" And Int( GetEnv( "MX2_USE_MSVC" ) ) ? "msvc" Else "gcc"
-		
 		Local copts:=""
 		For Local moddir:=Eachin Module.Dirs
 			copts+=" -I~q"+moddir+"~q"
@@ -279,32 +275,59 @@ Class GccBuildProduct Extends BuildProduct
 	Field LD_CMD:=""
 	
 	Method New( module:Module,opts:BuildOpts )
+		
 		Super.New( module,opts )
 		
 		Local target:="_"+opts.target.ToUpper()
 		Local config:="_"+opts.config.ToUpper()
 		
-		If toolchain="msvc"
+		Select opts.toolchain
+		Case "msvc"
+			
 			CC_CMD= "cl -c"
 			CXX_CMD="cl -c"
-			AS_CMD="ml -c"
+			AS_CMD=opts.arch="x64" ? "ml64 -c" Else "ml -c"
 			AR_CMD="lib"
 			LD_CMD="link"
 			target="_MSVC"
-		Else If opts.target="emscripten"
-			CC_CMD= "emcc -c"
-			CXX_CMD="em++ -c"
-			AR_CMD="emar"
-			LD_CMD="em++"
-		Else
-			Local prefix:=(opts.target="raspbian" ? "arm-linux-gnueabihf-" Else "")
-			Local suffix:=GetEnv( "MX2_GCC_SUFFIX" )
-			CC_CMD= prefix+"gcc"+suffix+" -c"
-			CXX_CMD=prefix+"g++"+suffix+" -c"
-			AS_CMD= prefix+"as"
-			AR_CMD= prefix+"ar"
-			LD_CMD= prefix+"g++"+suffix
-		Endif
+			
+		Case "gcc"
+			
+			Select opts.target
+			Case "emscripten"
+				
+				CC_CMD= "emcc -c"
+				CXX_CMD="em++ -c"
+				AR_CMD="emar"
+				LD_CMD="em++"
+				
+			Case "raspbian"
+
+				CC_CMD= "arm-linux-gnueabihf-gcc -c"
+				CXX_CMD="arm-linux-gnueabihf-g++ -c"
+				AS_CMD= "arm-linux-gnueabihf-as"
+				AR_CMD= "arm-linux-gnueabihf-ar"
+				LD_CMD= "arm-linux-gnueabihf-g++"
+				
+			Default
+				
+				Local suffix:=GetEnv( "MX2_GCC_SUFFIX" )
+				
+				Local mopt:=opts.target="windows" ? (opts.arch="x64" ? "-m64" Else "-m32") Else ""
+				
+				CC_CMD= "gcc"+suffix+" -c "+mopt
+				CXX_CMD="g++"+suffix+" -c "+mopt
+				AS_CMD= "as"
+				AR_CMD= "ar"
+				LD_CMD= "g++"+suffix+" "+mopt
+				
+			End
+			
+		Default
+			
+			RuntimeError( "Toolchain error: '"+opts.toolchain+"'" )
+			
+		End
 		
 		CC_CMD+=" "+GetEnv( "MX2_CC_OPTS"+target )+" "+GetEnv( "MX2_CC_OPTS"+target+config )
 		CXX_CMD+=" "+GetEnv( "MX2_CPP_OPTS"+target )+" "+GetEnv( "MX2_CPP_OPTS"+target+config )
@@ -320,20 +343,33 @@ Class GccBuildProduct Extends BuildProduct
 
 		Select ext
 		Case ".c",".m"
+			
 			cmd=CC_CMD+CC_OPTS
+			
 		Case ".cc",".cxx",".cpp",".mm"
+			
 			cmd=CXX_CMD+CPP_OPTS
+			
 		Case ".asm",".s"
+			
 			cmd=AS_CMD+AS_OPTS
 			
-			If toolchain="msvc"
+			If opts.toolchain="msvc"
+				
+				If opts.arch="x64" 
+					src=src.Replace( "_i386_","_x86_64_" )
+				Endif
+					
 				src=src.Replace( "_pe_gas.","_pe_masm." )
+				
 			Else If opts.target="ios"
+				
 				If src.Contains( "_arm64_" )
 					cmd+=" -arch arm64"
 				Else
 					cmd+=" -arch armv7"
 				Endif
+				
 			Endif
 			
 			isasm=True
@@ -346,7 +382,7 @@ Class GccBuildProduct Extends BuildProduct
 '		If rfile And opts.reflection obj+="_r"
 		If rfile obj+="_r"
 			
-		obj+=toolchain="msvc" ? ".obj" Else ".o"
+		obj+=opts.toolchain="msvc" ? ".obj" Else ".o"
 	
 		'Check dependancies
 		'			
@@ -360,12 +396,12 @@ Class GccBuildProduct Extends BuildProduct
 		
 			If isasm Return obj
 			
-			Local uptodate:=True
+			Local uptodate:=GetFileType( deps )=FileType.File
 			
-			If GetFileType( deps )=FILETYPE_NONE
-					
+			If Not uptodate And opts.toolchain="gcc"
+
 				If opts.verbose>0 Print "Scanning "+src
-				
+					
 				Local tmp:=cmd
 				
 				'A bit dodgy - rip out -arch's from ios
@@ -380,35 +416,34 @@ Class GccBuildProduct Extends BuildProduct
 					Forever
 					tmp+=" -arch armv7"
 					
-				Else If toolchain="msvc"
-					
-					If ext=".c" 
-						tmp="gcc -c "+GetEnv( "MX2_CC_OPTS_WINDOWS" )+" "+GetEnv( "MX2_CC_OPTS_WINDOWS_"+opts.config.ToUpper() )+CC_OPTS
-					Else
-						tmp="g++ -c "+GetEnv( "MX2_CPP_OPTS_WINDOWS" )+" "+GetEnv( "MX2_CPP_OPTS_WINDOWS_"+opts.config.ToUpper() )+CPP_OPTS
-					Endif
-					
 				Endif
 				
 				tmp+=" -MM ~q"+src+"~q >~q"+deps+"~q"
 				
 				Exec( tmp )
+				
+				uptodate=True
+				
 			Endif
-					
-			Local srcs:=LoadString( deps ).Split( " \" )
-					
-			For Local i:=1 Until srcs.Length
-					
-				Local src:=srcs[i].Trim().Replace( "\ "," " )
-					
-				If GetFileTime( src )>objTime
-					uptodate=False
-					Exit
-				Endif
+			
+			If uptodate
+			
+				Local srcs:=LoadString( deps ).Split( " \" )
 						
-			Next
+				For Local i:=1 Until srcs.Length
+						
+					Local src:=srcs[i].Trim().Replace( "\","" )
+						
+					If GetFileTime( src )>objTime
+						uptodate=False
+						Exit
+					Endif
+							
+				Next
 				
-			If uptodate Return obj
+				If uptodate Return obj
+				
+			Endif
 				
 		Else
 			
@@ -416,14 +451,59 @@ Class GccBuildProduct Extends BuildProduct
 
 		Endif
 			
-'		If opts.verbose>0 Print "Compiling "+src
+		If opts.verbose>0 Print StripDir( src )
+				
+		If opts.toolchain="msvc"
+
+			If isasm
+				cmd+=" -Fo~q"+obj+"~q ~q"+src+"~q"
+				
+				Exec( cmd )
+				
+				Return obj
+			Endif
 			
-		cmd+=(toolchain="msvc" ? " -Fo~q" Else " -o ~q") +obj+"~q ~q"+src+"~q"
-		
-		If opts.verbose>0 And toolchain<>"msvc" Print StripDir( src )
+			cmd+=" -showIncludes -Fo~q"+obj+"~q ~q"+src+"~q"
 		
+			Local incs:=AllocTmpFile( "incs" )
+			Local errs:=AllocTmpFile( "stderr" )
+			
+			If system( cmd+" 1>"+incs+" 2>"+errs )
+				Local terrs:=LoadString( errs )
+				Throw New BuildEx( "System command '"+cmd+"' failed.~n~n"+cmd+"~n~n"+terrs )
+			Endif
+			
+			Local buf:=New StringStack
+			buf.Push( StripDir( obj )+": "+src+" \" )
+
+			Local tincs:=LoadString( incs )
+			
+			For Local line:=Eachin tincs.Split( "~n" )
+				
+				line=line.Trim()
+				
+				If Not line.StartsWith( "Note: including file:" ) Continue
+				
+				line=line.Slice( 21 ).Trim()
+				
+				If line.Contains( "\Program Files (x86)\" ) Continue
+				
+				buf.Add( line+" \" )
+			Next
+			
+			Local str:=buf.Join( "~n" )
+			
+'			Print "deps="+str
+			
+			SaveString( str,deps )
+			
+			Return obj
+		Endif
+
+		cmd+=" -o~q"+obj+"~q ~q"+src+"~q"
+				
 		Exec( cmd )
-		
+			
 		Return obj
 	End
 	
@@ -451,7 +531,7 @@ Class GccBuildProduct Extends BuildProduct
 	Method BuildModule( objs:StringStack )
 
 		Local output:=module.afile
-		If toolchain="msvc" output=StripExt(output)+".lib"
+		If opts.toolchain="msvc" output=StripExt(output)+".lib"
 
 		Local maxObjTime:Long
 		For Local obj:=Eachin objs
@@ -472,7 +552,7 @@ Class GccBuildProduct Extends BuildProduct
 		
 			cmd="libtool -o ~q"+output+"~q"+args
 			
-		Else If toolchain="msvc"
+		Else If opts.toolchain="msvc"
 			
 			Local tmp:=AllocTmpFile( "libFiles" )
 			SaveString( args,tmp )
@@ -515,7 +595,7 @@ Class GccBuildProduct Extends BuildProduct
 		
 			If ExtractExt( outputFile ).ToLower()<>".exe" outputFile+=".exe"
 				
-			If toolchain="msvc"
+			If opts.toolchain="msvc"
 '				cmd+=" -entry:main"
 				If opts.appType="gui" cmd+=" -subsystem:windows" Else cmd+=" -subsystem:console"
 			Else
@@ -577,7 +657,7 @@ Class GccBuildProduct Extends BuildProduct
 		
 		If opts.verbose>=0 Print "Linking "+outputFile+"..."
 			
-		If toolchain="msvc"
+		If opts.toolchain="msvc"
 			cmd+=" -entry:mainCRTStartup -out:~q"+outputFile+"~q"
 		Else
 			cmd+=" -o ~q"+outputFile+"~q"
@@ -591,7 +671,7 @@ Class GccBuildProduct Extends BuildProduct
 		
 		For Local imp:=Eachin imports
 			Local afile:=imp.afile
-			If toolchain="msvc" afile=StripExt(afile)+".lib"
+			If opts.toolchain="msvc" afile=StripExt(afile)+".lib"
 			lnkFiles+=" ~q"+afile+"~q"
 		Next
 

+ 1 - 1
src/mx2cc/mx2.monkey2

@@ -50,4 +50,4 @@ Using libc
 ' 3) edit .sh and .bat files to use new version (common.sh, common.bat)
 ' 4) ./rebuildall
 '
-Const MX2CC_VERSION:="1.1.08"
+Const MX2CC_VERSION:="1.1.09"

+ 92 - 12
src/mx2cc/mx2cc.monkey2

@@ -24,14 +24,15 @@ Global opts_time:Bool
 
 Global StartDir:String
 
-Const TestArgs:="mx2cc makemods"
+'Const TestArgs:="mx2cc makemods -clean -config=release stb-image-write"	'release monkey libc miniz stb-image stb-image-write stb-vorbis std"
+Const TestArgs:="mx2cc makemods"' -clean -config=debug monkey libc miniz stb-image stb-image-write stb-vorbis std"
  
+'Const TestArgs:="mx2cc makeapp -clean -config=release src/mx2cc/test.monkey2"
+
 'Const TestArgs:="mx2cc makedocs mojo"
 'Const TestArgs:="pyro-framework pyro-gui pyro-scenegraph pyro-tiled"
 'Const TestArgs:="mx2cc makedocs"
 
-'Const TestArgs:="mx2cc makeapp src/mx2cc/test.monkey2"
-
 'To build with old mx2cc...
 '
 'Creates: src/mx2cc/mx2cc.buildv.VERSION/windows_release/mx2cc.exe
@@ -45,17 +46,21 @@ Const TestArgs:="mx2cc makemods"
 'Const TestArgs:="mx2cc makeapp -build -clean -config=release -target=raspbian src/mx2cc/mx2cc.monkey2"
 
 Function Main()
+	
+'	Print "YARGH!"
+	
+'	Return
 
 	'Set aside 64M for GC!
 	GCSetTrigger( 64*1024*1024 )
-
+	
 	Print ""
 	Print "Mx2cc version "+MX2CC_VERSION+MX2CC_VERSION_EXT
 	
 	StartDir=CurrentDir()
 	
 	ChangeDir( AppDir() )
-		
+	
 	Local env:="bin/env_"+HostOS+".txt"
 	
 	While Not IsRootDir( CurrentDir() ) And GetFileType( env )<>FILETYPE_FILE
@@ -70,6 +75,8 @@ Function Main()
 	Local args:String[]
 
 #If __CONFIG__="debug"
+	Local tenv:="bin/env_"+HostOS+"_dev.txt"
+	If GetFileType( tenv )=FileType.File env=tenv
 	args=TestArgs.Split( " " )
 #else
 	args=AppArgs()
@@ -228,7 +235,7 @@ Function MakeApp:Bool( args:String[] )
 	opts.mainSource=srcPath
 	
 	Print ""
-	Print "***** Building app '"+opts.mainSource+"' *****"
+	Print "***** Making app '"+opts.mainSource+"' ("+opts.target+" "+opts.config+" "+opts.arch+" "+opts.toolchain+") *****"
 	Print ""
 
 	New BuilderInstance( opts )
@@ -297,7 +304,7 @@ Function MakeMods:Bool( args:String[] )
 		If Not path Fail( "Module '"+modid+"' not found" )
 	
 		Print ""
-		Print "***** Making module '"+modid+"' *****"
+		Print "***** Making module '"+modid+"' ("+opts.target+" "+opts.config+" "+opts.arch+" "+opts.toolchain+") *****"
 		Print ""
 		
 		opts.mainSource=RealPath( path )
@@ -407,8 +414,12 @@ End
 
 Function ParseOpts:String[]( opts:BuildOpts,args:String[] )
 
+	Global done:=False
+	Assert( Not done )
+	done=True
+	
 	opts.verbose=Int( GetEnv( "MX2_VERBOSE" ) )
-
+	
 	For Local i:=0 Until args.Length
 	
 		Local arg:=args[i]
@@ -437,7 +448,9 @@ Function ParseOpts:String[]( opts:BuildOpts,args:String[] )
 			Case "-time"
 				opts_time=True
 			Default
-				Return args.Slice( i )
+				If arg.StartsWith( "-" ) Fail( "Unrecognized option '"+arg+"'" )
+				args=args.Slice( i )
+				Exit
 			End
 			Continue
 		Endif
@@ -481,21 +494,88 @@ Function ParseOpts:String[]( opts:BuildOpts,args:String[] )
 	
 	Next
 	
+	If Not opts.target Or opts.target="desktop" opts.target=HostOS
+		
+	opts.wholeArchive=Int( GetEnv( "MX2_WHOLE_ARCHIVE" ) )
+		
+	opts.toolchain="gcc"
+		
+	Select opts.target
+	Case "windows"
+		
+		If Not opts.appType opts.appType="gui"
+		
+		opts.arch=GetEnv( "MX2_ARCH_"+opts.target.ToUpper(),"x86" )
+		
+		If opts.arch<>"x64" And opts.arch<>"x86"
+			Fail( "Unrecognized architecture '"+opts.arch+"'" )
+		Endif
+		
+		If Int( GetEnv( "MX2_USE_MSVC" ) )
+			
+			opts.toolchain="msvc"
+			
+			Local arch:=opts.arch.ToUpper()
+			
+			SetEnv( "PATH",GetEnv( "MX2_MSVC_PATH_"+arch )+";"+GetEnv( "PATH" ) )
+			SetEnv( "INCLUDE",GetEnv( "MX2_MSVC_INCLUDE_"+arch ) )
+			SetEnv( "LIB",GetEnv( "MX2_MSVC_LIB_"+arch ) )
+			
+		Endif
+	
+	Case "macos","linux"
+		
+		If Not opts.appType opts.appType="gui"
+		
+		opts.arch="x64"
+		
+	Case "raspbian"
+
+		If Not opts.appType opts.appType="gui"
+			
+		opts.arch="arm32"
+			
+		SetEnv( "PATH",GetEnv( "MX2_RASPBIAN_TOOLS" )+";"+GetEnv( "PATH" ) )
+		
+	Case "emscripten"
+		
+		If Not opts.appType opts.appType="wasm"
+			
+		opts.arch="llvm"
+		
+	Case "android"
+		
+		opts.arch=GetEnv( "MX2_ANDROID_APP_ABI","armeabi-v7a" )
+		
+	Case "ios"
+		
+		opts.arch="arm64"
+		
+	Default
+		
+		Fail( "Unrecognized target '"+opts.target+"'" )
+	
+	End
+	
 	Select opts.appType
 	Case "console","gui"
+		
 		Select opts.target
-		Case "desktop","windows","macos","linux","raspbian"
+		Case "windows","macos","linux","raspbian"
 		Default
-			Fail( "apptype '"+opts.appType+"' may ponly be used with desktop targets" )
+			Fail( "apptype '"+opts.appType+"' is only valid for desktop targets" )
 		End
+		
 	case "wasm","asmjs","wasm+asmjs"
+		
 		If opts.target<>"emscripten" Fail( "apptype '"+opts.appType+"' is only valid for emscripten target" )
+			
 	case ""
 	Default
 		Fail( "Unrecognized apptype '"+opts.appType+"'" )
 	End
 		
-	Return Null
+	Return args
 End
 
 Function EnumModules( out:StringStack,cur:String,src:String,deps:StringMap<StringStack> )