← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2640: generation of MSVC project files via SCons

 

------------------------------------------------------------
revno: 2640
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Mon 2011-10-17 01:06:25 +0200
message:
  generation of MSVC project files via SCons
modified:
  .bzrignore
  Compile.txt
  SConstruct
  boost/SConscript
  boost/libs/regex/src/SConscript
  build_util.py
  bzip2/SConscript
  dcpp/SConscript
  dwarf/SConscript
  dwt/src/SConscript
  dwt/src/util/SConscript
  dwt/src/util/win32/SConscript
  dwt/src/widgets/SConscript
  geoip/SConscript
  intl/SConscript
  miniupnpc/SConscript
  natpmp/SConscript
  win32/SConscript
  zlib/SConscript


--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk

Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file '.bzrignore'
--- .bzrignore	2010-11-21 19:11:21 +0000
+++ .bzrignore	2011-10-16 23:06:25 +0000
@@ -18,3 +18,5 @@
 config.log
 .sconsign.dblite
 openssl/build/openssl*
+./msvc/debug-*
+./msvc/release-*

=== modified file 'Compile.txt'
--- Compile.txt	2011-10-10 20:18:18 +0000
+++ Compile.txt	2011-10-16 23:06:25 +0000
@@ -83,6 +83,9 @@
 		(read their instructions file; it's a matter of adding "debug" in the do_* file you use).
 		Rename debug libraries to libeay32d.lib and ssleay32d.lib; put them in openssl/lib.
 
+		To generate project files for MSVC, run "scons" with "msvcproj=1" and "tools=default".
+		The resulting solution file (DCPlusPlus.sln) will be in msvc/[mode-arch]/.
+
 
 3. Starting the build process
 

=== modified file 'SConstruct'
--- SConstruct	2011-10-10 20:18:18 +0000
+++ SConstruct	2011-10-16 23:06:25 +0000
@@ -31,7 +31,7 @@
 	# 4706: assignment within conditional expression
 	# 4800: converting from BOOL to bool
 	# 4996: fn unsafe, use fn_s
-	'common' : ['/W4', '/EHsc', '/Zi', '/GR', '/wd4100', '/wd4121', '/wd4127', '/wd4189', '/wd4244', '/wd4290', '/wd4355', '/wd4510', '/wd4512', '/wd4610', '/wd4706', '/wd4800', '/wd4996'],
+	'common' : ['/W4', '/EHsc', '/Zi', '/GR', '/FC', '/wd4100', '/wd4121', '/wd4127', '/wd4189', '/wd4244', '/wd4290', '/wd4355', '/wd4510', '/wd4512', '/wd4610', '/wd4706', '/wd4800', '/wd4996'],
 	'debug' : ['/MDd'],
 	'release' : ['/MD', '/O2']
 }
@@ -85,6 +85,7 @@
 	BoolVariable('test', 'Build test suite', 'no'),
 	('prefix', 'Prefix to use when cross compiling', ''),
 	EnumVariable('arch', 'Target architecture', 'x86', ['x86', 'x64', 'ia64']),
+	BoolVariable('msvcproj', 'Build MSVC project files', 'no'),
 	BoolVariable('distro', 'Produce the official distro (forces tools=mingw, mode=release, unicode=1, i18n=1, help=1, webhelp=1, arch=x86)', 'no')
 )
 
@@ -258,3 +259,5 @@
 else:
 	dev.win32 = dev.build('win32/')
 dev.installer = dev.build('installer/')
+
+dev.finalize()

=== modified file 'boost/SConscript'
--- boost/SConscript	2010-12-05 17:03:00 +0000
+++ boost/SConscript	2011-10-16 23:06:25 +0000
@@ -4,6 +4,6 @@
 
 glob = dev.env.Glob('libs/*/src', strings = 1)
 for path in glob:
-	ret += dev.build(path + '/')
+	ret.append(dev.build(path + '/'))
 
 Return('ret')

=== modified file 'boost/libs/regex/src/SConscript'
--- boost/libs/regex/src/SConscript	2010-12-05 17:03:00 +0000
+++ boost/libs/regex/src/SConscript	2011-10-16 23:06:25 +0000
@@ -2,6 +2,5 @@
 
 env, target, sources = dev.prepare_build(source_path, 'boost', in_bin = False)
 
-ret = env.StaticLibrary(target, sources)
-
+ret = dev.build_lib(env, target, sources)
 Return('ret')

=== modified file 'build_util.py'
--- build_util.py	2011-06-24 18:55:47 +0000
+++ build_util.py	2011-10-16 23:06:25 +0000
@@ -56,6 +56,38 @@
 			# some distros of windres fail when they receive Win paths as input, so convert...
 			self.env['RCCOM'] = self.env['RCCOM'].replace('-i $SOURCE', '-i ${SOURCE.posix}', 1)
 
+		if self.env['msvcproj']:
+			if 'msvs' not in self.env['TOOLS']:
+				raise Exception('This is not an MSVC build; specify tools=default')
+			msvcproj_arch = self.env['arch']
+			if msvcproj_arch == 'x86':
+				msvcproj_arch = 'Win32'
+			# TODO SCons doesn't seem to support multiple configs per project, so each config goes
+			# to a separate directory. when this is fixed, generate all projects in the root dir.
+			self.msvcproj_path = '#/msvc/' + self.env['mode'] + '-' + self.env['arch'] + '/'
+			self.msvcproj_variant = self.env['mode'] + '|' + msvcproj_arch
+			self.msvcproj_projects = []
+
+			# set up the command called when building from the VS IDE.
+			self.env['MSVSSCONSFLAGS'] = (self.env['MSVSSCONSFLAGS'] +
+				' tools=' + self.env['tools'] +
+				' mode=' + self.env['mode'] +
+				' arch=' + self.env['arch'])
+
+			# work around a few bugs in MSVC project generation, see msvcproj_workarounds for details.
+			from SCons.Action import Action
+			from SCons.Tool.msvs import GenerateProject
+			self.env['MSVSPROJECTCOM'] = [Action(GenerateProject, None), Action(msvcproj_workarounds, None)]
+
+	def finalize(self):
+		if self.env['msvcproj']:
+			path = self.msvcproj_path + 'DCPlusPlus' + self.env['MSVSSOLUTIONSUFFIX']
+			self.env.Precious(path)
+			self.env.MSVSSolution(
+				target = path,
+				variant = self.msvcproj_variant,
+				projects = self.msvcproj_projects)
+
 	def is_win32(self):
 		return sys.platform == 'win32' or 'mingw' in self.env['TOOLS']
 
@@ -74,6 +106,14 @@
 	def get_sources(self, source_path, source_glob):
 		return map(lambda x: self.get_build_path(source_path) + x, glob.glob(source_glob))
 
+	# execute the SConscript file in the specified sub-directory.
+	def build(self, source_path, local_env = None):
+		if not local_env:
+			local_env = self.env
+		full_path = local_env.Dir('.').path + '/' + source_path	
+		return local_env.SConscript(source_path + 'SConscript', exports = { 'dev': self, 'source_path': full_path })
+
+	# create a build environment and set up sources and targets.
 	def prepare_build(self, source_path, name, source_glob = '*.cpp', in_bin = True, precompiled_header = None):
 		env = self.env.Clone()
 		env.VariantDir(self.get_build_path(source_path), '.', duplicate = 0)
@@ -94,11 +134,34 @@
 
 		return (env, self.get_target(source_path, name, in_bin), sources)
 
-	def build(self, source_path, local_env = None):
-		if not local_env:
-			local_env = self.env
-		full_path = local_env.Dir('.').path + '/' + source_path	
-		return local_env.SConscript(source_path + 'SConscript', exports={'dev' : self, 'source_path' : full_path })
+	# helpers for the MSVC project builder (see build_lib)
+	def simple_lib(inc_ext, src_ext):
+		return lambda self, name: (self.env.Glob('#/' + name + '/*.' + inc_ext), self.env.Glob('#/' + name + '/*.' + src_ext))
+	c_lib = simple_lib('h', 'c')
+	cpp_lib = simple_lib('h', 'cpp')
+
+	def build_lib(self, env, target, sources, msvcproj_glob = None, msvcproj_name = None):
+		if env['msvcproj']:
+			if msvcproj_glob is None:
+				return
+			if msvcproj_name is None:
+				import os
+				msvcproj_name = os.path.basename(os.path.dirname(sources[0]))
+			glob_inc, glob_src = msvcproj_glob(msvcproj_name)
+			path = self.msvcproj_path + msvcproj_name + env['MSVSPROJECTSUFFIX']
+			env.Precious(path)
+			self.msvcproj_projects.append(env.MSVSProject(
+				path,
+				variant = self.msvcproj_variant,
+				auto_build_solution = 0,
+				incs = [f.abspath for f in glob_inc],
+				srcs = [f.abspath for f in glob_src],
+				# we cheat a bit here: only the main project will be buildable. this is to avoid
+				# simulatenous builds of all the projects at the same time and general mayhem.
+				MSVSSCONSCOM = env['MSVSSCONSCOM'] if msvcproj_name == 'win32' else ''))
+			return
+
+		return env.StaticLibrary(target, sources)
 
 	def i18n (self, source_path, buildenv, sources, name):
 		if not self.env['i18n']:
@@ -233,3 +296,26 @@
 		re.sub('^(' + line + ')', '', re.sub('(' + line + ')$', '',
 		re.sub('(' + line + ')+', line, re.sub('\s*<br ?/?>\s*', line,
 		string.replace('\\', '\\\\').replace('{', '\\{').replace('}', '\\}'))))))).replace('<u>', '{\\ul ')
+
+
+def msvcproj_workarounds(target, source, env):
+	f = open(str(target[0]), 'rb')
+	contents = f.read()
+	f.close()
+
+	import re
+
+	# include paths in MSVC projects are not expanded; expand them manually.
+	# bug: <http://scons.tigris.org/issues/show_bug.cgi?id=2382>
+	# TODO remove this when the bug is fixed in SCons.
+	contents = contents.replace('#/', env.Dir('#').abspath + '/')
+
+	# clean up empty commands for non-built projects to avoid build failures.
+	contents = re.sub('echo Starting SCons &amp;&amp;\s*(-c)?\s*&quot;&quot;', '', contents)
+
+	# remove SConstruct from included files since it points nowhere anyway.
+	contents = re.sub('<ItemGroup>\s*<None Include="SConstruct" />\s*</ItemGroup>', '', contents)
+
+	f = open(str(target[0]), 'wb')
+	f.write(contents)
+	f.close()

=== modified file 'bzip2/SConscript'
--- bzip2/SConscript	2007-02-28 12:56:10 +0000
+++ bzip2/SConscript	2011-10-16 23:06:25 +0000
@@ -1,9 +1,6 @@
-# vim: set filetype=py
- 
 Import('dev source_path')
 
-env, target, sources = dev.prepare_build(source_path, 'dcpp-bzip', source_glob="*.c", in_bin=False)
-
-ret = env.StaticLibrary(target, sources)
-
+env, target, sources = dev.prepare_build(source_path, 'bzip2', source_glob = '*.c', in_bin = False)
+
+ret = dev.build_lib(env, target, sources, dev.c_lib)
 Return('ret')

=== modified file 'dcpp/SConscript'
--- dcpp/SConscript	2011-09-23 11:47:15 +0000
+++ dcpp/SConscript	2011-10-16 23:06:25 +0000
@@ -38,9 +38,7 @@
 		sources[i] = env.StaticObject(source, CPPDEFINES=env['CPPDEFINES'] + rev)
 
 headers=dev.get_sources(source_path, "*.h")
-
 dev.i18n(source_path, env, [sources, headers], 'libdcpp')
 
-ret = env.StaticLibrary(target, sources)
-
+ret = dev.build_lib(env, target, sources, dev.cpp_lib)
 Return('ret')

=== modified file 'dwarf/SConscript'
--- dwarf/SConscript	2011-06-24 15:48:34 +0000
+++ dwarf/SConscript	2011-10-16 23:06:25 +0000
@@ -10,6 +10,5 @@
 	env.Append(CPPDEFINES = ['WIN32', '_WIN32_WINNT=0x501', '_WIN32_IE=0x501', 'WINVER=0x501', 'WIN32_LEAN_AND_MEAN'])
 env.Append(CPPPATH = ['#/dwarf'])
 
-ret = env.StaticLibrary(target, sources)
-
+ret = dev.build_lib(env, target, sources)
 Return('ret')

=== modified file 'dwt/src/SConscript'
--- dwt/src/SConscript	2008-10-16 20:09:19 +0000
+++ dwt/src/SConscript	2011-10-16 23:06:25 +0000
@@ -1,17 +1,20 @@
-# vim: set filetype=py
- 
 Import('dev source_path')
 
-env, target, sources = dev.prepare_build(source_path, 'dwt', in_bin=False)
-
-env.Append(CPPPATH=["#dwt/include"])
-
-ret = []
-
-ret += dev.build('util/')
-ret += dev.build('widgets/')
-
-ret += env.StaticLibrary(target, [sources, ret])
-
+env, target, sources = dev.prepare_build(source_path, 'dwt', in_bin = False)
+
+env.Append(CPPPATH = ['#/dwt/include'])
+
+def get_msvcproj_files(name):
+	def parse_patterns(patterns):
+		array = []
+		for pattern in patterns:
+			for file in env.Glob('#/' + name + '/' + pattern):
+				array.append(file)
+		return array
+	return (parse_patterns(['*.h', 'include/*.h', 'include/*/*.h', 'include/*/*/*.h']),
+			parse_patterns(['*.cpp', 'src/*.cpp', 'src/*/*.cpp', 'src/*/*/*.cpp']))
+
+ret = [dev.build('util/'), dev.build('widgets/')]
+
+ret.append(dev.build_lib(env, target, [sources, ret], get_msvcproj_files, 'dwt'))
 Return('ret')
-

=== modified file 'dwt/src/util/SConscript'
--- dwt/src/util/SConscript	2009-11-07 23:15:38 +0000
+++ dwt/src/util/SConscript	2011-10-16 23:06:25 +0000
@@ -1,12 +1,8 @@
-# vim: set filetype=py
- 
 Import('dev source_path')
 
-env, target, sources = dev.prepare_build(source_path, 'dwt-util', in_bin=False)
-
-env.Append(CPPPATH=["#/dwt/include"])
-
-ret = [env.StaticLibrary(target, sources), dev.build('win32/')]
-
+env, target, sources = dev.prepare_build(source_path, 'dwt', in_bin = False)
+
+env.Append(CPPPATH = ['#/dwt/include'])
+
+ret = [dev.build_lib(env, target, sources), dev.build('win32/')]
 Return('ret')
-

=== modified file 'dwt/src/util/win32/SConscript'
--- dwt/src/util/win32/SConscript	2009-11-07 23:15:38 +0000
+++ dwt/src/util/win32/SConscript	2011-10-16 23:06:25 +0000
@@ -1,12 +1,8 @@
-# vim: set filetype=py
- 
 Import('dev source_path')
 
-env, target, sources = dev.prepare_build(source_path, 'dwt', in_bin=False)
-
-env.Append(CPPPATH=["#/dwt/include"])
-
-ret = env.StaticLibrary(target, sources)
-
+env, target, sources = dev.prepare_build(source_path, 'dwt', in_bin = False)
+
+env.Append(CPPPATH = ['#/dwt/include'])
+
+ret = dev.build_lib(env, target, sources)
 Return('ret')
-

=== modified file 'dwt/src/widgets/SConscript'
--- dwt/src/widgets/SConscript	2008-04-03 20:54:10 +0000
+++ dwt/src/widgets/SConscript	2011-10-16 23:06:25 +0000
@@ -1,12 +1,8 @@
-# vim: set filetype=py
- 
 Import('dev source_path')
 
-env, target, sources = dev.prepare_build(source_path, 'dwt', in_bin=False)
-
-env.Append(CPPPATH=["#/dwt/include"])
-
-ret = env.StaticLibrary(target, sources)
-
+env, target, sources = dev.prepare_build(source_path, 'dwt', in_bin = False)
+
+env.Append(CPPPATH = ['#/dwt/include'])
+
+ret = dev.build_lib(env, target, sources)
 Return('ret')
-

=== modified file 'geoip/SConscript'
--- geoip/SConscript	2011-10-06 18:58:07 +0000
+++ geoip/SConscript	2011-10-16 23:06:25 +0000
@@ -8,6 +8,5 @@
 	if env['CC'] == 'cl': # MSVC
 		env.Append(CPPDEFINES = ['ssize_t=SSIZE_T'])
 
-ret = env.StaticLibrary(target, sources)
-
+ret = dev.build_lib(env, target, sources, dev.c_lib)
 Return('ret')

=== modified file 'intl/SConscript'
--- intl/SConscript	2010-09-17 15:59:10 +0000
+++ intl/SConscript	2011-10-16 23:06:25 +0000
@@ -1,7 +1,7 @@
 Import('dev source_path')
 
 if dev.is_win32():
-	env, target, sources = dev.prepare_build(source_path, 'aintl', '*.c', in_bin=False)
+	env, target, sources = dev.prepare_build(source_path, 'aintl', '*.c', in_bin = False)
 
 	empty_str = '"\\"\\""'
 	env.Append(CPPDEFINES = ['LOCALEDIR=' + empty_str, 'LOCALE_ALIAS_PATH=' + empty_str,
@@ -13,7 +13,8 @@
 	dev.env.Append(LIBS=['aintl'])
 	import os
 	dev.env.Append(LIBPATH=[os.path.dirname(target)])
-	ret = env.StaticLibrary(target, sources)
+
+	ret = dev.build_lib(env, target, sources, dev.c_lib)
 	Return('ret')
 
 else:

=== modified file 'miniupnpc/SConscript'
--- miniupnpc/SConscript	2010-06-25 20:23:07 +0000
+++ miniupnpc/SConscript	2011-10-16 23:06:25 +0000
@@ -5,6 +5,5 @@
 if dev.is_win32():
 	env.Append(CPPDEFINES = ['STATICLIB', 'WIN32', '_WIN32_WINNT=0x501', '_WIN32_IE=0x501', 'WINVER=0x501', 'WIN32_LEAN_AND_MEAN'])
 
-ret = env.StaticLibrary(target, sources)
-
+ret = dev.build_lib(env, target, sources, dev.c_lib)
 Return('ret')

=== modified file 'natpmp/SConscript'
--- natpmp/SConscript	2011-02-18 09:50:50 +0000
+++ natpmp/SConscript	2011-10-16 23:06:25 +0000
@@ -5,6 +5,5 @@
 if dev.is_win32():
 	env.Append(CPPDEFINES = ['errno="WSAGetLastError()"', 'STATICLIB', 'WIN32', '_WIN32_WINNT=0x501', '_WIN32_IE=0x501', 'WINVER=0x501', 'WIN32_LEAN_AND_MEAN'])
 
-ret = env.StaticLibrary(target, sources)
-
+ret = dev.build_lib(env, target, sources, dev.c_lib)
 Return('ret')

=== modified file 'win32/SConscript'
--- win32/SConscript	2011-09-23 11:47:15 +0000
+++ win32/SConscript	2011-10-16 23:06:25 +0000
@@ -44,7 +44,10 @@
 headers=dev.get_sources(source_path, "*.h")
 dev.i18n(source_path, env, [sources,headers], 'dcpp-win32')
 
-ret = env.Program(target, [sources, res, dev.client, dev.dwarf, dev.zlib, dev.boost, dev.bzip2, dev.geoip, dev.miniupnpc, dev.natpmp, dev.dwt, dev.intl])
+if env['msvcproj']:
+	ret = dev.build_lib(env, target, sources, dev.cpp_lib)
+else:
+	ret = env.Program(target, [sources, res, dev.client, dev.dwarf, dev.zlib, dev.boost, dev.bzip2, dev.geoip, dev.miniupnpc, dev.natpmp, dev.dwt, dev.intl])
 
 if 'gcc' in env['TOOLS']:
 	# strip debug info to a separate PDB file

=== modified file 'zlib/SConscript'
--- zlib/SConscript	2007-02-28 12:56:10 +0000
+++ zlib/SConscript	2011-10-16 23:06:25 +0000
@@ -1,9 +1,6 @@
-# vim: set filetype=py
- 
 Import('dev source_path')
 
-env, target, sources = dev.prepare_build(source_path, 'dcpp-zlib', source_glob="*.c", in_bin=False)
-
-ret = env.StaticLibrary(target, sources)
-
+env, target, sources = dev.prepare_build(source_path, 'zlib', source_glob = '*.c', in_bin = False)
+
+ret = dev.build_lib(env, target, sources, dev.c_lib)
 Return('ret')