Reputation: 3235
I have an impression that I can call bash function inside GNU makefile, but seems wrong. Here is a simple test, I have this function defined:
>type lsc
lsc is a function
lsc ()
{
ls --color=auto --color=tty
}
Here is my Makefile:
>cat Makefile
all:
lsc
Here is what I get in running make:
>make
lsc
make: lsc: Command not found
make: *** [all] Error 127
Is my impression wrong? Or is there any env setup issue? I can run "lsc" at the command line.
Upvotes: 10
Views: 9462
Reputation: 54859
This issue is not unique to make
. Make executes commands in the context of a shell, and that shell can execute functions if they've been made available.
The problem is that when you launch a new shell (or shell script, or make command), Bash doesn't automatically forward all functions from the calling environment.
Explicitly specifying that the shell should be /bin/bash
ensures that make won't invoke a different shell interpreter, which could affect function handling. There are a couple ways of doing this. In the examples below, I use the targeted-specific approach.
As an example, the below makefile snippets invoke nvm
which is implemented as a collection of bash functions.
WARNING: Using previously-defined functions means the makefile depends on the (potentially uncontrolled) state of your shell environment, so this type of solution should be used judiciously.
In this example, the functions are assumed to be defined as part of a users's .bashrc file. Running Bash in interactive mode (with -i
) causes .bashrc to be processed into the command environment.
mytarget1: SHELL:=/bin/bash -i
mytarget1:
nvm install 14 && npm version
This approach explicitly sources the script that defines the functions of interest.
mytarget2:
. ~/.nvm/nvm.sh && nvm install 14 && npm version
For this, you might prefer: Multi-line bash commands in makefile
Invoke make
with: export -f nvm ; make mytarget3
to export the function to any sub-commands.
mytarget3: SHELL:=/bin/bash
mytarget3:
nvm install 14 && npm version
Note: This example won't work fully because nvm
, internally, relies on a large collection of sub-functions which would also need to be exported.
Upvotes: 0
Reputation: 564
suppose compile is a function in you .bash_profile
.bash_profile
compile(){
...
}
Makefile
ACTIVE_ENV=source ~/.bash_profile
default:
$(ACTIVE_ENV) && compile boot_sect_simple.asm c
Upvotes: 0
Reputation: 9418
You can import all shell scripts functions from a shell file if you use this from the question How do I write the 'cd' command in a makefile?
.ONESHELL: my_target
my_target: dependency
. ./shell_script.sh
my_imported_shell_function "String Parameter"
If you like, you can also even do not use the .ONESHELL
thing and do it all in one line just by using a colon ;
right after the importing the shell script:
my_target: dependency
. ./shell_script.sh; my_imported_shell_function "String Parameter"
Upvotes: 1
Reputation: 1109
Use $*
in your BASH script:
functions.sh
_my_function() {
echo $1
}
# Allows to call a function based on arguments passed to the script
$*
Makefile
test:
./functions.sh _my_function "hello!"
Running example:
$ make test
./functions.sh _my_function "hello!"
hello!
Upvotes: 12
Reputation: 74018
You cannot call bash functions or aliases in a Makefile, only binaries and scripts. What you can do however, is calling an interactive bash and instruct it to call your function or alias:
all:
bash -i -c lsc
if lsc
is defined in your .bashrc
, for example.
Upvotes: 11
Reputation: 1889
Did you export your function with "export -f"?
Is bash the shell of your Makefile, or is is sh?
Upvotes: 2