theicfire / makefiletutorial Goto Github PK
View Code? Open in Web Editor NEWLearn make by example
Home Page: http://makefiletutorial.com
License: MIT License
Learn make by example
Home Page: http://makefiletutorial.com
License: MIT License
Can you include an example of how to use of MAKEFILE_LIST
?
From the book in your link:
3.5 The Variable MAKEFILE_LIST
As make reads various makefiles, including any obtained from the MAKEFILES variable, the com- mand line, the default files, or from include directives, their names will be automatically appended to the MAKEFILE_LIST variable. They are added right before make begins to parse them.
This means that if the first thing a makefile does is examine the last word in this variable, it will be the name of the current makefile. Once the current makefile has used include, however, the last word will be the just-included makefile.
If a makefile named Makefile has this content:
name1 := $(lastword $(MAKEFILE_LIST))
include inc.mk
name2 := $(lastword $(MAKEFILE_LIST)) all:
@echo name1 = $(name1)
@echo name2 = $(name2)
then you would expect to see this output:
name1 = Makefile name2 = inc.mk
What would you have to have in inc.mk
for this example to run?
Thanks for sharing.
Hello, first this site is an awesome tutorial.
However, it doesn't point out the fact that functions like wildcard are exclusive to GNU make and won't work on BSD make for example.
I suggest adding a note on the top that this assumes GNU make which might be available in your packages/ports as gmake
and you should go for that instead if certain examples don't work.
.PHONY should be mentioned in the make clean section, as while it is mentioned much later on in the article, clean is where it's commonly seen. https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html
make all section should also include it as well for completeness (should there be a file named all
for some reason)
Hello, thank you for your training. If possible, please insert the pdf and epub output. Unfortunately, the system browser cannot print properly from the site.
Hi there, noticing the button for the cookbook at the top's host is simply "localhost", which is obviously wrong.
Page: https://makefiletutorial.com/
Thanks
Issue: part Static Pattern Rules and Filter
example not works well, refer to issue 40.
Refer issue 40 and the issue was fixed by commmit b7e9438.
However, the code was reversed after the new design
commitment.
May the code change to this below due to 54?
obj_files = foo.result bar.o lose.o
src_files = foo.raw bar.c lose.c
all: $(obj_files)
$(filter %.o,$(obj_files)): %.o: %.c
cc -c $< -o $@
echo "target: $@ prereq: $<"
$(filter %.result,$(obj_files)): %.result: %.raw
cc -c $< -o $@
echo "target: $@ prereq: $<"
$(src_files):
touch $@
clean:
rm -f $(src_files) $(obj_files)
But unfortunately, the implicit rule failed to work in this example, and no X.result
file is generated.
Hi, thank you very much for the tutorial,
I am trying to adapt the cookbook so that object files are put into a seperate obj directory.
The following section gives me trouble:
# Find all the C and C++ files we want to compile
# Note the single quotes around the * expressions. Make will incorrectly expand these otherwise.
SRCS := $(shell find $(SRC_DIRS) -name '*.cpp' -or -name '*.c' -or -name '*.s')
# String substitution for every C/C++ file.
# As an example, hello.cpp turns into ./build/hello.cpp.o
OBJS := $(SRCS:%=$(BUILD_DIR)/%.o)
The example you give here for what the substitution does seems correct but given that SRCS is not of the format 'hello.cpp' but rather './src/hello.cpp' the output will be 'BUILD_DIR/./src/hello.cpp' and this of course applies to my attempts at having all object files in another directory as well.
Aside from this being (IMO) ugly it also, considering the mismatch between the example and what happens, seems rather unintended.
Great tutorial!
I suggest adding right at the beginning which major make version the tutorial targets — i.e. v3 or v4?
One of the most confusing aspects of make to me is that some projects rely on make v3.x, while others rely on v4.x, which introduces some syntax incompatibility issues — especially under Windows, where the official make for Windows from GNU is still v3, whereas the version bundled with MinGW is v4 (mingw32-make.exe
).
Unfortunately. most make tutorials omit mentioning the version they are targeting.
By stating right at the beginning which make version the tutorial was written for could avoid confusion right away.
Also, it might be worth spending a few paragraphs on the differences between make v3 and v4 and the fact that they are both currently used by many projects — and maybe also mention they key aspects in which they differ and how to write Makefiles that would work with both version?
I still don't know what they key differences between these two major versions are, and their coexistence in everyday use has been an obstacle in learning Make, which is why I'd definitely appreciate a tutorial which explains the issue (couldn't easily find a dedicated article on this).
Website's very helpful, but I think there's an error in the cookbook example that should be fixed:
SRCS := $(shell find $(SRC_DIRS) -name *.cpp -or -name *.c)
*.cpp
and *.c
should be wrapped in single quotes, or GNU make will expand the wildcard expression before passing to find
, which is unintended.
If you have a single .cpp
file, you'll be running find ./src -name foobar.cpp
, which will most likely only return that one file.
If you have multiple files with the .cpp
extension, you'll be passing multiple files after -name
to find
, e.g. find ./src -name foo.cpp bar.cpp
and it will throw an error like this:
find: paths must precede expression: `bar.cpp'
find: possible unquoted pattern after predicate `-name'?
If you go to the bottom of the comments where the example was pulled, you'll find someone who encountered this exact issue:
https://spin.atomicobject.com/2016/08/26/makefile-c-projects/
I got the opposite result, "wrong" can be printed while "objects" can't be printed.
zhuangyan@n25-146-090:~/coding/c/blah$ make --version
GNU Make 4.1
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
zhuangyan@n25-146-090:~/coding/c/blah$ cat Makefile
wrong = *.o # Wrong
objects := $(wildcard *.c) # Right
some_binary:
touch f1.c
touch f2.c
echo $(objects)
echo $(wrong)
clean:
rm -f *.c
zhuangyan@n25-146-090:~/coding/c/blah$ make
touch f1.c
touch f2.c
echo
echo *.o
*.o
When trying this in a Makefile:
obj_files = foo.result bar.o lose.o
src_files = foo.raw bar.c lose.call: $(obj_files)
$(filter %.o,$ (obj_files)): %.o: %.c
echo "target:$@ prereq: $ <"
$(filter %.result,$ (obj_files)): %.result: %.raw
echo "target:$@ prereq: $ <"%.c %.raw:
touch $@clean:
rm -f $(src_files)`
I get the following output:
$ make
touch foo.raw
echo "target: foo.result prereq: foo.raw"
target: foo.result prereq: foo.raw
touch bar.c
echo "target: bar.o prereq: bar.c"
target: bar.o prereq: bar.c
touch lose.c
echo "target: lose.o prereq: lose.c"
target: lose.o prereq: lose.c
touch all.c
cc -c -o all.o all.c
cc all.o foo.result bar.o lose.o -o all
cc: error: foo.result: No such file or directory
cc: error: bar.o: No such file or directory
cc: error: lose.o: No such file or directory
make: *** [: all] Error 1
rm all.o all.c
Is this intended output?
Hi, In Website , Chapter Implicit Rules:
in CPPFLAGS: Extra flags to give to the C preprosessor
, I guess that you want to say preprocessor. :)
Thanks to your article, it helps me a lot!
In https://makefiletutorial.com/ , example codes use spaces but not tabs for indent, which will not work with make
command.
Error occur:
Makefile:2: *** missing separator. Stop.
What do you think about translating the site to the other languages? Do you have plan or direction for this? I really want to contribute by translating the site into Turkish.
I think there is an error in multiple-targets chapter(https://makefiletutorial.com/#multiple-targets), miss :
after f1.o and f2.o, here is the screenshot:
should be:
# f1.o:
# echo $@
# f2.o:
# echo $@
and I think this will be more clear to show When there are multiple targets for a rule, the commands will be run for each target
and the meaning of $@
:
# f1.o:
# echo f1.o
# f2.o:
# echo f2.o
find some bugs:
all:
touch %@ -> touch $@
Looking at http://makefiletutorial.com/, There are seven "Intro" headings and then monotone increasing numbers: 2.4, 2.5, 4.1, 4.2, 4.2.3, etc...
What was the intent?
Here we ran make with make some_option=hi
that needs to be changed into make option_one=hi.
Very great tutorial!
But I'd like to point out a small error in comments of the cookbook.
In line 8 and line 9, you said:
# Note the single quotes around the * expressions. Make will incorrectly expand these otherwise.
SRCS := $(shell find $(SRC_DIRS) -name '*.cpp' -or -name '*.c' -or -name '*.s')
Of course you need the single quotes. However, without them, it is not Make which expands the wildcard *
, and actually it is your shell.
In GNU make docs, 4.4 Using Wildcard Characters in File Names said:
Wildcard expansion is performed by make automatically in targets and in prerequisites. In recipes, the shell is responsible for wildcard expansion. In other contexts, wildcard expansion happens only if you request it explicitly with the wildcard function.
and 4.4.3 The Function wildcard said:
But wildcard expansion does not normally take place when a variable is set, or inside the arguments of a function.
As part of argument of function shell
, GNU make will not expand *
, which is passed to your shell literally.
So why is there single quotes necessary? The reasons are as follows.
Before shell invokes command find
, it will execute filename expansion. I use bash for example here.
In GNU bash manual, 3.5.8 Filename Expansion said:
Bash scans each word for the characters ‘*’, ‘?’, and ‘[’. If one of these characters appears, and is not quoted, then the word is regarded as a pattern, and replaced with an alphabetically sorted list of filenames matching the pattern (see Pattern Matching).
Then *.cpp
will expand to c++ source files in current working directory, which is undesirable because command find
would not get the asterisk. Therefore, you need single quotes to prevent shell from filename expansion.
It could be great to adding an example for "MAKECMDGOALS": https://www.gnu.org/software/make/manual/html_node/Goals.html
As a web search returns this project page as first result and no entry clearly identified as "Makefile Cookbook", it would be nice to add the link to it.
Line 12 in f848b33
The beginner example is introduced with 3 rules. Following this dependency chain requires recursing two levels deep. I believe a simpler example would first introduce a trivial makefile with no dependency to get used to invoking compilation
blah:
cc -o blah blah.c
and then maybe just two rules with one dependency, for example
blah: blah.o
cc blah.o -o blah # Runs second
blah.o: blah.c
cc -c blah.c -o blah.o # Runs first
where blah.c exists; the echo is confusing because blah.c source would normally exist already.
Also there should be a separator between examples since the article immediately jumps to a new example with "This makefile has a single target..."
In "Static Pattern Rules", both "all.c" and "%.c" could match "all.c"
Readers(Including me a few minutes ago) may wonder which one will be matched, or if both, which one would be the first.
So I think pattern matching priority should be explained.
I would propose this addition (in bold):
Interpreted languages like Python, Ruby, and Javascript don't require an analogue to Makefiles. The goal of Makefiles is to compile whatever files need to be compiled, based on what files have changed. But when files in interpreted languages change, nothing needs to get recompiled. When the program runs, the most recent version of the file is used. (There are some exceptions, like transpiling Typescript files to Javascript)
In the mobile (and technically the desktop) versions of the site, there is no inline margin. This makes it annoying to read as the text goes all the way to the edge of the page.
Here's an example from the developer tools:
This could be solved by adding a 1em
or so inline margin on the main element. I feel this would improve the reading experience for mobile users.
I tried to visit the site today and encountered a redirect loop—https://makefiletutorial.com/
301s to itself:
$ curl --HEAD 'https://makefiletutorial.com/'
HTTP/2 301
date: Fri, 22 Sep 2023 16:03:53 GMT
content-type: text/html
location: https://makefiletutorial.com/
x-github-request-id: 7628:2424:A71BCB:F7B4DE:650DADA1
accept-ranges: bytes
via: 1.1 varnish
age: 3400
x-served-by: cache-chi-klot8100057-CHI
x-cache: HIT
x-cache-hits: 1
x-timer: S1695398634.956117,VS0,VE1
vary: Accept-Encoding
x-fastly-request-id: 1d429a81f19b38b5e0684ec0315709a1cf0afc9c
cf-cache-status: DYNAMIC
report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=%2FCopSq2xMM83HLSoN10nQdyRmcegqQXn1rzerlfWD5G58%2BvXaRoPuIR7z4CjkfdoPrsWyGTTk5zhMiBlNrBpK8AvqcC%2FXnXT9yJI4DOkeekAJdU2QUp%2FM4eLS1b%2FSwwRu2ba%2FUctjw%3D%3D"}],"group":"cf-nel","max_age":604800}
nel: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
server: cloudflare
cf-ray: 80abc7d6281510d3-ORD
alt-svc: h3=":443"; ma=86400
(https://www.makefiletutorial.com/
redirects to the above, as do (ultimately) the two domains over plaintext HTTP, so none of those works either.)
The Wayback Machine had a successful capture on Sept. 9, so the breaking change must have been relatively recent.
In chapter https://makefiletutorial.com/#automatic-variables-and-wildcards I can not find an example how to require some other target before processing % pattern rule.
For example, I want to execute bootstrap
rule before passing .in files to echo.
default: *.txt
bootstrap: boot.txt
# Define a pattern rule that compiles every .in file into a .txt file
%.txt: bootstrap %.in
echo $^ $@
This executes the command passing "bootstrap" string to it, which I did not expect.
echo bootstrap xxx.in xxx.txt
The automatic pattern $<
is used in Static Pattern Rules and Filter and the Makefile Cookbook but never explained in the Automatic Variables section directly.
The pattern $?
is explained in Automatic variables but is never used later. I think that $<
should be explained with the other automatic variables if it is used in the final cookbook example.
http://makefiletutorial.com isn't currently visible anywhere when visiting the repo - it would probably make sense to add it to the repo metadata and/or the README
Right now the hello world example includes echo "This line will always print, because the file hello does not exist."
which is misleading because the file hello
could exist.
I propose changing the second echo to echo "This line will print if the file hello does not exist"
. This is explained in the explanation below the code.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.