Stop GNU make from compiling by default - makefile

I just want to use GNU make to compress some files.
So I wrote the Makefile as follows:
lib.tar.lzma: $(shell find ~/lib -name "*")
rm -f lib.tar.lzma
tar -cavf lib.tar.lzma -C ~/ lib/
However, after I run make, it automatically compile the c++ source code in that directory.
How can I stop it from compiling them? I just want to compress them.
Update:
I got the following error:
<builtin>: recipe for target '/home/xxx/lib/app' failed
It seems a built-in recipe.

(We don't know your entire Makefile and your full file tree, so this is only a guess; I assume that you have shown us a fragment of your much bigger Makefile)
However, after I run make, it automatically compile the c++ source code in that directory.
This is probably happening because your $(shell find ~/lib -name "*") is expanded to something containing your object files. Since they are in your dependencies their source file is recompiled if it is newer. BTW you might want to use instead $(shell cd .. ; find lib -name "*") or if lib has no subdirectory even $(wildcard ../lib/*)
You probably don't need any dependency for that lib.tar.lzma target, so just have:
lib.tar.lzma:
rm -f lib.tar.lzma
tar -cavf lib.tar.lzma -C ~/ lib/
BTW, that -C ~/ perhaps should be -C $$HOME since make use /bin/sh to run commands, and that POSIX shell don't know about ~ ; perhaps a -C .. might be better ...
Perhaps you might write some shell script make-backup.sh to do a more clever tar and you would then code
lib.tar.lzma: make-backup.sh
./make-backup.sh $#
However, perhaps you do have dependencies (e.g. if you need to archive some generated files). Then you need to list them explicitly and wisely (you certainly don't want to depend on all the files; perhaps only the source ones). Also, you might not need to archive any object files *.o, if you have some (but YMMV).
I recommend using make --trace or remake -x to debug your Makefile.
BTW, having a Makefile only for a backup is useless; write a shell script instead.
I also strongly recommend using some version control system (like git) if you don't use any. Notice that git has an archive subcommand which might be a more clever backup.

Related

Calling CMake Makefile with another Makefile

I am attempting to call the auto-generated CMake makefile from outside of the CMake directory using make.
In order to accomplish this, I have made another makefile in the parent directory of my project. This file should cd into the CMake directory and call the makefile contained in there.
Unfortunately, I am having issues with the external makefile. The contents are as follows:
clean:
cd cmake-build-debug && $(MAKE) clean
I have a tab following the final line, but am still getting a separation error.
From the make man-page:
-C dir, --directory=dir
Change to directory dir before reading the makefiles or doing
anything else. If multiple -C options are specified,
each is interpreted relative to the previous one:
-C / -C etc is equivalent to -C /etc. This is typically
used with recursive invocations of make.
So, your clean rule can be:
clean:
$(MAKE) -C cmake-build-debug clean

custom install hook and rpmbuild

I have a package that uses autotools for build/install/etc. It is a Python module written in C++. (This isn't important except to know that the python scripts I have to install aren't part of what's being built, i.e. they're not a xxxxx_SOURCES primary.) This module is used solely for some "unit tests" for a driver that our team distributes in a HW solution. For various reasons, I have need to "install" the python unit tests with the system.
Since these python scripts aren't part of the module, I'm managing the installation separately in the Makefile. Here's what I have in my Makefile.am:
EXTRA_DIST = setupenv.sh bootstrap tests
dist-hook:
rm -rf $$(find $(distdir)/tests -name \*.swp -o -name \*.pyc)
install-exec-hook:
mkdir -p $(prefix)/unit_tests/unittest2
for f in tests/*.py; do \
cp $$f $(prefix)/unit_tests; \
done
for f in tests/unittest2/*.py; do \
cp $$f $(prefix)/unit_tests/unittest2; \
done
uninstall-hook:
rm -r $(prefix)/unit_tests
This works just fine except during rpmbuild for the module. The install-exec-hook rule isn't written correctly to make the directory where the rpm process redirects it. That is, when mkdir - $(prefix)/... is executed, the script literally tries to make the dir: /opt/oursw/.... How should this rule be rewritten so that rpmbuild puts them in the same place as the installation for the module?
You want to add $(DESTDIR) as a prefix to all those directories. That's standard for autotools installs.
As an aside, you also might want to look at the _SCRIPTS suffix, which allows "make install" to copy your scripts in for you the "official" way, removing the need for this hack in the first place.

Issues with wildcard (*) in Makefile

I am trying to symbolically link multiple files using my Makefile using the command: ln -s $(PWD)/bin/* ../../../bin/destination
If I run the command in native bash it works fine, but run in the Makefile it simply creates an * in the destination directory.
Any help would be appreciated.
You could use $(wildcard $(PWD)/bin/*) instead of $(PWD)/bin/* (assuming you are using GNU make; read it about wildcard pitfalls) and about the wildcard function
To debug the issue, I would suggest using remake (as remake -x) and/or make --trace

Specifying path to "makefile" using "make" command

I would like to run a makefile from another place in the file system. How do I pass the location of the makefile to make?
if I stand in "/" and I would like to run a makefile that resists in "/dir/dir2/dir3/makefile", how do I add that to the make command?
I tried:
make --file=dir/dir2/dir3/makefile
but it did not worked.
All relative paths in the makefile will be relative to your current directory and not the directory of the makefile.
Assuming that you understand that and what you want to do is still going to work then you want the -f flag to specify the makefile to use. (Which is in the man page, the manual and the --help output.)
If, instead, what you mean is you want to cd to somewhere else and run make then perhaps you are looking for (cd /some/path && make)?
You can use the -C flag to specify the path to your makefile. This way you can execute it from a different directory.
The -f flag has a different use. With that flag you can execute a makefile with a name other than makefile.

Make: $(wildcard) holding a directory open

So there seems to be this problem with GNU Make's $(wildcard) function keeping a directory open on Windows. See (unasnwered) post "make is holding a directory open". Google does not provide much information on the topic.
In short: the Makefile uses the $(wildcard) function at some point, and keeps a directory open, which typically prevents the "make clean" rule to do its work correctly. Re-running "make clean" a second time usually solves it.
I'm using GNU Make version 3.81 under a standard DOS-Box. The author of the post linked to above is using Cygwin.
Has anyone found a fix for this?
Sounds like a file descriptor leak, all right -- harmless for very-short-lived processes (like make) on UNIX, but a right PITA on Windows.
As this is allegedly a bug in make, as opposed to a problem with its usage, it should be addressed first by validating that it still exists when built from source on the newest upstream version, and then by filing a bug report with the GNU make project (or with any distributor with whom you have an appropriate support contract), or diving into the source and attempting to fix it yourself.
It wouldn't hurt to try to reproduce on Linux -- checking for file descriptor leaks are much easier here, as one can just look at /proc/self/fd (or, for a child of make, /proc/$PPID/fd) for things that don't belong.
I did find a workaround for the problem, which at least lets me work in peace.
The problem was that the $(wildcard) function was used to collect the sources files. My clean rule, however, only deletes a directory - no need for the collecting to take please. So I basically put the part of the Makefile that needs to collect the sources files in a conditional statement:
# The clean rule is always parsed
clean:
rm -rf $(OUTPUT_DIRECTORY)
# The compile rule is only interpreted if we did not invoke 'make clean'. We
# can test the value of $(MAKECMDGOALS) for that:
ifeq ($(filter $(MAKECMDGOALS),clean),)
SOURCE_FILES := $(wildcard ...)
compile:
g++ $(SOURCE_FILES) ...
endif

Resources