[erlang-questions] compile module from string, containing macro definitions
Chris Newcombe
chris.newcombe@REDACTED
Fri Jul 20 18:54:21 CEST 2007
> it does now support -include directives,
As I mentioned, I'm using this as a admin/diagnostic/support facility
for a service. I can send code to a private port, which compiles it,
loads it (on multiple nodes if necessary) and spawns a process to run
it.
In that context it is not clear what the search path for -include
directives should be.
This is what I ended up with:
... snip ...
%% Generate reasonable include path -- the 'include' directory
that is a sibling of every ebin directory that contains a loaded
module
Directories = lists:usort(
lists:foldl(
fun({_Module, AbsolutePath}, Acc) when
is_list(AbsolutePath) ->
case split_string_on_delimiter("/ebin/",
AbsolutePath) of
no_delimiter_found ->
?INFO_LOGGER("compile_and_execute_code (building include path)
ignoring module ~p~n", [AbsolutePath]),
Acc;
{Directory, _BeamFile} ->
[Directory|Acc]
end;
(_, Acc) -> Acc % some may have 'preloaded'
or 'cover_compiled' etc
end,
[],
code:all_loaded())),
%% We don't currently bother to filter out any that don't exist
%% (most uploaded modules won't even have a -include directive anyway)
IncludePathOptions = lists:map(fun(Dir) -> {i, Dir ++ "/include"} end,
Directories),
try
compile_module_from_string:compile(binary_to_list(CodeBinary),
[return_errors,
return_warnings, verbose]
++ IncludePathOptions)
of
{ModuleName, CompiledCode} ->
?INFO_LOGGER("compile_and_execute_code: successfully
compiled module ~w~n", [ModuleName]),
... snip ...
With this small helper function:
%% returns {BeforeDelimiter, AfterDelimiter} i.e. the first
occurance if Delimiter is dropped -- but 'After' may contain other
instances of Delimiter
%% or no_delimiter_found
split_string_on_delimiter("", Str) when is_list(Str) ->
{"", Str};
split_string_on_delimiter(Delimiter, Str) when is_list(Delimiter)
andalso is_list(Str) ->
case string:str(Str, Delimiter) of
0 -> no_delimiter_found;
Pos -> {string:substr(Str, 1, Pos - 1), string:substr(Str, Pos
+ length(Delimiter))}
end.
More information about the erlang-questions
mailing list