Skip to content
This repository has been archived by the owner on May 12, 2018. It is now read-only.

Repetition of environment variable definitions in child processes (ports) #98

Merged
merged 1 commit into from
Mar 5, 2014
Merged

Repetition of environment variable definitions in child processes (ports) #98

merged 1 commit into from
Mar 5, 2014

Conversation

jcomellas
Copy link
Contributor

I noticed this problem while working on a project that needs to run some pre compile hook scripts during the build process. During the build process, we also need to have a code base that is external to our project in the code path, and we cannot include this external project as a rebar dependency for the time being.

Basically, what I noticed was that while running the following command from the command line worked:

ERL_LIBS=/usr/local/lib/cloudi-1.2.3/lib rebar compile

Running the same thing from a Makefile target like this one didn't:

compile:
        ERL_LIBS=/usr/local/lib/cloudi-1.2.3/lib rebar compile

The issue was that when running from the command line the script's child process saw the ERL_LIBS environment variable as:

/home/jcomellas/devel/myproject/deps:/usr/local/lib/cloudi-1.2.3/lib

And when running rebar from a make invocation it saw it as just:

/usr/local/lib/cloudi-1.2.3/lib

The missing path in this last case is the one automatically added by rebar for the subdirectory where the dependencies reside.

What I've been able to assess is that the issue is caused by the interaction between rebar_deps:setup_env/1 and rebar_port_compiler:setup_env/1. The first of these functions to be called is rebar_deps:setup_env/1 and it generates the following output:

  [{"REBAR_DEPS_DIR", "/home/jcomellas/devel/myproject/deps"},
   {"ERL_LIBS", "/home/jcomellas/devel/myproject/deps:/usr/local/lib/cloudi-1.2.3/lib"}]

Then rebar_port_compiler:setup_env/1 is called and it generates another environment based on the one inherited from the parent process (make) which, among other things, contains the following entry:

   {"ERL_LIBS", "/usr/local/lib/cloudi-1.2.3/lib"},

These lists are then concatenated, leaving two repetitions of ERL_LIBS in the resulting environment. This happens in rebar_core:setup_envs/2 in the line where the tuple {C1, E++Env} is returned:

setup_envs(Config, Modules) ->
    lists:foldl(fun(M, {C,E}=T) ->
                        case erlang:function_exported(M, setup_env, 1) of
                            true ->
                                Env = M:setup_env(C),
                                C1 = rebar_config:save_env(C, M, Env),
                                {C1, E++Env};
                            false ->
                                T
                        end
                end, {Config, []}, Modules).

I haven't created a pull request because I'm not sure what the correct solution is:

  1. I could use lists:keystore/4 to store the values from one plugin's environment into the other one to avoid the repetitions, but how can I determine which plugin has precedence.
  2. I could make sure that no plugin other than rebar_deps emits the ERL_LIBS and REBAR_DEPS_DIR variables in their environment. This would fix my problem and most common occurrences, but other plugins might share other environment variables in the future.

What do you think is the correct solution?

This commit fixes issue #98 by removing the ERL_LIBS and REBAR_DEPS_DIR
from the list of environment variables exported by the rebar_port_compiler
plugin.
jaredmorrow added a commit that referenced this pull request Mar 5, 2014
Repetition of environment variable definitions in child processes (ports)
@jaredmorrow jaredmorrow merged commit b7e727a into rebar:master Mar 5, 2014
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
2 participants