Makefile always call all even with target - makefile

Okay, I think I'm missing something in my makefile and it's causing me headaches. In my local build I call it with "dev:" and it does the dev target; Great, but I also want it to always do the "all:" target. When I call make dev it runs the dev but not the all, is there a terminology fail here?
here is my makefile
BUILD="build/"
STATIC="static/"
APP_NAME="Open World"
all:
# Remove the current build folder
rm -rf ${BUILD}
# Create the build directory
mkdir -p ${BUILD}
dev:
all
dev=${STATIC}dev
echo "Doing DEVELOPMENT build"
# Copy the package.json
cp ${dev}package.json ${BUILD}
prod:
echo "production"

The default (first) target is only run if no target is explicitly given. If you want it to run when another target is given then you need to make it a dependency of that target.
dev: all

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

path in makefile not working

Im running the following makefile
which needs to change dir to specific target and run there npm install
The problem is that I was able to see in the output that it print the directory (project/app) to the right directory but the installation (npm install) run on level up (project), why ?
For example
When I run it I see from cd $(DIR)/app
/Users/i03432/go/src/project/app
Now the second command is
npm install
And I got error that id doesn’t find the package json in the project path which is right... it’s only in the app path. Why the cd is not working ?
it try to find it here
/Users/i03432/go/src/project/package.json
and here is the package.json
/Users/i03432/go/src/project/app/package.json
The makefile is
module:
DIR=$(PWD)
#echo $(DIR)
cd $(DIR)/app
npm install
Every command in a rule is run in a single process (sub-shell). Every change you perform on the environment is hence tied to that particular line. You want to change your snippet to
cd $(PWD)/app && npm install
This command runs in a single subprocess and should yield the desired result. Note that this problem occurs for the definition of DIR, too, so you might want to move this a few lines up:
DIR = $(PWD)
module:
cd $(DIR) && npm install
This way, you are referring to a variable that make provides, and you don't rely upon subprocesses here.

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)

qmake generated target_wrapper.sh fails on make check

I have a qmake project with a subdirs template and two child projects.
The subdir projects are two testcases. The project is built with on mingw64.
When I run "mingw32-make check", the process fails when the first testcase is called by the target_wrapper.sh:
cd && /C/JENKINS/workspace/MyProject/tests/test1/target_wrapper.sh release/test1.exe
/C/JENKINS/workspace/MyProject/tests/test1/target_wrapper.sh: Zeile 6: /home/jenluelokal/release/test1.exe: No such file or directory
mingw32-make[2]: *** [Makefile.Release:82: check] Error 127
The Makefile.Release calls the following line for the check target:
check: first
cd && /C/JENKINS/workspace/MyProject/tests/test1/target_wrapper.sh $(TESTRUNNER) release/$(TARGET) $(TESTARGS)
By request the target_wrapper.sh:
#!/bin/sh
PATH=/C/Qt/Qt5.9.2/5.9/mingw64/bin:$PATH
export PATH
QT_PLUGIN_PATH=/C/Qt/Qt5.9.2/5.9/mingw64/share/qt5/plugins${QT_PLUGIN_PATH:+:$QT_PLUGIN_PATH}
export QT_PLUGIN_PATH
exec "$#"
The first cd changes into the homedir of the current user and calls target_wrapper.sh. The target_wrapper.sh script tries to execute the
test1 binary - which is not inside the home directory.
What am I doing wrong?
DESTDIR needs be set, so the make check target knows where to look for the test executables. The "cd" changes into this directory before trying to run the target_wrapper.sh.

Wrap a scons build process in a Makefile

I've written a scons build chain form a little C project, but I'm afraid users won't like to be told "You should install SCons first. Besides, it's really cool!" (expecially my professor, as he's kind of from the old guard).
Is there a way I can set up a Makefile that will wrap scons, not requiring it to be installed on the target system?
After looking for such a solution some time ago, I ended up writing a Makefile for this purpose.
Because SCons also comes as a drop-in userspace package scons-local (see the download page), one can fetch in and run it. Here is a dissectioned and commented version of my Makefile, which I also uploaded as a gist.
all: get_scons
#$(SCONS_EXE)
↑ The default action depends on scons being available, and simply runs the scons command (set later in the script) (the # symbol prevents make from printing the command)
SCONS_VERSION=2.3.4
scons-local-%.tar.gz:
curl -L http://sourceforge.net/projects/scons/files/scons-local/$(SCONS_VERSION)/scons-local-$(SCONS_VERSION).tar.gz > scons-local-$(SCONS_VERSION).tar.gz
touch scons-local-$(SCONS_VERSION).tar.gz
scons-local: scons-local-$(SCONS_VERSION).tar.gz
mkdir -p scons-local
tar xzf scons-local-$(SCONS_VERSION).tar.gz --directory scons-local
touch scons-local
↑ Set up the rules for fetching the tarball and unpack it into the scons-local directory
NATIVE_SCONS=$(strip $(shell which scons 2>/dev/null))
ifeq ($(NATIVE_SCONS),)
SCONS_EXE=python2 ./scons-local/scons.py
get_scons: scons-local
#echo "Couldn't find an installation of SCons, using a local copy"
else
SCONS_EXE=$(NATIVE_SCONS)
get_scons:
#echo "Found SCons installation at $(SCONS_EXE)"
endif
↑ Look for the scons executable in the search path (using the which command): if it is available, set up the get-scons target to simply print it is available. If, instead, it is not available, create the get-scons target instructing it to depend on the scons-local target defined earlier.
clean:
$(SCONS_EXE) -c
rm -rf scons-local
rm -f scons-local-*.tar.gz
.PHONY: all clean get_scons
↑ Finally, set-up the clean target that delegates to scons and deletes the local installation afterwards. The .PHONY rule tells make that the following rules do not correspond to files being created.
At this point, one could add more proxy rules of the kind:
mytarget: get_scons
#$(SCONS_EXE) mytarget
Which will invoke scons with the corresponding target.
Hope this is useful, feel free to correct me in case there's something wrong (I'm actually not a Makefile expert, and I'm trying not to become one by using SCons instead :P )

Resources