Current section

Files

Jump to
re2 rebar.config.script
Raw

rebar.config.script

%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
%% ex: ts=4 sw=4 ft=erlang et
%%
%% Copyright 2016-2019 Tuncer Ayaz
%%
%% Permission to use, copy, modify, and distribute this software for any
%% purpose with or without fee is hereby granted, provided that the above
%% copyright notice and this permission notice appear in all copies.
%%
%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
%% If library matching wildcard can be found in common lib dirs, return Opt1,
%% otherwise Opt2.
FindLibByWC = fun(WC, Opt1, Opt2) ->
Dirs = [ "/usr/local/lib/"
, "/usr/lib64/"
, "/usr/lib/"
, "/lib64/"
, "/lib/"
],
case lists:flatmap(
fun(D) ->
filelib:wildcard(D ++ WC)
end,
Dirs)
of
[] -> Opt2;
[LibDir|_] -> {filename:dirname(LibDir), Opt1}
end
end.
LocalIncDir = "-Ic_src/re2".
%% Find RE2 include dir on system.
Re2IncDir = fun() ->
UsrLocalH = "/usr/local/include/re2/re2.h",
UsrH = "/usr/include/re2/re2.h",
%% Get include dir which contains the re2/ dir.
Hs = [filename:dirname(filename:dirname(F)) ||
F <- filelib:wildcard(UsrLocalH)
++ filelib:wildcard(UsrH)],
case Hs of
[] -> not_found;
[IncDir|_] -> "-I" ++ IncDir
end
end.
FindRe2 = fun(SysLib, LocalLib) ->
%% If there is libre2.so, use it, otherwise enable fetching
%% and building a local RE2 copy.
Lib = FindLibByWC("libre2.{so,dylib}", SysLib, LocalLib),
IncDir = Re2IncDir(),
case {IncDir, Lib} of
%% re2.h not found, and even though libre2 might
%% exist, we need the headers. Therefore, fall back to
%% local RE2.
{not_found, {_LibDir, SysLib}} ->
{LocalIncDir, LocalLib};
%% Neither re2.h nor libre2.so found, use local lib.
{not_found, not_found} ->
{LocalIncDir, LocalLib};
%% If re2.h is found, but there is no libre2.so, which
%% should never be the case, fall back to local RE2.
{IncDir, LocalLib} ->
{LocalIncDir, LocalLib};
%% If re2.h and libre2.so are found, we can use
%% system RE2.
{IncDir, {LibDir, SysLib}=Sys} ->
{IncDir, Sys}
end
end.
LibName = case os:type() of
{win32,_} -> "re2.lib";
_ -> "libre2.a"
end.
CLANG_GCC_EXTRA_CFLAGS="-Wall -Wextra -Wpedantic".
ExtraCFLAGS = case os:type() of
{unix,_} -> CLANG_GCC_EXTRA_CFLAGS;
_ -> ""
end.
GetFlagsAndLocalArchive =
fun() ->
WinRelFlags = "/MD",
WinDbgFlags = "/MDd",
RelFlags = [],
DbgFlags = "-g",
ObjDir = filename:join(["c_src", "re2", "obj"]),
RelArchive = filename:join(ObjDir, LibName),
DbgArchive = filename:join([ObjDir, "dbg", LibName]),
case {os:type(), os:getenv("RE2_DEBUG")} of
{{unix,_}, false} -> {RelFlags, RelArchive};
{{unix,_}, "1"} -> {DbgFlags, DbgArchive};
{{win32,_}, false} -> {WinRelFlags, RelArchive};
{{win32,_}, "1"} -> {WinDbgFlags, RelArchive}
end
end.
{Flags, LocalRe2Archive} = GetFlagsAndLocalArchive().
WhichRe2 = fun() ->
SysRe2Lib = {sys, "-lre2"},
LocalRe2Lib = {local, LocalRe2Archive},
%% If env var SYSTEM_RE2 is set, try to find system RE2 and
%% only fall back to local RE2 if it cannot be found in the
%% system. Ideally, the default should be the other way
%% around, but it's likely this would disrupt too many
%% users' environments due to the requirement of having
%% libre2.so available.
case os:getenv("SYSTEM_RE2") of
false ->
{LocalIncDir, LocalRe2Lib};
_ ->
FindRe2(SysRe2Lib, LocalRe2Lib)
end
end.
PortOpts = fun() ->
PortSpecs = {port_specs,
[
{"priv/re2_nif.so", ["c_src/re2_nif.cc"]}
]},
BaseCFLAGS = "$DRV_CFLAGS -O3 -std=c++11 " ++
ExtraCFLAGS ++ " " ++ Flags ++ " ",
Hooks = [ {pre_hooks,
[{{pc, compile}, "sh -c c_src/build_deps.sh"}]}
, {post_hooks,
[{{pc, clean}, "sh -c 'c_src/build_deps.sh clean'"}]}
],
case WhichRe2() of
{Inc, {LibDir, {sys, Lib}}} ->
%% Use existing (system) RE2
[ PortSpecs
, {port_env,
[ {"DRV_CFLAGS", BaseCFLAGS ++ Inc}
, {"DRV_LDFLAGS",
"$DRV_LDFLAGS -L" ++ LibDir
++ " " ++ Lib}
]}
];
{Inc, {local, Lib}} ->
%% Use local RE2, which is fetched
%% and built by a shell hook.
PortCompilerSettings =
[ PortSpecs
, {port_env,
[ {"DRV_CFLAGS", BaseCFLAGS ++ Inc}
, {"DRV_LDFLAGS",
"$DRV_LDFLAGS " ++ Lib}
]}
],
PortCompilerSettings ++ Hooks
end
end.
PCDep = {pc, {git, "https://github.com/blt/port_compiler", {tag, "v1.10.2"}}}.
%% PCDep = pc.
%% TestDeps = [{triq, ".*",
%% {git, "https://gitlab.com/triq/triq.git", {branch, "master"}}}].
TestDeps = [triq].
DebugWarns = [warnings_as_errors].
Artifact = case os:type() of
{win32,_} -> "priv/re2_nif.dll";
_ -> "priv/re2_nif.so"
end.
GeneralOpts = [ {plugins, [PCDep]}
, {artifacts, [Artifact]}
, {pc_clang_db, true}
, {provider_hooks,
[ {pre,
[ {compile, {pc, compile}}
, {clean, {pc, clean}}
]}
]}
, {eunit_opts, [verbose]}
, {profiles
, [ {test
, [ {deps, TestDeps}
, {erl_opts, DebugWarns}
]}
, {debug
, [ {port_env, [{"DRV_CFLAGS", "$DRV_CFLAGS -DDEBUG"}]}
, {erl_opts, DebugWarns ++ [{d, 'DEV'}, {d, 'DEBUG'}]}
]}
]}
].
Config = GeneralOpts ++ PortOpts().
case os:getenv("DEBUG_CONFIG") of
false ->
Config;
_ ->
io:format(standard_error, "rebar config:~n~p~n", [Config]),
Config
end.