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-2018 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.
{DebugFlags, LocalRe2Archive} = case os:getenv("RE2_DEBUG") of
false ->
{[], "c_src/re2/obj/libre2.a"};
_ ->
{"-g", "c_src/re2/obj/dbg/libre2.a"}
end,
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 "
"-Wall -Wextra -Wpedantic " ++ DebugFlags ++ " ",
Hooks = [ {pre_hooks,
[{{pc, compile}, "c_src/build_deps.sh"}]}
, {post_hooks,
[{{pc, clean}, "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.1"}}}.
%% PCDep = pc.
%% TestDeps = [{triq, ".*",
%% {git, "https://gitlab.com/triq/triq.git", {branch, "master"}}}].
TestDeps = [triq].
DebugWarns = [warnings_as_errors].
GeneralOpts = [ {plugins, [PCDep]}
, {artifacts, ["priv/re2_nif.so"]}
, {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.