From 56b801b2c9d91aa341695a24ac71f11c4efb7a69 Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz Date: Mon, 3 May 2010 04:03:38 +0200 Subject: Add new erl_opts option to specify platform-specific defines --- src/rebar_erlc_compiler.erl | 54 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 5 deletions(-) (limited to 'src/rebar_erlc_compiler.erl') diff --git a/src/rebar_erlc_compiler.erl b/src/rebar_erlc_compiler.erl index 760111f..805c145 100644 --- a/src/rebar_erlc_compiler.erl +++ b/src/rebar_erlc_compiler.erl @@ -38,6 +38,22 @@ %% Public API %% =================================================================== +%% Supported configuration variables: +%% +%% * erl_opts - Erlang list of options passed to compile:file/2 +%% It is also possible to specify platform specific +%% options by specifying a triplet where the first string +%% is a regex that is checked against Erlang's system +%% architecture string. E.g. to define HAVE_SENDFILE only +%% on systems with sendfile() and define BACKLOG on +%% Linux/FreeBSD as 128 do: +%% {erl_opts, [{platform_define, +%% "(linux|solaris|freebsd|darwin)", +%% 'HAVE_SENDFILE'}, +%% {platform_define, "(linux|freebsd)" +%% 'BACKLOG', 128}]}. +%% + -spec compile(Config::#config{}, AppFile::string()) -> 'ok'. compile(Config, _AppFile) -> rebar_base_compiler:run(Config, @@ -85,7 +101,8 @@ doterl_compile(Config, OutDir) -> doterl_compile(Config, OutDir, MoreSources) -> FirstErls = rebar_config:get_list(Config, erl_first_files, []), - ErlOpts = rebar_config:get(Config, erl_opts, []), + ErlOpts = filter_defines(rebar_config:get(Config, erl_opts, []), []), + ?DEBUG("erl_opts ~p~n",[ErlOpts]), %% Support the src_dirs option allowing multiple directories to %% contain erlang source. This might be used, for example, should eunit tests be %% separated from the core application source. @@ -103,7 +120,9 @@ doterl_compile(Config, OutDir, MoreSources) -> CurrPath = code:get_path(), code:add_path("ebin"), rebar_base_compiler:run(Config, FirstErls, SortedRestErls, - fun(S, C) -> internal_erl_compile(S, C, OutDir) end), + fun(S, C) -> internal_erl_compile(S, C, OutDir, + ErlOpts) + end), code:set_path(CurrPath), ok. @@ -166,8 +185,9 @@ needs_compile(Source, Target, Hrls) -> lists:any(fun(I) -> TargetLastMod < filelib:last_modified(I) end, [Source] ++ Hrls). --spec internal_erl_compile(Source::string(), Config::#config{}, Outdir::string()) -> 'ok' | 'skipped'. -internal_erl_compile(Source, Config, Outdir) -> +-spec internal_erl_compile(Source::string(), Config::#config{}, + Outdir::string(), ErlOpts::list()) -> 'ok' | 'skipped'. +internal_erl_compile(Source, Config, Outdir, ErlOpts) -> %% Determine the target name and includes list by inspecting the source file {Module, Hrls} = inspect(Source, include_path(Source, Config)), @@ -180,7 +200,7 @@ internal_erl_compile(Source, Config, Outdir) -> case needs_compile(Source, Target, Hrls) of true -> Opts = [{i, "include"}, {outdir, filename:dirname(Target)}, report, return] ++ - rebar_config:get(Config, erl_opts, []), + ErlOpts, case compile:file(Source, Opts) of {ok, _, []} -> ok; @@ -294,3 +314,27 @@ compile_priority(File) -> lists:foldl(F, 10, Trees) end. + +%% +%% Filter a list of env vars such that only those which match the provided +%% architecture regex (or do not have a regex) are returned. +%% +-spec filter_defines(ErlOpts::list(),Acc::list()) -> list(). +filter_defines([], Acc) -> + lists:reverse(Acc); +filter_defines([{platform_define, ArchRegex, Key} | Rest], Acc) -> + case rebar_utils:is_arch(ArchRegex) of + true -> + filter_defines(Rest, [{d, Key} | Acc]); + false -> + filter_defines(Rest, Acc) + end; +filter_defines([{platform_define, ArchRegex, Key, Value} | Rest], Acc) -> + case rebar_utils:is_arch(ArchRegex) of + true -> + filter_defines(Rest, [{d, Key, Value} | Acc]); + false -> + filter_defines(Rest, Acc) + end; +filter_defines([Opt | Rest], Acc) -> + filter_defines(Rest, [Opt | Acc]). -- cgit v1.1