瀏覽代碼

Merge pull request #6959 from RandomShaper/fix-big-libs

Adopt simpler strategy for big libs on Windows
Rémi Verschelde 8 年之前
父節點
當前提交
1944635ac4
共有 3 個文件被更改,包括 56 次插入46 次删除
  1. 1 0
      SConstruct
  2. 2 45
      drivers/SCsub
  3. 53 1
      methods.py

+ 1 - 0
SConstruct

@@ -100,6 +100,7 @@ env_base.__class__.disable_module = methods.disable_module
 
 
 env_base.__class__.add_source_files = methods.add_source_files
 env_base.__class__.add_source_files = methods.add_source_files
 env_base.__class__.use_windows_spawn_fix = methods.use_windows_spawn_fix
 env_base.__class__.use_windows_spawn_fix = methods.use_windows_spawn_fix
+env_base.__class__.split_lib = methods.split_lib
 
 
 env_base["x86_libtheora_opt_gcc"]=False
 env_base["x86_libtheora_opt_gcc"]=False
 env_base["x86_libtheora_opt_vc"]=False
 env_base["x86_libtheora_opt_vc"]=False

+ 2 - 45
drivers/SCsub

@@ -34,51 +34,8 @@ if (env["tools"]=="yes"):
 if env['vsproj']=="yes":
 if env['vsproj']=="yes":
 	env.AddToVSProject(env.drivers_sources)
 	env.AddToVSProject(env.drivers_sources)
 
 
-
-# Split drivers, this used to be needed for windows until separate builders for windows were created
-# FIXME: Check if still needed now that the drivers were made more lightweight
-if (env.split_drivers):
-	import string
-
-	num = 0
-	cur_base = ""
-	max_src = 64
-	list = []
-	lib_list = []
-
-	for f in env.drivers_sources:
-		fname = ""
-		if type(f) == type(""):
-			fname = env.File(f).path
-		else:
-			fname = env.File(f)[0].path
-		fname = fname.replace("\\", "/")
-		base = string.join(fname.split("/")[:2], "/")
-		if base != cur_base and len(list) > max_src:
-			if num > 0:
-				lib = env.Library("drivers"+str(num), list)
-				lib_list.append(lib)
-				list = []
-			num = num+1
-		cur_base = base
-		list.append(f)
-
-	lib = env.Library("drivers"+str(num), list)
-	lib_list.append(lib)
-
-	if len(lib_list) > 0:
-		import os, sys
-		if os.name=='posix' and sys.platform=='msys':
-			env.Replace(ARFLAGS=['rcsT'])
-
-			lib = env.Library("drivers_collated", lib_list)
-			lib_list = [lib]
-
-	drivers_base=[]
-	env.add_source_files(drivers_base,"*.cpp")
-	lib_list.insert(0, env.Library("drivers", drivers_base))
-
-	env.Prepend(LIBS=lib_list)
+if env.split_drivers:
+	env.split_lib("drivers")
 else:
 else:
 	env.add_source_files(env.drivers_sources,"*.cpp")
 	env.add_source_files(env.drivers_sources,"*.cpp")
 	lib = env.Library("drivers",env.drivers_sources)
 	lib = env.Library("drivers",env.drivers_sources)

+ 53 - 1
methods.py

@@ -1352,7 +1352,15 @@ def use_windows_spawn_fix(self, platform=None):
     if (os.name!="nt"):
     if (os.name!="nt"):
 	return #not needed, only for windows
 	return #not needed, only for windows
 
 
-    self.split_drivers=True
+    # On Windows, due to the limited command line length, when creating a static library
+    # from a very high number of objects SCons will invoke "ar" once per object file;
+    # that makes object files with same names to be overwritten so the last wins and
+    # the library looses symbols defined by overwritten objects.
+    # By enabling quick append instead of the default mode (replacing), libraries will
+    # got built correctly regardless the invokation strategy.
+    # Furthermore, since SCons will rebuild the library from scratch when an object file
+    # changes, no multiple versions of the same object file will be present.
+    self.Replace(ARFLAGS='q')
 
 
     import subprocess
     import subprocess
 
 
@@ -1394,6 +1402,50 @@ def use_windows_spawn_fix(self, platform=None):
     self['SPAWN'] = mySpawn
     self['SPAWN'] = mySpawn
 
 
 
 
+def split_lib(self, libname):
+	import string
+	env = self
+
+	num = 0
+	cur_base = ""
+	max_src = 64
+	list = []
+	lib_list = []
+
+	for f in getattr(env, libname + "_sources"):
+		fname = ""
+		if type(f) == type(""):
+			fname = env.File(f).path
+		else:
+			fname = env.File(f)[0].path
+		fname = fname.replace("\\", "/")
+		base = string.join(fname.split("/")[:2], "/")
+		if base != cur_base and len(list) > max_src:
+			if num > 0:
+				lib = env.Library(libname + str(num), list)
+				lib_list.append(lib)
+				list = []
+			num = num + 1
+		cur_base = base
+		list.append(f)
+
+	lib = env.Library(libname + str(num), list)
+	lib_list.append(lib)
+
+	if len(lib_list) > 0:
+		import os, sys
+		if os.name == 'posix' and sys.platform == 'msys':
+			env.Replace(ARFLAGS = ['rcsT'])
+			lib = env.Library(libname + "_collated", lib_list)
+			lib_list = [lib]
+
+	lib_base = []
+	env.add_source_files(lib_base, "*.cpp")
+	lib_list.insert(0, env.Library(libname, lib_base))
+
+	env.Prepend(LIBS = lib_list)
+
+
 def save_active_platforms(apnames,ap):
 def save_active_platforms(apnames,ap):
 
 
 	for x in ap:
 	for x in ap: