Let's say I have a makefile.am with
SUBDIRS = a . b c
I want to call the Makefile in a/ passing a target, and ONLY to the makefile in a/ (not ., b/ or c/).
Is there a way to do it, in case even not using SUBDIRS for a/ ?
Related
For my specific case, I have many folders and subfolders with .v files. I want to compile them folder by folder. I have made this:
# find folders and subfolders to work on
DIRS := $(wildcard */)
DIRS += $(shell find $(DIRS) -type d)
# compiler flags
SRC += *.v
COMPILE = $(general_compiler_flags) $(SRC)
# run the compiler
run:
$(foreach d, $(DIRS), $(shell cd $d && $(COMPILE)))
But this takes all folders that do not have .v files and compiles them anyway. How do I make it so on my DIRS I have only the folders that house .v files?
The way you use make functions (especially shell) in your recipes is not the recommended way to use make. Assuming you have simple directory names (no spaces, no special characters), you could use something like the following, instead:
VDIRS := $(sort $(foreach d,$(DIRS),$(if $(wildcard $(d)/*.v),$(d),)))
run:
for d in $(VDIRS); do ( cd $$d && $(COMPILE); ); done
An even more make-ish solution would rely on make to iterate over all source directories instead of doing so inside a recipe:
VDIRS := $(sort $(foreach d,$(DIRS),$(if $(wildcard $(d)/*.v),$(d),)))
RUN-VDIRS := $(addprefix run-,$(VDIRS))
.PHONY: run $(RUN-VDIRS)
run: $(RUN-VDIRS)
$(RUN-VDIRS): run-%:
cd $* && $(COMPILE)
And, finally, we should consider how to avoid useless re-compilations, but this is another, more complex, story.
Say a makefile includes multiple other makefiles. How can these included makefiles get to know the path to themselves relative to the main makefile?
An example structure is as follows:
main make:
include ../dir1/dir2/make1.mk
include dir3/dir4/dir5/make2.mk
.PHONY: print_paths
print_paths:
#echo $(dir1) && #echo $(dir2)
make1
dir1 = <some code>
make2
dir2 = <some code>
My expected output would be:
../dir1/dir2
dir3/dir4/dir5
I was able to solve this for a single include file through:
dir1 = $(dir $(lastword $(MAKEFILE_LIST)))
However, this does not seem to work for multiple files, as both dir1 and dir2 will be set equal to the directory of makefile two. (which is fair I guess? It is the last file included after all)
Alternatively them getting to know their absolute path would be fine as well.
You could simply add:
dir1 := $(dir $(lastword $(MAKEFILE_LIST)))
at the beginning of ../dir1/dir2/make1.mk and:
dir2 := $(dir $(lastword $(MAKEFILE_LIST)))
at the beginning of dir3/dir4/dir5/make2.mk.
I have the following directory tree
moving_files/
Makefile
source/
a
b
c
target/
With my Makefile I want to cp every file in source/ to target/.
The catch: I want to be able to move other files to source/ afterwards without having to edit the Makefile. For this purpose I have written this:
FILES = $(filter-out Makefile, $(wildcard source/*) )
all: $(subst source,target,$(FILES))
$(subst source,target,$(FILES)): $(FILES)
cat $< >| $#
And it works fine.
However, when I execute touch source/d afterwards and make once again, in addition to d, a, b and c get cated, as well. What do I have to do in order to change this behavior.
$(subst source,target,$(FILES)): $(FILES)
expands to
target/a target/b target/c: source/a source/b source/c
which means that each single target depends on all files in source, probably not what you intended. Either a static or an implicit rule can fix this, static rules are generally better as they are more specific:
$(subst source,target,$(FILES)): target/%: source/%
im trying to make a simple makefile that will build multiple artifacts named after subdirs of the src directory. here is my dir structure:
>find .
.
./makefile
./src
./src/binA
./src/binA/main.java
./src/binB
./src/binB/main.cpp
./src/binC
./src/binC/main.scala
and here is the makefile i am trying to use. for some reason the binary target refuses to expand its dependencies with when i use both a pattern and a wildcard in the same rule
>cat makefile
dirs := $(shell find src -mindepth 1 -type d)
all: $(dirs:src/%=bin/%.exe)
#echo $(dirs)
bin/%.exe: src/%/*
#echo "$# <-- $^"
i know dirs is getting set properly
src/binA src/binB src/binC
this is the error i get
>make
make: *** No rule to make target `bin/binA.exe', needed by `all'. Stop.
how can i make a generic rule that will properly expand its dependencies to be the contents of a subdir that is based on its name
i was able to get this to work by changing the rule matcher to bin/%.exe: $(wildcard src/%/*) and add a .SECONDARYEXPANSION: before that.
First, let me say that I am aware of the cons of using recursive Makefiles. So if you are here just to tell me don't use it, please don't.
Imagine this directory structure:
rootdir
`-- subdir
|-- a
|-- b
`-- c
Let's say the Makefile on rootdir reads like this:
.PHONY: all
all:
# build some stuff
$(MAKE) -C subdir
and the one in subdir reads like this:
.PHONY: all
all:
# nothing here except redirecting make to each of the subdirectories
$(MAKE) -C a
$(MAKE) -C b
$(MAKE) -C c
and another Makefile in each of a, b and c folders building something.
Since the Makefile in subdir serves no purpose except redirecting make, I want make not to print: Entering directory rootdir/subdir and Leaving directory rootdir/subdir to clean up the output a bit.
On the other hand, since there are commands being executed in the subfolders a, b and c, I do want make to print these outputs. Here's what I thought would work:
rootdir's Makefile:
.PHONY: all
all:
# build some stuff
$(MAKE) --no-print-directory -C subdir
subdir's Makefile:
.PHONY: all
all:
# nothing here except redirecting make to each of the subdirectories
$(MAKE) --print-directory -C a
$(MAKE) --print-directory -C b
$(MAKE) --print-directory -C c
The problem is, once the --no-print-directory is given to make when calling make for subdir, --print-directory doesn't enable it again when calling make for a, b or c.
So my question is, how can I re-enable printing directories when a parent make has disabled it?
Make command line flags get communicated to sub-makes via MAKEFLAGS variable. You may like to replace --no-print-directory (if any) from MAKEFLAGS with w manually before invoking the sub-makes:
${MAKE} MAKEFLAGS="$(subst --no-print-directory,w,${MAKEFLAGS})" -C ...