mirror of
https://github.com/Relintai/rcpp_framework.git
synced 2024-11-10 00:52:11 +01:00
Implemented a scons based build script based on godot's. Will need to be cleaned up when I understand how scons works better.
This commit is contained in:
parent
758c94c8af
commit
5b22c599a9
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,3 +1,5 @@
|
||||
|
||||
bin/**
|
||||
|
||||
*.dblite
|
||||
*.o
|
||||
*.a
|
||||
|
381
SConstruct
381
SConstruct
@ -7,32 +7,60 @@ import glob
|
||||
import os
|
||||
import pickle
|
||||
import sys
|
||||
|
||||
import re
|
||||
import subprocess
|
||||
from collections import OrderedDict
|
||||
#from compat import iteritems, isbasestring, open_utf8, decode_utf8, qualname
|
||||
|
||||
# scan possible build platforms
|
||||
from SCons import Node
|
||||
from SCons.Script import Glob
|
||||
|
||||
platform_list = [] # list of platforms
|
||||
platform_opts = {} # options for each platform
|
||||
platform_flags = {} # flags for each platform
|
||||
def isbasestring(s):
|
||||
return isinstance(s, (str, bytes))
|
||||
|
||||
active_platforms = []
|
||||
active_platform_ids = []
|
||||
platform_exporters = []
|
||||
platform_apis = []
|
||||
def add_source_files(self, sources, files, warn_duplicates=True):
|
||||
# Convert string to list of absolute paths (including expanding wildcard)
|
||||
if isbasestring(files):
|
||||
# Keep SCons project-absolute path as they are (no wildcard support)
|
||||
if files.startswith("#"):
|
||||
if "*" in files:
|
||||
print("ERROR: Wildcards can't be expanded in SCons project-absolute path: '{}'".format(files))
|
||||
return
|
||||
files = [files]
|
||||
else:
|
||||
dir_path = self.Dir(".").abspath
|
||||
files = sorted(glob.glob(dir_path + "/" + files))
|
||||
|
||||
custom_tools = ["default"]
|
||||
# Add each path as compiled Object following environment (self) configuration
|
||||
for path in files:
|
||||
obj = self.Object(path)
|
||||
if obj in sources:
|
||||
if warn_duplicates:
|
||||
print('WARNING: Object "{}" already included in environment sources.'.format(obj))
|
||||
else:
|
||||
continue
|
||||
sources.append(obj)
|
||||
|
||||
platform_arg = ARGUMENTS.get("platform", ARGUMENTS.get("p", False))
|
||||
def add_library(env, name, sources, **args):
|
||||
library = env.Library(name, sources, **args)
|
||||
env.NoCache(library)
|
||||
return library
|
||||
|
||||
if os.name == "nt" and (platform_arg == "android" or ARGUMENTS.get("use_mingw", False)):
|
||||
custom_tools = ["mingw"]
|
||||
elif platform_arg == "javascript":
|
||||
# Use generic POSIX build toolchain for Emscripten.
|
||||
custom_tools = ["cc", "c++", "ar", "link", "textfile", "zip"]
|
||||
def add_program(env, name, sources, **args):
|
||||
program = env.Program(name, sources, **args)
|
||||
env.NoCache(program)
|
||||
return program
|
||||
|
||||
env_base = Environment()
|
||||
|
||||
env_base.__class__.add_source_files = add_source_files
|
||||
env_base.__class__.add_library = add_library
|
||||
env_base.__class__.add_program = add_program
|
||||
|
||||
env_base = Environment(tools=custom_tools)
|
||||
if "TERM" in os.environ:
|
||||
env_base["ENV"]["TERM"] = os.environ["TERM"]
|
||||
|
||||
env_base.AppendENVPath("PATH", os.getenv("PATH"))
|
||||
env_base.AppendENVPath("PKG_CONFIG_PATH", os.getenv("PKG_CONFIG_PATH"))
|
||||
env_base.disabled_modules = []
|
||||
@ -45,26 +73,9 @@ env_base.SConsignFile(".sconsign{0}.dblite".format(pickle.HIGHEST_PROTOCOL))
|
||||
|
||||
# Build options
|
||||
|
||||
opts = Variables([], ARGUMENTS)
|
||||
|
||||
profile = ARGUMENTS.get("profile", False)
|
||||
if profile:
|
||||
if os.path.isfile(profile):
|
||||
customs.append(profile)
|
||||
elif os.path.isfile(profile + ".py"):
|
||||
customs.append(profile + ".py")
|
||||
|
||||
opts = Variables(customs, ARGUMENTS)
|
||||
|
||||
# Target build options
|
||||
opts.Add("arch", "Platform-dependent architecture (arm/arm64/x86/x64/mips/...)", "")
|
||||
opts.Add(EnumVariable("bits", "Target platform bits", "default", ("default", "32", "64")))
|
||||
opts.Add("p", "Platform (alias for 'platform')", "")
|
||||
opts.Add("platform", "Target platform (%s)" % ("|".join(platform_list),), "")
|
||||
opts.Add(EnumVariable("target", "Compilation target", "debug", ("debug", "release_debug", "release")))
|
||||
opts.Add(EnumVariable("optimize", "Optimization type", "speed", ("speed", "size")))
|
||||
opts.Add(BoolVariable("tools", "Build the tools (a.k.a. the Godot editor)", True))
|
||||
opts.Add(BoolVariable("use_lto", "Use link-time optimization", False))
|
||||
opts.Add(BoolVariable("use_precise_math_checks", "Math checks use very precise epsilon (debug option)", False))
|
||||
|
||||
# Compilation environment setup
|
||||
opts.Add("CXX", "C++ compiler")
|
||||
@ -75,301 +86,21 @@ opts.Add("CFLAGS", "Custom flags for the C compiler")
|
||||
opts.Add("CXXFLAGS", "Custom flags for the C++ compiler")
|
||||
opts.Add("LINKFLAGS", "Custom flags for the linker")
|
||||
|
||||
# add platform specific options
|
||||
|
||||
for k in platform_opts.keys():
|
||||
opt_list = platform_opts[k]
|
||||
for o in opt_list:
|
||||
opts.Add(o)
|
||||
|
||||
# Update the environment now as the "custom_modules" option may be
|
||||
# defined in a file rather than specified via the command line.
|
||||
opts.Update(env_base)
|
||||
|
||||
# Detect modules.
|
||||
modules_detected = OrderedDict()
|
||||
module_search_paths = ["modules"] # Built-in path.
|
||||
|
||||
# Update the environment again after all the module options are added.
|
||||
opts.Update(env_base)
|
||||
Help(opts.GenerateHelpText(env_base))
|
||||
|
||||
# add default include paths
|
||||
env_base.Prepend(CPPPATH=["#", "libs"])
|
||||
env_base.Prepend(CPPPATH=["#libs"])
|
||||
#env_base.Prepend(CXXFLAGS=["-lpthread"])
|
||||
env_base.Prepend(LINKFLAGS=["-lpthread"])
|
||||
|
||||
env_base.Prepend(CPPPATH=["#"])
|
||||
env = env_base.Clone()
|
||||
|
||||
# configure ENV for platform
|
||||
env_base.platform_exporters = platform_exporters
|
||||
env_base.platform_apis = platform_apis
|
||||
Export("env")
|
||||
|
||||
env_base.platforms = {}
|
||||
SConscript("core/SCsub")
|
||||
|
||||
selected_platform = ""
|
||||
env.prg_sources = ["rdn_application.cpp"]
|
||||
plib = env.add_library("prg", env.prg_sources)
|
||||
env.Prepend(LIBS=[plib])
|
||||
|
||||
if env_base["platform"] != "":
|
||||
selected_platform = env_base["platform"]
|
||||
elif env_base["p"] != "":
|
||||
selected_platform = env_base["p"]
|
||||
env_base["platform"] = selected_platform
|
||||
else:
|
||||
# Missing `platform` argument, try to detect platform automatically
|
||||
if sys.platform.startswith("linux"):
|
||||
selected_platform = "x11"
|
||||
elif sys.platform == "darwin":
|
||||
selected_platform = "osx"
|
||||
elif sys.platform == "win32":
|
||||
selected_platform = "windows"
|
||||
else:
|
||||
print("Could not detect platform automatically. Supported platforms:")
|
||||
for x in platform_list:
|
||||
print("\t" + x)
|
||||
print("\nPlease run SCons again and select a valid platform: platform=<string>")
|
||||
prog = env.add_program("#bin/server", ["main.cpp"])
|
||||
|
||||
if selected_platform != "":
|
||||
print("Automatically detected platform: " + selected_platform)
|
||||
env_base["platform"] = selected_platform
|
||||
|
||||
if selected_platform in ["linux", "bsd", "linuxbsd"]:
|
||||
if selected_platform == "linuxbsd":
|
||||
# Alias for forward compatibility.
|
||||
print('Platform "linuxbsd" is still called "x11" in Godot 3.2.x. Building for platform "x11".')
|
||||
# Alias for convenience.
|
||||
selected_platform = "x11"
|
||||
env_base["platform"] = selected_platform
|
||||
|
||||
if selected_platform in platform_list:
|
||||
tmppath = "./platform/" + selected_platform
|
||||
sys.path.insert(0, tmppath)
|
||||
import detect
|
||||
|
||||
if "create" in dir(detect):
|
||||
env = detect.create(env_base)
|
||||
else:
|
||||
env = env_base.Clone()
|
||||
|
||||
# Compilation DB requires SCons 3.1.1+.
|
||||
from SCons import __version__ as scons_raw_version
|
||||
|
||||
scons_ver = env._get_major_minor_revision(scons_raw_version)
|
||||
|
||||
if scons_ver >= (4, 0, 0):
|
||||
env.Tool("compilation_db")
|
||||
env.Alias("compiledb", env.CompilationDatabase())
|
||||
|
||||
if env["dev"]:
|
||||
env["verbose"] = True
|
||||
env["warnings"] = "extra"
|
||||
env["werror"] = True
|
||||
|
||||
env.extra_suffix = ""
|
||||
|
||||
if env["extra_suffix"] != "":
|
||||
env.extra_suffix += "." + env["extra_suffix"]
|
||||
|
||||
# Environment flags
|
||||
CCFLAGS = env.get("CCFLAGS", "")
|
||||
env["CCFLAGS"] = ""
|
||||
env.Append(CCFLAGS=str(CCFLAGS).split())
|
||||
|
||||
CFLAGS = env.get("CFLAGS", "")
|
||||
env["CFLAGS"] = ""
|
||||
env.Append(CFLAGS=str(CFLAGS).split())
|
||||
|
||||
CXXFLAGS = env.get("CXXFLAGS", "")
|
||||
env["CXXFLAGS"] = ""
|
||||
env.Append(CXXFLAGS=str(CXXFLAGS).split())
|
||||
|
||||
LINKFLAGS = env.get("LINKFLAGS", "")
|
||||
env["LINKFLAGS"] = ""
|
||||
env.Append(LINKFLAGS=str(LINKFLAGS).split())
|
||||
|
||||
# Platform specific flags
|
||||
flag_list = platform_flags[selected_platform]
|
||||
for f in flag_list:
|
||||
if not (f[0] in ARGUMENTS): # allow command line to override platform flags
|
||||
env[f[0]] = f[1]
|
||||
|
||||
# Must happen after the flags definition, so that they can be used by platform detect
|
||||
detect.configure(env)
|
||||
|
||||
# Set our C and C++ standard requirements.
|
||||
# Prepending to make it possible to override
|
||||
# This needs to come after `configure`, otherwise we don't have env.msvc.
|
||||
if not env.msvc:
|
||||
# Specifying GNU extensions support explicitly, which are supported by
|
||||
# both GCC and Clang. This mirrors GCC and Clang's current default
|
||||
# compile flags if no -std is specified.
|
||||
env.Prepend(CFLAGS=["-std=gnu11"])
|
||||
env.Prepend(CXXFLAGS=["-std=gnu++14"])
|
||||
else:
|
||||
# MSVC doesn't have clear C standard support, /std only covers C++.
|
||||
# We apply it to CCFLAGS (both C and C++ code) in case it impacts C features.
|
||||
env.Prepend(CCFLAGS=["/std:c++14"])
|
||||
|
||||
# Configure compiler warnings
|
||||
if env.msvc:
|
||||
# Truncations, narrowing conversions, signed/unsigned comparisons...
|
||||
disable_nonessential_warnings = ["/wd4267", "/wd4244", "/wd4305", "/wd4018", "/wd4800"]
|
||||
if env["warnings"] == "extra":
|
||||
env.Append(CCFLAGS=["/Wall"]) # Implies /W4
|
||||
elif env["warnings"] == "all":
|
||||
env.Append(CCFLAGS=["/W3"] + disable_nonessential_warnings)
|
||||
elif env["warnings"] == "moderate":
|
||||
env.Append(CCFLAGS=["/W2"] + disable_nonessential_warnings)
|
||||
else: # 'no'
|
||||
env.Append(CCFLAGS=["/w"])
|
||||
# Set exception handling model to avoid warnings caused by Windows system headers.
|
||||
env.Append(CCFLAGS=["/EHsc"])
|
||||
if env["werror"]:
|
||||
env.Append(CCFLAGS=["/WX"])
|
||||
# Force to use Unicode encoding
|
||||
env.Append(MSVC_FLAGS=["/utf8"])
|
||||
else: # Rest of the world
|
||||
version = methods.get_compiler_version(env) or [-1, -1]
|
||||
|
||||
shadow_local_warning = []
|
||||
all_plus_warnings = ["-Wwrite-strings"]
|
||||
|
||||
if methods.using_gcc(env):
|
||||
env.Append(CCFLAGS=["-Wno-misleading-indentation"])
|
||||
if version[0] >= 7:
|
||||
shadow_local_warning = ["-Wshadow-local"]
|
||||
|
||||
if env["warnings"] == "extra":
|
||||
# Note: enable -Wimplicit-fallthrough for Clang (already part of -Wextra for GCC)
|
||||
# once we switch to C++11 or later (necessary for our FALLTHROUGH macro).
|
||||
env.Append(CCFLAGS=["-Wall", "-Wextra", "-Wno-unused-parameter"] + all_plus_warnings + shadow_local_warning)
|
||||
env.Append(CXXFLAGS=["-Wctor-dtor-privacy", "-Wnon-virtual-dtor"])
|
||||
if methods.using_gcc(env):
|
||||
env.Append(
|
||||
CCFLAGS=[
|
||||
"-Walloc-zero",
|
||||
"-Wduplicated-branches",
|
||||
"-Wduplicated-cond",
|
||||
"-Wstringop-overflow=4",
|
||||
"-Wlogical-op",
|
||||
]
|
||||
)
|
||||
env.Append(CXXFLAGS=["-Wnoexcept", "-Wplacement-new=1"])
|
||||
if version[0] >= 9:
|
||||
env.Append(CCFLAGS=["-Wattribute-alias=2"])
|
||||
elif env["warnings"] == "all":
|
||||
env.Append(CCFLAGS=["-Wall"] + shadow_local_warning)
|
||||
elif env["warnings"] == "moderate":
|
||||
env.Append(CCFLAGS=["-Wall", "-Wno-unused"] + shadow_local_warning)
|
||||
else: # 'no'
|
||||
env.Append(CCFLAGS=["-w"])
|
||||
if env["werror"]:
|
||||
env.Append(CCFLAGS=["-Werror"])
|
||||
else: # always enable those errors
|
||||
env.Append(CCFLAGS=["-Werror=return-type"])
|
||||
|
||||
if hasattr(detect, "get_program_suffix"):
|
||||
suffix = "." + detect.get_program_suffix()
|
||||
else:
|
||||
suffix = "." + selected_platform
|
||||
|
||||
if env["target"] == "release":
|
||||
if env["tools"]:
|
||||
print("Tools can only be built with targets 'debug' and 'release_debug'.")
|
||||
sys.exit(255)
|
||||
suffix += ".opt"
|
||||
env.Append(CPPDEFINES=["NDEBUG"])
|
||||
|
||||
elif env["target"] == "release_debug":
|
||||
if env["tools"]:
|
||||
suffix += ".opt.tools"
|
||||
else:
|
||||
suffix += ".opt.debug"
|
||||
else:
|
||||
if env["tools"]:
|
||||
suffix += ".tools"
|
||||
else:
|
||||
suffix += ".debug"
|
||||
|
||||
if env["arch"] != "":
|
||||
suffix += "." + env["arch"]
|
||||
elif env["bits"] == "32":
|
||||
suffix += ".32"
|
||||
elif env["bits"] == "64":
|
||||
suffix += ".64"
|
||||
|
||||
suffix += env.extra_suffix
|
||||
|
||||
sys.path.remove(tmppath)
|
||||
sys.modules.pop("detect")
|
||||
|
||||
modules_enabled = OrderedDict()
|
||||
env.module_icons_paths = []
|
||||
env.doc_class_path = {}
|
||||
|
||||
methods.update_version(env.module_version_string)
|
||||
|
||||
env["PROGSUFFIX"] = suffix + env.module_version_string + env["PROGSUFFIX"]
|
||||
env["OBJSUFFIX"] = suffix + env["OBJSUFFIX"]
|
||||
# (SH)LIBSUFFIX will be used for our own built libraries
|
||||
# LIBSUFFIXES contains LIBSUFFIX and SHLIBSUFFIX by default,
|
||||
# so we need to append the default suffixes to keep the ability
|
||||
# to link against thirdparty libraries (.a, .so, .lib, etc.).
|
||||
if os.name == "nt":
|
||||
# On Windows, only static libraries and import libraries can be
|
||||
# statically linked - both using .lib extension
|
||||
env["LIBSUFFIXES"] += [env["LIBSUFFIX"]]
|
||||
else:
|
||||
env["LIBSUFFIXES"] += [env["LIBSUFFIX"], env["SHLIBSUFFIX"]]
|
||||
env["LIBSUFFIX"] = suffix + env["LIBSUFFIX"]
|
||||
env["SHLIBSUFFIX"] = suffix + env["SHLIBSUFFIX"]
|
||||
|
||||
if not env["verbose"]:
|
||||
methods.no_verbose(sys, env)
|
||||
|
||||
scons_cache_path = os.environ.get("SCONS_CACHE")
|
||||
if scons_cache_path != None:
|
||||
CacheDir(scons_cache_path)
|
||||
print("Scons cache enabled... (path: '" + scons_cache_path + "')")
|
||||
|
||||
if env["vsproj"]:
|
||||
env.vs_incs = []
|
||||
env.vs_srcs = []
|
||||
|
||||
Export("env")
|
||||
|
||||
# build subdirs, the build order is dependent on link order.
|
||||
|
||||
# Microsoft Visual Studio Project Generation
|
||||
if env["vsproj"]:
|
||||
env["CPPPATH"] = [Dir(path) for path in env["CPPPATH"]]
|
||||
methods.generate_vs_project(env, GetOption("num_jobs"))
|
||||
methods.generate_cpp_hint_file("cpp.hint")
|
||||
|
||||
# Check for the existence of headers
|
||||
conf = Configure(env)
|
||||
if "check_c_headers" in env:
|
||||
for header in env["check_c_headers"]:
|
||||
if conf.CheckCHeader(header[0]):
|
||||
env.AppendUnique(CPPDEFINES=[header[1]])
|
||||
|
||||
elif selected_platform != "":
|
||||
if selected_platform == "list":
|
||||
print("The following platforms are available:\n")
|
||||
else:
|
||||
print('Invalid target platform "' + selected_platform + '".')
|
||||
print("The following platforms were detected:\n")
|
||||
|
||||
for x in platform_list:
|
||||
print("\t" + x)
|
||||
|
||||
print("\nPlease run SCons again and select a valid platform: platform=<string>")
|
||||
|
||||
if selected_platform == "list":
|
||||
# Exit early to suppress the rest of the built-in SCons messages
|
||||
sys.exit(0)
|
||||
else:
|
||||
sys.exit(255)
|
||||
|
||||
# The following only makes sense when the 'env' is defined, and assumes it is.
|
||||
if "env" in locals():
|
||||
methods.show_progress(env)
|
||||
# TODO: replace this with `env.Dump(format="json")`
|
||||
# once we start requiring SCons 4.0 as min version.
|
||||
methods.dump(env)
|
||||
|
@ -1,3 +1,6 @@
|
||||
g++ -o3 -g main.cpp ./core/settings.cpp ./core/request.cpp ./core/http_server.cpp ./core/file_cache.cpp ./core/application.cpp ./rdn_application.cpp \
|
||||
./core/theme.cpp \
|
||||
-o ./bin/server -Ilibs -lpthread -std=c++11
|
||||
|
||||
|
||||
|
||||
|
11
core/SCsub
Normal file
11
core/SCsub
Normal file
@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
Import("env")
|
||||
|
||||
env.core_sources = []
|
||||
|
||||
env.add_source_files(env.core_sources, "*.cpp")
|
||||
|
||||
# Build it all as a library
|
||||
lib = env.add_library("core", env.core_sources)
|
||||
env.Prepend(LIBS=[lib])
|
Loading…
Reference in New Issue
Block a user