View Issue Details

IDProjectCategoryView StatusLast Update
0005232The Dark ModCodingpublic02.01.2023 16:10
Reportert405 Assigned Tostgatilov  
PrioritylowSeveritymajorReproducibilityalways
Status closedResolutionduplicate 
Fixed in VersionTDM 2.10 
Summary0005232: scons configuration files are not compatible with python3 [patch included]
DescriptionAfter trying to compile according to the wiki instructions, using scons, a number of errors occurred. Most of these errors were due to the code being written in python2 and being incompatible with python3.

The problematic files were

SConstruct
sys/scons/scons_utils.py
tdm_update/SConstruct
tdm_update/scons_utils.py
Steps To ReproduceI checked out the svn repo 8693 and attempted to compile using the wiki instructions

Immediately got an error:
scons: Reading SConscript files ...
  File "/home/shawn/Code/darkmod-svn-wd/trunk/SConstruct", line 150
    print 'Loading build configuration from ' + conf_filename + ':'
          ^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print('Loading build configuration from ' + conf_filename + ':')?

There were a number of other errors: a missing module (popen2) and problems with the pickle and raise syntax.
Additional InformationCompilation was successful after I patched the files by translating them with 2to3, cleaning them up with black, and manually fixing the other errors.

`uname -a`:
 Linux 5.6.7-arch1-1 0000001 SMP PREEMPT Thu, 23 Apr 2020 09:13:56 +0000 x86_64 GNU/Linux
`scons --version | xargs`:
 SCons by Steven Knight et al.: script: v3.1.2.__BUILD__, 2019-12-17 02:06:27, by none on none engine: v3.1.2.__BUILD__, 2019-12-17 02:06:27, by none on none engine path: [/usr/lib/python3.8/site-packages/SCons] Copyright (c) 2001 - 2019 The SCons Foundation
`black --version`:
 black, version 19.10b0

Let me know if you need additional information. Patch is included in uploads.
TagsNo tags attached.
Attached Files
fix-scons-python2-001.patch (43,655 bytes)   
diff --git a/SConstruct b/SConstruct
index 14e504ed5..a3e043322 100644
--- a/SConstruct
+++ b/SConstruct
@@ -3,32 +3,50 @@
 # TTimo <ttimo@idsoftware.com>
 # http://scons.sourceforge.net
 
-import sys, os, time, commands, re, pickle, StringIO, popen2, commands, pdb, zipfile, string
+import sys, os, time, subprocess, re, pickle, io, subprocess, pdb, zipfile, string
 import SCons
 
-sys.path.append( 'sys/scons' )
+sys.path.append("sys/scons")
 import scons_utils
 
-conf_filename='site.conf'
+conf_filename = "site.conf"
 # choose configuration variables which should be saved between runs
 # ( we handle all those as strings )
-serialized=['CC', 'CXX', 'JOBS', 'BUILD', 'GL_HARDLINK',
-	'DEBUG_MEMORY', 'LIBC_MALLOC', 'ID_MCHECK', 'NOCURL',
-	'BUILD_ROOT', 'BASEFLAGS', 'SILENT', 'NO_GCH', 'OPENMP',
-	'TARGET_ARCH' ]
+serialized = [
+    "CC",
+    "CXX",
+    "JOBS",
+    "BUILD",
+    "GL_HARDLINK",
+    "DEBUG_MEMORY",
+    "LIBC_MALLOC",
+    "ID_MCHECK",
+    "NOCURL",
+    "BUILD_ROOT",
+    "BASEFLAGS",
+    "SILENT",
+    "NO_GCH",
+    "OPENMP",
+    "TARGET_ARCH",
+]
 
 # ------------------------------------------------
 
 # help -------------------------------------------
 
-help_string = """
+help_string = (
+    """
 Usage: scons [OPTIONS] [TARGET] [CONFIG]
 
 [OPTIONS] and [TARGET] are covered in command line options, use scons -H
 
 [CONFIG]: KEY="VALUE" [...]
-a number of configuration options saved between runs in the """ + conf_filename + """ file
-erase """ + conf_filename + """ to start with default settings again
+a number of configuration options saved between runs in the """
+    + conf_filename
+    + """ file
+erase """
+    + conf_filename
+    + """ to start with default settings again
 
 CC (default gcc)
 CXX (default g++)
@@ -90,122 +108,118 @@ ID_MCHECK (default 2)
 NOCURL (default 0)
 	set to 1 to disable usage of libcurl and http/ftp downloads feature
 """
+)
 
-Help( help_string )
+Help(help_string)
 
 # end help ---------------------------------------
 
 # sanity -----------------------------------------
 
-EnsureSConsVersion( 0, 96 )
+EnsureSConsVersion(0, 96)
 
 # end sanity -------------------------------------
 
 # system detection -------------------------------
 
 # CPU type
-cpu = commands.getoutput('uname -m')
-exp = re.compile('.*i?86.*')
+cpu = subprocess.getoutput("uname -m")
+exp = re.compile(".*i?86.*")
 if exp.match(cpu):
-	cpu = 'x86'
+    cpu = "x86"
 else:
-	cpu = commands.getoutput('uname -p')
-	if ( cpu == 'powerpc' ):
-		cpu = 'ppc'
-	else:
-		cpu = 'cpu'
-g_os = 'Linux'
+    cpu = subprocess.getoutput("uname -p")
+    if cpu == "powerpc":
+        cpu = "ppc"
+    else:
+        cpu = "cpu"
+g_os = "Linux"
 
 # end system detection ---------------------------
 
 # default settings -------------------------------
 
-CC = 'gcc'
-CXX = 'g++'
-JOBS = '1'
-BUILD = 'debug'
-GL_HARDLINK = '0'
-DEBUG_MEMORY = '0'
-LIBC_MALLOC = '1'
-ID_MCHECK = '2'
-BUILD_ROOT = 'build'
-NOCONF = '0'
-NOCURL = '0'
-BASEFLAGS = ''
-SILENT = '0'
-NO_GCH = '0'
-OPENMP = '0'
-TARGET_ARCH = 'x86'
+CC = "gcc"
+CXX = "g++"
+JOBS = "1"
+BUILD = "debug"
+GL_HARDLINK = "0"
+DEBUG_MEMORY = "0"
+LIBC_MALLOC = "1"
+ID_MCHECK = "2"
+BUILD_ROOT = "build"
+NOCONF = "0"
+NOCURL = "0"
+BASEFLAGS = ""
+SILENT = "0"
+NO_GCH = "0"
+OPENMP = "0"
+TARGET_ARCH = "x86"
 
 # end default settings ---------------------------
 
 # site settings ----------------------------------
-
-if ( not ARGUMENTS.has_key( 'NOCONF' ) or ARGUMENTS['NOCONF'] != '1' ):
-	site_dict = {}
-	if (os.path.exists(conf_filename)):
-		site_file = open(conf_filename, 'r')
-		p = pickle.Unpickler(site_file)
-		site_dict = p.load()
-		print 'Loading build configuration from ' + conf_filename + ':'
-		for k, v in site_dict.items():
-			exec_cmd = k + '=\'' + v + '\''
-			print '  ' + exec_cmd
-			exec(exec_cmd)
+if "NOCONF" not in ARGUMENTS or ARGUMENTS["NOCONF"] != "1":
+    site_dict = {}
+    if os.path.exists(conf_filename):
+        print("Loading build configuration from " + conf_filename + ":")
+        with open(conf_filename, "rb") as handle:
+            site_dict = pickle.load(handle)
+        for k, v in list(site_dict.items()):
+            exec_cmd = k + "='" + v + "'"
+            print("  " + exec_cmd)
+            exec(exec_cmd)
 else:
-	print 'Site settings ignored'
+    print("Site settings ignored")
 
 # end site settings ------------------------------
 
 # command line settings --------------------------
 
-for k in ARGUMENTS.keys():
-	exec_cmd = k + '=\'' + ARGUMENTS[k] + '\''
-	print 'Command line: ' + exec_cmd
-	exec( exec_cmd )
+for k in list(ARGUMENTS.keys()):
+    exec_cmd = k + "='" + ARGUMENTS[k] + "'"
+    print("Command line: " + exec_cmd)
+    exec(exec_cmd)
 
 # stgatilov: avoid annoying human errors when you set target='x32'
 # and get surprised that it does not build properly =)
-if TARGET_ARCH == 'x32':
-	TARGET_ARCH = 'x86'
+if TARGET_ARCH == "x32":
+    TARGET_ARCH = "x86"
 
 # end command line settings ----------------------
 
 # save site configuration ----------------------
 
-if ( not ARGUMENTS.has_key( 'NOCONF' ) or ARGUMENTS['NOCONF'] != '1' ):
-	for k in serialized:
-		exec_cmd = 'site_dict[\'' + k + '\'] = ' + k
-		exec(exec_cmd)
-
-	site_file = open(conf_filename, 'w')
-	p = pickle.Pickler(site_file)
-	p.dump(site_dict)
-	site_file.close()
+if "NOCONF" not in ARGUMENTS or ARGUMENTS["NOCONF"] != "1":
+    for k in serialized:
+        exec_cmd = "site_dict['" + k + "'] = " + k
+        exec(exec_cmd)
+    with open(conf_filename, "wb") as handle:
+        pickle.dump(site_dict, handle, protocol=pickle.HIGHEST_PROTOCOL)
 
 # end save site configuration ------------------
 
 # general configuration, target selection --------
 
-g_build = BUILD_ROOT + '/scons_' + TARGET_ARCH + '/' + BUILD
+g_build = BUILD_ROOT + "/scons_" + TARGET_ARCH + "/" + BUILD
 
-# 
+#
 # Use an absolute path to a single signature file to avoid a problem
 # whereby everything gets rebuilt every time due to the signature file
 # not being detected.
-# 
-SConsignFile(os.path.join(Dir('#').abspath, 'scons.signatures'))
+#
+SConsignFile(os.path.join(Dir("#").abspath, "scons.signatures"))
 
-if ( GL_HARDLINK != '0' ):
-	g_build += '-hardlink'
+if GL_HARDLINK != "0":
+    g_build += "-hardlink"
 
-if ( DEBUG_MEMORY != '0' ):
-	g_build += '-debugmem'
-	
-if ( LIBC_MALLOC != '1' ):
-	g_build += '-nolibcmalloc'
+if DEBUG_MEMORY != "0":
+    g_build += "-debugmem"
 
-SetOption('num_jobs', JOBS)
+if LIBC_MALLOC != "1":
+    g_build += "-nolibcmalloc"
+
+SetOption("num_jobs", JOBS)
 
 LINK = CXX
 
@@ -214,126 +228,141 @@ LINK = CXX
 # BASE + GAME + OPT for game
 # _noopt versions of the environements are built without the OPT
 
-BASECPPFLAGS = [ ]
-CORECPPPATH = [ ]
-CORELIBPATH = [ ]
-CORECPPFLAGS = [ ]
-BASELINKFLAGS = [ ]
-CORELINKFLAGS = [ ]
+BASECPPFLAGS = []
+CORECPPPATH = []
+CORELIBPATH = []
+CORECPPFLAGS = []
+BASELINKFLAGS = []
+CORELINKFLAGS = []
 
 # for release build, further optimisations that may not work on all files
-OPTCPPFLAGS = [ ]
+OPTCPPFLAGS = []
 
-BASECPPFLAGS.append( BASEFLAGS )
-BASECPPFLAGS.append( '-pipe' )
+BASECPPFLAGS.append(BASEFLAGS)
+BASECPPFLAGS.append("-pipe")
 # warn all
-BASECPPFLAGS.append( '-Wall' )
-BASECPPFLAGS.append( '-Wno-unknown-pragmas' )               # MSVC-specific pragmas
-BASECPPFLAGS.append( '-Wno-unused-variable' )               # too many, often happens from commenting out code
-BASECPPFLAGS.append( '-Wno-unused-but-set-variable' )       # useful for debugging, also may remain after commenting stuff
-BASECPPFLAGS.append( '-Wno-sign-compare' )                  # very nasty warning in the world of STL and size_t
+BASECPPFLAGS.append("-Wall")
+BASECPPFLAGS.append("-Wno-unknown-pragmas")  # MSVC-specific pragmas
+BASECPPFLAGS.append(
+    "-Wno-unused-variable"
+)  # too many, often happens from commenting out code
+BASECPPFLAGS.append(
+    "-Wno-unused-but-set-variable"
+)  # useful for debugging, also may remain after commenting stuff
+BASECPPFLAGS.append(
+    "-Wno-sign-compare"
+)  # very nasty warning in the world of STL and size_t
 
 # this define is necessary to make sure threading support is enabled in X
-CORECPPFLAGS.append( '-DXTHREADS' )
+CORECPPFLAGS.append("-DXTHREADS")
 # don't wrap gcc messages
-BASECPPFLAGS.append( '-fmessage-length=0' )
+BASECPPFLAGS.append("-fmessage-length=0")
 # C++11 features
-BASECPPFLAGS.append( '-std=c++14' )
+BASECPPFLAGS.append("-std=c++14")
 # maintain this dangerous optimization off at all times
-BASECPPFLAGS.append( '-fno-strict-aliasing' )
-
-if ( g_os == 'Linux' ):
-	# use old ABI for std::string and std::list (which is not fully compliant with C++11 standard)
-	# this allows to run TDM binary on OSes which have old glibcxx (e.g. Ubuntu 14.04 from years 2014-2016)
-	BASECPPFLAGS.append( '-D_GLIBCXX_USE_CXX11_ABI=0' )
-	# gcc 4.x option only - only export what we mean to from the game SO
-	BASECPPFLAGS.append( '-fvisibility=hidden' )
-	# get the 64 bits machine on the distcc array to produce 32 bit binaries :)
-	if ( TARGET_ARCH == 'x86' ):
-		BASECPPFLAGS.append( '-m32' )
-		BASELINKFLAGS.append( '-m32' )
-		BASECPPFLAGS.append( '-msse2' );
-	if ( TARGET_ARCH == 'x64' ):
-		BASECPPFLAGS.append( '-m64' )
-		BASELINKFLAGS.append( '-m64' )
-		# current ffmpeg dep was built without -fPIC, so can't use position-independent code generation
-		BASELINKFLAGS.append( '-no-pie' )
-    
-	if ( OPENMP != '0' ):
-		# openmp support for changes made to the renderer
-		BASECPPFLAGS.append( '-fopenmp' )
-		BASELINKFLAGS.append( '-fopenmp' )
-
-if ( BUILD == 'debug-all' ):
-	OPTCPPFLAGS = [ '-g', '-D_DEBUG' ]
-	if ( ID_MCHECK == '0' ):
-		ID_MCHECK = '1'
-elif ( BUILD == 'debug' ):
-	OPTCPPFLAGS = [ '-g', '-O1', '-D_DEBUG' ]
-	if ( ID_MCHECK == '0' ):
-		ID_MCHECK = '1'
-elif ( BUILD == 'profile' ):
-	# -fprofile-arcs is needed for gcc 3.x and 4.x
-	OPTCPPFLAGS = [ '-pg', '-fprofile-arcs', '-ftest-coverage', '-O1', '-D_DEBUG' ]
-	BASELINKFLAGS.append( '-pg' );
-	BASELINKFLAGS.append( '-fprofile-arcs' );
-	if ( ID_MCHECK == '0' ):
-		ID_MCHECK = '1'
-elif ( BUILD == 'release' ):
-	# -fomit-frame-pointer: not set because if prohibits debugging (which is necessary even on release build)
-	# -finline-functions: implicit at -O3
-	# -fschedule-insns2: implicit at -O2
-	# -fno-unsafe-math-optimizations: that should be on by default really. hit some wonko bugs in physics code because of that
-	OPTCPPFLAGS = [ '-g', '-O3', '-ffast-math', '-fno-unsafe-math-optimizations' ] 
-	if ( ID_MCHECK == '0' ):
-		ID_MCHECK = '2'
+BASECPPFLAGS.append("-fno-strict-aliasing")
+
+if g_os == "Linux":
+    # use old ABI for std::string and std::list (which is not fully compliant with C++11 standard)
+    # this allows to run TDM binary on OSes which have old glibcxx (e.g. Ubuntu 14.04 from years 2014-2016)
+    BASECPPFLAGS.append("-D_GLIBCXX_USE_CXX11_ABI=0")
+    # gcc 4.x option only - only export what we mean to from the game SO
+    BASECPPFLAGS.append("-fvisibility=hidden")
+    # get the 64 bits machine on the distcc array to produce 32 bit binaries :)
+    if TARGET_ARCH == "x86":
+        BASECPPFLAGS.append("-m32")
+        BASELINKFLAGS.append("-m32")
+        BASECPPFLAGS.append("-msse2")
+    if TARGET_ARCH == "x64":
+        BASECPPFLAGS.append("-m64")
+        BASELINKFLAGS.append("-m64")
+        # current ffmpeg dep was built without -fPIC, so can't use position-independent code generation
+        BASELINKFLAGS.append("-no-pie")
+
+    if OPENMP != "0":
+        # openmp support for changes made to the renderer
+        BASECPPFLAGS.append("-fopenmp")
+        BASELINKFLAGS.append("-fopenmp")
+
+if BUILD == "debug-all":
+    OPTCPPFLAGS = ["-g", "-D_DEBUG"]
+    if ID_MCHECK == "0":
+        ID_MCHECK = "1"
+elif BUILD == "debug":
+    OPTCPPFLAGS = ["-g", "-O1", "-D_DEBUG"]
+    if ID_MCHECK == "0":
+        ID_MCHECK = "1"
+elif BUILD == "profile":
+    # -fprofile-arcs is needed for gcc 3.x and 4.x
+    OPTCPPFLAGS = ["-pg", "-fprofile-arcs", "-ftest-coverage", "-O1", "-D_DEBUG"]
+    BASELINKFLAGS.append("-pg")
+    BASELINKFLAGS.append("-fprofile-arcs")
+    if ID_MCHECK == "0":
+        ID_MCHECK = "1"
+elif BUILD == "release":
+    # -fomit-frame-pointer: not set because if prohibits debugging (which is necessary even on release build)
+    # -finline-functions: implicit at -O3
+    # -fschedule-insns2: implicit at -O2
+    # -fno-unsafe-math-optimizations: that should be on by default really. hit some wonko bugs in physics code because of that
+    OPTCPPFLAGS = ["-g", "-O3", "-ffast-math", "-fno-unsafe-math-optimizations"]
+    if ID_MCHECK == "0":
+        ID_MCHECK = "2"
 else:
-	print 'Unknown build configuration ' + BUILD
-	sys.exit(0)
+    print("Unknown build configuration " + BUILD)
+    sys.exit(0)
 
-if ( GL_HARDLINK != '0' ):
-	CORECPPFLAGS.append( '-DID_GL_HARDLINK' )
+if GL_HARDLINK != "0":
+    CORECPPFLAGS.append("-DID_GL_HARDLINK")
 
-if ( DEBUG_MEMORY != '0' ):
-	BASECPPFLAGS += [ '-DID_DEBUG_MEMORY', '-DID_REDIRECT_NEWDELETE' ]
-	
-if ( LIBC_MALLOC != '1' ):
-	BASECPPFLAGS.append( '-DUSE_LIBC_MALLOC=0' )
+if DEBUG_MEMORY != "0":
+    BASECPPFLAGS += ["-DID_DEBUG_MEMORY", "-DID_REDIRECT_NEWDELETE"]
+
+if LIBC_MALLOC != "1":
+    BASECPPFLAGS.append("-DUSE_LIBC_MALLOC=0")
+
+if ID_MCHECK == "1":
+    BASECPPFLAGS.append("-DID_MCHECK")
 
-if ( ID_MCHECK == '1' ):
-	BASECPPFLAGS.append( '-DID_MCHECK' )
-	
 # create the build environements
-g_env_base = Environment( ENV = os.environ, CC = CC, CXX = CXX, LINK = LINK, CPPFLAGS = BASECPPFLAGS, LINKFLAGS = BASELINKFLAGS, CPPPATH = CORECPPPATH, LIBPATH = CORELIBPATH )
-scons_utils.SetupUtils( g_env_base )
-
-g_env_base.Prepend(CPPPATH=['.'])
-path_template = '#/ThirdParty/artefacts/{0}/include'
-g_env_base.Append(CPPPATH = path_template.format('zlib'))
-g_env_base.Append(CPPPATH = path_template.format('libcurl'))
-g_env_base.Append(CPPPATH = path_template.format('openal'))
-g_env_base.Append(CPPPATH = path_template.format('ogg'))
-g_env_base.Append(CPPPATH = path_template.format('vorbis'))
-g_env_base.Append(CPPPATH = path_template.format('devil'))
-g_env_base.Append(CPPPATH = path_template.format('libjpeg'))
-g_env_base.Append(CPPPATH = path_template.format('ffmpeg'))
-g_env_base.Append(CPPPATH = path_template.format('doctest'))
-g_env_base.Append(CPPPATH = path_template.format('pugixml'))
-g_env_base.Append(CPPPATH = '#/renderer')
-g_env_base.Append(CPPPATH = '#/')
-
-g_env_base['CPPFLAGS'] += OPTCPPFLAGS
-g_env_base['CPPFLAGS'] += CORECPPFLAGS
-g_env_base['LINKFLAGS'] += CORELINKFLAGS
-
-
-#if ( int(JOBS) > 1 ):
-#	print 'Using buffered process output'
-#	silent = False
-#	if ( SILENT == '1' ):
-#		silent = True
-#	scons_utils.SetupBufferedOutput( g_env, silent )
-#	scons_utils.SetupBufferedOutput( g_game_env, silent )
+g_env_base = Environment(
+    ENV=os.environ,
+    CC=CC,
+    CXX=CXX,
+    LINK=LINK,
+    CPPFLAGS=BASECPPFLAGS,
+    LINKFLAGS=BASELINKFLAGS,
+    CPPPATH=CORECPPPATH,
+    LIBPATH=CORELIBPATH,
+)
+scons_utils.SetupUtils(g_env_base)
+
+g_env_base.Prepend(CPPPATH=["."])
+path_template = "#/ThirdParty/artefacts/{0}/include"
+g_env_base.Append(CPPPATH=path_template.format("zlib"))
+g_env_base.Append(CPPPATH=path_template.format("libcurl"))
+g_env_base.Append(CPPPATH=path_template.format("openal"))
+g_env_base.Append(CPPPATH=path_template.format("ogg"))
+g_env_base.Append(CPPPATH=path_template.format("vorbis"))
+g_env_base.Append(CPPPATH=path_template.format("devil"))
+g_env_base.Append(CPPPATH=path_template.format("libjpeg"))
+g_env_base.Append(CPPPATH=path_template.format("ffmpeg"))
+g_env_base.Append(CPPPATH=path_template.format("doctest"))
+g_env_base.Append(CPPPATH=path_template.format("pugixml"))
+g_env_base.Append(CPPPATH="#/renderer")
+g_env_base.Append(CPPPATH="#/")
+
+g_env_base["CPPFLAGS"] += OPTCPPFLAGS
+g_env_base["CPPFLAGS"] += CORECPPFLAGS
+g_env_base["LINKFLAGS"] += CORELINKFLAGS
+
+
+# if ( int(JOBS) > 1 ):
+#     print 'Using buffered process output'
+#     silent = False
+#     if ( SILENT == '1' ):
+#         silent = True
+#     scons_utils.SetupBufferedOutput( g_env, silent )
+#     scons_utils.SetupBufferedOutput( g_game_env, silent )
 
 # mark the globals
 
@@ -341,50 +370,50 @@ g_env_base['LINKFLAGS'] += CORELINKFLAGS
 local_curl = 0
 curl_lib = []
 
-GLOBALS = 'g_env_base g_os ID_MCHECK curl_lib local_curl NO_GCH TARGET_ARCH'
+GLOBALS = "g_env_base g_os ID_MCHECK curl_lib local_curl NO_GCH TARGET_ARCH"
 
 # end general configuration ----------------------
 
 # targets ----------------------------------------
 
-Export( 'GLOBALS ' + GLOBALS )
+Export("GLOBALS " + GLOBALS)
 
 thedarkmod = None
 
 # insert SVN revision number into header (requires svnversion)
 # svnversion must be run from SVN root, otherwise revision information may be incomplete
-os.chdir(Dir('#').abspath)
+os.chdir(Dir("#").abspath)
 svnversion_command = r'sed "s/\!SVNVERSION\!/$(svnversion -c)/g" idlib/svnversion_template.h >idlib/svnversion.h'
 if os.system(svnversion_command) != 0:
-	exit()
+    exit()
 print("Inserted SVN revision number into svnversion.h")
 
 
 # build curl if needed
-if ( NOCURL == '0' ):
-	# 1: debug, 2: release
-	if ( BUILD == 'release' ):
-		local_curl = 2
-	else:
-		local_curl = 1
-	Export( 'GLOBALS ' + GLOBALS )
-	if ( TARGET_ARCH == 'x86' ):
-		curl_lib = [ '#linux/libcurl/libcurl.a' ] # Use the static one built for TDM
-	if ( TARGET_ARCH == 'x64' ):
-		curl_lib = [ '#linux/libcurl/lib64/libcurl.a' ]
-
-
-VariantDir( g_build + '/core', '.', duplicate = 0 )
-thedarkmod = SConscript( g_build + '/core/sys/scons/SConscript.darkmod' )
-
-exe_name = 'thedarkmod.' + ('x64' if TARGET_ARCH == 'x64' else cpu)
+if NOCURL == "0":
+    # 1: debug, 2: release
+    if BUILD == "release":
+        local_curl = 2
+    else:
+        local_curl = 1
+    Export("GLOBALS " + GLOBALS)
+    if TARGET_ARCH == "x86":
+        curl_lib = ["#linux/libcurl/libcurl.a"]  # Use the static one built for TDM
+    if TARGET_ARCH == "x64":
+        curl_lib = ["#linux/libcurl/lib64/libcurl.a"]
+
+
+VariantDir(g_build + "/core", ".", duplicate=0)
+thedarkmod = SConscript(g_build + "/core/sys/scons/SConscript.darkmod")
+
+exe_name = "thedarkmod." + ("x64" if TARGET_ARCH == "x64" else cpu)
 # Note: this target only runs if you append ".." (without quotes) as the last argument to scons command line
 # It copies executable into ../darkmod, which is default location of darkmod installation in development environment
-InstallAs( '../darkmod/' + exe_name, thedarkmod )
+InstallAs("../darkmod/" + exe_name, thedarkmod)
 # this runs always and produces TDM binary in local directory
-if ( BUILD == 'release' ):	# strip debug info in release
-	Command(exe_name, thedarkmod, "strip $SOURCE -o $TARGET")
+if BUILD == "release":  # strip debug info in release
+    Command(exe_name, thedarkmod, "strip $SOURCE -o $TARGET")
 else:
-	InstallAs( '#' + exe_name, thedarkmod )
+    InstallAs("#" + exe_name, thedarkmod)
 
 # end targets ------------------------------------
diff --git a/sys/scons/scons_utils.py b/sys/scons/scons_utils.py
index 377562c16..6593f64eb 100644
--- a/sys/scons/scons_utils.py
+++ b/sys/scons/scons_utils.py
@@ -1,189 +1,201 @@
 # -*- mode: python -*-
-import sys, os, string, time, commands, re, pickle, StringIO, popen2, commands, pdb, zipfile, tempfile
+import sys, os, time, subprocess, re, pickle, io, subprocess, pdb, zipfile, tempfile
 import SCons
 
 # need an Environment and a matching buffered_spawn API .. encapsulate
 class idBuffering:
-	silent = False
-
-	def buffered_spawn( self, sh, escape, cmd, args, env ):
-		stderr = StringIO.StringIO()
-		stdout = StringIO.StringIO()
-		command_string = ''
-		for i in args:
-			if ( len( command_string ) ):
-				command_string += ' '
-			command_string += i
-		try:
-			retval = self.env['PSPAWN']( sh, escape, cmd, args, env, stdout, stderr )
-		except OSError, x:
-			if x.errno != 10:
-				raise x
-			print 'OSError ignored on command: %s' % command_string
-			retval = 0
-		print command_string
-		if ( retval != 0 or not self.silent ):
-			sys.stdout.write( stdout.getvalue() )
-			sys.stderr.write( stderr.getvalue() )
-		return retval		
+    silent = False
+
+    def buffered_spawn(self, sh, escape, cmd, args, env):
+        stderr = io.StringIO()
+        stdout = io.StringIO()
+        command_string = ""
+        for i in args:
+            if len(command_string):
+                command_string += " "
+            command_string += i
+        try:
+            retval = self.env["PSPAWN"](sh, escape, cmd, args, env, stdout, stderr)
+        except OSError as x:
+            if x.errno != 10:
+                raise x
+            print("OSError ignored on command: %s" % command_string)
+            retval = 0
+        print(command_string)
+        if retval != 0 or not self.silent:
+            sys.stdout.write(stdout.getvalue())
+            sys.stderr.write(stderr.getvalue())
+        return retval
+
 
 class idSetupBase:
-	
-	def SimpleCommand( self, cmd ):
-		print cmd
-		ret = commands.getstatusoutput( cmd )
-		if ( len( ret[ 1 ] ) ):
-			sys.stdout.write( ret[ 1 ] )
-			sys.stdout.write( '\n' )
-		if ( ret[ 0 ] != 0 ):
-			raise 'command failed'
-		return ret[ 1 ]
-
-	def TrySimpleCommand( self, cmd ):
-		print cmd
-		ret = commands.getstatusoutput( cmd )
-		sys.stdout.write( ret[ 1 ] )
-
-	def M4Processing( self, file, d ):
-		file_out = file[:-3]
-		cmd = 'm4 '
-		for ( key, val ) in d.items():
-			cmd += '--define=%s="%s" ' % ( key, val )
-		cmd += '%s > %s' % ( file, file_out )
-		self.SimpleCommand( cmd )	
-
-	def ExtractProtocolVersion( self ):
-		f = open( 'framework/Licensee.h' )
-		l = f.readlines()
-		f.close()
-
-		major = 'X'
-		p = re.compile( '^#define ASYNC_PROTOCOL_MAJOR\t*(.*)' )
-		for i in l:
-			if ( p.match( i ) ):
-				major = p.match( i ).group(1)
-				break
-
-		f = open( 'framework/async/AsyncNetwork.h' )
-		l = f.readlines()
-		f.close()
-
-		minor = 'X'
-		p = re.compile( '^const int ASYNC_PROTOCOL_MINOR\t*= (.*);' )
-		for i in l:
-			if ( p.match( i ) ):
-				minor = p.match( i ).group(1)
-				break	
-	
-		return '%s.%s' % ( major, minor )
-
-	def ExtractEngineVersion( self ):
-		f = open( 'framework/Licensee.h' )
-		l = f.readlines()
-		f.close()
-
-		version = 'X'
-		p = re.compile( '^#define.*ENGINE_VERSION\t*"DOOM (.*)"' )
-		for i in l:
-			if ( p.match( i ) ):
-				version = p.match( i ).group(1)
-				break
-	
-		return version
-
-	def ExtractBuildVersion( self ):
-		f = open( 'framework/BuildVersion.h' )
-		l = f.readlines()[ 4 ]
-		f.close()
-		pat = re.compile( '.* = (.*);\n' )
-		return pat.split( l )[ 1 ]
-
-def checkLDD( target, source, env ):
-	file = target[0]
-	if (not os.path.isfile(file.abspath)):
-		print('ERROR: CheckLDD: target %s not found\n' % target[0])
-		Exit(1)
-	( status, output ) = commands.getstatusoutput( 'ldd -r %s' % file )
-	if ( status != 0 ):
-		print 'ERROR: ldd command returned with exit code %d' % ldd_ret
-		os.system( 'rm %s' % target[ 0 ] )
-		sys.exit(1)
-	lines = string.split( output, '\n' )
-	have_undef = 0
-	for i_line in lines:
-		#print repr(i_line)
-		regex = re.compile('undefined symbol: (.*)\t\\((.*)\\)')
-		if ( regex.match(i_line) ):
-			symbol = regex.sub('\\1', i_line)
-			try:
-				env['ALLOWED_SYMBOLS'].index(symbol)
-			except:
-				have_undef = 1
-	if ( have_undef ):
-		print output
-		print "ERROR: undefined symbols"
-		os.system('rm %s' % target[0])
-		sys.exit(1)
-
-def SharedLibrarySafe( env, target, source ):
-	ret = env.SharedLibrary( target, source )
-	env.AddPostAction( ret, checkLDD )
-	return ret
-
-def NotImplementedStub( *whatever ):
-	print 'Not Implemented'
-	sys.exit( 1 )
+    def SimpleCommand(self, cmd):
+        print(cmd)
+        ret = subprocess.getstatusoutput(cmd)
+        if len(ret[1]):
+            sys.stdout.write(ret[1])
+            sys.stdout.write("\n")
+        if ret[0] != 0:
+            raise RuntimeError("command failed")
+        return ret[1]
+
+    def TrySimpleCommand(self, cmd):
+        print(cmd)
+        ret = subprocess.getstatusoutput(cmd)
+        sys.stdout.write(ret[1])
+
+    def M4Processing(self, file, d):
+        file_out = file[:-3]
+        cmd = "m4 "
+        for (key, val) in list(d.items()):
+            cmd += '--define=%s="%s" ' % (key, val)
+        cmd += "%s > %s" % (file, file_out)
+        self.SimpleCommand(cmd)
+
+    def ExtractProtocolVersion(self):
+        f = open("framework/Licensee.h")
+        l = f.readlines()
+        f.close()
+
+        major = "X"
+        p = re.compile("^#define ASYNC_PROTOCOL_MAJOR\t*(.*)")
+        for i in l:
+            if p.match(i):
+                major = p.match(i).group(1)
+                break
+
+        f = open("framework/async/AsyncNetwork.h")
+        l = f.readlines()
+        f.close()
+
+        minor = "X"
+        p = re.compile("^const int ASYNC_PROTOCOL_MINOR\t*= (.*);")
+        for i in l:
+            if p.match(i):
+                minor = p.match(i).group(1)
+                break
+
+        return "%s.%s" % (major, minor)
+
+    def ExtractEngineVersion(self):
+        f = open("framework/Licensee.h")
+        l = f.readlines()
+        f.close()
+
+        version = "X"
+        p = re.compile('^#define.*ENGINE_VERSION\t*"DOOM (.*)"')
+        for i in l:
+            if p.match(i):
+                version = p.match(i).group(1)
+                break
+
+        return version
+
+    def ExtractBuildVersion(self):
+        f = open("framework/BuildVersion.h")
+        l = f.readlines()[4]
+        f.close()
+        pat = re.compile(".* = (.*);\n")
+        return pat.split(l)[1]
+
+
+def checkLDD(target, source, env):
+    file = target[0]
+    if not os.path.isfile(file.abspath):
+        print(("ERROR: CheckLDD: target %s not found\n" % target[0]))
+        Exit(1)
+    (status, output) = subprocess.getstatusoutput("ldd -r %s" % file)
+    if status != 0:
+        print("ERROR: ldd command returned with exit code %d" % ldd_ret)
+        os.system("rm %s" % target[0])
+        sys.exit(1)
+    lines = output.split("\n")
+    have_undef = 0
+    for i_line in lines:
+        # print repr(i_line)
+        regex = re.compile("undefined symbol: (.*)\t\\((.*)\\)")
+        if regex.match(i_line):
+            symbol = regex.sub("\\1", i_line)
+            try:
+                env["ALLOWED_SYMBOLS"].index(symbol)
+            except:
+                have_undef = 1
+    if have_undef:
+        print(output)
+        print("ERROR: undefined symbols")
+        os.system("rm %s" % target[0])
+        sys.exit(1)
+
+
+def SharedLibrarySafe(env, target, source):
+    ret = env.SharedLibrary(target, source)
+    env.AddPostAction(ret, checkLDD)
+    return ret
+
+
+def NotImplementedStub(*whatever):
+    print("Not Implemented")
+    sys.exit(1)
+
 
 # --------------------------------------------------------------------
 
-class idGamePaks( idSetupBase ):
-
-	def BuildGamePak( self, target = None, source = None, env = None ):
-		# NOTE: ew should have done with zipfile module
-		temp_dir = tempfile.mkdtemp( prefix = 'gamepak' )
-		# source[0] is the binary path of the game DLL
-		# source[2] is the DLL name 'gamex64.so'
-		dllName = source[2].name
-		self.SimpleCommand( 'cp %s %s' % ( source[0].abspath, os.path.join( temp_dir, dllName ) ) )
-		self.SimpleCommand( 'strip %s' % os.path.join( temp_dir, dllName ) )
-		self.SimpleCommand( 'echo 2 > %s' % ( os.path.join( temp_dir, 'binary.conf' ) ) )
-		self.SimpleCommand( 'cd %s ; zip %s %s binary.conf' % ( temp_dir, os.path.join( temp_dir, target[0].abspath ), dllName ) )
-		self.SimpleCommand( 'rm -r %s' % temp_dir )
-		return None
+
+class idGamePaks(idSetupBase):
+    def BuildGamePak(self, target=None, source=None, env=None):
+        # NOTE: ew should have done with zipfile module
+        temp_dir = tempfile.mkdtemp(prefix="gamepak")
+        # source[0] is the binary path of the game DLL
+        # source[2] is the DLL name 'gamex64.so'
+        dllName = source[2].name
+        self.SimpleCommand(
+            "cp %s %s" % (source[0].abspath, os.path.join(temp_dir, dllName))
+        )
+        self.SimpleCommand("strip %s" % os.path.join(temp_dir, dllName))
+        self.SimpleCommand("echo 2 > %s" % (os.path.join(temp_dir, "binary.conf")))
+        self.SimpleCommand(
+            "cd %s ; zip %s %s binary.conf"
+            % (temp_dir, os.path.join(temp_dir, target[0].abspath), dllName)
+        )
+        self.SimpleCommand("rm -r %s" % temp_dir)
+        return None
+
 
 # --------------------------------------------------------------------
 
 # get a clean error output when running multiple jobs
-def SetupBufferedOutput( env, silent ):
-	buf = idBuffering()
-	buf.silent = silent
-	buf.env = env
-	env['SPAWN'] = buf.buffered_spawn
+def SetupBufferedOutput(env, silent):
+    buf = idBuffering()
+    buf.silent = silent
+    buf.env = env
+    env["SPAWN"] = buf.buffered_spawn
+
 
 # setup utilities on an environement
-def SetupUtils( env ):
-	gamepaks = idGamePaks()
-	env.BuildGamePak = gamepaks.BuildGamePak
-	env.SharedLibrarySafe = SharedLibrarySafe
-	# no longer used by TDM
-	env.PreBuildSDK = NotImplementedStub
-	env.BuildSDK = NotImplementedStub
-	env.BuildSetup = NotImplementedStub
-
-def BuildList( s_prefix, s_string ):
-	s_list = string.split( s_string )
-	for i in range( len( s_list ) ):
-		s_list[i] = os.path.join(s_prefix, s_list[i])
-	return s_list
+def SetupUtils(env):
+    gamepaks = idGamePaks()
+    env.BuildGamePak = gamepaks.BuildGamePak
+    env.SharedLibrarySafe = SharedLibrarySafe
+    # no longer used by TDM
+    env.PreBuildSDK = NotImplementedStub
+    env.BuildSDK = NotImplementedStub
+    env.BuildSetup = NotImplementedStub
 
-def CloneWithoutOptimization(env, opt_level):
-	res = env.Clone()
-	try:
-		res['CPPFLAGS'].remove('-O3')
-	except:
-		print('Error: -O3 not found in CPPFLAGS, optimization not suppressed.')
-		pass
-	if opt_level is not None:
-		res.Append(CPPFLAGS = opt_level)
-	return res
 
+def BuildList(s_prefix, s_string):
+    s_list = s_string.split()
+    for i in range(len(s_list)):
+        s_list[i] = os.path.join(s_prefix, s_list[i])
+    return s_list
+
+
+def CloneWithoutOptimization(env, opt_level):
+    res = env.Clone()
+    try:
+        res["CPPFLAGS"].remove("-O3")
+    except:
+        print("Error: -O3 not found in CPPFLAGS, optimization not suppressed.")
+        pass
+    if opt_level is not None:
+        res.Append(CPPFLAGS=opt_level)
+    return res
diff --git a/tdm_update/SConstruct b/tdm_update/SConstruct
index 6d12703e2..119bc3c7c 100644
--- a/tdm_update/SConstruct
+++ b/tdm_update/SConstruct
@@ -1,32 +1,32 @@
 # -*- mode: python -*-
 # coding=utf-8
 
-#*****************************************************************************
+# *****************************************************************************
 #                    The Dark Mod GPL Source Code
-# 
-# This file is part of the The Dark Mod Source Code, originally based 
+#
+# This file is part of the The Dark Mod Source Code, originally based
 # on the Doom 3 GPL Source Code as published in 2011.
-# 
-# The Dark Mod Source Code is free software: you can redistribute it 
-# and/or modify it under the terms of the GNU General Public License as 
-# published by the Free Software Foundation, either version 3 of the License, 
+#
+# The Dark Mod Source Code is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation, either version 3 of the License,
 # or (at your option) any later version. For details, see LICENSE.TXT.
-# 
+#
 # Project: The Dark Mod Updater & Packager (http://www.thedarkmod.com/)
-# 
-#*****************************************************************************
+#
+# *****************************************************************************
 
 # The Dark Mod Updater & Packager build script for Linux
 # Based on id's game sconscript
 # Author: greebo
 
-import sys, os, time, commands, re, pickle, StringIO, commands, pdb, string
+import sys, os, time, subprocess, re, pickle, io, subprocess, pdb, string
 import SCons
 import scons_utils
 
 # choose configuration variables which should be saved between runs
 # ( we handle all those as strings )
-serialized=['CC', 'CXX', 'JOBS', 'BUILD', 'TARGET_ARCH']
+serialized = ["CC", "CXX", "JOBS", "BUILD", "TARGET_ARCH"]
 
 # global build mode ------------------------------
 
@@ -59,199 +59,211 @@ TARGET_ARCH (default: "x86")
 
 """
 
-Help( help_string )
+Help(help_string)
 
 # end help ---------------------------------------
 
 # sanity -----------------------------------------
 
-EnsureSConsVersion( 0, 98 )
+EnsureSConsVersion(0, 98)
 
 # end sanity -------------------------------------
 
 # system detection -------------------------------
 
 # CPU type
-cpu = commands.getoutput('uname -m')
-exp = re.compile('.*i?86.*')
+cpu = subprocess.getoutput("uname -m")
+exp = re.compile(".*i?86.*")
 if exp.match(cpu):
-	cpu = 'x86'
+    cpu = "x86"
 else:
-	cpu = commands.getoutput('uname -p')
-	if ( cpu == 'powerpc' ):
-		cpu = 'ppc'
-	elif ( cpu == 'amd64' ):
-		# leave as is
-		pass
-	else:
-		cpu = 'cpu'
-
-if sys.platform == 'darwin':
-	g_os = 'MacOSX'
-elif sys.platform == 'freebsd10':
-	# taaaki: only tested on FreeBSD 10 so far
-	g_os = 'FreeBSD'
+    cpu = subprocess.getoutput("uname -p")
+    if cpu == "powerpc":
+        cpu = "ppc"
+    elif cpu == "amd64":
+        # leave as is
+        pass
+    else:
+        cpu = "cpu"
+
+if sys.platform == "darwin":
+    g_os = "MacOSX"
+elif sys.platform == "freebsd10":
+    # taaaki: only tested on FreeBSD 10 so far
+    g_os = "FreeBSD"
 else:
-	g_os = 'Linux'
+    g_os = "Linux"
 
 # end system detection ---------------------------
 
 # default settings -------------------------------
 
-CC = 'gcc'
-CXX = 'g++'
-if g_os == 'FreeBSD':
-	# FreeBSD 10 uses Clang instead of GCC
-	CC = 'cc'
-	CXX = 'c++'
-JOBS = '1'
-BUILD = 'release'
-BASEFLAGS = ''
-TARGET_ARCH = 'x86'
+CC = "gcc"
+CXX = "g++"
+if g_os == "FreeBSD":
+    # FreeBSD 10 uses Clang instead of GCC
+    CC = "cc"
+    CXX = "c++"
+JOBS = "1"
+BUILD = "release"
+BASEFLAGS = ""
+TARGET_ARCH = "x86"
 
 # end default settings ---------------------------
 
 # command line settings --------------------------
 
-for k in ARGUMENTS.keys():
-	exec_cmd = k + '=\'' + ARGUMENTS[k] + '\''
-	print 'Command line: ' + exec_cmd
-	exec( exec_cmd )
+for k in list(ARGUMENTS.keys()):
+    exec_cmd = k + "='" + ARGUMENTS[k] + "'"
+    print("Command line: " + exec_cmd)
+    exec(exec_cmd)
 
-if TARGET_ARCH == 'x32':
-	TARGET_ARCH = 'x86'
+if TARGET_ARCH == "x32":
+    TARGET_ARCH = "x86"
 
 # end command line settings ----------------------
 
 # general configuration, target selection --------
 
-BUILD_ROOT = 'build'
-g_build = BUILD_ROOT + '/scons_' + TARGET_ARCH + '/' + BUILD
+BUILD_ROOT = "build"
+g_build = BUILD_ROOT + "/scons_" + TARGET_ARCH + "/" + BUILD
 
-SConsignFile( 'scons.signatures' )
-Decider('MD5-timestamp')
+SConsignFile("scons.signatures")
+Decider("MD5-timestamp")
 
-SetOption('num_jobs', JOBS)
+SetOption("num_jobs", JOBS)
 
 LINK = CXX
 
 # common flags
-BASECPPFLAGS = [ ]
-CORECPPPATH = [ ]
-CORELIBPATH = [ ]
-CORECPPFLAGS = [ ]
-BASELINKFLAGS = [ ]
+BASECPPFLAGS = []
+CORECPPPATH = []
+CORELIBPATH = []
+CORECPPFLAGS = []
+BASELINKFLAGS = []
 
 # for release build, further optimisations that may not work on all files
-OPTCPPFLAGS = [ ]
+OPTCPPFLAGS = []
 
-BASECPPFLAGS.append( BASEFLAGS )
-BASECPPFLAGS.append( '-pipe' )
+BASECPPFLAGS.append(BASEFLAGS)
+BASECPPFLAGS.append("-pipe")
 # warn all
-BASECPPFLAGS.append( '-Wall' )
+BASECPPFLAGS.append("-Wall")
 # Use C++11 features
-BASECPPFLAGS.append( '-std=c++11' )
-if ( g_os == 'Linux' ):
-	# Use old ABI for std::string and std::list (which is not fully compliant with C++11)
-	# This allows to link with C++ libraries, which were built in older versions of GCC
-	BASECPPFLAGS.append( '-D_GLIBCXX_USE_CXX11_ABI=0' )
+BASECPPFLAGS.append("-std=c++11")
+if g_os == "Linux":
+    # Use old ABI for std::string and std::list (which is not fully compliant with C++11)
+    # This allows to link with C++ libraries, which were built in older versions of GCC
+    BASECPPFLAGS.append("-D_GLIBCXX_USE_CXX11_ABI=0")
 
 # Don't throw warnings for unknown pragmas (used by VC++)
-BASECPPFLAGS.append('-Wno-unknown-pragmas')
+BASECPPFLAGS.append("-Wno-unknown-pragmas")
 
 # this define is necessary to make sure threading support is enabled in X
-CORECPPFLAGS.append( '-DXTHREADS' )
+CORECPPFLAGS.append("-DXTHREADS")
 
 # don't wrap gcc messages
-BASECPPFLAGS.append( '-fmessage-length=0' )
-
-if ( TARGET_ARCH == 'x86' ):
-	BASECPPFLAGS.append( '-m32' )
-	BASELINKFLAGS.append( '-m32' )
-if ( TARGET_ARCH == 'x64' ):
-	BASECPPFLAGS.append( '-m64' )
-	BASELINKFLAGS.append( '-m64' )
-
-if g_os == 'Linux':
-	BASELINKFLAGS.append( '-pthread' )
-	BASELINKFLAGS.append( '-lrt' )
-	# Add the __linux__ define
-	BASECPPFLAGS.append('-D__linux__')
-elif g_os == 'FreeBSD':
-	# FreeBSD 10
-	BASELINKFLAGS.append( '-L/usr/local/lib' )
-	BASELINKFLAGS.append( '-pthread' )
-	BASELINKFLAGS.append( '-lrt' )
- 	# Add the __linux__ define - leave as is even though it isn't true
-	BASECPPFLAGS.append('-D__linux__')
-elif g_os == 'MacOSX':
-	# Mac OS X
-	BASECPPFLAGS.append('-DMACOS_X')
-	if TARGET_ARCH == 'x86':
-		# Perform an Intel build
-		BASECPPFLAGS.append(['-arch', 'i386', '-D__i386__'])
-		BASELINKFLAGS.append(['-arch', 'i386'])
-	elif TARGET_ARCH == 'ppc':
-		# Perform a PowerPC build
-		BASECPPFLAGS.append(['-arch', 'ppc', '-D__ppc__'])
-		BASELINKFLAGS.append(['-arch', 'ppc'])
-
-if ( BUILD == 'debug' ):
-	OPTCPPFLAGS = [ '-g', '-O1', '-D_DEBUG' ]
-elif ( BUILD == 'release' ):
-	OPTCPPFLAGS = [ '-O2' ]
+BASECPPFLAGS.append("-fmessage-length=0")
+
+if TARGET_ARCH == "x86":
+    BASECPPFLAGS.append("-m32")
+    BASELINKFLAGS.append("-m32")
+if TARGET_ARCH == "x64":
+    BASECPPFLAGS.append("-m64")
+    BASELINKFLAGS.append("-m64")
+
+if g_os == "Linux":
+    BASELINKFLAGS.append("-pthread")
+    BASELINKFLAGS.append("-lrt")
+    # Add the __linux__ define
+    BASECPPFLAGS.append("-D__linux__")
+elif g_os == "FreeBSD":
+    # FreeBSD 10
+    BASELINKFLAGS.append("-L/usr/local/lib")
+    BASELINKFLAGS.append("-pthread")
+    BASELINKFLAGS.append("-lrt")
+    # Add the __linux__ define - leave as is even though it isn't true
+    BASECPPFLAGS.append("-D__linux__")
+elif g_os == "MacOSX":
+    # Mac OS X
+    BASECPPFLAGS.append("-DMACOS_X")
+    if TARGET_ARCH == "x86":
+        # Perform an Intel build
+        BASECPPFLAGS.append(["-arch", "i386", "-D__i386__"])
+        BASELINKFLAGS.append(["-arch", "i386"])
+    elif TARGET_ARCH == "ppc":
+        # Perform a PowerPC build
+        BASECPPFLAGS.append(["-arch", "ppc", "-D__ppc__"])
+        BASELINKFLAGS.append(["-arch", "ppc"])
+
+if BUILD == "debug":
+    OPTCPPFLAGS = ["-g", "-O1", "-D_DEBUG"]
+elif BUILD == "release":
+    OPTCPPFLAGS = ["-O2"]
 else:
-	print 'Unknown build configuration ' + BUILD
-	sys.exit(0)
+    print("Unknown build configuration " + BUILD)
+    sys.exit(0)
 
 # create the build environements
-g_base_env = Environment( ENV = os.environ, CC = CC, CXX = CXX, LINK = LINK, CPPFLAGS = BASECPPFLAGS, LINKFLAGS = BASELINKFLAGS, CPPPATH = CORECPPPATH, LIBPATH = CORELIBPATH )
+g_base_env = Environment(
+    ENV=os.environ,
+    CC=CC,
+    CXX=CXX,
+    LINK=LINK,
+    CPPFLAGS=BASECPPFLAGS,
+    LINKFLAGS=BASELINKFLAGS,
+    CPPPATH=CORECPPPATH,
+    LIBPATH=CORELIBPATH,
+)
 
 # use includes from fbsd userland before darkmod includes
 # note: used only on TDM server
-if g_os == 'FreeBSD':
-	g_base_env.Append(CPPPATH = '/usr/local/include')
+if g_os == "FreeBSD":
+    g_base_env.Append(CPPPATH="/usr/local/include")
 
-g_base_env.Append(CPPPATH = '#/')
-path_template = '#/../ThirdParty/artefacts/{0}/include'
-g_base_env.Append(CPPPATH = path_template.format('zlib'))
-g_base_env.Append(CPPPATH = path_template.format('libcurl'))
-g_base_env.Append(CPPPATH = path_template.format('tinyformat'))
-g_base_env.Append(CPPPATH = '#/libtdm_update')
+g_base_env.Append(CPPPATH="#/")
+path_template = "#/../ThirdParty/artefacts/{0}/include"
+g_base_env.Append(CPPPATH=path_template.format("zlib"))
+g_base_env.Append(CPPPATH=path_template.format("libcurl"))
+g_base_env.Append(CPPPATH=path_template.format("tinyformat"))
+g_base_env.Append(CPPPATH="#/libtdm_update")
 
 g_env = g_base_env.Clone()
 
-g_env['CPPFLAGS'] += OPTCPPFLAGS
-g_env.Append( CPPFLAGS = '-fno-strict-aliasing' )
-g_env['CPPFLAGS'] += CORECPPFLAGS
+g_env["CPPFLAGS"] += OPTCPPFLAGS
+g_env.Append(CPPFLAGS="-fno-strict-aliasing")
+g_env["CPPFLAGS"] += CORECPPFLAGS
 
 # mark the globals
-GLOBALS = 'g_env g_os TARGET_ARCH libtdm_update_list'
+GLOBALS = "g_env g_os TARGET_ARCH libtdm_update_list"
 
 # end general configuration ----------------------
 
 # targets ----------------------------------------
 
 libtdm_update_list = None
-Export( 'GLOBALS ' + GLOBALS )
+Export("GLOBALS " + GLOBALS)
 
 # map this whole directory into build dir
-VariantDir( g_build, '.', duplicate = 0 )
+VariantDir(g_build, ".", duplicate=0)
 # map 'ThirdParty' dir from parent directory into 'ThirdParty' subdir
-VariantDir( g_build + '/ThirdParty', '../ThirdParty', duplicate = 0 )
-Export( 'GLOBALS ' + GLOBALS )
+VariantDir(g_build + "/ThirdParty", "../ThirdParty", duplicate=0)
+Export("GLOBALS " + GLOBALS)
 
 # build libraries
-libtdm_update_list = SConscript( g_build + '/SConscript.libtdm_update' )
-Export( 'GLOBALS ' + GLOBALS )
+libtdm_update_list = SConscript(g_build + "/SConscript.libtdm_update")
+Export("GLOBALS " + GLOBALS)
 
 # Build the updater
-tdm_update = SConscript(g_build + '/SConscript.tdm_update')
-InstallAs( '#' + scons_utils.ExecutableName('bin/tdm_update', g_os, TARGET_ARCH), tdm_update )
+tdm_update = SConscript(g_build + "/SConscript.tdm_update")
+InstallAs(
+    "#" + scons_utils.ExecutableName("bin/tdm_update", g_os, TARGET_ARCH), tdm_update
+)
 
 # Build the packager
-tdm_package = SConscript(g_build + '/SConscript.tdm_package')
-InstallAs( '#' + scons_utils.ExecutableName('bin/tdm_package', g_os, TARGET_ARCH), tdm_package )
+tdm_package = SConscript(g_build + "/SConscript.tdm_package")
+InstallAs(
+    "#" + scons_utils.ExecutableName("bin/tdm_package", g_os, TARGET_ARCH), tdm_package
+)
 
 # end targets ------------------------------------
-
diff --git a/tdm_update/scons_utils.py b/tdm_update/scons_utils.py
index b61bbc22f..1f144fce8 100644
--- a/tdm_update/scons_utils.py
+++ b/tdm_update/scons_utils.py
@@ -1,19 +1,20 @@
-import sys, os, string
+import sys, os
 
 def BuildList( s_prefix, s_string ):
-	s_list = string.split( s_string )
-	for i in range( len( s_list ) ):
-		s_list[i] = os.path.join(s_prefix, s_list[i])
-	return s_list
+    s_list = s_string.split()
+    for i in range( len( s_list ) ):
+        s_list[i] = os.path.join(s_prefix, s_list[i])
+    return s_list
+
 
 def ExecutableName(base_name, os, arch):
-	if os == 'Linux':
-		if arch == 'x86':
-			return base_name + '.linux'
-		elif arch == 'x64':
-			return base_name + '.linux64'
-	elif os == 'FreeBSD':
-		return base_name + '.fbsd'
-	elif os == 'MacOSX':
-		return base_name + '.macosx'
-	return base_name
+    if os == "Linux":
+        if arch == "x86":
+            return base_name + ".linux"
+        elif arch == "x64":
+            return base_name + ".linux64"
+    elif os == "FreeBSD":
+        return base_name + ".fbsd"
+    elif os == "MacOSX":
+        return base_name + ".macosx"
+    return base_name
fix-scons-python2-001.patch (43,655 bytes)   

Relationships

duplicate of 0005234 closedstgatilov compilation: scons configuration and documentation 

Activities

t405

t405

30.04.2020 15:29

reporter   ~0012435

I just noticed this is a darkmod issue, not darkradiant. Put it in the wrong project. I will copy it over now.
t405

t405

30.04.2020 15:39

reporter   ~0012437

I filed this for the wrong project, please close as duplicate of https://bugs.thedarkmod.com/view.php?id=5234

Issue History

Date Modified Username Field Change
30.04.2020 14:49 t405 New Issue
30.04.2020 14:49 t405 File Added: fix-scons-python2-001.patch
30.04.2020 15:29 t405 Note Added: 0012435
30.04.2020 15:39 t405 Note Added: 0012437
30.04.2020 17:47 greebo Project DarkRadiant => The Dark Mod
30.04.2020 17:47 greebo Category Compilation/Build => General
30.04.2020 17:48 greebo Relationship added duplicate of 0005234
02.01.2023 16:10 nbohr1more Assigned To => stgatilov
02.01.2023 16:10 nbohr1more Status new => closed
02.01.2023 16:10 nbohr1more Resolution open => duplicate
02.01.2023 16:10 nbohr1more Category General => Coding
02.01.2023 16:10 nbohr1more Fixed in Version => TDM 2.10