wesnoth/scons/boost.py
Sergey Popov 3933ebab5c
Use coroutines via boost::asio::spawn to improve overall code structure in servers (#5341)
* Convert server_base class to use coroutine instead of handlers

* Rework wesnothd's client login to use coroutine

* Merge 3 player handling functions into a single coroutine

* update cmakelists too

* Implement send_doc_queued in terms of coroutine

* Use brace initialization for making asio buffers

* Implement campaignd's request handling in coroutine

* Brace-initialize entire vector

* Remove old handler based send/receive helpers

* Document coroutine send/receive helpers

* Made coro_send_doc() helper take wml doc by reference

In most cases there is no need to rely on shared pointers to ensure
object lifetime if using coroutines since even when coroutine is
suspended args are still kept alive by its context.

* Document coro_send_file()

* Silence deprecation warning to fix build on earlier versions of boost

* Explicitly check for boost.context to allow linking against static boost libs

* Add boost.coroutine to flatpak manifest

* Port winapi TransmitFile codepath to coroutines

* Exception safety fix

* Add boost.scope_exit to vcpkg

* Fix build with pre-1.66 boost

* Move coro_* helpers into server_base class

Those helpers were in .ipp solely because they were templated on handler
types, this is no longer true after coroutine based rework.

* Make server_base::coro_send_file non-inline

* CleanUp Xcode project

Co-authored-by: Martin Hrubý (hrubymar10) <hrubymar10@gmail.com>
2020-12-30 19:08:34 +03:00

236 lines
8.2 KiB
Python

# vi: syntax=python:et:ts=4
from config_check_utils import find_include
from os.path import join, dirname, basename, normpath
import sys
from glob import glob
import re
def find_boost(env):
prefixes = [env["prefix"], "C:\\Boost"]
crosscompile = env["host"]
include = find_include(prefixes, "boost/config.hpp", default_prefixes=not crosscompile)
if include:
prefix, includefile = include[0]
env["boostdir"] = join(prefix, "include")
env["boostlibdir"] = join(prefix, "lib")
if not env.get("boost_suffix"):
for libdir in ["lib", "lib64"]:
if glob(join(prefix, libdir, "libboost_*-mt.*")):
env["boost_suffix"] = "-mt"
env["boostlibdir"] = join(prefix, libdir)
break
else:
env["boost_suffix"] = ""
return
includes = find_include(prefixes, "boost/config.hpp", include_subdir="include/boost-*")
if includes:
versions = []
for prefix, includefile in includes:
try:
testname = basename(dirname(dirname(includefile)))
major, minor = re.findall(r"^boost-(\d*)_(\d*)$", testname)[0]
versions.append((int(major), int(minor)))
except IndexError:
versions.append((0,0))
version_nums = [100000 * major_minor[0] + 100 * major_minor[1] for major_minor in versions]
include_index = version_nums.index(max(version_nums))
prefix, includefile = includes[include_index]
version = versions[include_index]
env["boostdir"] = join(prefix, "include", "boost-" + str(version[0]) + "_" + str(version[1]))
env["boostlibdir"] = join(prefix, "lib")
if not env.get("boost_suffix"):
libs = glob(join(prefix, "lib", "libboost_*"))
for lib in libs:
try:
env["boost_suffix"] = re.findall(r"libboost_\w*(-.*%d_%d)" % tuple(version), lib)[0]
break
except:
pass
def CheckBoost(context, boost_lib, require_version = None, header_only = False):
env = context.env
if require_version:
context.Message("Checking for Boost %s library version >= %s... " % (boost_lib, require_version))
else:
context.Message("Checking for Boost %s library... " % boost_lib)
if not env.get("boostdir", "") and not env.get("boostlibdir", ""):
find_boost(env)
boostdir = env.get("boostdir", "")
boostlibdir = env.get("boostlibdir", "")
backup = env.Clone().Dictionary()
boost_headers = { "regex" : "regex/config.hpp",
"iostreams" : "iostreams/constants.hpp",
"locale" : "locale/info.hpp",
"unit_test_framework" : "test/unit_test.hpp",
"filesystem" : "filesystem/operations.hpp",
"random" : "random/random_number_generator.hpp",
"system" : "system/error_code.hpp",
"context" : "context/continuation.hpp",
"coroutine" : "coroutine/coroutine.hpp" }
header_name = boost_headers.get(boost_lib, boost_lib + ".hpp")
libname = "boost_" + boost_lib + env.get("boost_suffix", "")
if sys.platform == "win32" or normpath(boostdir) != "/usr/include":
if env["fast"]:
env.AppendUnique(CXXFLAGS = ["-isystem", boostdir], LIBPATH = [boostlibdir])
else:
env.AppendUnique(CPPPATH = [boostdir], LIBPATH = [boostlibdir])
if not header_only:
env.PrependUnique(LIBS = [libname])
if boost_lib == "thread" and env["PLATFORM"] == "posix":
env.AppendUnique(CCFLAGS = ["-pthread"], LINKFLAGS = ["-pthread"])
test_program = """
#include <boost/%s>
\n""" % header_name
if require_version:
version = require_version.split(".", 2)
major = int(version[0])
minor = int(version[1])
try:
sub_minor = int(version[2])
except (ValueError, IndexError):
sub_minor = 0
test_program += "#include <boost/version.hpp>\n"
test_program += \
"#if BOOST_VERSION < %d\n#error Boost version is too old!\n#endif\n" \
% (major * 100000 + minor * 100 + sub_minor)
if boost_lib == "unit_test_framework":
test_program += """
boost::unit_test::test_suite* init_unit_test_suite ( int, char**)
{
return nullptr;
}
\n"""
test_program += """
// Workaround for sdl #defining main breaking non sdl programs
#ifdef main
#undef main
#endif
int main()
{
return 0;
}
\n"""
if context.TryLink(test_program, ".cpp"):
context.Result("yes")
return True
else:
context.Result("no")
env.Replace(**backup)
return False
def CheckBoostIostreamsGZip(context):
env = context.env
backup = env.Clone().Dictionary()
context.Message("Checking for gzip support in Boost Iostreams... ")
test_program = """
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/gzip.hpp>
int main()
{
boost::iostreams::filtering_stream<boost::iostreams::output> filter;
filter.push(boost::iostreams::gzip_compressor(boost::iostreams::gzip_params()));
return 0;
}
\n"""
for zlib in ["", "z"]:
env.Append(LIBS = [zlib])
comment = ""
if zlib:
comment = " //Trying to link against '%s'.\n" % zlib
if context.TryLink(comment + test_program, ".cpp"):
context.Result("yes")
return True
else:
env.Replace(**backup)
context.Result("no")
return False
def CheckBoostIostreamsBZip2(context):
env = context.env
backup = env.Clone().Dictionary()
context.Message("Checking for bzip2 support in Boost Iostreams... ")
test_program = """
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/bzip2.hpp>
int main()
{
boost::iostreams::filtering_stream<boost::iostreams::output> filter;
filter.push(boost::iostreams::bzip2_compressor(boost::iostreams::bzip2_params()));
return 0;
}
\n"""
# bzip2 library name when it's statically compiled into Boost
boostname = "boost_bzip2" + env.get("boost_suffix", "")
for libbz2 in ["", "bz2", boostname]:
env.Append(LIBS = [libbz2])
comment = ""
if libbz2:
comment = " //Trying to link against '%s'.\n" % libbz2
if context.TryLink(comment + test_program, ".cpp"):
context.Result("yes")
return True
else:
env.Replace(**backup)
context.Result("no")
return False
def CheckBoostLocaleBackends(context, backends):
env = context.env
backup = env.Clone().Dictionary()
context.Message("Checking for available Boost Locale backends... ")
test_program = """
#include <boost/locale/localization_backend.hpp>
#include <iostream>
#include <assert.h>
int main()
{
auto manager { boost::locale::localization_backend_manager::global() };
auto backends { manager.get_all_backends() };
assert(backends.size() >= 1);
for(auto backend : backends) {
std::cout << backend << std::endl;
}
return 0;
}
\n"""
if(env["PLATFORM"] != "win32"):
env.Append(LIBS = ["icudata", "icui18n", "icuuc"])
res, output = context.TryRun(test_program, ".cpp")
result = False
found_backends = "no"
if res:
supported_backends = output.splitlines()
result = bool(set(backends).intersection(supported_backends))
found_backends = ",".join(supported_backends)
context.Result(found_backends)
if result:
return True
else:
env.Replace(**backup)
return False
config_checks = { "CheckBoost" : CheckBoost, "CheckBoostIostreamsGZip" : CheckBoostIostreamsGZip, "CheckBoostIostreamsBZip2" : CheckBoostIostreamsBZip2, "CheckBoostLocaleBackends" : CheckBoostLocaleBackends }