2017-06-30 19:21:38 +02:00
import methods
2015-10-01 21:25:36 +02:00
import os
2015-11-08 23:53:58 +01:00
import sys
2015-10-01 21:25:36 +02:00
2016-10-30 19:05:14 +01:00
2015-10-01 21:25:36 +02:00
def is_active ( ) :
2016-10-30 18:44:57 +01:00
return True
2016-04-02 20:26:12 +02:00
2016-10-30 19:05:14 +01:00
2015-10-01 21:25:36 +02:00
def get_name ( ) :
2016-10-30 18:44:57 +01:00
return " Windows "
2015-10-01 21:25:36 +02:00
2016-10-30 19:05:14 +01:00
2015-10-01 21:25:36 +02:00
def can_build ( ) :
2016-04-02 20:26:12 +02:00
2016-10-30 18:57:40 +01:00
if ( os . name == " nt " ) :
2017-08-18 21:45:52 +02:00
# Building natively on Windows
if ( os . getenv ( " VCINSTALLDIR " ) ) : # MSVC
2016-10-30 18:44:57 +01:00
return True
2017-08-18 21:45:52 +02:00
print ( " MSVC not detected (no VCINSTALLDIR environment variable), attempting MinGW. " )
mingw32 = " "
mingw64 = " "
if ( os . getenv ( " MINGW32_PREFIX " ) ) :
mingw32 = os . getenv ( " MINGW32_PREFIX " )
if ( os . getenv ( " MINGW64_PREFIX " ) ) :
mingw64 = os . getenv ( " MINGW64_PREFIX " )
test = " gcc --version > NUL 2>&1 "
if ( os . system ( test ) == 0 or os . system ( mingw32 + test ) == 0 or os . system ( mingw64 + test ) == 0 ) :
2016-10-30 18:44:57 +01:00
return True
2016-10-30 18:57:40 +01:00
if ( os . name == " posix " ) :
2017-08-18 21:45:52 +02:00
# Cross-compiling with MinGW-w64 (old MinGW32 is not supported)
2016-10-30 18:44:57 +01:00
mingw32 = " i686-w64-mingw32- "
2017-08-18 21:45:52 +02:00
mingw64 = " x86_64-w64-mingw32- "
2016-10-30 18:44:57 +01:00
if ( os . getenv ( " MINGW32_PREFIX " ) ) :
2016-10-30 18:57:40 +01:00
mingw32 = os . getenv ( " MINGW32_PREFIX " )
2016-10-30 18:44:57 +01:00
if ( os . getenv ( " MINGW64_PREFIX " ) ) :
2016-10-30 18:57:40 +01:00
mingw64 = os . getenv ( " MINGW64_PREFIX " )
2016-10-30 18:44:57 +01:00
2017-07-25 20:44:16 +02:00
test = " gcc --version > /dev/null 2>&1 "
2017-08-18 21:45:52 +02:00
if ( os . system ( mingw64 + test ) == 0 or os . system ( mingw32 + test ) == 0 ) :
2016-10-30 18:44:57 +01:00
return True
return False
2016-04-02 20:26:12 +02:00
2016-10-30 19:05:14 +01:00
2015-10-01 21:25:36 +02:00
def get_opts ( ) :
2017-09-25 06:37:17 +02:00
from SCons . Variables import BoolVariable , EnumVariable
2015-10-01 21:25:36 +02:00
2016-10-30 18:57:40 +01:00
mingw32 = " "
mingw64 = " "
if ( os . name == " posix " ) :
2016-10-30 18:44:57 +01:00
mingw32 = " i686-w64-mingw32- "
mingw64 = " x86_64-w64-mingw32- "
2016-04-02 20:26:12 +02:00
2016-10-30 18:44:57 +01:00
if ( os . getenv ( " MINGW32_PREFIX " ) ) :
2016-10-30 18:57:40 +01:00
mingw32 = os . getenv ( " MINGW32_PREFIX " )
2016-10-30 18:44:57 +01:00
if ( os . getenv ( " MINGW64_PREFIX " ) ) :
2016-10-30 18:57:40 +01:00
mingw64 = os . getenv ( " MINGW64_PREFIX " )
2015-10-01 21:25:36 +02:00
2016-10-30 18:44:57 +01:00
return [
2017-08-18 21:45:52 +02:00
( ' mingw_prefix_32 ' , ' MinGW prefix (Win32) ' , mingw32 ) ,
( ' mingw_prefix_64 ' , ' MinGW prefix (Win64) ' , mingw64 ) ,
2017-12-01 21:15:56 +01:00
# Targeted Windows version: 7 (and later), minimum supported version
# XP support dropped after EOL due to missing API for IPv6 and other issues
# Vista support dropped after EOL due to GH-10243
( ' target_win_version ' , ' Targeted Windows version, >= 0x0601 (Windows 7) ' , ' 0x0601 ' ) ,
2017-09-25 05:06:45 +02:00
EnumVariable ( ' debug_symbols ' , ' Add debug symbols to release version ' , ' yes ' , ( ' yes ' , ' no ' , ' full ' ) ) ,
2018-01-26 20:46:56 +01:00
BoolVariable ( ' separate_debug_symbols ' , ' Create a separate file with the debug symbols ' , False ) ,
2016-10-30 18:44:57 +01:00
]
2016-04-02 20:26:12 +02:00
2016-10-30 19:05:14 +01:00
2015-10-01 21:25:36 +02:00
def get_flags ( ) :
2016-10-30 18:44:57 +01:00
return [
]
2016-04-02 20:26:12 +02:00
2016-10-30 19:05:14 +01:00
2016-10-30 18:57:40 +01:00
def build_res_file ( target , source , env ) :
2015-10-01 21:25:36 +02:00
2016-10-30 18:44:57 +01:00
if ( env [ " bits " ] == " 32 " ) :
2017-08-18 21:45:52 +02:00
cmdbase = env [ ' mingw_prefix_32 ' ]
2016-10-30 18:44:57 +01:00
else :
cmdbase = env [ ' mingw_prefix_64 ' ]
cmdbase = cmdbase + ' windres --include-dir . '
import subprocess
for x in range ( len ( source ) ) :
cmd = cmdbase + ' -i ' + str ( source [ x ] ) + ' -o ' + str ( target [ x ] )
try :
2016-10-30 18:57:40 +01:00
out = subprocess . Popen ( cmd , shell = True , stderr = subprocess . PIPE ) . communicate ( )
2016-10-30 18:44:57 +01:00
if len ( out [ 1 ] ) :
return 1
except :
return 1
return 0
2015-10-01 21:25:36 +02:00
2016-10-30 19:05:14 +01:00
2015-10-01 21:25:36 +02:00
def configure ( env ) :
2016-10-30 18:44:57 +01:00
env . Append ( CPPPATH = [ ' #platform/windows ' ] )
2017-01-08 20:41:11 +01:00
2017-06-30 19:21:38 +02:00
if ( os . name == " nt " and os . getenv ( " VCINSTALLDIR " ) ) : # MSVC
2016-10-30 18:44:57 +01:00
env [ ' ENV ' ] [ ' TMP ' ] = os . environ [ ' TMP ' ]
2017-06-30 19:21:38 +02:00
## Build type
2016-10-30 18:44:57 +01:00
2017-06-30 19:21:38 +02:00
if ( env [ " target " ] == " release " ) :
2016-10-30 18:44:57 +01:00
env . Append ( CCFLAGS = [ ' /O2 ' ] )
env . Append ( LINKFLAGS = [ ' /SUBSYSTEM:WINDOWS ' ] )
env . Append ( LINKFLAGS = [ ' /ENTRY:mainCRTStartup ' ] )
2016-10-30 18:57:40 +01:00
elif ( env [ " target " ] == " release_debug " ) :
env . Append ( CCFLAGS = [ ' /O2 ' , ' /DDEBUG_ENABLED ' ] )
2016-10-30 18:44:57 +01:00
env . Append ( LINKFLAGS = [ ' /SUBSYSTEM:CONSOLE ' ] )
2017-06-30 19:21:38 +02:00
elif ( env [ " target " ] == " debug_release " ) :
2016-10-30 18:57:40 +01:00
env . Append ( CCFLAGS = [ ' /Z7 ' , ' /Od ' ] )
2016-10-30 18:44:57 +01:00
env . Append ( LINKFLAGS = [ ' /DEBUG ' ] )
env . Append ( LINKFLAGS = [ ' /SUBSYSTEM:WINDOWS ' ] )
env . Append ( LINKFLAGS = [ ' /ENTRY:mainCRTStartup ' ] )
2016-10-30 18:57:40 +01:00
elif ( env [ " target " ] == " debug " ) :
2017-09-08 03:01:49 +02:00
env . Append ( CCFLAGS = [ ' /Z7 ' , ' /DDEBUG_ENABLED ' , ' /DDEBUG_MEMORY_ENABLED ' , ' /DD3D_DEBUG_INFO ' , ' /Od ' , ' /EHsc ' ] )
2016-10-30 18:44:57 +01:00
env . Append ( LINKFLAGS = [ ' /SUBSYSTEM:CONSOLE ' ] )
env . Append ( LINKFLAGS = [ ' /DEBUG ' ] )
2017-06-30 19:21:38 +02:00
## Architecture
# Note: this detection/override code from here onward should be here instead of in SConstruct because it's platform and compiler specific (MSVC/Windows)
if ( env [ " bits " ] != " default " ) :
print ( " Error: bits argument is disabled for MSVC " )
print ( """
Bits argument is not supported for MSVC compilation . Architecture depends on the Native / Cross Compile Tools Prompt / Developer Console
( or Visual Studio settings ) that is being used to run SCons . As a consequence , bits argument is disabled . Run scons again without bits
argument ( example : scons p = windows ) and SCons will attempt to detect what MSVC compiler will be executed and inform you .
""" )
sys . exit ( )
# Forcing bits argument because MSVC does not have a flag to set this through SCons... it's different compilers (cl.exe's) called from the proper command prompt
# that decide the architecture that is build for. Scons can only detect the os.getenviron (because vsvarsall.bat sets a lot of stuff for cl.exe to work with)
env [ " bits " ] = " 32 "
env [ " x86_libtheora_opt_vc " ] = True
## Compiler configuration
env [ ' ENV ' ] = os . environ
2018-02-21 17:30:55 +01:00
# This detection function needs the tools env (that is env['ENV'], not SCons's env), and that is why it's this far below in the code
2017-06-30 19:21:38 +02:00
compiler_version_str = methods . detect_visual_c_compiler_version ( env [ ' ENV ' ] )
print ( " Detected MSVC compiler: " + compiler_version_str )
2018-02-21 17:30:55 +01:00
# If building for 64bit architecture, disable assembly optimisations for 32 bit builds (theora as of writing)... vc compiler for 64bit can not compile _asm
2017-06-30 19:21:38 +02:00
if ( compiler_version_str == " amd64 " or compiler_version_str == " x86_amd64 " ) :
env [ " bits " ] = " 64 "
env [ " x86_libtheora_opt_vc " ] = False
print ( " Compiled program architecture will be a 64 bit executable (forcing bits=64). " )
elif ( compiler_version_str == " x86 " or compiler_version_str == " amd64_x86 " ) :
print ( " Compiled program architecture will be a 32 bit executable. (forcing bits=32). " )
else :
print ( " Failed to detect MSVC compiler architecture version... Defaulting to 32bit executable settings (forcing bits=32). Compilation attempt will continue, but SCons can not detect for what architecture this build is compiled for. You should check your settings/compilation setup. " )
## Compile flags
env . Append ( CCFLAGS = [ ' /MT ' , ' /Gd ' , ' /GR ' , ' /nologo ' ] )
2016-10-30 18:44:57 +01:00
env . Append ( CXXFLAGS = [ ' /TP ' ] )
env . Append ( CPPFLAGS = [ ' /DMSVC ' , ' /GR ' , ] )
2016-10-30 18:57:40 +01:00
env . Append ( CCFLAGS = [ ' /I ' + os . getenv ( " WindowsSdkDir " ) + " /Include " ] )
2017-06-30 19:21:38 +02:00
2016-10-30 18:44:57 +01:00
env . Append ( CCFLAGS = [ ' /DWINDOWS_ENABLED ' ] )
2017-06-30 19:21:38 +02:00
env . Append ( CCFLAGS = [ ' /DOPENGL_ENABLED ' ] )
2016-10-30 18:44:57 +01:00
env . Append ( CCFLAGS = [ ' /DRTAUDIO_ENABLED ' ] )
2017-08-27 19:01:34 +02:00
env . Append ( CCFLAGS = [ ' /DWASAPI_ENABLED ' ] )
2016-10-30 18:44:57 +01:00
env . Append ( CCFLAGS = [ ' /DTYPED_METHOD_BIND ' ] )
2017-06-30 19:21:38 +02:00
env . Append ( CCFLAGS = [ ' /DWIN32 ' ] )
2017-12-01 21:15:56 +01:00
env . Append ( CCFLAGS = [ ' /DWINVER= %s ' % env [ ' target_win_version ' ] , ' /D_WIN32_WINNT= %s ' % env [ ' target_win_version ' ] ] )
2017-06-30 19:21:38 +02:00
if env [ " bits " ] == " 64 " :
env . Append ( CCFLAGS = [ ' /D_WIN64 ' ] )
2016-10-30 18:44:57 +01:00
2018-02-15 09:06:00 +01:00
LIBS = [ ' winmm ' , ' opengl32 ' , ' dsound ' , ' kernel32 ' , ' ole32 ' , ' oleaut32 ' , ' user32 ' , ' gdi32 ' , ' IPHLPAPI ' , ' Shlwapi ' , ' wsock32 ' , ' Ws2_32 ' , ' shell32 ' , ' advapi32 ' , ' dinput8 ' , ' dxguid ' , ' imm32 ' ]
2016-10-30 18:57:40 +01:00
env . Append ( LINKFLAGS = [ p + env [ " LIBSUFFIX " ] for p in LIBS ] )
2016-10-30 18:44:57 +01:00
2016-10-30 18:57:40 +01:00
env . Append ( LIBPATH = [ os . getenv ( " WindowsSdkDir " ) + " /Lib " ] )
2015-10-01 21:25:36 +02:00
2016-10-30 18:44:57 +01:00
if ( os . getenv ( " VCINSTALLDIR " ) ) :
2016-10-30 18:57:40 +01:00
VC_PATH = os . getenv ( " VCINSTALLDIR " )
2016-10-30 18:44:57 +01:00
else :
2016-10-30 18:57:40 +01:00
VC_PATH = " "
2015-10-01 21:25:36 +02:00
2017-12-17 01:29:02 +01:00
if ( env [ " use_lto " ] ) :
env . Append ( CCFLAGS = [ ' /GL ' ] )
2017-12-31 17:35:38 +01:00
env . Append ( ARFLAGS = [ ' /LTCG ' ] )
if env [ " progress " ] :
env . Append ( LINKFLAGS = [ ' /LTCG:STATUS ' ] )
else :
env . Append ( LINKFLAGS = [ ' /LTCG ' ] )
2017-12-14 12:59:46 +01:00
2016-10-30 18:44:57 +01:00
env . Append ( CCFLAGS = [ " /I " + p for p in os . getenv ( " INCLUDE " ) . split ( " ; " ) ] )
env . Append ( LIBPATH = [ p for p in os . getenv ( " LIB " ) . split ( " ; " ) ] )
2016-09-04 00:25:43 +02:00
2016-10-30 18:44:57 +01:00
# Incremental linking fix
env [ ' BUILDERS ' ] [ ' ProgramOriginal ' ] = env [ ' BUILDERS ' ] [ ' Program ' ]
env [ ' BUILDERS ' ] [ ' Program ' ] = methods . precious_program
2016-09-04 00:25:43 +02:00
2017-06-30 19:21:38 +02:00
else : # MinGW
2015-10-01 21:25:36 +02:00
2016-10-30 18:44:57 +01:00
# Workaround for MinGW. See:
# http://www.scons.org/wiki/LongCmdLinesOnWin32
env . use_windows_spawn_fix ( )
2015-10-01 21:25:36 +02:00
2017-06-30 19:21:38 +02:00
## Build type
if ( env [ " target " ] == " release " ) :
env . Append ( CCFLAGS = [ ' -msse2 ' ] )
if ( env [ " bits " ] == " 64 " ) :
env . Append ( CCFLAGS = [ ' -O3 ' ] )
else :
env . Append ( CCFLAGS = [ ' -O2 ' ] )
env . Append ( LINKFLAGS = [ ' -Wl,--subsystem,windows ' ] )
2017-09-13 19:32:24 +02:00
if ( env [ " debug_symbols " ] == " yes " ) :
env . Prepend ( CCFLAGS = [ ' -g1 ' ] )
if ( env [ " debug_symbols " ] == " full " ) :
env . Prepend ( CCFLAGS = [ ' -g2 ' ] )
2017-06-30 19:21:38 +02:00
elif ( env [ " target " ] == " release_debug " ) :
env . Append ( CCFLAGS = [ ' -O2 ' , ' -DDEBUG_ENABLED ' ] )
2017-09-13 19:32:24 +02:00
if ( env [ " debug_symbols " ] == " yes " ) :
env . Prepend ( CCFLAGS = [ ' -g1 ' ] )
if ( env [ " debug_symbols " ] == " full " ) :
env . Prepend ( CCFLAGS = [ ' -g2 ' ] )
2017-06-30 19:21:38 +02:00
elif ( env [ " target " ] == " debug " ) :
2017-09-13 19:32:24 +02:00
env . Append ( CCFLAGS = [ ' -g3 ' , ' -DDEBUG_ENABLED ' , ' -DDEBUG_MEMORY_ENABLED ' ] )
2017-06-30 19:21:38 +02:00
## Compiler configuration
2016-10-30 18:57:40 +01:00
if ( os . name == " nt " ) :
env [ ' ENV ' ] [ ' TMP ' ] = os . environ [ ' TMP ' ] # way to go scons, you can be so stupid sometimes
2016-10-30 18:44:57 +01:00
else :
2016-10-30 18:57:40 +01:00
env [ " PROGSUFFIX " ] = env [ " PROGSUFFIX " ] + " .exe " # for linux cross-compilation
2015-10-01 21:25:36 +02:00
2016-10-30 18:57:40 +01:00
if ( env [ " bits " ] == " default " ) :
2017-09-13 22:36:15 +02:00
if ( os . name == " nt " ) :
env [ " bits " ] = " 64 " if " PROGRAMFILES(X86) " in os . environ else " 32 "
else : # default to 64-bit on Linux
env [ " bits " ] = " 64 "
mingw_prefix = " "
2015-10-01 21:25:36 +02:00
2016-10-30 18:57:40 +01:00
if ( env [ " bits " ] == " 32 " ) :
2016-10-30 18:44:57 +01:00
env . Append ( LINKFLAGS = [ ' -static ' ] )
env . Append ( LINKFLAGS = [ ' -static-libgcc ' ] )
env . Append ( LINKFLAGS = [ ' -static-libstdc++ ' ] )
2017-08-18 21:45:52 +02:00
mingw_prefix = env [ " mingw_prefix_32 " ]
2016-10-30 18:44:57 +01:00
else :
env . Append ( LINKFLAGS = [ ' -static ' ] )
2016-11-01 00:24:30 +01:00
mingw_prefix = env [ " mingw_prefix_64 " ]
2015-10-01 21:25:36 +02:00
2016-10-30 18:57:40 +01:00
env [ " CC " ] = mingw_prefix + " gcc "
env [ ' AS ' ] = mingw_prefix + " as "
env [ ' CXX ' ] = mingw_prefix + " g++ "
2017-09-23 22:55:26 +02:00
env [ ' AR ' ] = mingw_prefix + " gcc-ar "
env [ ' RANLIB ' ] = mingw_prefix + " gcc-ranlib "
2018-01-05 20:37:18 +01:00
env [ ' LINK ' ] = mingw_prefix + " g++ "
2016-10-30 18:57:40 +01:00
env [ " x86_libtheora_opt_gcc " ] = True
2015-10-01 21:25:36 +02:00
2017-09-25 06:37:17 +02:00
if env [ ' use_lto ' ] :
2017-09-23 22:55:26 +02:00
env . Append ( CCFLAGS = [ ' -flto ' ] )
2017-10-27 20:28:17 +02:00
env . Append ( LINKFLAGS = [ ' -flto= ' + str ( env . GetOption ( " num_jobs " ) ) ] )
2017-09-23 22:55:26 +02:00
2017-12-14 12:59:46 +01:00
2017-06-30 19:21:38 +02:00
## Compile flags
2015-10-01 21:25:36 +02:00
2016-10-30 18:57:40 +01:00
env . Append ( CCFLAGS = [ ' -DWINDOWS_ENABLED ' , ' -mwindows ' ] )
2017-01-02 21:38:20 +01:00
env . Append ( CCFLAGS = [ ' -DOPENGL_ENABLED ' ] )
2017-06-30 19:21:38 +02:00
env . Append ( CCFLAGS = [ ' -DRTAUDIO_ENABLED ' ] )
2017-08-27 19:01:34 +02:00
env . Append ( CCFLAGS = [ ' -DWASAPI_ENABLED ' ] )
2017-12-07 04:59:11 +01:00
env . Append ( CCFLAGS = [ ' -DWINVER= %s ' % env [ ' target_win_version ' ] , ' -D_WIN32_WINNT= %s ' % env [ ' target_win_version ' ] ] )
2018-02-15 09:06:00 +01:00
env . Append ( LIBS = [ ' mingw32 ' , ' opengl32 ' , ' dsound ' , ' ole32 ' , ' d3d9 ' , ' winmm ' , ' gdi32 ' , ' iphlpapi ' , ' shlwapi ' , ' wsock32 ' , ' ws2_32 ' , ' kernel32 ' , ' oleaut32 ' , ' dinput8 ' , ' dxguid ' , ' ksuser ' , ' imm32 ' ] )
2015-10-01 21:25:36 +02:00
2016-10-30 18:44:57 +01:00
env . Append ( CPPFLAGS = [ ' -DMINGW_ENABLED ' ] )
2015-10-01 21:25:36 +02:00
2016-10-30 18:44:57 +01:00
# resrc
2016-10-30 18:57:40 +01:00
env . Append ( BUILDERS = { ' RES ' : env . Builder ( action = build_res_file , suffix = ' .o ' , src_suffix = ' .rc ' ) } )