forked from OctaForge/libostd
build: add meson as the new buildsystem for libostd
This commit is contained in:
parent
4a55d315e4
commit
3906e5f1ee
28
README.md
28
README.md
|
@ -17,33 +17,15 @@ files in there directly if you don't need the API documentation.
|
|||
|
||||
## Building
|
||||
|
||||
Libostd is built using the supplied C++ build tool. You need to compile the
|
||||
build tool first using the compiler you will use to build the library itself.
|
||||
|
||||
On a typical Unix-like setup, this will involve:
|
||||
Libostd is built using Meson. Therefore, you need to install Meson and then
|
||||
you can compile it as usual. Typically, this will be something like
|
||||
|
||||
~~~
|
||||
c++ build.cc -o build -std=c++1z -I. -pthread
|
||||
./build --help
|
||||
mkdir build && cd build
|
||||
meson ..
|
||||
ninja all
|
||||
~~~
|
||||
|
||||
This will typically build using either GCC or Clang with the default standard
|
||||
library. **Keep in mind that it is you need at least Clang 4.0 or
|
||||
GCC 7.1 to build.**
|
||||
|
||||
You can skip `-pthread` on Windows.
|
||||
|
||||
Using the tool should be straightforward. The `./build --help` command lists
|
||||
the available options.
|
||||
|
||||
It also recognizes the environment variables `CXX` (the C++ compiler used
|
||||
to build, defaults to `c++`), `AS` (the assembler used to build, defaults to
|
||||
`c++` as well, as Clang and GCC can compile assembly files), `AR` (the tool
|
||||
to create static lib archives, `ar` by default) and `STRIP` (the tool used
|
||||
to strip the library in release mode, `strip` by default).
|
||||
|
||||
Additionally, the `CXXFLAGS`, `LDFLAGS` and `ASFLAGS` environment variables
|
||||
are also used. The `CXXFLAGS` are passed when compiling C++ source files as
|
||||
well as when linking (the compiler is used to link). The `LDFLAGS` are passed
|
||||
additionally to `CXXFLAGS` only when linking. The `ASFLAGS` are passed to
|
||||
the assembler (`CXXFLAGS` are not, even when Clang/GCC is used).
|
||||
|
|
572
build.cc
572
build.cc
|
@ -1,572 +0,0 @@
|
|||
/* A simple build system to build libostd.
|
||||
*
|
||||
* This file is a part of the libostd project. Libostd is licensed under the
|
||||
* University of Illinois/NCSA Open Source License, as is this file. See the
|
||||
* COPYING.md file further information.
|
||||
*/
|
||||
|
||||
/* just glibc bein awful */
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
|
||||
#include "ostd/io.hh"
|
||||
#include "ostd/range.hh"
|
||||
#include "ostd/format.hh"
|
||||
#include "ostd/string.hh"
|
||||
#include "ostd/path.hh"
|
||||
#include "ostd/thread_pool.hh"
|
||||
#include "ostd/channel.hh"
|
||||
#include "ostd/argparse.hh"
|
||||
|
||||
namespace fs = ostd::fs;
|
||||
using path = ostd::path;
|
||||
|
||||
/* ugly, but do not explicitly compile */
|
||||
#include "src/io.cc"
|
||||
#include "src/process.cc"
|
||||
#include "src/path.cc"
|
||||
#include "src/thread_pool.cc"
|
||||
#include "src/channel.cc"
|
||||
#include "src/string.cc"
|
||||
#include "src/argparse.cc"
|
||||
|
||||
#define OSTD_GEN_UNICODE_INCLUDE
|
||||
#include "gen_unicode.cc"
|
||||
|
||||
using strvec = std::vector<std::string>;
|
||||
using pathvec = std::vector<path>;
|
||||
|
||||
/* THESE VARIABLES CAN BE ALTERED */
|
||||
|
||||
/* all examples in the directory are built */
|
||||
static path EXAMPLES_DIR = "examples";
|
||||
|
||||
static path ASM_SOURCE_DIR = path{"src"} / "asm";
|
||||
static pathvec ASM_SOURCES = {
|
||||
"jump_all_gas", "make_all_gas", "ontop_all_gas"
|
||||
};
|
||||
|
||||
/* all sources in the directory are built */
|
||||
static path CXX_SOURCE_DIR = "src";
|
||||
|
||||
static path TEST_DIR = "tests";
|
||||
static pathvec TEST_CASES = {
|
||||
"algorithm", "range"
|
||||
};
|
||||
|
||||
static path OSTD_UNICODE_DATA = "data/UnicodeData-11.0.txt";
|
||||
static path OSTD_UNICODE_SRC = CXX_SOURCE_DIR / "string_utf.hh";
|
||||
|
||||
static path OSTD_SHARED_LIB = "libostd.so";
|
||||
static path OSTD_STATIC_LIB = "libostd.a";
|
||||
|
||||
static std::string DEFAULT_CXXFLAGS = "-std=c++1z -I. -O2 -Wall -Wextra "
|
||||
"-Wshadow -Wold-style-cast -fPIC "
|
||||
"-D_FILE_OFFSET_BITS=64";
|
||||
static std::string DEFAULT_LDFLAGS = "-pthread";
|
||||
static std::string DEFAULT_ASFLAGS = "-fPIC";
|
||||
|
||||
static std::string DEBUG_CXXFLAGS = "-g";
|
||||
|
||||
static std::string SHARED_CXXFLAGS = "";
|
||||
static std::string SHARED_LDFLAGS = "-shared";
|
||||
static std::string SHARED_ASFLAGS = "";
|
||||
|
||||
/* DO NOT CHANGE PAST THIS POINT */
|
||||
|
||||
static std::string from_env_or(char const *evar, char const *defval) {
|
||||
char const *varv = std::getenv(evar);
|
||||
if (!varv || !varv[0]) {
|
||||
return defval;
|
||||
}
|
||||
return varv;
|
||||
}
|
||||
|
||||
static void add_cross(std::string &arg) {
|
||||
char const *cross = std::getenv("CROSS");
|
||||
if (!cross || !cross[0]) {
|
||||
return;
|
||||
}
|
||||
arg.insert(0, cross);
|
||||
}
|
||||
|
||||
static void add_env(std::string &val, char const *evar) {
|
||||
char const *varv = std::getenv(evar);
|
||||
if (!varv || !varv[0]) {
|
||||
return;
|
||||
}
|
||||
val += ' ';
|
||||
val += varv;
|
||||
}
|
||||
|
||||
static void exec_command(strvec const &args) {
|
||||
if (int ret = ostd::subprocess{nullptr, ostd::iter(args)}.close(); ret) {
|
||||
throw std::runtime_error{ostd::format(
|
||||
ostd::appender<std::string>(), "command failed with code %d", ret
|
||||
).get()};
|
||||
}
|
||||
}
|
||||
|
||||
static std::string get_command(strvec const &args) {
|
||||
std::string ret;
|
||||
for (auto &s: args) {
|
||||
if (!ret.empty()) {
|
||||
ret += ' ';
|
||||
}
|
||||
ret += s;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void add_args(strvec &args, std::string const &cmdl) {
|
||||
ostd::split_args([&args](ostd::string_range arg) {
|
||||
args.emplace_back(arg);
|
||||
}, cmdl);
|
||||
}
|
||||
|
||||
static void try_remove(path const &path, bool all = false) {
|
||||
try {
|
||||
if (all) {
|
||||
fs::remove_all(path);
|
||||
} else {
|
||||
fs::remove(path);
|
||||
}
|
||||
} catch (fs::fs_error const &) {}
|
||||
}
|
||||
|
||||
static bool verbose = false;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
bool build_examples = true;
|
||||
bool build_testsuite = true;
|
||||
bool build_static = true;
|
||||
bool build_shared = false;
|
||||
std::string build_cfg = "debug";
|
||||
bool clean = false;
|
||||
|
||||
std::string cxxflags = DEFAULT_CXXFLAGS;
|
||||
std::string ldflags = DEFAULT_LDFLAGS;
|
||||
std::string asflags = DEFAULT_ASFLAGS;
|
||||
|
||||
ostd::arg_parser ap;
|
||||
|
||||
auto &help = ap.add_optional("-h", "--help", 0)
|
||||
.help("print this message and exit")
|
||||
.action(ostd::arg_print_help(ap));
|
||||
|
||||
ap.add_optional("--no-examples", 0)
|
||||
.help("do not build examples")
|
||||
.action(ostd::arg_store_false(build_examples));
|
||||
|
||||
ap.add_optional("--no-test-suite", 0)
|
||||
.help("do not build test suite")
|
||||
.action(ostd::arg_store_false(build_testsuite));
|
||||
|
||||
ap.add_optional("--no-static", 0)
|
||||
.help("do not build static libostd")
|
||||
.action(ostd::arg_store_false(build_static));
|
||||
|
||||
ap.add_optional("--shared", 0)
|
||||
.help("build shared libostd")
|
||||
.action(ostd::arg_store_true(build_shared));
|
||||
|
||||
ap.add_optional("--config", 1)
|
||||
.help("build configuration (debug/release)")
|
||||
.action(ostd::arg_store_str(build_cfg));
|
||||
|
||||
ap.add_optional("-v", "--verbose", 0)
|
||||
.help("print entire commands")
|
||||
.action(ostd::arg_store_true(verbose));
|
||||
|
||||
ap.add_positional("target", ostd::arg_value::OPTIONAL)
|
||||
.help("the action to perform")
|
||||
.action([&clean](auto vals) {
|
||||
if (!vals.empty()) {
|
||||
if (vals.front() == "clean") {
|
||||
clean = true;
|
||||
} else if (vals.front() != "build") {
|
||||
throw ostd::arg_error{"invalid build action"};
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
ap.parse(argc, argv);
|
||||
} catch (ostd::arg_error const &e) {
|
||||
ostd::cerr.writefln("argument parsing failed: %s", e.what());
|
||||
ap.print_help(ostd::cerr.iter());
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (help.used()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string default_lib = OSTD_SHARED_LIB;
|
||||
if (build_static) {
|
||||
default_lib = OSTD_STATIC_LIB;
|
||||
}
|
||||
|
||||
auto strip = from_env_or("STRIP", "strip");
|
||||
auto cxx = from_env_or("CXX", "c++");
|
||||
auto as = from_env_or("AS", "c++");
|
||||
auto ar = from_env_or("AR", "ar");
|
||||
|
||||
add_cross(strip);
|
||||
add_cross(cxx);
|
||||
add_cross(as);
|
||||
add_cross(ar);
|
||||
|
||||
if (build_cfg == "debug") {
|
||||
cxxflags += ' ';
|
||||
cxxflags += DEBUG_CXXFLAGS;
|
||||
} else if (build_cfg != "release") {
|
||||
ostd::cerr.writefln("invalid build configuration: %s", build_cfg);
|
||||
ap.print_help(ostd::cerr.iter());
|
||||
return 1;
|
||||
}
|
||||
|
||||
add_env(cxxflags, "CXXFLAGS");
|
||||
add_env(ldflags, "LDFLAGS");
|
||||
add_env(asflags, "ASFLAGS");
|
||||
|
||||
auto examples = ostd::appender<pathvec>();
|
||||
fs::glob_match(examples, EXAMPLES_DIR / "*.cc");
|
||||
for (auto &ex: examples.get()) {
|
||||
ex.replace_suffix();
|
||||
}
|
||||
|
||||
auto cxx_sources = ostd::appender<pathvec>();
|
||||
fs::glob_match(cxx_sources, CXX_SOURCE_DIR / "*.cc");
|
||||
for (auto &cc: cxx_sources.get()) {
|
||||
cc.replace_suffix();
|
||||
}
|
||||
|
||||
if (clean) {
|
||||
ostd::writeln("Cleaning...");
|
||||
|
||||
for (auto &ex: examples.get()) {
|
||||
auto rp = ex;
|
||||
try_remove(rp);
|
||||
rp.replace_suffix(".o");
|
||||
try_remove(rp);
|
||||
}
|
||||
for (auto &aso: ASM_SOURCES) {
|
||||
auto rp = (ASM_SOURCE_DIR / aso).with_suffix(".o");
|
||||
try_remove(rp);
|
||||
rp.replace_name((aso + "_dyn.o").string());
|
||||
try_remove(rp);
|
||||
}
|
||||
for (auto &cso: cxx_sources.get()) {
|
||||
auto rp = cso.with_suffix(".o");
|
||||
try_remove(rp);
|
||||
rp.replace_name((cso + "_dyn.o").string());
|
||||
try_remove(rp);
|
||||
}
|
||||
try_remove(OSTD_UNICODE_SRC);
|
||||
try_remove(OSTD_STATIC_LIB);
|
||||
try_remove(OSTD_SHARED_LIB);
|
||||
try_remove("test_runner.o");
|
||||
try_remove("test_runner");
|
||||
try_remove("tests", true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* a queue of stuff to print to stdout */
|
||||
ostd::channel<std::string> io_msgs;
|
||||
|
||||
/* a thread which reads from the queue */
|
||||
std::thread io_thread{[&io_msgs]() {
|
||||
try {
|
||||
for (;;) {
|
||||
/* wait for a msg; if closed, throw channel_error */
|
||||
ostd::writeln(io_msgs.get());
|
||||
}
|
||||
} catch (ostd::channel_error const &) {
|
||||
/* the queue is empty and closed, thread is done */
|
||||
return;
|
||||
}
|
||||
}};
|
||||
|
||||
auto echo_q = [&io_msgs](ostd::string_range fmt, auto const &...args) {
|
||||
if (!verbose) {
|
||||
auto app = ostd::appender<std::string>();
|
||||
ostd::format(app, fmt, args...);
|
||||
io_msgs.put(std::move(app.get()));
|
||||
}
|
||||
};
|
||||
|
||||
auto exec_v = [&io_msgs](strvec const &args) {
|
||||
if (verbose) {
|
||||
io_msgs.put(get_command(args));
|
||||
}
|
||||
exec_command(args);
|
||||
};
|
||||
|
||||
auto call_cxx = [&](
|
||||
path const &input, path const &output, bool lib, bool shared
|
||||
) {
|
||||
strvec args = { cxx };
|
||||
add_args(args, cxxflags);
|
||||
|
||||
auto ifs = input.string();
|
||||
auto outp = output;
|
||||
|
||||
if (shared) {
|
||||
outp.replace_suffix();
|
||||
outp += "_dyn.o";
|
||||
echo_q("CXX (shared): %s", ifs);
|
||||
add_args(args, SHARED_CXXFLAGS);
|
||||
} else {
|
||||
echo_q("CXX: %s", ifs);
|
||||
}
|
||||
|
||||
if (lib) {
|
||||
args.push_back("-DOSTD_BUILD");
|
||||
if (shared) {
|
||||
args.push_back("-DOSTD_DLL");
|
||||
}
|
||||
}
|
||||
|
||||
args.push_back("-c");
|
||||
args.push_back("-o");
|
||||
args.push_back(outp);
|
||||
args.push_back(ifs);
|
||||
|
||||
exec_v(args);
|
||||
|
||||
return outp;
|
||||
};
|
||||
|
||||
/* mostly unnecessary to separately compile shared, but
|
||||
* the files may check for __PIC__ (at least mips32 does)
|
||||
*/
|
||||
auto call_as = [&](
|
||||
path const &input, path const &output, bool, bool shared
|
||||
) {
|
||||
strvec args = { as };
|
||||
add_args(args, asflags);
|
||||
|
||||
auto ifs = input.string();
|
||||
auto outp = output;
|
||||
|
||||
if (shared) {
|
||||
outp.replace_suffix();
|
||||
outp += "_dyn.o";
|
||||
echo_q("AS (shared): %s", ifs);
|
||||
add_args(args, SHARED_ASFLAGS);
|
||||
} else {
|
||||
echo_q("AS: %s", ifs);
|
||||
}
|
||||
|
||||
args.push_back("-c");
|
||||
args.push_back("-o");
|
||||
args.push_back(outp);
|
||||
args.push_back(ifs);
|
||||
|
||||
exec_v(args);
|
||||
|
||||
return outp;
|
||||
};
|
||||
|
||||
auto call_ld = [&](
|
||||
path const &output, pathvec const &files, strvec const &flags
|
||||
) {
|
||||
echo_q("LD: %s", output);
|
||||
|
||||
strvec args = { cxx };
|
||||
add_args(args, cxxflags);
|
||||
|
||||
args.push_back("-o");
|
||||
args.push_back(output);
|
||||
for (auto &p: files) {
|
||||
args.push_back(p);
|
||||
}
|
||||
args.insert(args.cend(), flags.begin(), flags.end());
|
||||
|
||||
add_args(args, ldflags);
|
||||
|
||||
exec_v(args);
|
||||
|
||||
if (build_cfg == "release") {
|
||||
args.clear();
|
||||
args.push_back(strip);
|
||||
args.push_back(output);
|
||||
exec_v(args);
|
||||
}
|
||||
};
|
||||
|
||||
auto call_ldlib = [&](
|
||||
path const &output, pathvec const &files, bool shared
|
||||
) {
|
||||
if (shared) {
|
||||
strvec flags;
|
||||
add_args(flags, SHARED_CXXFLAGS);
|
||||
add_args(flags, SHARED_LDFLAGS);
|
||||
call_ld(output, files, flags);
|
||||
} else {
|
||||
strvec args = { ar };
|
||||
echo_q("AR: %s", output);
|
||||
|
||||
args.push_back("rcs");
|
||||
args.push_back(output);
|
||||
for (auto &p: files) {
|
||||
args.push_back(p);
|
||||
}
|
||||
|
||||
exec_v(args);
|
||||
}
|
||||
};
|
||||
|
||||
auto build_example = [&](path const &name) {
|
||||
auto base = name;
|
||||
auto ccf = base.with_suffix(".cc");
|
||||
auto obf = base.with_suffix(".o");
|
||||
|
||||
call_cxx(ccf, obf, false, false);
|
||||
call_ld(base, { obf }, { default_lib });
|
||||
|
||||
try_remove(obf);
|
||||
};
|
||||
|
||||
auto build_test = [&](path const &name) {
|
||||
auto base = TEST_DIR / name;
|
||||
auto ccf = base.with_suffix(".cc");
|
||||
auto obf = base.with_suffix(".o");
|
||||
|
||||
try_remove(ccf);
|
||||
ostd::file_stream f{ccf.string(), ostd::stream_mode::WRITE};
|
||||
if (!f.is_open()) {
|
||||
auto app = ostd::appender<std::string>();
|
||||
ostd::format(app, "cannot open '%s' for writing", ccf);
|
||||
throw std::runtime_error{app.get()};
|
||||
}
|
||||
f.writef(
|
||||
"#define OSTD_BUILD_TESTS libostd_%s\n"
|
||||
"\n"
|
||||
"#include <ostd/unit_test.hh>\n"
|
||||
"#include <ostd/%s.hh>\n"
|
||||
"#include <ostd/io.hh>\n"
|
||||
"\n"
|
||||
"int main() {\n"
|
||||
" auto [ succ, fail ] = ostd::test::run();\n"
|
||||
" ostd::writeln(succ, \" \", fail);\n"
|
||||
" return 0;\n"
|
||||
"}\n",
|
||||
name, name
|
||||
);
|
||||
f.close();
|
||||
|
||||
call_cxx(ccf, obf, false, false);
|
||||
call_ld(base, { obf }, { default_lib });
|
||||
try_remove(obf);
|
||||
};
|
||||
|
||||
auto build_test_runner = [&]() {
|
||||
call_cxx("test_runner.cc", "test_runner.o", false, false);
|
||||
call_ld("test_runner", { "test_runner.o" }, { default_lib });
|
||||
try_remove("test_runner.o");
|
||||
};
|
||||
|
||||
ostd::thread_pool tp{};
|
||||
tp.start();
|
||||
|
||||
std::queue<std::future<path>> future_obj, future_dynobj;
|
||||
|
||||
/* build object files in static and shared (PIC) variants */
|
||||
auto build_all = [&](
|
||||
pathvec const &list, path const &spath,
|
||||
path const &sext, auto &buildf
|
||||
) {
|
||||
auto build_obj = [&](path const &fpath, bool shared) {
|
||||
auto srcf = fpath.with_suffix(sext.string());
|
||||
auto srco = srcf.with_suffix(".o");
|
||||
auto &fq = (shared ? future_dynobj : future_obj);
|
||||
fq.push(tp.push([&buildf, srcf, srco, shared]() {
|
||||
return buildf(srcf, srco, true, shared);
|
||||
}));
|
||||
};
|
||||
for (auto &sf: list) {
|
||||
auto sp = spath.empty() ? sf : (spath / sf);
|
||||
if (build_static) {
|
||||
build_obj(sp, false);
|
||||
}
|
||||
if (build_shared) {
|
||||
build_obj(sp, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
echo_q("Generating Unicode tables...");
|
||||
ostd::unicode_gen::parse_state{}.build_all_from_file(
|
||||
OSTD_UNICODE_DATA.string(), OSTD_UNICODE_SRC.string()
|
||||
);
|
||||
|
||||
echo_q("Building the library...");
|
||||
build_all(ASM_SOURCES, ASM_SOURCE_DIR, ".S", call_as);
|
||||
build_all(cxx_sources.get(), path{}, ".cc", call_cxx);
|
||||
|
||||
if (build_static) {
|
||||
pathvec objs;
|
||||
while (!future_obj.empty()) {
|
||||
objs.push_back(future_obj.front().get());
|
||||
future_obj.pop();
|
||||
}
|
||||
call_ldlib(OSTD_STATIC_LIB, objs, false);
|
||||
}
|
||||
if (build_shared) {
|
||||
pathvec objs;
|
||||
while (!future_dynobj.empty()) {
|
||||
objs.push_back(future_dynobj.front().get());
|
||||
future_dynobj.pop();
|
||||
}
|
||||
call_ldlib(OSTD_SHARED_LIB, objs, true);
|
||||
}
|
||||
|
||||
std::queue<std::future<void>> future_bin;
|
||||
|
||||
if (build_examples) {
|
||||
echo_q("Building examples...");
|
||||
for (auto &ex: examples.get()) {
|
||||
future_bin.push(tp.push([&build_example, ex]() {
|
||||
build_example(ex);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if (build_testsuite) {
|
||||
echo_q("Building tests...");
|
||||
build_test_runner();
|
||||
if (!fs::is_directory(TEST_DIR)) {
|
||||
if (!fs::create_directory(TEST_DIR)) {
|
||||
echo_q("Failed creating test directory");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
for (auto &test: TEST_CASES) {
|
||||
future_bin.push(tp.push([&build_test, test]() {
|
||||
build_test(test);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
while (!future_bin.empty()) {
|
||||
/* wait and propagate possible exception */
|
||||
future_bin.front().get();
|
||||
future_bin.pop();
|
||||
}
|
||||
|
||||
if (build_testsuite) {
|
||||
exec_v({ "./test_runner", TEST_DIR });
|
||||
}
|
||||
|
||||
io_msgs.close();
|
||||
io_thread.join();
|
||||
|
||||
return 0;
|
||||
}
|
25
examples/meson.build
Normal file
25
examples/meson.build
Normal file
|
@ -0,0 +1,25 @@
|
|||
libostd_examples_src = [
|
||||
'argparse.cc',
|
||||
'concurrency.cc',
|
||||
'coroutine1.cc',
|
||||
'coroutine2.cc',
|
||||
'format.cc',
|
||||
'glob.cc',
|
||||
'listdir.cc',
|
||||
'range.cc',
|
||||
'range_pipe.cc',
|
||||
'signal.cc',
|
||||
'stream1.cc',
|
||||
'stream2.cc'
|
||||
]
|
||||
|
||||
thread_dep = dependency('threads')
|
||||
|
||||
foreach example: libostd_examples_src
|
||||
executable(example.split('.')[0],
|
||||
[example],
|
||||
dependencies: [libostd, thread_dep],
|
||||
include_directories: libostd_includes,
|
||||
install: false
|
||||
)
|
||||
endforeach
|
|
@ -19,6 +19,12 @@
|
|||
#include <ostd/string.hh>
|
||||
#include <ostd/algorithm.hh>
|
||||
|
||||
#ifdef OSTD_GEN_UNICODE_BUILD
|
||||
#define OSTD_NO_UNICODE_TABLES
|
||||
#include "src/string.cc"
|
||||
#include "src/io.cc"
|
||||
#endif
|
||||
|
||||
namespace ostd {
|
||||
namespace unicode_gen {
|
||||
|
||||
|
|
35
meson.build
Normal file
35
meson.build
Normal file
|
@ -0,0 +1,35 @@
|
|||
project('libostd', ['cpp'],
|
||||
version: '0.1.0',
|
||||
default_options: ['buildtype=plain', 'cpp_std=c++17'],
|
||||
meson_version: '>=0.46'
|
||||
)
|
||||
|
||||
dir_prefix = get_option('prefix')
|
||||
dir_include = join_paths(dir_prefix, get_option('includedir'))
|
||||
dir_data = join_paths(dir_prefix, get_option('datadir'))
|
||||
dir_lib = join_paths(dir_prefix, get_option('libdir'))
|
||||
|
||||
dir_package_include = join_paths(dir_include, 'ostd')
|
||||
|
||||
unicode_data = join_paths('data', 'UnicodeData-11.0.txt')
|
||||
|
||||
libostd_includes = [include_directories('.')]
|
||||
|
||||
tgt_compiler_id = meson.get_compiler('cpp').get_id()
|
||||
|
||||
if tgt_compiler_id == 'gcc' or tgt_compiler_id == 'clang'
|
||||
add_global_arguments(
|
||||
'-Wextra', '-Wshadow', '-Wold-style-cast',
|
||||
language: 'cpp'
|
||||
)
|
||||
endif
|
||||
|
||||
subdir('src')
|
||||
|
||||
if get_option('build-tests')
|
||||
subdir('tests')
|
||||
endif
|
||||
|
||||
if get_option('build-examples')
|
||||
subdir('examples')
|
||||
endif
|
11
meson_options.txt
Normal file
11
meson_options.txt
Normal file
|
@ -0,0 +1,11 @@
|
|||
option('build-examples',
|
||||
type: 'boolean',
|
||||
value: true,
|
||||
description: 'Build examples'
|
||||
)
|
||||
|
||||
option('build-tests',
|
||||
type: 'boolean',
|
||||
value: true,
|
||||
description: 'Build tests'
|
||||
)
|
81
src/meson.build
Normal file
81
src/meson.build
Normal file
|
@ -0,0 +1,81 @@
|
|||
libostd_header_src = [
|
||||
'../ostd/algorithm.hh',
|
||||
'../ostd/argparse.hh',
|
||||
'../ostd/channel.hh',
|
||||
'../ostd/concurrency.hh',
|
||||
'../ostd/context_stack.hh',
|
||||
'../ostd/coroutine.hh',
|
||||
'../ostd/environ.hh',
|
||||
'../ostd/event.hh',
|
||||
'../ostd/format.hh',
|
||||
'../ostd/generic_condvar.hh',
|
||||
'../ostd/io.hh',
|
||||
'../ostd/path.hh',
|
||||
'../ostd/platform.hh',
|
||||
'../ostd/process.hh',
|
||||
'../ostd/range.hh',
|
||||
'../ostd/stream.hh',
|
||||
'../ostd/string.hh',
|
||||
'../ostd/thread_pool.hh',
|
||||
'../ostd/unit_test.hh',
|
||||
'../ostd/vecmath.hh',
|
||||
|
||||
'../ostd/build/make.hh',
|
||||
'../ostd/build/make_coroutine.hh',
|
||||
|
||||
'../ostd/ext/sdl_rwops.hh'
|
||||
]
|
||||
|
||||
libostd_src = [
|
||||
'argparse.cc',
|
||||
'build_make.cc',
|
||||
'channel.cc',
|
||||
'concurrency.cc',
|
||||
'context_stack.cc',
|
||||
'environ.cc',
|
||||
'io.cc',
|
||||
'path.cc',
|
||||
'process.cc',
|
||||
'string.cc',
|
||||
'thread_pool.cc',
|
||||
|
||||
'asm/jump_all_gas.S',
|
||||
'asm/make_all_gas.S',
|
||||
'asm/ontop_all_gas.S'
|
||||
]
|
||||
|
||||
thread_dep = dependency('threads')
|
||||
|
||||
libostd_gen_unicode_exe = executable('gen_unicode',
|
||||
['../gen_unicode.cc'],
|
||||
include_directories: libostd_includes,
|
||||
cpp_args: '-DOSTD_GEN_UNICODE_BUILD',
|
||||
install: false
|
||||
)
|
||||
|
||||
libostd_extra_src = []
|
||||
|
||||
libostd_extra_src += custom_target('libostd_unicode_tables',
|
||||
input: join_paths('..', unicode_data),
|
||||
output: ['string_utf.hh'],
|
||||
install: false,
|
||||
command: [
|
||||
libostd_gen_unicode_exe, '@INPUT@',
|
||||
join_paths(meson.current_build_dir(), 'string_utf.hh')
|
||||
]
|
||||
)
|
||||
|
||||
libostd_lib = library('ostd',
|
||||
libostd_src, libostd_extra_src,
|
||||
dependencies: thread_dep,
|
||||
include_directories: libostd_includes + [include_directories('.')],
|
||||
install: true,
|
||||
version: meson.project_version()
|
||||
)
|
||||
|
||||
libostd = declare_dependency(
|
||||
include_directories: libostd_includes,
|
||||
link_with: libostd_lib
|
||||
)
|
||||
|
||||
install_headers(libostd_header_src, install_dir: dir_package_include)
|
|
@ -508,7 +508,7 @@ OSTD_EXPORT bool isupper(char32_t c) noexcept;
|
|||
OSTD_EXPORT char32_t tolower(char32_t c) noexcept;
|
||||
OSTD_EXPORT char32_t toupper(char32_t c) noexcept;
|
||||
|
||||
#if __has_include("string_utf.hh")
|
||||
#ifndef OSTD_NO_UNICODE_TABLES
|
||||
#include "string_utf.hh"
|
||||
#else
|
||||
|
||||
|
@ -558,7 +558,7 @@ OSTD_EXPORT char32_t toupper(char32_t c) noexcept {
|
|||
return c;
|
||||
}
|
||||
|
||||
#endif /* __has_include("string_utf.hh") */
|
||||
#endif /* !OSTD_NO_UNICODE_TABLES */
|
||||
|
||||
namespace detail {
|
||||
template<typename C>
|
||||
|
|
28
tests/meson.build
Normal file
28
tests/meson.build
Normal file
|
@ -0,0 +1,28 @@
|
|||
test_runner_exe = executable('test_runner',
|
||||
['test_runner.cc'],
|
||||
dependencies: libostd,
|
||||
include_directories: libostd_includes,
|
||||
install: false
|
||||
)
|
||||
|
||||
libostd_tests_src = [
|
||||
'algorithm.cc',
|
||||
'range.cc'
|
||||
]
|
||||
|
||||
test_target = []
|
||||
foreach test_src: libostd_tests_src
|
||||
test_target += executable(test_src.split('.')[0],
|
||||
[test_src],
|
||||
dependencies: libostd,
|
||||
include_directories: libostd_includes,
|
||||
install: false
|
||||
)
|
||||
endforeach
|
||||
|
||||
test('libostd',
|
||||
test_runner_exe,
|
||||
args: [meson.current_build_dir()],
|
||||
workdir: meson.current_build_dir(),
|
||||
depends: test_target
|
||||
)
|
Loading…
Reference in a new issue