I have the following code to untar all the files in a directory and move it to build directory. If I call make multiple times, it tries to execute "build" target everytime even if build directory already exists. Has anyone comes across this?
I found this question but it is not the same.
Makefile always running target
OS: Ubuntu 12.04
Program: GNU Make 3.81
build: mkBuildDir untar
chmod 700 build
.PHONY: mkBuildDir untar
mkBuildDir:
mkdir build
untar: *.tar.gz
for prefix in *.tar.gz; do \
tar xvf $$prefix --directory=build; \
done
clean:
rm -Rf build
This is pretty much the same as the question you've linked. You never create a file called mkBuildDir, so it's always out-of-date, so build is always out of date.
Your mkBuildDir target isn't doing anything useful (though I presume this is a cut-down makefile). If instead you did
# it'd be better to list the TARFILES explicitly, though this will probably work
TARFILES=`ls *.tar.gz`
all: build untar
build: $(TARFILES)
test -d build || mkdir build
chmod 700 build
for prefix in $(TARFILES); do \
tar xvf $$prefix --directory=build; \
done
clean:
rm -Rf build
that would probably accomplish what you're looking for.
Having too many phony targets in a Makefile is usually a makefile 'code smell'. They are rarely the best/idiomatic way of doing things.
Related
To decrease library size, used cmake -E tar "zcvf" "lib.tar.gz" out.lib in cmake to automatically create .tar.gz then lib.tar.gz is moved to folder f, ie. f/lib.tar.gz.
However, to use this library in another project, it's needed to extract to specific folder. The command without cmake is clear: tar -xzf f/lib.tar.gz -C target-folder.
The problem is that, in cmake, how to combine cmake -E tar "xzf" f/lib.tar.gz with -C option? Commands such as cmake -E tar "xzf" f/lib.tar.gz -C f/ will result error.
Ideal script would be sth. like
add_custom_target(PrepareLib
COMMAND ${CMAKE_COMMAND} -E tar "xzf" command....
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} ## note, this line must not be modified
)
Tools version: Visual Studio 2017, Windows 10 and CMake 3.17.1.
I need to prepare an apt-package for stuff to enable building kernel modules for a custom Linux. I have cross-built on a different machine the kernel headers and modules using headers_install and modules_install make-targets. After copying the generated directories I'm still not able to build kernel modules on the target machine since /lib/modules/$(shell uname -r)/build is missing.
Here is my question. What are the minimal dependencies I need to include to my package in order to enable module builds (alongside with the generated kernel headers and modules mentioned above)?
Thanks in advance.
After some experimenting I've got to a working solution:
#!/bin/bash
ARCH=arm
SRC_DIR=$1
MOD_DIR=$2
BUILD_DIR=$MOD_DIR/build
set -ex
cd $SRC_DIR
make modules_install INSTALL_HDR_PATH=$MOD_DIR
rm $MOD_DIR/{build,source}
mkdir $BUILD_DIR
cp $SRC_DIR/{.config,Makefile,System.map,Module.symvers} $BUILD_DIR
mkdir -p $BUILD_DIR/arch/$ARCH
cp $SRC_DIR/arch/$ARCH/Makefile $BUILD_DIR/arch/$ARCH/
cp -r $SRC_DIR/scripts $BUILD_DIR/
# Build a headers tree manually, because
# `make headers_install` doesn't put everything needed.
cp -r $SRC_DIR/include $BUILD_DIR/
cp -r $SRC_DIR/arch/$ARCH/include/* $BUILD_DIR/include/
cp -r $SRC_DIR/include/generated/* $BUILD_DIR/include/
cp -r $SRC_DIR/arch/$ARCH/include/generated/* $BUILD_DIR/include/
cp $SRC_DIR/include/linux/kconfig.h $BUILD_DIR/include/linux/
This script is fed with a path to a kernel source tree after the latter was built natively (not cross-platform).
What I did were as follows step by step:
Git clone go-ethereum project to my local PC. It is located in
D:\GOPATH\src\github.com\ethereum\go-ethereum. It is the source code
of go-ethereum
Note: The OS is windows 7. Go has already been installed. And GOPATH env has already been set to "D:\GOPATH"
cd /d D:\GOPATH\src\github.com\ethereum\go-ethereum. Then execute
"go install". Some exe files were genereated under D:\GOPATH\bin
directory, and many pkg file with suffix .a were generated under
D:\GOPATH\pkg directory. Everything seems no problem.
Execute "go clean -n -r -i github.com/ethereum/go-ethereum..." to
remove all the generated exe files and .a files. But something very
interesting happened:
In the command's log, it showed that some files are deleted, but actually they are not deleted from disk.
For example, event.a exists under D:\GOPATH\pkg\windows_amd64\github.com\ethereum\go-ethereum, but the log of "git clean" shows:"rm -f D:\GOPATH\pkg\windows_amd64\github.com\ethereum\go-ethereum\event.a"
The detailed information is in the attached images.
It is very strange. The log does not match with the actual result:
A small segment of go clean command is as follows(since there are more than 1300 lines in log, I can not paste all of it):
cd D:\GOPATH\src\github.com\ethereum\go-ethereum\event
rm -f event.test event.test.exe
rm -f D:\GOPATH\pkg\windows_amd64\github.com\ethereum\go-ethereum\event.a
cd D:\GOPATH\src\github.com\ethereum\go-ethereum\common\mclock
rm -f mclock.test mclock.test.exe
rm -f D:\GOPATH\pkg\windows_amd64\github.com\ethereum\go-ethereum\common\mclock.a
cd D:\GOPATH\src\github.com\ethereum\go-ethereum\vendor\github.com\aristanetworks\goarista\monotime
rm -f monotime.test monotime.test.exe
rm -f D:\GOPATH\pkg\windows_amd64\github.com\ethereum\go-ethereum\vendor\github.com\aristanetworks\goarista\monotime.a
cd D:\GOPATH\src\github.com\ethereum\go-ethereum\accounts\abi
rm -f abi.test abi.test.exe
rm -f D:\GOPATH\pkg\windows_amd64\github.com\ethereum\go-ethereum\accounts\abi.a
cd D:\GOPATH\src\github.com\ethereum\go-ethereum\accounts\abi\bind
rm -f bind.test bind.test.exe
rm -f D:\GOPATH\pkg\windows_amd64\github.com\ethereum\go-ethereum\accounts\abi\bind.a
But some of the files remain:
The correct answer is actually provided by #Peter in comment. As Peter said "The -n flag causes clean to print the remove commands it would execute, but not run them."
I tried "-x" instead of "-n", and it works well. Thanks Peter. But you posted your answer in comment section, so I have to post your answer here and close this question.
How do I write a make target that will watch for any file changes in specific folders and execute some other make target to compile files? I am looking for a way that can do this with minimal dependency on tools in addition to make itself to keep things simple.
For the watching you can use fswatch. (There's also a go version of this program which may be easier to install: fswatch) For example:
fswatch -ext cpp,c,h make -f Makefile
Anytime you change a cpp, c or h file it will run make again.
Make can be a bit slow for this, so I tend to use ninja instead, but that really depends on the size of your project.
Another option is tup, which has watching built-in:
tup monitor
But, sadly, only for linux.
You can use entr and adjust your Makefile similar to this one
.DEFAULT_GOAL := run
SHELL := /bin/bash
run:
clear && \
cp one.txt two.txt && \
rm -f _* *.l2m *.o2m && \
Ganlib < testgan2.x2m
watch:
while sleep 1 ; do find . -name '*.x2m' -o -name '*.c2m' \
| entr -d make -f ./Makefile ; done
.PHONY: run watch
followed by
$ make watch
I am writing a master makefile to compile and install multiple autoconf based libraries, which depend on each other. All works well for the first go. The issue is: if I am working on one of these libraries individually and do "make && make install" header files in the prefix folder are overwritten (even if they are untouched). This causes all dependent libraries to compile from scratch.
Is there a way to avoid the unnecessary recompiles without hacking into the makefiles?
Maybe the solution is a little late, but
./configure INSTALL="install -p"
fixes the recompilation problem. This flag makes GNU install set the timestamps of the installed files to the timestamps of the built files.
You could use sentinel files that exist only to establish your dependency graph. For eg.
prefix := /usr/local
.PHONY: all
all: libx-built
libx-built \
: libx.tar.gz \
; tar xzvf $# \
&& cd libx \
&& ./configure --prefix=$(prefix) \
&& make && make install \
&& touch $#
Then, you'd make a dependent liby build only when libx-built is new.
liby-built \
: liby.tar.gz libx-built \
; ...