You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
386 lines
9.8 KiB
386 lines
9.8 KiB
/**
|
|
* ***** BEGIN LICENSE BLOCK *****
|
|
*
|
|
* Copyright 2017-2023 Yzena, LLC
|
|
*
|
|
* Licensed under the Yzena Viral User License, Version 0.1 (the "Yzena Viral
|
|
* User License" or "YVUL"), the GNU Affero General Public License (the "GNU
|
|
* AGPL"), Version 3.0, and the Server Side Public License (the "SSPL"),
|
|
* Version 1. You may not use this file except in compliance with all of those
|
|
* licenses.
|
|
*
|
|
* You may obtain a copy of the Yzena Viral User License at
|
|
*
|
|
* https://yzena.com/yzena-viral-user-license/
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the Yzena Viral User License is distributed under the
|
|
* following disclaimer:
|
|
*
|
|
* As far as the law allows, this software comes as is, without any
|
|
* warranty or condition, and no contributor will be liable to anyone for
|
|
* any damages related to this software or this license, under any kind of
|
|
* legal claim.
|
|
*
|
|
* You may obtain a copy of the GNU Affero General Public License at
|
|
*
|
|
* https://www.gnu.org/licenses/agpl-3.0.html
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the GNU Affero General Public License is distributed under
|
|
* the following disclaimer:
|
|
*
|
|
* This software is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
|
|
* General Public License for more details.
|
|
*
|
|
* You may obtain a copy of the Server Side Public License at
|
|
*
|
|
* https://www.mongodb.com/licensing/server-side-public-license
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the Server Side Public License is distributed under the
|
|
* following disclaimer:
|
|
*
|
|
* This software is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Server
|
|
* Side Public License for more details.
|
|
*
|
|
* ****** END LICENSE BLOCK ******
|
|
*
|
|
* *****************************************************************
|
|
*
|
|
* ******* BEGIN FILE DESCRIPTION *******
|
|
*
|
|
* Main build script file.
|
|
*
|
|
* ******** END FILE DESCRIPTION ********
|
|
*/
|
|
|
|
if config["afl"] && !config["debug"]
|
|
{
|
|
error "Cannot enable AFL for non-debug builds";
|
|
}
|
|
|
|
if config["ftrace"] && !config["alloc_accounting"]
|
|
{
|
|
error "Must enable allocator accounting with ftrace";
|
|
}
|
|
|
|
if config["cflags.opt"] == ""
|
|
{
|
|
config["cflags.opt"]! = "0";
|
|
}
|
|
|
|
dbg: str = if config["debug"] { sysdb["debug"]; } else { ""; };
|
|
opt: str = sysdb["cflags.opt"] +~ config["optimization"];
|
|
cc: str = if config["cc"] != "" { config["cc"]; } else { sysdb["cc"]; };
|
|
|
|
if !(rigdb["execs"] contains cc)
|
|
{
|
|
error "C compiler " +~ cc +~ " does not exist";
|
|
}
|
|
|
|
outopt: str = sysdb[cc]["outopt"];
|
|
objopt: str = sysdb[cc]["objopt"];
|
|
incopt: str = sysdb[cc]["incopt"] +~ "include";
|
|
defopt: str = sysdb[cc]["defopt"];
|
|
|
|
defs: ![]str =
|
|
if platform.os == "Windows"
|
|
{
|
|
#[ ];
|
|
}
|
|
else
|
|
{
|
|
if platform.os != "FreeBSD"
|
|
{
|
|
#[ "-D_BSD_SOURCE", "-D_GNU_SOURCE", "-D_DEFAULT_SOURCE",
|
|
"-D_DARWIN_C_SOURCE", "-D_POSIX_C_SOURCE=200809L",
|
|
"-D_XOPEN_SOURCE=700" ];
|
|
}
|
|
else
|
|
{
|
|
#[ "-D_BSD_SOURCE", "-D_GNU_SOURCE", "-D_DEFAULT_SOURCE",
|
|
"-D_DARWIN_C_SOURCE" ];
|
|
}
|
|
};
|
|
|
|
defs! +~= option(defopt, "YC_SAFE", "safe");
|
|
defs! +~= option(defopt, "YC_ENABLE_STACKTRACES", "stacktraces");
|
|
defs! +~= option(defopt, "YC_ENABLE_FTRACE", "ftrace");
|
|
defs! +~= option(defopt, "YC_ENABLE_AFL", "afl");
|
|
defs! +~= option(defopt, "YC_ENABLE_ALLOC_ACCOUNTING", "alloc_accounting");
|
|
defs! +~= option(defopt, "YC_ENABLE_BUILTIN_128", "builtin_128");
|
|
|
|
cflags: ![]str = config["cflags"];
|
|
ldflags: ![]str = config["ldflags"];
|
|
|
|
// We need pthread for POSIX systems.
|
|
if platform.os != "Windows"
|
|
{
|
|
ldflags! +~= "-lpthread";
|
|
}
|
|
|
|
if platform.os != "Windows"
|
|
{
|
|
defs! +~= option(defopt, "YC_USE_VALGRIND", "use_valgrind");
|
|
|
|
if cc contains "clang" || cc contains "gcc"
|
|
{
|
|
cflags! +~= "-std=c11";
|
|
|
|
if config["strict"]
|
|
{
|
|
cflags! +~= #[ "-Wall", "-Wextra", "-Werror", "-pedantic" ];
|
|
|
|
if cc contains "clang"
|
|
{
|
|
// I also want to see all of the errors at once.
|
|
cflags! +~= #[ "-Weverything", "-Wno-c++98-compat",
|
|
"-ferror-limit=100000" ];
|
|
}
|
|
}
|
|
|
|
if !config["debug"]
|
|
{
|
|
cflags! +~= #[ "-flto", "-fsanitize=cfi", "-fvisibility=hidden" ];
|
|
}
|
|
}
|
|
|
|
defs! +~= option(defopt, "YC_USE_POSIX_SPAWN", "use_posix_spawn");
|
|
}
|
|
else
|
|
{
|
|
if config["strict"]
|
|
{
|
|
cflags! +~= #[ "/W4", "/WX", "/wd\"4996\"", "/permissive-" ];
|
|
}
|
|
}
|
|
|
|
if cc contains "clang"
|
|
{
|
|
if config["debug"]
|
|
{
|
|
sanitizer: sym = config["sanitizer"];
|
|
|
|
if sanitizer != #none
|
|
{
|
|
if config["use_valgrind"]
|
|
{
|
|
error "Cannot use a sanitizer with Valgrind";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
flags: []str = #[ "-fno-omit-frame-pointer",
|
|
"-fno-optimize-sibling-calls", "-fno-common" ];
|
|
|
|
cflags! +~= flags;
|
|
ldflags! +~= flags;
|
|
|
|
cflags! +~= #[ "-fno-sanitize-recover=all" ];
|
|
}
|
|
|
|
if sanitizer == #address
|
|
{
|
|
cflags! +~= #[ "-fsanitize=address" ];
|
|
}
|
|
else if sanitizer == #memory
|
|
{
|
|
cflags! +~= #[ "-fsanitize=memory" ];
|
|
}
|
|
else if sanitizer == #undefined
|
|
{
|
|
cflags! +~= #[ "-fsanitize=undefined" ];
|
|
}
|
|
else if sanitizer == #thread
|
|
{
|
|
cflags! +~= #[ "-fsanitize=thread" ];
|
|
}
|
|
}
|
|
}
|
|
|
|
if config["debug"]
|
|
{
|
|
defs! = defs +~ option(defopt, "YC_DEBUG_CODE", "debug_code");
|
|
defs! = defs +~ option(defopt, "YC_DEBUG_PRINT", "debug_print");
|
|
}
|
|
else
|
|
{
|
|
defs! = defs +~ #[ defopt +~ "YC_DEBUG_CODE=0" ];
|
|
defs! = defs +~ #[ defopt +~ "YC_DEBUG_PRINT=0" ];
|
|
}
|
|
|
|
cmd_line: []str = #[ cc ] +~ cflags +~ defs +~ ldflags +~ #[ dbg, opt, objout,
|
|
incopt, outopt ];
|
|
config["cmd_line"]! = cmd_line;
|
|
|
|
exe_cmd_line: []str = #[ cc ] +~ cflags +~ defs +~ ldflags +~ #[ dbg, opt,
|
|
incopt,
|
|
outopt ];
|
|
config["exe_cmd_line"]! = exe_cmd_line;
|
|
|
|
src_files: []str = walk_src_dir();
|
|
libyc: str = add_lib("yc", src_files);
|
|
yc: str = add_exe(yc, #[ "src/main.c", libyc ]);
|
|
|
|
extras: ![]str = #[ ];
|
|
exes: ![]str = #[ ];
|
|
exes! +~= yc;
|
|
|
|
exes! +~= walk_test_dir(libyc);
|
|
|
|
if config["benchmarks"]
|
|
{
|
|
if config["benchmark.arith"]
|
|
{
|
|
exes! +~= add_exe("benchmarks/yc_benchmark_arith",
|
|
#[ "benchmarks/arith.c", libyc ]);
|
|
}
|
|
|
|
if config["benchmark.memcpy"]
|
|
{
|
|
exes! +~= add_exe("benchmarks/yc_benchmark_memcpy",
|
|
#[ "benchmarks/memcpy.c", libyc ]);
|
|
}
|
|
|
|
if config["benchmark.xxh3_v_spooky"]
|
|
{
|
|
exes! +~= add_exe("benchmarks/yc_benchmark_xxh3_v_spooky",
|
|
#[ "benchmarks/xxh3_v_spooky.c", libyc ]);
|
|
}
|
|
|
|
if config["benchmark.listdir"]
|
|
{
|
|
exes! +~= add_exe("benchmarks/yc_benchmark_listdir",
|
|
#[ "benchmarks/listdir.c", libyc ]);
|
|
}
|
|
}
|
|
|
|
if config["samples"] && config["samples.io"]
|
|
{
|
|
exes! +~= add_exe("samples/io/file_open",
|
|
#[ "samples/io/file_open.c", libyc ]);
|
|
exes! +~= add_exe("samples/io/random_access",
|
|
#[ "samples/io/random_access.c", libyc ]);
|
|
exes! +~= add_exe("samples/io/interactive",
|
|
#[ "samples/io/interactive.c", libyc ]);
|
|
exes! +~= add_exe("samples/io/list_to_file",
|
|
#[ "samples/io/list_to_file.c", libyc ]);
|
|
}
|
|
|
|
pub_headers: []str = find "*.h", "include/yc";
|
|
if config["docs.install"]
|
|
{
|
|
install #include: pub_headers;
|
|
}
|
|
|
|
if platform.os != "Windows" && config["docs"]
|
|
{
|
|
if !(rigdb["execs"] contains "doxygen")
|
|
{
|
|
error "Cannot find doxygen, required for docs";
|
|
}
|
|
|
|
if !(rigdb["execs"] contains "sphinx-build")
|
|
{
|
|
error "Cannot find sphinx-build, required for docs";
|
|
}
|
|
|
|
if config["docs.versioned"] &&
|
|
!(rigdb["execs"] contains "sphinx-multiversion")
|
|
{
|
|
error "Cannot find sphinx-multiversion, required for versioned docs";
|
|
}
|
|
|
|
priv_headers: []str =
|
|
if config["docs.internal"]
|
|
{
|
|
find_recursive "*.h", "src/";
|
|
}
|
|
else
|
|
{
|
|
#[ ];
|
|
};
|
|
|
|
config["YC_DOCS_INTERNAL"]! =
|
|
if config["docs.internal"]
|
|
{
|
|
"INTERNAL";
|
|
}
|
|
else
|
|
{
|
|
"";
|
|
};
|
|
|
|
doxy_out_dir: str = config["binary"] +~ "/doxygen";
|
|
doxy_idx: str = doxy_out_dir +~ "xml/index.xml";
|
|
|
|
config["doxy_out_dir"]! = doxy_out_dir;
|
|
|
|
doxyfile: str = add_config_file("docs/doxyfile", "docs/doxyfile.in");
|
|
|
|
target #doxygen: doxy_idx;
|
|
target doxy_idx: doxyfile, pub_headers, priv_headers
|
|
{
|
|
$ doxygen @(deps[0]);
|
|
}
|
|
|
|
sphinx_bin_dir: str = rigdb["binary_dir"] +~ "/sphinx";
|
|
config["sphinx_bin_dir"]! = sphinx_bin_dir;
|
|
sphinx_idx: str = sphinx_bin_dir +~ "/index.html";
|
|
sphinx_conf: str = rigdb["source_dir"] +~ "/docs/conf.py";
|
|
|
|
rst_files: str = find_recursive "*.rst", "docs/";
|
|
|
|
if config["docs.versioned"]
|
|
{
|
|
target sphinx_idx: sphinx_conf, rst_files, doxy_idx
|
|
{
|
|
$ sphinx-multiversion
|
|
@("-Dbreathe_projects.yc=" +~ config["doxy_out_dir"] +~ "/xml")
|
|
@(rigdb["source_dir"] +~ "/docs")
|
|
@(config["sphinx_bin_dir"]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
target sphinx_idx: sphinx_conf, rst_files, doxy_idx
|
|
{
|
|
$ sphinx-build -b html
|
|
@("-Dbreathe_projects.yc=" +~ config["doxy_out_dir"] +~ "/xml")
|
|
@(config["source_dir"] +~ "/docs")
|
|
@(config["sphinx_bin_dir"] +~ "/docs");
|
|
}
|
|
}
|
|
|
|
target #docs: sphinx_idx
|
|
{
|
|
$ @(config["source_dir"] +~ "/docs/_res/compress.sh")
|
|
@(config["sphinx_bin_dir"])
|
|
@(rigdb["binary_dir"] +~ "/docs");
|
|
$ @(config["source_dir"] +~ "/docs/_res/copy_static.sh")
|
|
@(config["source_dir"] +~ "/docs")
|
|
@(config["sphinx_bin_dir"]);
|
|
}
|
|
|
|
// TODO: Handle installing docs. This has to be done *after* I make my own
|
|
// docs system to replace sphinx and breathe because the only docs that
|
|
// should be installed are manpages, and I need to make my system able to
|
|
// handle generating manpages.
|
|
|
|
// Make sure to generate docs when running the #all target.
|
|
extras! +~= #docs;
|
|
}
|
|
|
|
exes! +~= add_link_exe("rig", yc);
|
|
exes! +~= add_link_exe("rigc", yc);
|
|
|
|
install #bin: execs;
|
|
install #lib: libyc;
|
|
|
|
target #all: exes, extras;
|