scons: Get working on Windows with MSVC

This commit is contained in:
2015-09-13 00:15:28 -04:00
parent 09b117776a
commit 853c270146
7 changed files with 116 additions and 54 deletions

View File

@@ -5,14 +5,16 @@ import subprocess
platform = ARGUMENTS.get('OS', Platform()) platform = ARGUMENTS.get('OS', Platform())
if str(platform) not in ("darwin", "windows"): if str(platform) not in ("darwin", "win32"):
print "Sorry, your platform is not supported." print "Sorry, your platform is not supported."
print "Platform is:", platform print "Platform is:", platform
print "Specify OS=<your-platform> if you believe this is incorrect." print "Specify OS=<your-platform> if you believe this is incorrect."
print "(Supported platforms are: darwin, windows)" print "(Supported platforms are: darwin, win32)"
Exit(1) Exit(1)
env = Environment() print 'Building for:', platform
env = Environment(TARGET_ARCH='x86')
env.VariantDir('#build/obj', 'src') env.VariantDir('#build/obj', 'src')
env.VariantDir('#build/obj/test', 'test') env.VariantDir('#build/obj/test', 'test')
@@ -118,16 +120,35 @@ if str(platform) == "darwin":
Execute(Copy(dest_path, src_path)) Execute(Copy(dest_path, src_path))
bundle_libraries_for(target, [File(check_path)], env) bundle_libraries_for(target, [File(check_path)], env)
break break
elif str(platform) == "windows": elif str(platform) == "win32":
if 'msvc' in env['TOOLS']:
env.Append(
LINKFLAGS='/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup /MACHINE:X86',
CXXFLAGS='/EHsc /MD',
LIBS=Split("""
kernel32
user32
gdi32
winspool
comdlg32
advapi32
shell32
ole32
oleaut32
uuid
odbc32
odbccp32
""")
)
def build_app_package(env, source, build_dir, info): def build_app_package(env, source, build_dir, info):
env.Install("#build/Blades of Exile/", source) env.Install(build_dir, source)
env.AddMethod(build_app_package, "Package") env.AddMethod(build_app_package, "Package")
# Allow user to specify additional library/include paths # Allow user to specify additional library/include paths
env.Append( env.Append(
LIBPATH = ARGUMENTS.get('LIBPATH', '').split(path.pathsep), LIBPATH = ARGUMENTS.get('LIBPATH', '').split(path.pathsep),
INCLUDEPATH = ARGUMENTS.get('INCLUDEPATH', '').split(path.pathsep) CPPPATH = ARGUMENTS.get('CPPPATH', '').split(path.pathsep)
) )
if str(platform) == 'darwin': if str(platform) == 'darwin':
env.Append(FRAMEWORKPATH=ARGUMENTS.get('FRAMEWORKPATH', '').split(path.pathsep)) env.Append(FRAMEWORKPATH=ARGUMENTS.get('FRAMEWORKPATH', '').split(path.pathsep))
@@ -135,13 +156,13 @@ if str(platform) == 'darwin':
if subprocess.call(['which', '-s', 'port']) == 0: # MacPorts if subprocess.call(['which', '-s', 'port']) == 0: # MacPorts
env.Append( env.Append(
LIBPATH = '/opt/local/lib', LIBPATH = '/opt/local/lib',
INCLUDEPATH = '/opt/local/include', CPPPATH = '/opt/local/include',
FRAMEWORKPATH = '/opt/local/Library/Frameworks' FRAMEWORKPATH = '/opt/local/Library/Frameworks'
) )
if subprocess.call(['which', '-s', 'fink']) == 0: # Fink if subprocess.call(['which', '-s', 'fink']) == 0: # Fink
env.Append( env.Append(
LIBPATH = '/sw/lib', LIBPATH = '/sw/lib',
INCLUDEPATH = '/sw/include' CPPPATH = '/sw/include'
) )
# HomeBrew apparently creates symlinks in /usr/local, so no special handling needed? # HomeBrew apparently creates symlinks in /usr/local, so no special handling needed?
@@ -153,35 +174,56 @@ if path.exists('deps/lib'):
env.Append(FRAMEWORKPATH='deps/lib') env.Append(FRAMEWORKPATH='deps/lib')
if path.exists('deps/include'): if path.exists('deps/include'):
env.Append(INCLUDEPATH='deps/include') env.Append(CPPPATH='deps/include')
env['CONFIGUREDIR'] = '#build/conf' env['CONFIGUREDIR'] = '#build/conf'
env['CONFIGURELOG'] = '#build/conf/config.log' env['CONFIGURELOG'] = '#build/conf/config.log'
conf = Configure(env) conf = Configure(env)
if not conf.CheckLib('z'): if not conf.CheckLib('zlib' if str(platform) == "win32" else 'z'):
print 'zlib must be installed!' print 'zlib must be installed!'
Exit(1) Exit(1)
def check_lib(lib, disp): def check_lib(lib, disp, suffixes=[], versions=[]):
if not conf.CheckLib(lib, language='C++', autoadd=False): if str(platform) == "win32" and lib.startswith("boost"):
print disp, 'must be installed!' lib = "lib" + lib
Exit(1) possible_names = [lib]
if str(platform) == "win32":
if 'msvc' in env['TOOLS']:
vc_suffix = '-vc' + env['MSVC_VERSION'].replace('.','')
possible_names.append(lib + vc_suffix)
n = len(possible_names)
for i in xrange(n):
for suff in suffixes:
possible_names.append(possible_names[i] + suff)
for test in possible_names:
if conf.CheckLib(test, language='C++'):
bundled_libs.append(test)
return # Success!
for ver in versions:
if conf.CheckLib(test + ver, language='C++'):
bundled_libs.append(test + ver)
return # Success!
print disp, 'must be installed!'
Exit(1)
def check_header(header, disp): def check_header(header, disp):
if not conf.CheckCXXHeader(header, '<>'): if not conf.CheckCXXHeader(header, '<>'):
print disp, 'must be installed!' print disp, 'must be installed!'
Exit(1) Exit(1)
boost_versions = ['-1_55', '-1_56', '-1_57', '-1_58'] # This is a bit of a hack. :(
bundled_libs = []
check_header('boost/lexical_cast.hpp', 'Boost.LexicalCast') check_header('boost/lexical_cast.hpp', 'Boost.LexicalCast')
check_header('boost/optional.hpp', 'Boost.Optional') check_header('boost/optional.hpp', 'Boost.Optional')
check_header('boost/ptr_container/ptr_container.hpp', 'Boost.PointerContainer') check_header('boost/ptr_container/ptr_container.hpp', 'Boost.PointerContainer')
check_header('boost/any.hpp', 'Boost.Any') check_header('boost/any.hpp', 'Boost.Any')
check_header('boost/math_fwd.hpp', 'Boost.Math') check_header('boost/math_fwd.hpp', 'Boost.Math')
check_header('boost/spirit/include/classic.hpp', 'Boost.Spirit.Classic') check_header('boost/spirit/include/classic.hpp', 'Boost.Spirit.Classic')
check_lib('boost_system', 'Boost.System') check_lib('boost_system', 'Boost.System', ['-mt'], boost_versions)
check_lib('boost_filesystem', 'Boost.Filesystem') check_lib('boost_filesystem', 'Boost.Filesystem', ['-mt'], boost_versions)
check_lib('boost_thread', 'Boost.Thread') check_lib('boost_thread', 'Boost.Thread', ['-mt'], boost_versions)
check_lib('sfml-system', 'SFML-system') check_lib('sfml-system', 'SFML-system')
check_lib('sfml-window', 'SFML-window') check_lib('sfml-window', 'SFML-window')
check_lib('sfml-audio', 'SFML-audio') check_lib('sfml-audio', 'SFML-audio')
@@ -203,19 +245,9 @@ env.Append(CPPPATH=Split("""
#src/dialogxml/xml-parser/ #src/dialogxml/xml-parser/
""")) """))
# Linked libraries if str(platform) == "win32":
# For the *resource.h headers
bundled_libs = Split(""" env.Append(CPPPATH="#rsrc/menus")
boost_system
boost_filesystem
boost_thread
sfml-audio
sfml-graphics
sfml-system
sfml-window
""")
env.Append(LIBS = bundled_libs)
if str(platform) == "darwin": if str(platform) == "darwin":
env.Append(LIBS=Split(""" env.Append(LIBS=Split("""
@@ -228,26 +260,27 @@ if str(platform) == "darwin":
""")) """))
else: else:
env.Append(LIBS=Split(""" env.Append(LIBS=Split("""
GL opengl32
""")) """))
Export("env platform") Export("env platform")
# The VariantDir directives near the top mean that the SConscript files are
# copied from src/ and test/ into build/obj/ and build/obj/test respectively.
# Thus, any edits to them should be made there.
# However, when referencing them we have to reference the copies.
# Gather common sources # Gather common sources
common_classes, party_classes = SConscript("src/classes/SConscript") common_classes, party_classes = SConscript("build/obj/classes/SConscript")
tools = SConscript("src/tools/SConscript") tools = SConscript("build/obj/tools/SConscript")
dlog_util = SConscript("src/dialogxml/SConscript") dlog_util = SConscript("build/obj/dialogxml/SConscript")
common_sources = common_classes + dlog_util + tools common_sources = common_classes + dlog_util + tools
install_dir = "#build/Blades of Exile" install_dir = "#build/Blades of Exile"
Export("install_dir party_classes common_sources") Export("install_dir party_classes common_sources")
# Programs # Programs
# The VariantDir directives near the top mean that the SConscript files are
# copied from src/ and test/ into the corresponding build/obj/ location.
# Thus, any edits to them should be made there.
SConscript([ SConscript([
"build/obj/SConscript", "build/obj/SConscript",
"build/obj/pcedit/SConscript", "build/obj/pcedit/SConscript",
@@ -257,7 +290,7 @@ SConscript([
# Data files # Data files
data_dir = path.join(install_dir, "/data") data_dir = path.join(install_dir, "data")
Export("data_dir") Export("data_dir")
SConscript(["rsrc/SConscript", "doc/SConscript"]) SConscript(["rsrc/SConscript", "doc/SConscript"])
@@ -273,6 +306,25 @@ if str(platform) == "darwin":
target_dir = path.join(install_dir, targ + '.app', 'Contents/Frameworks') target_dir = path.join(install_dir, targ + '.app', 'Contents/Frameworks')
binary = path.join(install_dir, targ + '.app', 'Contents/MacOS', targ) binary = path.join(install_dir, targ + '.app', 'Contents/MacOS', targ)
env.Command(Dir(target_dir), binary, [Delete(target_dir), bundle_libraries_for]) env.Command(Dir(target_dir), binary, [Delete(target_dir), bundle_libraries_for])
elif str(platform) == "windows": elif str(platform) == "win32":
lib_dirs = [install_dir] bundled_libs = Split("""
libsndfile-1
openal32
sfml-audio-2
sfml-graphics-2
sfml-system-2
sfml-window-2
zlib1
""")
target_dirs = ["#build/Blades of Exile", "#build/test"]
for lib in bundled_libs:
for lpath in env['LIBPATH']:
if 'Visual Studio' in lpath:
lpath = lpath.replace('lib', 'bin')
src_file = path.join(lpath, lib + ".dll")
if path.exists(src_file):
for targ in target_dirs:
env.Install(targ, src_file)
break
#env.Command(install_dir, 'Blades of Exile.exe', [Delete(Glob(path.join(install_dir, '*.dll'))), bundle_libraries_for])

View File

@@ -30,10 +30,11 @@ if str(platform) == "darwin":
boe.appleevents.mm boe.appleevents.mm
boe.menus.mac.mm boe.menus.mac.mm
""")) """))
elif str(platform) == "windows": elif str(platform) == "win32":
game_sources.extend(Split(""" game_sources.extend(Split("""
boe.menus.win.cpp boe.menus.win.cpp
""")) """))
game_sources.append(env.RES('#build/obj/BladesOfExile.res', '#rsrc/menus/BladesOfExile.rc'))
boe = env.Program("#build/bin/Blades of Exile", common_sources + party_classes + game_sources) boe = env.Program("#build/bin/Blades of Exile", common_sources + party_classes + game_sources)
@@ -44,7 +45,7 @@ if str(platform) == "darwin":
'creator': 'blx!', 'creator': 'blx!',
'icons': 'BoE boegraphics boeresources boesave boesounds', 'icons': 'BoE boegraphics boeresources boesave boesounds',
} }
elif str(platform) == "windows": elif str(platform) == "win32":
pass boe_info = {}
env.Package(boe, install_dir, boe_info) env.Package(boe, install_dir, boe_info)

View File

@@ -15,10 +15,11 @@ if str(platform) == "darwin":
pc.appleevents.mm pc.appleevents.mm
pc.menus.mac.mm pc.menus.mac.mm
""")) """))
elif str(platform) == "windows": elif str(platform) == "win32":
pced_sources.extend(Split(""" pced_sources.extend(Split("""
pc.menus.win.cpp pc.menus.win.cpp
""")) """))
pced_sources.append(env.RES('#rsrc/menus/CharEditor.rc'))
pced = env.Program("#build/bin/BoE Character Editor", common_sources + party_classes + pced_sources) pced = env.Program("#build/bin/BoE Character Editor", common_sources + party_classes + pced_sources)
@@ -29,7 +30,7 @@ if str(platform) == "darwin":
'creator': 'blxe', 'creator': 'blxe',
'icons': 'BoECharEd', 'icons': 'BoECharEd',
} }
elif str(platform) == "windows": elif str(platform) == "win32":
pass pced_info = {}
env.Package(pced, install_dir, pced_info) env.Package(pced, install_dir, pced_info)

View File

@@ -17,10 +17,11 @@ if str(platform) == "darwin":
scen.appleevents.mm scen.appleevents.mm
scen.menus.mac.mm scen.menus.mac.mm
""")) """))
elif str(platform) == "windows": elif str(platform) == "win32":
scened_sources.extend(Split(""" scened_sources.extend(Split("""
scen.menus.win.cpp scen.menus.win.cpp
""")) """))
scened_sources.extend(env.RES('#rsrc/menus/ScenEditor.rc'))
scened = env.Program("#build/bin/BoE Scenario Editor", common_sources + scened_sources) scened = env.Program("#build/bin/BoE Scenario Editor", common_sources + scened_sources)
@@ -31,7 +32,7 @@ if str(platform) == "darwin":
'creator': 'BlEd', 'creator': 'BlEd',
'icons': 'boescenario BoEScenEd', 'icons': 'boescenario BoEScenEd',
} }
elif str(platform) == "windows": elif str(platform) == "win32":
pass scened_info = {}
env.Package(scened, install_dir, scened_info) env.Package(scened, install_dir, scened_info)

View File

@@ -22,7 +22,7 @@ if str(platform) == "darwin":
qdpict.cpp qdpict.cpp
winutil.mac.mm winutil.mac.mm
""")) """))
elif str(platform) == "windows": elif str(platform) == "win32":
tools.extend(Split(""" tools.extend(Split("""
cursors.win.cpp cursors.win.cpp
menu_accel.win.cpp menu_accel.win.cpp

View File

@@ -2,7 +2,14 @@
Import("env platform party_classes common_sources") Import("env platform party_classes common_sources")
test_sources = Glob("""*.cpp""") + Split(""" test_sources = Glob("""*.cpp""") + Split("""
#src/scenedit/scen.fileio.cpp #build/obj/scenedit/scen.fileio.cpp
""") """)
test = env.Program("#build/bin/boe_test", party_classes + common_sources + test_sources) if str(platform) == "win32" and 'msvc' in env["TOOLS"]:
test = env.Program("#build/bin/boe_test", party_classes + common_sources + test_sources, LINKFLAGS='/nologo /SUBSYSTEM:CONSOLE /MACHINE:X86')
else:
test = env.Program("#build/bin/boe_test", party_classes + common_sources + test_sources)
env.Install("#build/test/", test)
env.Install("#build/test/", Dir("#test/files"))
env.Command("#build/test/junk/", '', 'mkdir "' + Dir("#build/test/junk").path + '"')

View File

@@ -8,7 +8,7 @@ sf::Texture fields_gworld, anim_gworld, boom_gworld, dlogpics_gworld, items_gwor
sf::Texture pc_gworld, roads_gworld, small_ter_gworld, status_gworld, talkfaces_gworld, terrain_gworld[NUM_TER_SHEETS]; sf::Texture pc_gworld, roads_gworld, small_ter_gworld, status_gworld, talkfaces_gworld, terrain_gworld[NUM_TER_SHEETS];
sf::Texture tiny_obj_gworld, vehicle_gworld; sf::Texture tiny_obj_gworld, vehicle_gworld;
sf::RenderWindow mainPtr; sf::RenderWindow mainPtr;
fs::path scenario_temp_dir_name = "test_scenario"; std::string scenario_temp_dir_name = "test_scenario";
cCustomGraphics spec_scen_g; cCustomGraphics spec_scen_g;
// And these are referenced from the scenario code, though not used in test cases // And these are referenced from the scenario code, though not used in test cases