Skip to content
This repository
Browse code

Add support for target-specific port options

{port_specs, [{".*", "priv/foo.so", ["c_src/foo.c"], [{env, []}]}]}.
  • Loading branch information...
commit 7c418ed2b4a4316e4a784b83c2ffbdc1adf33dbe 1 parent 2ae73cc
Tuncer Ayaz tuncer authored
6 rebar.config.sample
@@ -37,14 +37,16 @@
37 37
38 38 %% Port compilation environment variables. See rebar_port_compiler.erl for
39 39 %% more info. Default is `[]'
40   -{port_env, []}.
  40 +{port_env, [{"CFLAGS", "$CFLAGS -Ifoo"},
  41 + {"freebsd", "LDFLAGS", "$LDFLAGS -lfoo"}]}.
41 42
42 43 %% port_specs
43 44 %% List of filenames or wildcards to be compiled. May also contain a tuple
44 45 %% consisting of a regular expression to be applied against the system
45 46 %% architecture as a filter.
46 47 {port_specs, [{"priv/so_name.so", ["c_src/*.c"]},
47   - {"linux", "priv/hello_linux", ["c_src/hello_linux.c"]]}.
  48 + {"linux", "priv/hello_linux", ["c_src/hello_linux.c"]},
  49 + {"linux", "priv/hello_linux", ["c_src/*.c"], [{env, []}]}}.
48 50
49 51 %% == LFE Compiler ==
50 52
25 src/rebar_config.erl
@@ -31,12 +31,17 @@
31 31 get_all/2,
32 32 set/3,
33 33 set_global/2, get_global/2,
34   - is_verbose/0, get_jobs/0]).
  34 + is_verbose/0, get_jobs/0,
  35 + set_env/3, get_env/2]).
35 36
36 37 -include("rebar.hrl").
37 38
38 39 -record(config, { dir :: file:filename(),
39   - opts :: list() }).
  40 + opts = [] :: list(),
  41 + envs = [] :: list({module(), env()}) }).
  42 +
  43 +-type env() :: [env_var()].
  44 +-type env_var() :: {string(), string()}.
40 45
41 46 %% Types that can be used from other modules -- alphabetically ordered.
42 47 -export_type([config/0]).
@@ -53,8 +58,7 @@ base_config(#config{opts=Opts0}) ->
53 58 new(Opts0, ConfName).
54 59
55 60 new() ->
56   - #config { dir = rebar_utils:get_cwd(),
57   - opts = [] }.
  61 + #config{dir = rebar_utils:get_cwd()}.
58 62
59 63 new(ConfigFile) when is_list(ConfigFile) ->
60 64 case consult_file(ConfigFile) of
@@ -88,7 +92,7 @@ new(Opts0, ConfName) ->
88 92 ?ABORT("Failed to load ~s: ~p\n", [ConfigFile, Other])
89 93 end,
90 94
91   - #config { dir = Dir, opts = Opts }.
  95 + #config{dir = Dir, opts = Opts}.
92 96
93 97 get(Config, Key, Default) ->
94 98 proplists:get_value(Key, Config#config.opts, Default).
@@ -143,6 +147,17 @@ consult_file(File) ->
143 147 end
144 148 end.
145 149
  150 +set_env(Config, Mod, Env) ->
  151 + OldEnvs = Config#config.envs,
  152 + NewEnvs = case lists:keymember(Mod, 1, OldEnvs) of
  153 + true -> lists:keyreplace(Mod, 1, OldEnvs, {Mod, Env});
  154 + false -> [{Mod,Env}|OldEnvs]
  155 + end,
  156 + Config#config{envs=NewEnvs}.
  157 +
  158 +get_env(Config, Mod) ->
  159 + proplists:get_value(Mod, Config#config.envs, []).
  160 +
146 161 %% ===================================================================
147 162 %% Internal functions
148 163 %% ===================================================================
78 src/rebar_core.erl
@@ -168,7 +168,7 @@ maybe_process_dir0(AppFile, ModuleSet, Config, CurrentCodePath,
168 168 CurrentCodePath, ModuleSet)
169 169 end.
170 170
171   -process_dir0(Dir, Command, DirSet, Config, CurrentCodePath,
  171 +process_dir0(Dir, Command, DirSet, Config0, CurrentCodePath,
172 172 {DirModules, ModuleSetFile}) ->
173 173 %% Get the list of modules for "any dir". This is a catch-all list
174 174 %% of modules that are processed in addition to modules associated
@@ -180,21 +180,21 @@ process_dir0(Dir, Command, DirSet, Config, CurrentCodePath,
180 180
181 181 %% Invoke 'preprocess' on the modules -- this yields a list of other
182 182 %% directories that should be processed _before_ the current one.
183   - Predirs = acc_modules(Modules, preprocess, Config, ModuleSetFile),
  183 + Predirs = acc_modules(Modules, preprocess, Config0, ModuleSetFile),
184 184
185 185 SubdirAssoc = remember_cwd_subdir(Dir, Predirs),
186 186
187 187 %% Get the list of plug-in modules from rebar.config. These
188 188 %% modules may participate in preprocess and postprocess.
189   - {ok, PluginModules} = plugin_modules(Config, SubdirAssoc),
  189 + {ok, PluginModules} = plugin_modules(Config0, SubdirAssoc),
190 190
191 191 PluginPredirs = acc_modules(PluginModules, preprocess,
192   - Config, ModuleSetFile),
  192 + Config0, ModuleSetFile),
193 193
194 194 AllPredirs = Predirs ++ PluginPredirs,
195 195
196 196 ?DEBUG("Predirs: ~p\n", [AllPredirs]),
197   - DirSet2 = process_each(AllPredirs, Command, Config,
  197 + DirSet2 = process_each(AllPredirs, Command, Config0,
198 198 ModuleSetFile, DirSet),
199 199
200 200 %% Make sure the CWD is reset properly; processing the dirs may have
@@ -202,25 +202,31 @@ process_dir0(Dir, Command, DirSet, Config, CurrentCodePath,
202 202 ok = file:set_cwd(Dir),
203 203
204 204 %% Check that this directory is not on the skip list
205   - case is_skip_dir(Dir) of
206   - true ->
207   - %% Do not execute the command on the directory, as some
208   - %% module has requested a skip on it.
209   - ?INFO("Skipping ~s in ~s\n", [Command, Dir]);
  205 + Config = case is_skip_dir(Dir) of
  206 + true ->
  207 + %% Do not execute the command on the directory, as some
  208 + %% module has requested a skip on it.
  209 + ?INFO("Skipping ~s in ~s\n", [Command, Dir]),
  210 + Config0;
210 211
211   - false ->
212   - %% Execute any before_command plugins on this directory
213   - execute_pre(Command, PluginModules,
214   - Config, ModuleSetFile),
  212 + false ->
  213 + %% Check for and get command specific environments
  214 + {Config1, Env} = setup_envs(Config0, Modules),
215 215
216   - %% Execute the current command on this directory
217   - execute(Command, Modules ++ PluginModules,
218   - Config, ModuleSetFile),
  216 + %% Execute any before_command plugins on this directory
  217 + execute_pre(Command, PluginModules,
  218 + Config1, ModuleSetFile, Env),
219 219
220   - %% Execute any after_command plugins on this directory
221   - execute_post(Command, PluginModules,
222   - Config, ModuleSetFile)
223   - end,
  220 + %% Execute the current command on this directory
  221 + execute(Command, Modules ++ PluginModules,
  222 + Config1, ModuleSetFile, Env),
  223 +
  224 + %% Execute any after_command plugins on this directory
  225 + execute_post(Command, PluginModules,
  226 + Config1, ModuleSetFile, Env),
  227 +
  228 + Config1
  229 + end,
224 230
225 231 %% Mark the current directory as processed
226 232 DirSet3 = sets:add_element(Dir, DirSet2),
@@ -311,22 +317,22 @@ is_dir_type(rel_dir, Dir) ->
311 317 is_dir_type(_, _) ->
312 318 false.
313 319
314   -execute_pre(Command, Modules, Config, ModuleFile) ->
  320 +execute_pre(Command, Modules, Config, ModuleFile, Env) ->
315 321 execute_plugin_hook("pre_", Command, Modules,
316   - Config, ModuleFile).
  322 + Config, ModuleFile, Env).
317 323
318   -execute_post(Command, Modules, Config, ModuleFile) ->
  324 +execute_post(Command, Modules, Config, ModuleFile, Env) ->
319 325 execute_plugin_hook("post_", Command, Modules,
320   - Config, ModuleFile).
  326 + Config, ModuleFile, Env).
321 327
322   -execute_plugin_hook(Hook, Command, Modules, Config, ModuleFile) ->
  328 +execute_plugin_hook(Hook, Command, Modules, Config, ModuleFile, Env) ->
323 329 HookFunction = list_to_atom(Hook ++ atom_to_list(Command)),
324   - execute(HookFunction, Modules, Config, ModuleFile).
  330 + execute(HookFunction, Modules, Config, ModuleFile, Env).
325 331
326 332 %%
327 333 %% Execute a command across all applicable modules
328 334 %%
329   -execute(Command, Modules, Config, ModuleFile) ->
  335 +execute(Command, Modules, Config, ModuleFile, Env) ->
330 336 case select_modules(Modules, Command, []) of
331 337 [] ->
332 338 Cmd = atom_to_list(Command),
@@ -346,9 +352,6 @@ execute(Command, Modules, Config, ModuleFile) ->
346 352
347 353 increment_operations(),
348 354
349   - %% Check for and get command specific environments
350   - Env = setup_envs(Config, Modules),
351   -
352 355 %% Run the available modules
353 356 apply_hooks(pre_hooks, Config, Command, Env),
354 357 case catch(run_modules(TargetModules, Command,
@@ -443,9 +446,16 @@ apply_hook({Env, {Command, Hook}}) ->
443 446 rebar_utils:sh(Hook, [{env, Env}, {abort_on_error, Msg}]).
444 447
445 448 setup_envs(Config, Modules) ->
446   - lists:flatten([M:setup_env(Config) ||
447   - M <- Modules,
448   - erlang:function_exported(M, setup_env, 1)]).
  449 + lists:foldl(fun(M, {C,E}=T) ->
  450 + case erlang:function_exported(M, setup_env, 1) of
  451 + true ->
  452 + Env = M:setup_env(C),
  453 + C1 = rebar_config:set_env(C, M, Env),
  454 + {C1, E++Env};
  455 + false ->
  456 + T
  457 + end
  458 + end, {Config, []}, Modules).
449 459
450 460 acc_modules(Modules, Command, Config, File) ->
451 461 acc_modules(select_modules(Modules, Command, []),
376 src/rebar_port_compiler.erl
@@ -39,8 +39,9 @@
39 39 %% Supported configuration variables:
40 40 %%
41 41 %% * port_specs - Erlang list of tuples of the forms
42   -%% {arch_regex(), "priv/foo.so", ["c_src/foo.c"]}
43   -%% {"priv/foo", ["c_src/foo.c"]}
  42 +%% {ArchRegex, TargetFile, Sources, Options}
  43 +%% {ArchRegex, TargetFile, Sources}
  44 +%% {TargetFile, Sources}
44 45 %%
45 46 %% * port_env - Erlang list of key/value pairs which will control
46 47 %% the environment when running the compiler and linker.
@@ -85,43 +86,55 @@
85 86 %% "$CFLAGS -X86Options"}]}
86 87 %%
87 88
  89 +%% TODO: reconsider keeping both sources and objects once
  90 +%% support for deprecated options has been remove.
  91 +%% remove [] as valid value for sources, objects, and opts
  92 +%% when removing deprecated options.
  93 +-record(spec, {type::'drv' | 'exe',
  94 + target::file:filename(),
  95 + sources = [] :: [file:filename(), ...] | [],
  96 + objects = [] :: [file:filename(), ...] | [],
  97 + opts = [] ::list() | []}).
  98 +
88 99 compile(Config, AppFile) ->
89 100 rebar_utils:deprecated(port_sources, port_specs, Config, "soon"),
90 101 rebar_utils:deprecated(so_name, port_specs, Config, "soon"),
91 102 rebar_utils:deprecated(so_specs, port_specs, Config, "soon"),
92 103
93   - SourceFiles = get_sources(Config),
  104 + %% TODO: remove SpecType and OldSources make get_specs/2
  105 + %% return list(#spec{}) when removing deprecated options
  106 + {SpecType, {OldSources, Specs}} = get_specs(Config, AppFile),
  107 +
  108 + case {SpecType, OldSources, Specs} of
  109 + {old, [], _} ->
  110 + ok; % old specs empty
  111 + {new, [], []} ->
  112 + ok; % port_specs empty
94 113
95   - case SourceFiles of
96   - [] ->
97   - ok;
98   - _ ->
99   - Env = setup_env(Config),
  114 + _ -> % have old/new specs
  115 +
  116 + SharedEnv = rebar_config:get_env(Config, ?MODULE),
100 117
101 118 %% Compile each of the sources
102   - {NewBins, ExistingBins} = compile_each(SourceFiles, Config, Env,
103   - [], []),
  119 + NewBins = compile_sources(OldSources, Specs, SharedEnv),
104 120
105   - %% Construct the target filename and make sure that the
106   - %% target directory exists
107   - Specs = port_specs(Config, AppFile, NewBins ++ ExistingBins),
  121 + %% Make sure that the target directories exist
108 122 ?INFO("Using specs ~p\n", [Specs]),
109   - lists:foreach(fun({_, Target,_}) ->
110   - ok = filelib:ensure_dir(Target);
111   - ({Target, _}) ->
  123 + lists:foreach(fun(#spec{target=Target}) ->
112 124 ok = filelib:ensure_dir(Target)
113 125 end, Specs),
114 126
115 127 %% Only relink if necessary, given the Target
116 128 %% and list of new binaries
117 129 lists:foreach(
118   - fun({Target, Bins}) ->
  130 + fun(#spec{target=Target, objects=Bins, opts=Opts}) ->
119 131 AllBins = [sets:from_list(Bins),
120 132 sets:from_list(NewBins)],
121 133 Intersection = sets:intersection(AllBins),
122 134 case needs_link(Target, sets:to_list(Intersection)) of
123 135 true ->
124 136 LinkTemplate = select_link_template(Target),
  137 + Env = proplists:get_value(env, Opts, SharedEnv),
125 138 Cmd = expand_command(LinkTemplate, Env,
126 139 string:join(Bins, " "),
127 140 Target),
@@ -134,113 +147,83 @@ compile(Config, AppFile) ->
134 147 end.
135 148
136 149 clean(Config, AppFile) ->
137   - %% Build a list of sources so as to derive all the bins we generated
138   - Sources = get_sources(Config),
139   - rebar_file_utils:delete_each([source_to_bin(S) || S <- Sources]),
140   -
141   - %% Delete the target file
142   - ExtractTarget = fun({_, Target, _}) ->
143   - Target;
144   - ({Target, _}) ->
145   - Target
146   - end,
147   - rebar_file_utils:delete_each([ExtractTarget(S)
148   - || S <- port_specs(Config, AppFile,
149   - expand_objects(Sources))]).
  150 + %% TODO: remove SpecType and OldSources make get_specs/2
  151 + %% return list(#spec{}) when removing deprecated options
  152 + {SpecType, {OldSources, Specs}} = get_specs(Config, AppFile),
  153 +
  154 + case {SpecType, OldSources, Specs} of
  155 + {old, [], _} ->
  156 + ok; % old specs empty
  157 + {new, [], []} ->
  158 + ok; % port_specs empty
  159 +
  160 + _ -> % have old/new specs
  161 +
  162 + lists:foreach(fun(#spec{target=Target, objects=Objects}) ->
  163 + rebar_file_utils:delete_each([Target]),
  164 + rebar_file_utils:delete_each(Objects)
  165 + end, Specs)
  166 + end.
150 167
151 168 setup_env(Config) ->
  169 + setup_env(Config, []).
  170 +
  171 +%% ===================================================================
  172 +%% Internal functions
  173 +%% ===================================================================
  174 +
  175 +setup_env(Config, ExtraEnv) ->
152 176 %% Extract environment values from the config (if specified) and
153 177 %% merge with the default for this operating system. This enables
154 178 %% max flexibility for users.
155 179 DefaultEnv = filter_env(default_env(), []),
156   - PortEnv = port_env(Config),
157   - OverrideEnv = global_defines() ++ filter_env(PortEnv, []),
  180 + PortEnv = filter_env(port_env(Config), []),
  181 + OverrideEnv = global_defines() ++ PortEnv ++ filter_env(ExtraEnv, []),
158 182 RawEnv = apply_defaults(os_env(), DefaultEnv) ++ OverrideEnv,
159 183 expand_vars_loop(merge_each_var(RawEnv, [])).
160 184
161   -%% ===================================================================
162   -%% Internal functions
163   -%% ===================================================================
164   -
165 185 global_defines() ->
166 186 Defines = rebar_config:get_global(defines, []),
167 187 Flags = string:join(["-D" ++ D || D <- Defines], " "),
168 188 [{"ERL_CFLAGS", "$ERL_CFLAGS " ++ Flags}].
169 189
170   -get_sources(Config) ->
171   - case rebar_config:get_list(Config, port_specs, []) of
172   - [] ->
173   - %% TODO: DEPRECATED: remove
174   - expand_sources(rebar_config:get_list(Config, port_sources,
175   - ["c_src/*.c"]), []);
176   - PortSpecs ->
177   - expand_port_specs(PortSpecs)
178   - end.
179   -
180   -expand_port_specs(Specs) ->
181   - lists:flatmap(fun({_, Target, FileSpecs}) ->
182   - expand_file_specs(Target, FileSpecs);
183   - ({Target, FileSpecs}) ->
184   - expand_file_specs(Target, FileSpecs)
185   - end, filter_port_specs(Specs)).
186   -
187   -expand_file_specs(Target, FileSpecs) ->
188   - Sources = lists:flatmap(fun filelib:wildcard/1, FileSpecs),
189   - [{Target, Src} || Src <- Sources].
  190 +replace_extension(File, NewExt) ->
  191 + OldExt = filename:extension(File),
  192 + replace_extension(File, OldExt, NewExt).
190 193
191   -filter_port_specs(Specs) ->
192   - lists:filter(fun({ArchRegex, _, _}) ->
193   - rebar_utils:is_arch(ArchRegex);
194   - ({_, _}) ->
195   - true
196   - end, Specs).
  194 +replace_extension(File, OldExt, NewExt) ->
  195 + filename:rootname(File, OldExt) ++ NewExt.
197 196
  197 +%%
  198 +%% == compile and link ==
  199 +%%
198 200
199   -%% TODO: DEPRECATED: remove
200   -expand_sources([], Acc) ->
201   - Acc;
202   -expand_sources([{ArchRegex, Spec} | Rest], Acc) ->
203   - case rebar_utils:is_arch(ArchRegex) of
204   - true ->
205   - Acc2 = expand_sources(Spec, Acc),
206   - expand_sources(Rest, Acc2);
207   - false ->
208   - expand_sources(Rest, Acc)
209   - end;
210   -expand_sources([Spec | Rest], Acc) ->
211   - Acc2 = filelib:wildcard(Spec) ++ Acc,
212   - expand_sources(Rest, Acc2).
213   -
214   -expand_objects(Sources) ->
215   - [expand_object(".o", Src) || Src <- Sources].
216   -
217   -expand_object(Ext, {_Target, Source}) ->
218   - expand_object(Ext, Source);
219   -expand_object(Ext, Source) ->
220   - filename:join(filename:dirname(Source), filename:basename(Source) ++ Ext).
221   -
222   -compile_each([], _Config, _Env, NewBins, ExistingBins) ->
223   - {lists:reverse(NewBins), lists:reverse(ExistingBins)};
224   -compile_each([RawSource | Rest], Config, Env, NewBins, ExistingBins) ->
225   - %% TODO: DEPRECATED: remove
226   - {Type, Source} = source_type(RawSource),
  201 +compile_sources([], Specs, SharedEnv) -> % port_spec
  202 + lists:foldl(
  203 + fun(#spec{sources=Sources, type=Type, opts=Opts}, NewBins) ->
  204 + Env = proplists:get_value(env, Opts, SharedEnv),
  205 + compile_each(Sources, Type, Env, NewBins)
  206 + end, [], Specs);
  207 +compile_sources(OldSources, _Specs, SharedEnv) -> % deprecated
  208 + compile_each(OldSources, drv, SharedEnv, []).
  209 +
  210 +compile_each([], _Type, _Env, NewBins) ->
  211 + lists:reverse(NewBins);
  212 +compile_each([Source | Rest], Type, Env, NewBins) ->
227 213 Ext = filename:extension(Source),
228   - Bin = filename:rootname(Source, Ext) ++ ".o",
  214 + Bin = replace_extension(Source, Ext, ".o"),
229 215 case needs_compile(Source, Bin) of
230 216 true ->
231 217 ?CONSOLE("Compiling ~s\n", [Source]),
232 218 Template = select_compile_template(Type, compiler(Ext)),
233 219 rebar_utils:sh(expand_command(Template, Env, Source, Bin),
234 220 [{env, Env}]),
235   - compile_each(Rest, Config, Env, [Bin | NewBins], ExistingBins);
  221 + compile_each(Rest, Type, Env, [Bin | NewBins]);
236 222 false ->
237 223 ?INFO("Skipping ~s\n", [Source]),
238   - compile_each(Rest, Config, Env, NewBins, [Bin | ExistingBins])
  224 + compile_each(Rest, Type, Env, NewBins)
239 225 end.
240 226
241   -source_type({Target, Source}) -> {target_type(Target), Source};
242   -source_type(Source) -> {drv, Source}.
243   -
244 227 needs_compile(Source, Bin) ->
245 228 %% TODO: Generate depends using gcc -MM so we can also
246 229 %% check for include changes
@@ -259,6 +242,127 @@ needs_link(SoName, NewBins) ->
259 242 MaxLastMod >= Other
260 243 end.
261 244
  245 +%%
  246 +%% == port_specs ==
  247 +%%
  248 +
  249 +get_specs(Config, AppFile) ->
  250 + case rebar_config:get(Config, port_specs, undefined) of
  251 + undefined ->
  252 + %% TODO: DEPRECATED: remove support for non-port_specs syntax
  253 + {old, old_get_specs(Config, AppFile)};
  254 + PortSpecs ->
  255 + {new, get_port_specs(Config, PortSpecs)}
  256 + end.
  257 +
  258 +get_port_specs(Config, PortSpecs) ->
  259 + Filtered = filter_port_specs(PortSpecs),
  260 + OsType = os:type(),
  261 + {[], [get_port_spec(Config, OsType, Spec) || Spec <- Filtered]}.
  262 +
  263 +filter_port_specs(Specs) ->
  264 + [S || S <- Specs, filter_port_spec(S)].
  265 +
  266 +filter_port_spec({ArchRegex, _, _, _}) ->
  267 + rebar_utils:is_arch(ArchRegex);
  268 +filter_port_spec({ArchRegex, _, _}) ->
  269 + rebar_utils:is_arch(ArchRegex);
  270 +filter_port_spec({_, _}) ->
  271 + true.
  272 +
  273 +get_port_spec(Config, OsType, {Target, Sources}) ->
  274 + get_port_spec(Config, OsType, {undefined, Target, Sources, []});
  275 +get_port_spec(Config, OsType, {Arch, Target, Sources}) ->
  276 + get_port_spec(Config, OsType, {Arch, Target, Sources, []});
  277 +get_port_spec(Config, OsType, {_Arch, Target, Sources, Opts}) ->
  278 + SourceFiles = port_sources(Sources),
  279 + ObjectFiles = port_objects(SourceFiles),
  280 + #spec{type=target_type(Target),
  281 + target=maybe_switch_extension(OsType, Target),
  282 + sources=SourceFiles,
  283 + objects=ObjectFiles,
  284 + opts=port_opts(Config, Opts)}.
  285 +
  286 +port_sources(Sources) ->
  287 + lists:flatmap(fun filelib:wildcard/1, Sources).
  288 +
  289 +port_objects(SourceFiles) ->
  290 + [replace_extension(O, ".o") || O <- SourceFiles].
  291 +
  292 +port_opts(Config, Opts) ->
  293 + [port_opt(Config, O) || O <- Opts].
  294 +
  295 +port_opt(Config, {env, Env}) ->
  296 + {env, setup_env(Config, Env)};
  297 +port_opt(_Config, Opt) ->
  298 + Opt.
  299 +
  300 +maybe_switch_extension({win32, nt}, Target) ->
  301 + switch_to_dll_or_exe(Target);
  302 +maybe_switch_extension(_OsType, Target) ->
  303 + Target.
  304 +
  305 +switch_to_dll_or_exe(Target) ->
  306 + case filename:extension(Target) of
  307 + ".so" -> filename:rootname(Target, ".so") ++ ".dll";
  308 + [] -> Target ++ ".exe";
  309 + Other -> Other
  310 + end.
  311 +
  312 +%% TODO: DEPRECATED: remove support for non-port_specs syntax [old_*()]
  313 +old_get_specs(Config, AppFile) ->
  314 + OsType = os:type(),
  315 + SourceFiles = old_get_sources(Config),
  316 + Specs =
  317 + case rebar_config:get(Config, so_specs, undefined) of
  318 + undefined ->
  319 + Objects = port_objects(SourceFiles),
  320 + %% New form of so_specs is not provided. See if the old form
  321 + %% of {so_name} is available instead
  322 + Dir = "priv",
  323 + SoName = case rebar_config:get(Config, so_name, undefined) of
  324 + undefined ->
  325 + %% Ok, neither old nor new form is
  326 + %% available. Use the app name and
  327 + %% generate a sensible default.
  328 + AppName = rebar_app_utils:app_name(AppFile),
  329 + DrvName = ?FMT("~s_drv.so", [AppName]),
  330 + filename:join([Dir, DrvName]);
  331 + AName ->
  332 + %% Old form is available -- use it
  333 + filename:join(Dir, AName)
  334 + end,
  335 + [old_get_so_spec({SoName, Objects}, OsType)];
  336 + SoSpecs ->
  337 + [old_get_so_spec(S, OsType) || S <- SoSpecs]
  338 + end,
  339 + {SourceFiles, Specs}.
  340 +
  341 +old_get_sources(Config) ->
  342 + RawSources = rebar_config:get_list(Config, port_sources,
  343 + ["c_src/*.c"]),
  344 + FilteredSources = old_filter_port_sources(RawSources),
  345 + old_expand_sources(FilteredSources).
  346 +
  347 +old_filter_port_sources(PortSources) ->
  348 + [S || S <- PortSources, old_is_arch_port_sources(S)].
  349 +
  350 +old_is_arch_port_sources({Arch, _Sources}) -> rebar_utils:is_arch(Arch);
  351 +old_is_arch_port_sources(_Sources) -> true.
  352 +
  353 +old_expand_sources(Sources) ->
  354 + lists:flatmap(fun filelib:wildcard/1, Sources).
  355 +
  356 +old_get_so_spec({Target, Objects}, OsType) ->
  357 + #spec{type=drv,
  358 + target=maybe_switch_extension(OsType, Target),
  359 + sources=[],
  360 + objects=Objects,
  361 + opts=[]}.
  362 +
  363 +%%
  364 +%% == port_env ==
  365 +%%
262 366
263 367 %%
264 368 %% Choose a compiler variable, based on a provided extension
@@ -365,7 +469,6 @@ expand_keys_in_value([Key | Rest], Value, Vars) ->
365 469 end,
366 470 expand_keys_in_value(Rest, NewValue, Vars).
367 471
368   -
369 472 expand_command(TmplName, Env, InFiles, OutFile) ->
370 473 Cmd0 = proplists:get_value(TmplName, Env),
371 474 Cmd1 = rebar_utils:expand_env_variable(Cmd0, "PORT_IN_FILES", InFiles),
@@ -426,7 +529,6 @@ filter_env([{ArchRegex, Key, Value} | Rest], Acc) ->
426 529 filter_env([{Key, Value} | Rest], Acc) ->
427 530 filter_env(Rest, [{Key, Value} | Acc]).
428 531
429   -
430 532 erts_dir() ->
431 533 lists:concat([code:root_dir(), "/erts-", erlang:system_info(version)]).
432 534
@@ -520,81 +622,3 @@ default_env() ->
520 622 {"darwin11.*-32", "CXXFLAGS", "-m32 $CXXFLAGS"},
521 623 {"darwin11.*-32", "LDFLAGS", "-arch i386 $LDFLAGS"}
522 624 ].
523   -
524   -source_to_bin({_Target, Source}) ->
525   - source_to_bin(Source);
526   -source_to_bin(Source) ->
527   - Ext = filename:extension(Source),
528   - filename:rootname(Source, Ext) ++ ".o".
529   -
530   -port_specs(Config, AppFile, Bins) ->
531   - Specs = make_port_specs(Config, AppFile, Bins),
532   - case os:type() of
533   - {win32, nt} ->
534   - [switch_to_dll_or_exe(Spec) || Spec <- Specs];
535   - _ ->
536   - Specs
537   - end.
538   -
539   -switch_to_dll_or_exe(Orig = {Name, Spec}) ->
540   - case filename:extension(Name) of
541   - ".so" ->
542   - {filename:rootname(Name, ".so") ++ ".dll", Spec};
543   - [] ->
544   - {Name ++ ".exe", Spec};
545   - _ ->
546   - %% Not a .so; leave it
547   - Orig
548   - end.
549   -
550   -make_port_specs(Config, AppFile, Bins) ->
551   - case rebar_config:get(Config, port_specs, undefined) of
552   - undefined ->
553   - %% TODO: DEPRECATED: remove
554   - make_so_specs(Config, AppFile, Bins);
555   - PortSpecs ->
556   - %% filter based on ArchRegex
557   - Specs0 = lists:filter(fun({ArchRegex, _Target, _Sources}) ->
558   - rebar_utils:is_arch(ArchRegex);
559   - (_) ->
560   - true
561   - end, PortSpecs),
562   - %% TODO: DEPRECATED: remove support for non-port_specs syntax
563   -
564   -
565   - %% drop ArchRegex from specs
566   - lists:map(fun({_, Target, RawSources}) ->
567   - {Target, sources_to_bins(RawSources)};
568   - ({Target, RawSources}) ->
569   - {Target, sources_to_bins(RawSources)}
570   - end, Specs0)
571   - end.
572   -
573   -sources_to_bins(RawSources) ->
574   - Sources = lists:flatmap(fun filelib:wildcard/1, RawSources),
575   - lists:map(fun source_to_bin/1, Sources).
576   -
577   -%% DEPRECATED
578   -make_so_specs(Config, AppFile, Bins) ->
579   - case rebar_config:get(Config, so_specs, undefined) of
580   - undefined ->
581   - %% New form of so_specs is not provided. See if the old form
582   - %% of {so_name} is available instead
583   - Dir = "priv",
584   - SoName = case rebar_config:get(Config, so_name, undefined) of
585   - undefined ->
586   - %% Ok, neither old nor new form is available. Use
587   - %% the app name and generate a sensible default.
588   - AppName = rebar_app_utils:app_name(AppFile),
589   - filename:join(Dir,
590   - lists:concat([AppName, "_drv.so"]));
591   -
592   - AName ->
593   - %% Old form is available -- use it
594   - filename:join(Dir, AName)
595   - end,
596   - [{SoName, Bins}];
597   -
598   - SoSpecs ->
599   - SoSpecs
600   - end.

0 comments on commit 7c418ed

Please sign in to comment.
Something went wrong with that request. Please try again.