Change Directory of a Makefile - makefile

I'm trying to run a makefile as though it is in another directory:
For example something like this but actually works:
cd ../../ && include ./somdir1/somdir2/make_example.mk

Related

Makefile: Avoid recompilation of a cloned repository

I'm trying to clone a repository from git and compile it locally. The relevant part of the Makefile is pasted below.
BUILDDIR = $(PWD)/build
# rest of the Makefile
...
all: release
release: $(BUILDDIR)/buildr/Makedir $(BUILDDIR)/depqbf
$(BUILDDIR)/buildr/Makedir:
mkdir -p $(BUILDDIR)/buildr
$(BUILDDIR)/depqbf:
cd $(BUILDDIR); rm -rf depqbf; git clone git#github.com:lonsing/depqbf.git
cd $(BUILDDIR)/depqbf;./compile.sh
The problem is if I use rm -rf depqbf, the compilation process happens everytime I run make.
If I remove it, and perform make again
fatal: destination path 'depqbf' already exists and is not an empty directory.
Is it possible to only clone and compile if the directory is not present.
the compilation process happens everytime I run make
The target of your recipe:
$(BUILDDIR)/depqbf/depqbf:
cd $(BUILDDIR); rm -rf depqbf; git clone git#github.com:lonsing/depqbf.git
cd $(BUILDDIR)/depqbf;./compile.sh
is the file $(BUILDDIR)/depqbf/depqbf. You are telling Make that, if the target $(BUILDDIR)/depqbf/depqbf
does not exist, then Make is to make the target by running the commands:
cd $(BUILDDIR); rm -rf depqbf; git clone git#github.com:lonsing/depqbf.git
cd $(BUILDDIR)/depqbf;./compile.sh
But those commands never create a file called $(BUILDDIR)/depqbf/depqbf. They
never make the target.
So every time Make considers the target it will decide that it has to made, by
running those commands.
If you remove rm -rf depqbf, then when Make attempts the target:
fatal: destination path 'depqbf' already exists and is not an empty directory.
Naturally, because you cannot clone into an existing non empty-directory. This is
not connected with the fact that the recipe is always being run. It is always being run
because it never makes its target.
Your other recipe:
$(BUILDDIR)/buildr/Makedir:
mkdir -p $(BUILDDIR)/buildr
likewise is one that that never makes it target. The command:
mkdir -p $(BUILDDIR)/buildr
will never create the file $(BUILDDIR)/buildr/Makedir. I do not see the purpose
of this recipe, so I'll assume it is just supposed to create the file
$(BUILDDIR)/buildr/Makedir if it does not exist, for some reason.
Then this makefile will attempt to make the targets if and only if they don't exist:
Makefile
BUILDDIR := $(PWD)/build
.PHONY: all release
all: release
release: $(BUILDDIR)/buildr/Makedir $(BUILDDIR)/depqbf
$(BUILDDIR)/buildr/Makedir: | $(BUILDDIR)/buildr
touch $#
$(BUILDDIR)/depqbf: | $(BUILDDIR)
cd $(dir $#); git clone git#github.com:lonsing/depqbf.git
cd $#; ./compile.sh
$(BUILDDIR) $(BUILDDIR)/buildr:
mkdir -p $#
Useful references in The GNU Make manual:-
An Introduction to Makefiles
Phony Targets
Types of Prerequisites
Automatic Variables

Dynamic target for root or nested directory

My makefile contains a target for node_modules directory, which depends on package.json file:
node_modules: package.json
npm install && touch "$#"
My current project happens to have a "sub-package" with its own set of dependencies. I modify the target above to the following:
%/node_modules: %/package.json
cd $(shell dirname "$<") && npm install && touch node_modules
Now, I can do make path/to/subpackage/node_modules and make runs the expected npm install command. However, I no longer seem to be able to do make node_modules - make exits with status code 0 and message Nothing to be done for 'node_modules'.
This indicates make will now only run the appropriate command for node_modules folders which exist within a subdirectory.
How can I change the target so that it supports both nested and root node_modules directories within the same target?
In other words, I would like to remove the duplicated target definition because the command to make the root's node_modules directory is the same as the command to make the nested path/to/node_modules directory.
As research, I tried to look at the GNU Make tutorial but could not find any relevant information - possibly because I simply do not know what to look for.
It isn't very elegant, but you could use a "canned recipe":
define MAKE_NODE_MODULES
npm install && touch node_modules
endef
node_modules: package.json
$(MAKE_NODE_MODULES)
%/node_modules: %/package.json
cd $* && $(MAKE_NODE_MODULES)

Run a command with relative path from symlink directory

I've got a directory structure like this:
bin
drush
build -> vendor/drupal/core
vendor
drupal
core
So as you see, build is a symlink to the core directory.
drush is an executable file. I need to be able to cd into build and call drush from there.
But if I do this:
cd build
../bin/drush
This doesn't work, because .. points to vendor/drupal directory, because when I cd into build, it in fact goes to vendor/drupal/core, of course.
I know I can call it this way: ../../../bin/drush, but is there some kind of workaround to make .. point to the root, not the actual parent?
You can create an another symlink in the folder "drupal" on the executable drush. So with this way, you can call it from "build".
$ cd vendor/drupal/
$ ln -s absolute_path/bin/drush dummy-drush
$ cd build
$ ./dummy-drush
Solution 1 :
If you don't want to create anything in vendor, maybe it's better to create an alias which allows to you to execute drush (be careful to give the good path).
Solution 2 :
If the directory bin in your example is not the folder "/bin" from the root, you can add it in your PATH in order to execute every executable .
$ export PATH=$PATH:/personal_bin/
$ cd bin
$ ln -s drush dummy-drush

Unix Command Line Current Directory

Let's say I have a folder structure like this:
mygame
play.command
otherstuff
code.py
I want play.command to cd to mygame no matter where mygame is and run code.py from there. How do I do that?
Put that code.py in /bin folder. Then you can access it from anywhere.
From your question it seems you want to go to the parent directory. You do this via
cd ..
otherstuff/code.py
(with the space after 'cd')
or call code.py more directly with
../otherstuff/code.py
I think you are trying something like this,
You have two ways to run scripts:
absolute path:
python /path/to/script.py
none-absolute path:
cd ../to/your/directory && python script.py
First cd to the directory where the script is stored in, and then execute the python script
#!/bin/bash
cd "$(dirname "${BASH_SOURCE[0]}")"
otherstuff/code.py

copy multiple files to null directory

I want to check if source file exist, so I assign TO_DIR=/dev/null in my gnu makefile.
APPS=a b c d
install:
cp $(APPS) $(TO_DIR)
for normal case, I'll run 'TO_DIR=~/bin make install'
for test case(just make sure file exist for copy), I'll run 'TO_DIR=/dev/null make install'
But it will failed, because /dev/null is not a pseudo directory.
Is there better solution?
You could do another make target, like this:
check:
file $(APPS) > /dev/null
file utility will check the existence of all the files and fail when any of these does not exist. Its output is excessive for this task, so we pipe it to /dev/null
You will run check like this:
make check
Here's a modification of spacediver's answer that just branches based on the value of TO_DIR
install:
[ -z "$(TO_DIR)" ] && make install_for_real || make check
install_for_real:
cp $(APPS) $(TO_DIR)
check:
file $(APPS) > /dev/null
This should do the check for either of
make install
make install TO_DIR=
but the real installation for
make install TO_DIR=/path/to/installation/dir

Resources