mirror of
https://github.com/zekexiao/pocketlang.git
synced 2025-02-06 04:37:47 +08:00
252 lines
8.8 KiB
Python
252 lines
8.8 KiB
Python
#!python
|
|
import os, subprocess, sys
|
|
|
|
def CONFIGURE_ENV(env):
|
|
root_dir = env['variant_dir']
|
|
assert(root_dir.endswith('/'))
|
|
|
|
env.PROJECT_NAME = "pocketlang"
|
|
env.RUN_TARGET = root_dir + 'bin/pocket'
|
|
|
|
## PocketLang source files
|
|
SOURCES = [
|
|
Glob(root_dir + '*.c'),
|
|
Glob(root_dir + 'buffers/*.c'),
|
|
]
|
|
|
|
target_dir = root_dir + '../bin/'
|
|
|
|
if env['lib_shared']:
|
|
## Compile pocketlang dynamic lib.
|
|
dll = env.SharedLibrary(
|
|
target = target_dir + 'pocket' + env['bin_suffix'],
|
|
source = SOURCES,
|
|
CPPPATH = [root_dir + 'include/'],
|
|
CPPDEFINES = [env['CPPDEFINES'], 'PK_DLL', 'PK_COMPILE'],
|
|
)
|
|
else:
|
|
## Compile pocketlang static lib.
|
|
lib = env.Library(
|
|
target = target_dir + 'pocket' + env['bin_suffix'],
|
|
source = SOURCES,
|
|
CPPPATH = [root_dir + 'include/'],
|
|
)
|
|
|
|
## Test executable
|
|
test = env.Program(
|
|
target = target_dir + 'pocket' + env['bin_suffix'],
|
|
source = [root_dir + 'main/main.c'],
|
|
CPPPATH = [root_dir + 'include/'],
|
|
LIBPATH = target_dir,
|
|
LIBS = 'pocket' + env['bin_suffix'],
|
|
)
|
|
Requires(test, lib)
|
|
|
|
env.Append(CPPPATH=['src/include/'])
|
|
|
|
|
|
## -----------------------------------------------------------------------------
|
|
## END OF CONFIGURATION
|
|
## -----------------------------------------------------------------------------
|
|
|
|
opts = Variables([], ARGUMENTS)
|
|
## Define our options
|
|
opts.Add(EnumVariable('platform', "Compilation platform", '', ['', 'windows', 'x11', 'linux', 'osx']))
|
|
opts.Add(EnumVariable('target', "Compilation target", 'debug', ['debug', 'release']))
|
|
opts.Add(EnumVariable('bits', 'output program bits', '64', ['32', '64']))
|
|
opts.Add(BoolVariable('use_llvm', "Use the LLVM / Clang compiler", False))
|
|
opts.Add(BoolVariable('use_mingw', "Use Mingw compiler", False))
|
|
|
|
opts.Add(BoolVariable('vsproj', "make a visual studio project", False))
|
|
opts.Add(BoolVariable('verbose', "use verbose build command", True))
|
|
|
|
opts.Add(BoolVariable('lib_shared', "Compile as a shared library (only).", False))
|
|
|
|
## VariantDir
|
|
_build_target = ARGUMENTS.get('target', 'debug')
|
|
if _build_target in ('debug', 'release'): ## Otherwise error below.
|
|
_build_target = 'build/' + _build_target + '/src/'
|
|
VariantDir(_build_target, 'src', duplicate=0)
|
|
|
|
## Setup the Environment
|
|
DefaultEnvironment(tools=[]) ## not using any tools
|
|
env = Environment()
|
|
|
|
## Updates the environment with the option variables.
|
|
opts.Update(env)
|
|
|
|
if env['use_llvm']:
|
|
env['CC'] = 'clang'
|
|
env['CXX'] = 'clang++'
|
|
elif env['use_mingw']:
|
|
env['tools'] = ['mingw']
|
|
|
|
## find platform
|
|
if env['platform'] == '':
|
|
if sys.platform == 'win32':
|
|
env['platform'] = 'windows'
|
|
elif sys.platform in ('x11', 'linux', 'linux2'):
|
|
env['platform'] = 'linux'
|
|
elif sys.platform == 'darwin':
|
|
env['platform'] = 'osx'
|
|
else:
|
|
print("platform(%s) not supported." % sys.platform)
|
|
quit()
|
|
|
|
## For the reference:
|
|
## - CCFLAGS are compilation flags shared between C and C++
|
|
## - CFLAGS are for C-specific compilation flags
|
|
## - CXXFLAGS are for C++-specific compilation flags
|
|
## - CPPFLAGS are for pre-processor flags
|
|
## - CPPDEFINES are for pre-processor defines
|
|
## - LINKFLAGS are for linking flags
|
|
|
|
## Check our platform specifics
|
|
if env['platform'] == "osx":
|
|
env.Append(CXXFLAGS=['-std=c++17'])
|
|
if env['target'] == 'debug':
|
|
env.Append(CCFLAGS=['-g', '-O2', '-arch', 'x86_64'])
|
|
env.Append(LINKFLAGS=['-arch', 'x86_64'])
|
|
else:
|
|
env.Append(CCFLAGS=['-g', '-O3', '-arch', 'x86_64'])
|
|
env.Append(LINKFLAGS=['-arch', 'x86_64'])
|
|
|
|
elif env['platform'] == 'x11':
|
|
env.Append(LIBS=['dl', 'pthread'])
|
|
env.Append(CXXFLAGS=['-std=c++17'])
|
|
if env['target'] == 'debug':
|
|
env.Append(CCFLAGS=['-fPIC', '-g3', '-Og'])
|
|
else:
|
|
env.Append(CCFLAGS=['-fPIC', '-g', '-O3'])
|
|
|
|
elif env['platform'] == "windows":
|
|
env.Append(CXXFLAGS=['/std:c++17', '/bigobj'])
|
|
env.Append(CPPDEFINES=['_CRT_SECURE_NO_WARNINGS'])
|
|
env.Append(CPPDEFINES=['WIN32', '_WIN32', '_WINDOWS'])
|
|
env.Append(CCFLAGS=['-W3', '-GR', '/FS'])
|
|
env.Append(LINKFLAGS='-SUBSYSTEM:CONSOLE')
|
|
env.Append(LIBS=[])
|
|
|
|
if env['bits'] == '32': env['TARGET_ARCH'] = 'x86'
|
|
else: env['TARGET_ARCH'] = 'x86_64'
|
|
|
|
if env['target'] == 'debug':
|
|
env.Append(CPPDEFINES=['DEBUG'])
|
|
env.Append(CCFLAGS=['-EHsc', '-MDd', '-ZI'])
|
|
env.Append(LINKFLAGS=['-DEBUG'])
|
|
else:
|
|
env.Append(CPPDEFINES=['NDEBUG'])
|
|
env.Append(CCFLAGS=['-O2', '-EHsc', '-MD'])
|
|
|
|
## --------------------------------------------------------------------------------
|
|
|
|
## no_verbose function is from : https://github.com/godotengine/godot/blob/master/methods.py
|
|
def no_verbose(sys, env):
|
|
colors = {}
|
|
# Colors are disabled in non-TTY environments such as pipes. This means
|
|
# that if output is redirected to a file, it will not contain color codes
|
|
|
|
colors["cyan"] = "\033[96m" if sys.stdout.isatty() else ""
|
|
colors["purple"] = "\033[95m" if sys.stdout.isatty() else ""
|
|
colors["blue"] = "\033[94m" if sys.stdout.isatty() else ""
|
|
colors["green"] = "\033[92m" if sys.stdout.isatty() else ""
|
|
colors["yellow"] = "\033[93m" if sys.stdout.isatty() else ""
|
|
colors["red"] = "\033[91m" if sys.stdout.isatty() else ""
|
|
colors["end"] = "\033[0m" if sys.stdout.isatty() else ""
|
|
|
|
compile_source_message = "{}Compiling {}==> {}$SOURCE{}".format(
|
|
colors["blue"], colors["purple"], colors["yellow"], colors["end"])
|
|
java_compile_source_message = "{}Compiling {}==> {}$SOURCE{}".format(
|
|
colors["blue"], colors["purple"], colors["yellow"], colors["end"])
|
|
compile_shared_source_message = "{}Compiling shared {}==> {}$SOURCE{}".format(
|
|
colors["blue"], colors["purple"], colors["yellow"], colors["end"])
|
|
link_program_message = "{}Linking Program {}==> {}$TARGET{}".format(
|
|
colors["red"], colors["purple"], colors["yellow"], colors["end"])
|
|
link_library_message = "{}Linking Static Library {}==> {}$TARGET{}".format(
|
|
colors["red"], colors["purple"], colors["yellow"], colors["end"])
|
|
ranlib_library_message = "{}Ranlib Library {}==> {}$TARGET{}".format(
|
|
colors["red"], colors["purple"], colors["yellow"], colors["end"])
|
|
link_shared_library_message = "{}Linking Shared Library {}==> {}$TARGET{}".format(
|
|
colors["red"], colors["purple"], colors["yellow"], colors["end"])
|
|
java_library_message = "{}Creating Java Archive {}==> {}$TARGET{}".format(
|
|
colors["red"], colors["purple"], colors["yellow"], colors["end"])
|
|
env.Append(CXXCOMSTR=[compile_source_message])
|
|
env.Append(CCCOMSTR=[compile_source_message])
|
|
env.Append(SHCCCOMSTR=[compile_shared_source_message])
|
|
env.Append(SHCXXCOMSTR=[compile_shared_source_message])
|
|
env.Append(ARCOMSTR=[link_library_message])
|
|
env.Append(RANLIBCOMSTR=[ranlib_library_message])
|
|
env.Append(SHLINKCOMSTR=[link_shared_library_message])
|
|
env.Append(LINKCOMSTR=[link_program_message])
|
|
env.Append(JARCOMSTR=[java_library_message])
|
|
env.Append(JAVACCOMSTR=[java_compile_source_message])
|
|
|
|
if not env['verbose']:
|
|
no_verbose(sys, env)
|
|
|
|
Export('env')
|
|
env['variant_dir'] = _build_target
|
|
env['bin_suffix'] = '' ## TODO: Maybe '.%s.%s' % (env['platform'], env['bits'])
|
|
CONFIGURE_ENV(env)
|
|
|
|
## --------------------------------------------------------------------------------
|
|
|
|
## visual studio targets
|
|
def get_vsproj_context():
|
|
targets = []
|
|
variants = [] ## ["debug|Win32", "debug|x64", "release|Win32", "release|x64"]
|
|
for target in 'debug', 'release':
|
|
for bits in '32', '64':
|
|
variants.append(target+'|'+('Win32' if bits=='32' else 'x64'))
|
|
targets.append(env.RUN_TARGET)
|
|
return variants, targets
|
|
|
|
|
|
def recursive_collect(dir, suffix):
|
|
ret = []
|
|
for file in os.listdir(dir):
|
|
file = os.path.join(dir, file)
|
|
if os.path.isfile(file):
|
|
for suff in suffix:
|
|
if (file.endswith(suff)):
|
|
ret.append('$(ProjectDir)' + os.path.relpath(file))
|
|
elif os.path.isdir(file):
|
|
ret += recursive_collect(file, suffix)
|
|
return ret
|
|
|
|
def msvs_collect_header():
|
|
return recursive_collect('.', ('.h', '.hpp'))
|
|
|
|
def msvc_collect_sources():
|
|
return recursive_collect('.', ('.c', '.cpp', '.cc', '.cxx'))
|
|
|
|
def msvc_build_commandline(commands):
|
|
common_build_prefix = [
|
|
'cmd /V /C set "bits=64"',
|
|
'(if "$(PlatformTarget)"=="x86" (set "bits=32"))',
|
|
]
|
|
return " ^& ".join(common_build_prefix + [commands])
|
|
|
|
|
|
if env['vsproj']:
|
|
env["MSVSBUILDCOM"] = msvc_build_commandline(
|
|
"scons --directory=\"$(ProjectDir.TrimEnd('\\'))\" platform=windows target=$(Configuration) bits=!bits!"
|
|
)
|
|
env["MSVSREBUILDCOM"] = msvc_build_commandline(
|
|
"scons --directory=\"$(ProjectDir.TrimEnd('\\'))\" platform=windows target=$(Configuration) bits=!bits! vsproj=yes"
|
|
)
|
|
env["MSVSCLEANCOM"] = msvc_build_commandline(
|
|
"scons --directory=\"$(ProjectDir.TrimEnd('\\'))\" --clean platform=windows bits=!bits! target=$(Configuration)"
|
|
)
|
|
variants, targets = get_vsproj_context()
|
|
env.MSVSProject(target = env.PROJECT_NAME + env['MSVSPROJECTSUFFIX'],
|
|
srcs = msvc_collect_sources(),
|
|
incs = msvs_collect_header(),
|
|
variant = variants,
|
|
runfile = targets,
|
|
buildtarget = targets,
|
|
)
|
|
|
|
|
|
## Generates help for the -h scons option.
|
|
Help(opts.GenerateHelpText(env)) |