[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