Find the answer to your Linux question:
Results 1 to 6 of 6
I am trying to run a script to setup environment variables and then run other commands in a make file. But the source or the dot operator (shell is bash) ...
  1. #1
    lfu
    lfu is offline
    Just Joined!
    Join Date
    Apr 2010
    Posts
    4

    source or dot command not working in makefile

    I am trying to run a script to setup environment variables and then run other commands in a make file. But the source or the dot operator (shell is bash) does not seem to take any effect as the subsequent command didn't pick the environment up.

    Wondering how I can do this. Do I have to put every lines of the environment setup in the first script into the makefile instead?

    sample setenv.sh
    ------------------------
    #!/bin/sh
    export MYDIR=/somedir

    sample makefile:
    --------------------------
    all:
    source ./setenv.sh
    echo $(MYDIR)

  2. #2
    Linux Newbie theNbomr's Avatar
    Join Date
    May 2007
    Location
    BC Canada
    Posts
    150
    To restate your problem, you are trying to use make o perform some 'intelligent' management of a bash enviroment. This can not work for the same reason that you can not use a child shell to modify the enviroment of the parent shell. When bash launches make, it does so by creating make as a child process. The environment of the child process is private and cannot affect the environment of its parent. When the make process terminates, all of the environment variables created within it are lost.
    The only way to accomplish what you are attempting might be to have make compose a standard output stream that contains a list of shell variable assignments. The standard output could then be used as the input to the parent 'source' or '.' command. Using a 'noisy' program such as make to do this will be significantly challenging.
    --- rod.
    Stuff happens. Then stays happened.

  3. #3
    lfu
    lfu is offline
    Just Joined!
    Join Date
    Apr 2010
    Posts
    4
    Quote Originally Posted by theNbomr View Post
    To restate your problem, you are trying to use make o perform some 'intelligent' management of a bash enviroment. This can not work for the same reason that you can not use a child shell to modify the enviroment of the parent shell. When bash launches make, it does so by creating make as a child process. The environment of the child process is private and cannot affect the environment of its parent. When the make process terminates, all of the environment variables created within it are lost.
    The only way to accomplish what you are attempting might be to have make compose a standard output stream that contains a list of shell variable assignments. The standard output could then be used as the input to the parent 'source' or '.' command. Using a 'noisy' program such as make to do this will be significantly challenging.
    --- rod.
    Thank you for your response! But could you please clarify:

    - do you mean for each line executed under target, in this case the source command and the echo command, they belong to different shell processes?

    - can you elaborate this: "to have make compose a standard output stream that contains a list of shell variable assignments. The standard output could then be used as the input to the parent 'source' or '.' command."

    - in makefile, if I export the environment variables outside of a target, it actually works. But it would not allow me to call a source command outside of a target. Wondering if there is a way to do this.
    makefile
    export MYDIR=/somedir #can I call a source command here instead?
    all:
    echo $MYDIR

    Thank you!

  4. #4
    Linux Newbie theNbomr's Avatar
    Join Date
    May 2007
    Location
    BC Canada
    Posts
    150
    On your first and third points:

    You are over-thinking the whole thing. The bottom line is that make is a child process. Whatever is run by make is a child of make. Therefore, the processes run by make are two levels removed from the shell whose environment you are trying to alter. No child process can alter the environment of it parent. Period.

    On the second point:

    The child process can write to standard output. If the data written looks like "export HORTY=florty", then you could capture that output in backticks, and use it as the argument to the parent shell. Same as if you had another shell script or program that prints "export HORTY=florty":
    Code:
    #! /bin/sh
    #  emitCommands.sh
    # Shell script to print environment setting commands....
    echo "export HORTY=florty"
    Run the script
    Code:
    #> ./emitCommands.sh
    export HORTY=florty
    Now run it in backticks...
    Code:
    `./emitCommands.sh`
    echo $HORTY
    florty
    Now if you replace 'emitCommands.sh' with a Makefile that emits the same text, it can be used in the same way. Harder to do with make than with a shell.
    Sorry about the mis-statement about the 'source'/'.' command. Backticks is what I should have said.

    --- rod.
    Stuff happens. Then stays happened.

  5. #5
    lfu
    lfu is offline
    Just Joined!
    Join Date
    Apr 2010
    Posts
    4

    How to use shell scripts to set up environment variables for makefiles?

    Quote Originally Posted by theNbomr View Post
    On the second point:

    The child process can write to standard output. If the data written looks like "export HORTY=florty", then you could capture that output in backticks, and use it as the argument to the parent shell. Same as if you had another shell script or program that prints "export HORTY=florty":
    Code:
    #! /bin/sh
    #  emitCommands.sh
    # Shell script to print environment setting commands....
    echo "export HORTY=florty"
    Run the script
    Code:
    #> ./emitCommands.sh
    export HORTY=florty
    Now run it in backticks...
    Code:
    `./emitCommands.sh`
    echo $HORTY
    florty
    Now if you replace 'emitCommands.sh' with a Makefile that emits the same text, it can be used in the same way. Harder to do with make than with a shell.
    Sorry about the mis-statement about the 'source'/'.' command. Backticks is what I should have said.

    --- rod.
    Now I am confused. For a shell program to set environment by calling another script, it works:
    Code:
    #setenv.sh
    export MYDIR=/somedir
    In the calling shell script:
    Code:
    source ./setenv.sh
    echo $MYDIR
    works. Why do we need to use the backtick trick?

    Go back to the question of setting up environment for makefile, I yet to see any good way to do this.

  6. #6
    Linux Newbie theNbomr's Avatar
    Join Date
    May 2007
    Location
    BC Canada
    Posts
    150
    'source' works without launching a child shell. That is its whole purpose. If the shell script is simply run as a child process, it cannot affect the parent shell's environment. It is not possible to run make with the same technique; you can't do
    Code:
    source make someTarget
    'source' (or the shorthand form '.') is akin to redirecting the file as standard input to the shell, and is not what is generally meant by 'calling' another script. 'sourcing' and 'calling' have distinctly different behaviors, and 'sourcing' only works on shell scripts of the same type as the parent shell (you can't source a csh script from bash).

    Backticks (or the newer form, '$(childProcess)', in bash work by making the standard output of the child process into a commandline argument of the shell. So, in order for make to provide something that can influence the shell's environment, it must generate standard output that is of the form one would type interactively to set environment variables in a shell.

    Go back to the question of setting up environment for makefile, I yet to see any good way to do this.
    Okay, that is semantically different. Setting environment variables to be used by make is no different from setting environment variables in any other sense. make treats shell variables just like internal variables. If you really mean 'setting environment variables by using make', then I think that dead horse has been thoroughly beaten here.

    --- rod.
    Stuff happens. Then stays happened.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...