forked from OctaForge/libostd
more build cleanups and emplace for channels
This commit is contained in:
parent
1cc0577513
commit
fc6935151d
156
build.cc
156
build.cc
|
@ -27,25 +27,27 @@ namespace fs = ostd::filesystem;
|
||||||
/* ugly, but do not explicitly compile */
|
/* ugly, but do not explicitly compile */
|
||||||
#include "src/io.cc"
|
#include "src/io.cc"
|
||||||
|
|
||||||
|
using strvec = std::vector<std::string>;
|
||||||
|
|
||||||
/* THESE VARIABLES CAN BE ALTERED */
|
/* THESE VARIABLES CAN BE ALTERED */
|
||||||
|
|
||||||
static std::string EXAMPLES[] = {
|
static std::vector<std::string> EXAMPLES = {
|
||||||
"format", "listdir", "range", "range_pipe", "signal",
|
"format", "listdir", "range", "range_pipe", "signal",
|
||||||
"stream1", "stream2", "coroutine1", "coroutine2", "concurrency"
|
"stream1", "stream2", "coroutine1", "coroutine2", "concurrency"
|
||||||
};
|
};
|
||||||
|
|
||||||
static fs::path ASM_SOURCE_DIR = "src/asm";
|
static fs::path ASM_SOURCE_DIR = "src/asm";
|
||||||
static std::string ASM_SOURCES[] = {
|
static strvec ASM_SOURCES = {
|
||||||
"jump_all_gas", "make_all_gas", "ontop_all_gas"
|
"jump_all_gas", "make_all_gas", "ontop_all_gas"
|
||||||
};
|
};
|
||||||
|
|
||||||
static fs::path CXX_SOURCE_DIR = "src";
|
static fs::path CXX_SOURCE_DIR = "src";
|
||||||
static std::string CXX_SOURCES[] = {
|
static strvec CXX_SOURCES = {
|
||||||
"context_stack", "environ", "io", "concurrency"
|
"context_stack", "environ", "io", "concurrency"
|
||||||
};
|
};
|
||||||
|
|
||||||
static fs::path TEST_DIR = "tests";
|
static fs::path TEST_DIR = "tests";
|
||||||
static std::string TEST_CASES[] = {
|
static strvec TEST_CASES = {
|
||||||
"algorithm", "range"
|
"algorithm", "range"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -107,9 +109,7 @@ static void print_help(ostd::string_range arg0) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void exec_command(
|
static void exec_command(std::string const &cmd, strvec const &args) {
|
||||||
std::string const &cmd, std::vector<std::string> const &args
|
|
||||||
) {
|
|
||||||
auto argp = std::make_unique<char *[]>(args.size() + 2);
|
auto argp = std::make_unique<char *[]>(args.size() + 2);
|
||||||
argp[0] = const_cast<char *>(cmd.data());
|
argp[0] = const_cast<char *>(cmd.data());
|
||||||
for (std::size_t i = 0; i < args.size(); ++i) {
|
for (std::size_t i = 0; i < args.size(); ++i) {
|
||||||
|
@ -134,9 +134,7 @@ static void exec_command(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string get_command(
|
static std::string get_command(std::string const &cmd, strvec const &args) {
|
||||||
std::string const &cmd, std::vector<std::string> const &args
|
|
||||||
) {
|
|
||||||
std::string ret = cmd;
|
std::string ret = cmd;
|
||||||
for (auto &s: args) {
|
for (auto &s: args) {
|
||||||
ret += ' ';
|
ret += ' ';
|
||||||
|
@ -145,7 +143,7 @@ static std::string get_command(
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_args(std::vector<std::string> &args, std::string const &cmdl) {
|
static void add_args(strvec &args, std::string const &cmdl) {
|
||||||
wordexp_t p;
|
wordexp_t p;
|
||||||
if (wordexp(cmdl.data(), &p, 0)) {
|
if (wordexp(cmdl.data(), &p, 0)) {
|
||||||
return;
|
return;
|
||||||
|
@ -297,9 +295,7 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto exec_v = [&io_msgs](
|
auto exec_v = [&io_msgs](std::string const &cmd, strvec const &args) {
|
||||||
std::string const &cmd, std::vector<std::string> const &args
|
|
||||||
) {
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
io_msgs.put(get_command(cmd, args));
|
io_msgs.put(get_command(cmd, args));
|
||||||
}
|
}
|
||||||
|
@ -307,58 +303,70 @@ int main(int argc, char **argv) {
|
||||||
};
|
};
|
||||||
|
|
||||||
auto call_cxx = [&](
|
auto call_cxx = [&](
|
||||||
std::string const &input, std::string const &output, bool shared
|
fs::path const &input, fs::path const &output, bool shared
|
||||||
) {
|
) {
|
||||||
std::vector<std::string> args;
|
strvec args;
|
||||||
add_args(args, cxxflags);
|
add_args(args, cxxflags);
|
||||||
|
|
||||||
|
auto ifs = input.string();
|
||||||
|
auto outp = output;
|
||||||
|
|
||||||
if (shared) {
|
if (shared) {
|
||||||
echo_q("CXX (shared): %s", input);
|
outp.replace_extension();
|
||||||
|
outp += "_dyn.o";
|
||||||
|
echo_q("CXX (shared): %s", ifs);
|
||||||
add_args(args, SHARED_CXXFLAGS);
|
add_args(args, SHARED_CXXFLAGS);
|
||||||
} else {
|
} else {
|
||||||
echo_q("CXX: %s", input);
|
echo_q("CXX: %s", ifs);
|
||||||
}
|
}
|
||||||
|
|
||||||
args.push_back("-c");
|
args.push_back("-c");
|
||||||
args.push_back("-o");
|
args.push_back("-o");
|
||||||
args.push_back(output);
|
args.push_back(outp.string());
|
||||||
args.push_back(input);
|
args.push_back(ifs);
|
||||||
|
|
||||||
exec_v(cxx, args);
|
exec_v(cxx, args);
|
||||||
|
|
||||||
|
return outp;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* mostly unnecessary to separately compile shared, but
|
/* mostly unnecessary to separately compile shared, but
|
||||||
* the files may check for __PIC__ (at least mips32 does)
|
* the files may check for __PIC__ (at least mips32 does)
|
||||||
*/
|
*/
|
||||||
auto call_as = [&](
|
auto call_as = [&](
|
||||||
std::string const &input, std::string const &output, bool shared
|
fs::path const &input, fs::path const &output, bool shared
|
||||||
) {
|
) {
|
||||||
std::vector<std::string> args;
|
strvec args;
|
||||||
add_args(args, asflags);
|
add_args(args, asflags);
|
||||||
|
|
||||||
|
auto ifs = input.string();
|
||||||
|
auto outp = output;
|
||||||
|
|
||||||
if (shared) {
|
if (shared) {
|
||||||
echo_q("AS (shared): %s", input);
|
outp.replace_extension();
|
||||||
|
outp += "_dyn.o";
|
||||||
|
echo_q("AS (shared): %s", ifs);
|
||||||
add_args(args, SHARED_ASFLAGS);
|
add_args(args, SHARED_ASFLAGS);
|
||||||
} else {
|
} else {
|
||||||
echo_q("AS: %s", input);
|
echo_q("AS: %s", ifs);
|
||||||
}
|
}
|
||||||
|
|
||||||
args.push_back("-c");
|
args.push_back("-c");
|
||||||
args.push_back("-o");
|
args.push_back("-o");
|
||||||
args.push_back(output);
|
args.push_back(outp.string());
|
||||||
args.push_back(input);
|
args.push_back(ifs);
|
||||||
|
|
||||||
exec_v(as, args);
|
exec_v(as, args);
|
||||||
|
|
||||||
|
return outp;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto call_ld = [&](
|
auto call_ld = [&](
|
||||||
std::string const &output,
|
std::string const &output, strvec const &files, strvec const &flags
|
||||||
std::vector<std::string> const &files,
|
|
||||||
std::vector<std::string> const &flags
|
|
||||||
) {
|
) {
|
||||||
echo_q("LD: %s", output);
|
echo_q("LD: %s", output);
|
||||||
|
|
||||||
std::vector<std::string> args;
|
strvec args;
|
||||||
add_args(args, cxxflags);
|
add_args(args, cxxflags);
|
||||||
|
|
||||||
args.push_back("-o");
|
args.push_back("-o");
|
||||||
|
@ -378,10 +386,9 @@ int main(int argc, char **argv) {
|
||||||
};
|
};
|
||||||
|
|
||||||
auto call_ldlib = [&](
|
auto call_ldlib = [&](
|
||||||
std::string const &output, std::vector<std::string> const &files,
|
std::string const &output, strvec const &files, bool shared
|
||||||
bool shared
|
|
||||||
) {
|
) {
|
||||||
std::vector<std::string> args;
|
strvec args;
|
||||||
if (shared) {
|
if (shared) {
|
||||||
add_args(args, SHARED_CXXFLAGS);
|
add_args(args, SHARED_CXXFLAGS);
|
||||||
add_args(args, SHARED_LDFLAGS);
|
add_args(args, SHARED_LDFLAGS);
|
||||||
|
@ -402,7 +409,7 @@ int main(int argc, char **argv) {
|
||||||
auto ccf = path_with_ext(base, ".cc");
|
auto ccf = path_with_ext(base, ".cc");
|
||||||
auto obf = path_with_ext(base, ".o");
|
auto obf = path_with_ext(base, ".o");
|
||||||
|
|
||||||
call_cxx(ccf.string(), obf.string(), false);
|
call_cxx(ccf, obf, false);
|
||||||
call_ld(base.string(), { obf.string() }, { default_lib });
|
call_ld(base.string(), { obf.string() }, { default_lib });
|
||||||
|
|
||||||
try_remove(obf);
|
try_remove(obf);
|
||||||
|
@ -436,7 +443,7 @@ int main(int argc, char **argv) {
|
||||||
);
|
);
|
||||||
f.close();
|
f.close();
|
||||||
|
|
||||||
call_cxx(ccf.string(), obf.string(), false);
|
call_cxx(ccf, obf, false);
|
||||||
call_ld(base.string(), { obf.string() }, { default_lib });
|
call_ld(base.string(), { obf.string() }, { default_lib });
|
||||||
try_remove(obf);
|
try_remove(obf);
|
||||||
};
|
};
|
||||||
|
@ -447,68 +454,61 @@ int main(int argc, char **argv) {
|
||||||
try_remove("test_runner.o");
|
try_remove("test_runner.o");
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<std::string> asm_obj, cxx_obj, asm_dynobj, cxx_dynobj;
|
|
||||||
|
|
||||||
ostd::thread_pool tp;
|
ostd::thread_pool tp;
|
||||||
tp.start();
|
tp.start();
|
||||||
|
|
||||||
std::queue<std::future<void>> futures;
|
std::queue<std::future<fs::path>> future_obj, future_dynobj;
|
||||||
|
|
||||||
/* build object file in static and shared (PIC) variants */
|
/* build object files in static and shared (PIC) variants */
|
||||||
auto build_obj = [&tp, &futures, build_static, build_shared](
|
auto build_all = [&](
|
||||||
fs::path const &fpath, fs::path const &sext, auto &buildf,
|
strvec &list, fs::path const &spath, fs::path const &sext, auto &buildf
|
||||||
auto &obj, auto &dynobj
|
|
||||||
) {
|
) {
|
||||||
|
auto build_obj = [&](fs::path const &fpath, bool shared) {
|
||||||
auto srcf = path_with_ext(fpath, sext);
|
auto srcf = path_with_ext(fpath, sext);
|
||||||
if (build_static) {
|
|
||||||
auto srco = path_with_ext(srcf, ".o");
|
auto srco = path_with_ext(srcf, ".o");
|
||||||
futures.push(tp.push([&, srcf, srco]() {
|
auto &fq = (shared ? future_dynobj : future_obj);
|
||||||
buildf(srcf.string(), srco.string(), false);
|
fq.push(tp.push([&buildf, srcf, srco, shared]() {
|
||||||
|
return buildf(srcf, srco, shared);
|
||||||
}));
|
}));
|
||||||
obj.push_back(srco.string());
|
};
|
||||||
|
for (auto sf: list) {
|
||||||
|
auto sp = spath / sf;
|
||||||
|
if (build_static) {
|
||||||
|
build_obj(sp, false);
|
||||||
}
|
}
|
||||||
if (build_shared) {
|
if (build_shared) {
|
||||||
auto srco = srcf;
|
build_obj(sp, true);
|
||||||
srco.replace_extension();
|
}
|
||||||
srco += "_dyn.o";
|
|
||||||
futures.push(tp.push([&, srcf, srco]() {
|
|
||||||
buildf(srcf.string(), srco.string(), true);
|
|
||||||
}));
|
|
||||||
dynobj.push_back(srco.string());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
echo_q("Building the library...");
|
echo_q("Building the library...");
|
||||||
for (auto aso: ASM_SOURCES) {
|
build_all(ASM_SOURCES, ASM_SOURCE_DIR, ".S", call_as);
|
||||||
build_obj(ASM_SOURCE_DIR / aso, ".S", call_as, asm_obj, asm_dynobj);
|
build_all(CXX_SOURCES, CXX_SOURCE_DIR, ".cc", call_cxx);
|
||||||
}
|
|
||||||
for (auto cso: CXX_SOURCES) {
|
|
||||||
build_obj(CXX_SOURCE_DIR / cso, ".cc", call_cxx, cxx_obj, cxx_dynobj);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!futures.empty()) {
|
|
||||||
/* wait and propagate possible exception */
|
|
||||||
futures.front().get();
|
|
||||||
futures.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (build_static) {
|
if (build_static) {
|
||||||
std::vector<std::string> all_obj;
|
strvec objs;
|
||||||
all_obj.insert(all_obj.cend(), asm_obj.begin(), asm_obj.end());
|
while (!future_obj.empty()) {
|
||||||
all_obj.insert(all_obj.cend(), cxx_obj.begin(), cxx_obj.end());
|
objs.push_back(future_obj.front().get());
|
||||||
call_ldlib(OSTD_STATIC_LIB, all_obj, false);
|
future_obj.pop();
|
||||||
|
}
|
||||||
|
call_ldlib(OSTD_STATIC_LIB, objs, false);
|
||||||
}
|
}
|
||||||
if (build_shared) {
|
if (build_shared) {
|
||||||
std::vector<std::string> all_obj;
|
strvec objs;
|
||||||
all_obj.insert(all_obj.cend(), asm_dynobj.begin(), asm_dynobj.end());
|
while (!future_dynobj.empty()) {
|
||||||
all_obj.insert(all_obj.cend(), cxx_dynobj.begin(), cxx_dynobj.end());
|
objs.push_back(future_dynobj.front().get());
|
||||||
call_ldlib(OSTD_SHARED_LIB, all_obj, true);
|
future_dynobj.pop();
|
||||||
}
|
}
|
||||||
|
call_ldlib(OSTD_SHARED_LIB, objs, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::queue<std::future<void>> future_bin;
|
||||||
|
|
||||||
if (build_examples) {
|
if (build_examples) {
|
||||||
echo_q("Building examples...");
|
echo_q("Building examples...");
|
||||||
for (auto ex: EXAMPLES) {
|
for (auto ex: EXAMPLES) {
|
||||||
futures.push(tp.push([&build_example, ex]() {
|
future_bin.push(tp.push([&build_example, ex]() {
|
||||||
build_example(ex);
|
build_example(ex);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -524,16 +524,16 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto test: TEST_CASES) {
|
for (auto test: TEST_CASES) {
|
||||||
futures.push(tp.push([&build_test, test]() {
|
future_bin.push(tp.push([&build_test, test]() {
|
||||||
build_test(test);
|
build_test(test);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!futures.empty()) {
|
while (!future_bin.empty()) {
|
||||||
/* wait and propagate possible exception */
|
/* wait and propagate possible exception */
|
||||||
futures.front().get();
|
future_bin.front().get();
|
||||||
futures.pop();
|
future_bin.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (build_testsuite) {
|
if (build_testsuite) {
|
||||||
|
|
|
@ -115,12 +115,22 @@ struct channel {
|
||||||
*
|
*
|
||||||
* @throws ostd::channel_error when the channel is closed.
|
* @throws ostd::channel_error when the channel is closed.
|
||||||
*
|
*
|
||||||
* @see put(T const &)
|
* @see put(T const &), emplace()
|
||||||
*/
|
*/
|
||||||
void put(T &&val) {
|
void put(T &&val) {
|
||||||
p_state->put(std::move(val));
|
p_state->put(std::move(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Like put(), but constructs the element in-place.
|
||||||
|
*
|
||||||
|
* The arguments are to be passed to the element constructor.
|
||||||
|
* No copy or move operations are performed.
|
||||||
|
*/
|
||||||
|
template<typename ...A>
|
||||||
|
void emplace(A &&...args) {
|
||||||
|
p_state->emplace(std::forward<A>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
/** @brief Waits for a value and returns it.
|
/** @brief Waits for a value and returns it.
|
||||||
*
|
*
|
||||||
* If the queue is empty at the time of the call, this will block the
|
* If the queue is empty at the time of the call, this will block the
|
||||||
|
@ -211,6 +221,18 @@ private:
|
||||||
p_cond.notify_one();
|
p_cond.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename ...A>
|
||||||
|
void emplace(A &&...args) {
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> l{p_lock};
|
||||||
|
if (p_closed) {
|
||||||
|
throw channel_error{"emplace in a closed channel"};
|
||||||
|
}
|
||||||
|
p_messages.emplace(std::forward<A>(args)...);
|
||||||
|
}
|
||||||
|
p_cond.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
bool get(T &val, bool w) {
|
bool get(T &val, bool w) {
|
||||||
std::unique_lock<std::mutex> l{p_lock};
|
std::unique_lock<std::mutex> l{p_lock};
|
||||||
if (w) {
|
if (w) {
|
||||||
|
|
Loading…
Reference in a new issue