bmk_util.bmx 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. Strict
  2. Import "bmk_config.bmx"
  3. Import "bmk_ng.bmx"
  4. 'OS X Nasm doesn't work? Used to produce incorrect reloc offsets - haven't checked for a while
  5. Const USE_NASM=False
  6. Const CC_WARNINGS=False'True
  7. Type TModOpt ' BaH
  8. Field cc_opts:String = ""
  9. Field ld_opts:TList = New TList
  10. Method addOption(qval:String)
  11. If qval.startswith("CC_OPTS") Then
  12. cc_opts:+ " " + qval[qval.find(":") + 1..].Trim()
  13. ElseIf qval.startswith("LD_OPTS") Then
  14. Local opt:String = qval[qval.find(":") + 1..].Trim()
  15. If opt.startsWith("-L") Then
  16. opt = "-L" + CQuote(opt[2..])
  17. End If
  18. ld_opts.addLast opt
  19. End If
  20. End Method
  21. Method hasCCopt:Int(value:String)
  22. Return cc_opts.find(value) >= 0
  23. End Method
  24. Method hasLDopt:Int(value:String)
  25. For Local opt:String = EachIn ld_opts
  26. If opt.find(value) >= 0 Then
  27. Return True
  28. End If
  29. Next
  30. Return False
  31. End Method
  32. Function setPath:String(value:String, path:String)
  33. Return value.Replace("%PWD%", path)
  34. End Function
  35. End Type
  36. Global mod_opts:TModOpt ' BaH
  37. Function Match( ext$,pat$ )
  38. Return (";"+pat+";").Find( ";"+ext+";" )<>-1
  39. End Function
  40. Function HTTPEsc$( t$ )
  41. t=t.Replace( " ","%20" )
  42. Return t
  43. End Function
  44. Function Sys( cmd$ )
  45. If opt_verbose
  46. Print cmd
  47. Else If opt_dumpbuild
  48. Local p$=cmd
  49. p=p.Replace( BlitzMaxPath()+"/","./" )
  50. WriteStdout p+"~n"
  51. Local t$="mkdir "
  52. If cmd.StartsWith( t ) And FileType( cmd[t.length..] ) Return
  53. EndIf
  54. Return system_( cmd )
  55. End Function
  56. Function Ranlib( dir$ )
  57. For Local f$=EachIn LoadDir( dir )
  58. Local p$=dir+"/"+f
  59. Select FileType( p )
  60. Case FILETYPE_DIR
  61. Ranlib p
  62. Case FILETYPE_FILE
  63. If ExtractExt(f).ToLower()="a" Sys "ranlib "+p
  64. End Select
  65. Next
  66. End Function
  67. Function Assemble( src$,obj$ )
  68. RunCommand("assemble", [src, obj])
  69. End Function
  70. Function CompileC( src$,obj$,opts$ )
  71. RunCommand("CompileC", [src, obj, opts])
  72. End Function
  73. Function CompileBMX( src$,obj$,opts$ )
  74. DeleteFile obj
  75. Local azm$=StripExt(obj)+".s"
  76. ?threaded
  77. processManager.WaitForThreads()
  78. ?
  79. RunCommand("CompileBMX", [src, azm, opts])
  80. ' it would be nice to be able to call this from the script... but we need more refactoring first :-p
  81. Assemble azm,obj
  82. End Function
  83. Function CreateArc( path$ , oobjs:TList )
  84. DeleteFile path
  85. Local cmd$,t$
  86. If processor.Platform() = "win32"
  87. For t$=EachIn oobjs
  88. If Len(cmd)+Len(t)>1000
  89. If Sys( cmd )
  90. DeleteFile path
  91. Throw "Build Error: Failed to create archive "+path
  92. EndIf
  93. cmd=""
  94. EndIf
  95. If Not cmd cmd= processor.Option("path_to_ar", "ar") + " -r "+CQuote(path)
  96. cmd:+" "+CQuote(t)
  97. Next
  98. End If
  99. If processor.Platform() = "macos"
  100. cmd="libtool -o "+CQuote(path)
  101. For Local t$=EachIn oobjs
  102. cmd:+" "+CQuote(t)
  103. Next
  104. End If
  105. If processor.Platform() = "linux"
  106. For Local t$=EachIn oobjs
  107. If Len(cmd)+Len(t)>1000
  108. If Sys( cmd )
  109. DeleteFile path
  110. Throw "Build Error: Failed to create archive "+path
  111. EndIf
  112. cmd=""
  113. EndIf
  114. If Not cmd cmd="ar -r "+CQuote(path)
  115. cmd:+" "+CQuote(t)
  116. Next
  117. End If
  118. If cmd And Sys( cmd )
  119. DeleteFile path
  120. Throw "Build Error: Failed to create archive "+path
  121. EndIf
  122. End Function
  123. Function LinkApp( path$,lnk_files:TList,makelib )
  124. DeleteFile path
  125. Local cmd$
  126. Local files$
  127. Local tmpfile$=BlitzMaxPath()+"/tmp/ld.tmp"
  128. If processor.Platform() = "macos"
  129. cmd="g++"
  130. If processor.CPU()="ppc"
  131. cmd:+" -arch ppc"
  132. Else
  133. cmd:+" -arch i386 -read_only_relocs suppress"
  134. EndIf
  135. If macos_version>=$1050
  136. cmd:+" -mmacosx-version-min=10.5"
  137. EndIf
  138. cmd:+" -o "+CQuote( path )
  139. ' cmd:+" -bind_at_load"
  140. cmd:+" "+CQuote( "-L"+CQuote( BlitzMaxPath()+"/lib" ) )
  141. If Not opt_dumpbuild cmd:+" -filelist "+CQuote( tmpfile )
  142. For Local t$=EachIn lnk_files
  143. If opt_dumpbuild Or (t[..1]="-")
  144. cmd:+" "+t
  145. Else
  146. files:+t+Chr(10)
  147. EndIf
  148. Next
  149. cmd:+" -lSystem -framework CoreServices -framework CoreFoundation"
  150. If processor.CPU() = "ppc"
  151. cmd:+ " -lc -lgcc_eh"
  152. End If
  153. End If
  154. If processor.Platform() = "win32"
  155. Local version:Int = processor.GCCVersion()
  156. Local usingLD:Int = False
  157. ' always use g++ instead of LD...
  158. ' uncomment if we want to change to only use LD for GCC's < 4.x
  159. 'If version < 40000 Then
  160. ' usingLD = True
  161. 'End If
  162. ' or we can override in the config...
  163. If globals.Get("link_with_ld") Then
  164. usingLD = True
  165. End If
  166. If usingLD
  167. cmd=CQuote(processor.Option("path_to_ld", BlitzMaxPath()+"/bin/ld.exe"))+" -s -stack 4194304"
  168. If opt_apptype="gui" cmd:+" -subsystem windows"
  169. Else
  170. cmd=CQuote(processor.Option("path_to_gpp", "g++"))+" -s --stack=4194304"
  171. If opt_apptype="gui"
  172. cmd:+" --subsystem,windows -mwindows"
  173. Else
  174. If Not makelib
  175. cmd:+" -mconsole"
  176. End If
  177. End If
  178. If opt_threaded Then
  179. cmd:+" -mthread"
  180. End If
  181. End If
  182. If makelib cmd:+" -shared"
  183. cmd:+" -o "+CQuote( path )
  184. If usingLD Then
  185. cmd:+" "+CQuote( "-L"+CQuote( BlitzMaxPath()+"/lib") ) ' the BlitzMax lib folder
  186. If globals.Get("path_to_mingw_lib") Then
  187. cmd:+" "+CQuote( "-L"+CQuote( processor.Option("path_to_mingw_lib", BlitzMaxPath()+"/lib") ) )
  188. End If
  189. If globals.Get("path_to_mingw_lib2") Then
  190. cmd:+" "+CQuote( "-L"+CQuote( processor.Option("path_to_mingw_lib2", BlitzMaxPath()+"/lib") ) )
  191. End If
  192. If globals.Get("path_to_mingw_lib3") Then
  193. cmd:+" "+CQuote( "-L"+CQuote( processor.Option("path_to_mingw_lib3", BlitzMaxPath()+"/lib") ) )
  194. End If
  195. End If
  196. If makelib
  197. Local imp$=StripExt(path)+".a"
  198. Local def$=StripExt(path)+".def"
  199. If FileType( def )<>FILETYPE_FILE Throw "Cannot locate .def file"
  200. cmd:+" "+def
  201. cmd:+" --out-implib "+imp
  202. If usingLD Then
  203. files:+"~n"+CQuote( processor.Option("path_to_mingw_lib", BlitzMaxPath()+"/lib") + "/dllcrt2.o" )
  204. End If
  205. Else
  206. If usingLD
  207. files:+"~n"+CQuote( processor.Option("path_to_mingw_lib2", BlitzMaxPath()+"/lib") + "/crtbegin.o" )
  208. files:+"~n"+CQuote( processor.Option("path_to_mingw_lib", BlitzMaxPath()+"/lib") + "/crt2.o" )
  209. End If
  210. EndIf
  211. Local xpmanifest$
  212. For Local f$=EachIn lnk_files
  213. Local t$=CQuote( f )
  214. If opt_dumpbuild Or (t[..1]="-" And t[..2]<>"-l")
  215. cmd:+" "+t
  216. Else
  217. If f.EndsWith( "/win32maxguiex.mod/xpmanifest.o" )
  218. xpmanifest=t
  219. Else
  220. files:+"~n"+t
  221. EndIf
  222. EndIf
  223. Next
  224. If xpmanifest files:+"~n"+xpmanifest
  225. cmd:+" "+CQuote( tmpfile )
  226. files:+"~n-lgdi32 -lwsock32 -lwinmm -ladvapi32"
  227. If usingLD
  228. files:+" -lstdc++ -lmingwex"
  229. ' for a native Win32 runtiime of mingw 3.4.5, this needs to appear early.
  230. 'If Not processor.Option("path_to_mingw", "") Then
  231. files:+" -lmingw32"
  232. 'End If
  233. files:+" -lgcc -lmoldname -lmsvcrt "
  234. End If
  235. files :+ " -luser32 -lkernel32 "
  236. 'If processor.Option("path_to_mingw", "") Then
  237. ' for a non-native Win32 runtime, this needs to appear last.
  238. ' (Actually, also for native gcc 4.x, but I dunno how we'll handle that yet!)
  239. If usingLD
  240. files:+"-lmingw32 "
  241. End If
  242. 'End If
  243. If Not makelib
  244. If usingLD
  245. files:+" "+CQuote( processor.Option("path_to_mingw_lib2", BlitzMaxPath()+"/lib") + "/crtend.o" )
  246. End If
  247. EndIf
  248. files="INPUT("+files+")"
  249. End If
  250. If processor.Platform() = "linux"
  251. cmd$="g++"
  252. cmd:+" -m32 -s --eh-frame-hdr -pthread"
  253. cmd:+" -o "+CQuote( path )
  254. cmd:+" "+CQuote( tmpfile )
  255. cmd:+" -L/usr/lib32"
  256. cmd:+" -L/usr/X11R6/lib"
  257. cmd:+" -L/usr/lib"
  258. cmd:+" -L"+CQuote( BlitzMaxPath()+"/lib" )
  259. For Local t$=EachIn lnk_files
  260. t=CQuote(t)
  261. If opt_dumpbuild Or (t[..1]="-" And t[..2]<>"-l")
  262. cmd:+" "+t
  263. Else
  264. files:+" "+t
  265. EndIf
  266. Next
  267. files="INPUT("+files+")"
  268. End If
  269. Local t$=getenv_( "BMK_LD_OPTS" )
  270. If t
  271. cmd:+" "+t
  272. EndIf
  273. Local stream:TStream=WriteStream( tmpfile )
  274. stream.WriteBytes files.ToCString(),files.length
  275. stream.Close
  276. If Sys( cmd ) Throw "Build Error: Failed to link "+path
  277. End Function
  278. Function MergeApp(fromFile:String, toFile:String)
  279. If Not opt_quiet Print "Merging:"+StripDir(fromFile) + " + " + StripDir(toFile)
  280. Local cmd:String = "lipo -create ~q" + fromFile + "~q ~q" + toFile + "~q -output ~q" + toFile + "~q"
  281. If Sys( cmd ) Throw "Merge Error: Failed to merge " + toFile
  282. DeleteFile fromFile
  283. End Function