How to use command line argument in GNU make? - makefile

For example, I have 10 source files named ex1.c, ex2.c, ex3.c....ex10.c and maybe more in the future.
Is it possible that I can use commandline argument as a variable in GNU Make so that when I want to compile ex1.c, I can type in make 1. If I want to compile ex10.c, I can type in make 10. And I don't need to add more lines to makefile when I add more sources like ex100.c later.

This doesn't strike me as a good idea, but yes, you can do it.
To build object files (e.g. ex3.o):
%: ex%.c
$(CC) -c $< -o ex$*.o
To build executables (e.g.ex3):
%: ex%.c
$(CC) $< -o ex$*

Related

GNU make generate assembly first, them compile them to .o and link

SOURCE=a.c b.c c.c
ASM=$(patsubst %.c,%.s, $(SOURCE))
all:%.o
gcc -o test $^
$(ASM):%.c
gcc -S -o $# $<
%.o:%.s
gcc -c -o$# $<
I want to generate assembly code (.s) first, then compile the assembly code to object (.o), then link them.
But it seems above makefile code does not work. What is the correct code?
When asking questions, does not work is never very useful... if it worked you probably wouldn't be asking a question! :-) Instead you should always show the command you ran and the output you received (or at least the failing part of the output if it's long). Please cut and paste the actual text rather than paraphrasing messages. Also, including the version of the make program you're using (make --version) and the platform you're running on is often helpful.
Luckily this time we can figure out the problem without this information:
This:
$(ASM):%.c
gcc -S -o $# $<
where ASM is a.s b.s c.s, is not a pattern rule because the targets don't contain a pattern character %. That means the prerequisite %.c is not treated as a pattern, but as an actual file name, literally %.c which obviously doesn't exist.
Similarly, this:
all: %.o
has the same problem: all is a target, so this depends on the literal file named %.o which doesn't exist, and can't be created.
Also as a general rule every recipe that creates a target must create the actual target you told make it would, so this all rule is wrong because the target name is all but the recipe creates the target test.
Finally, it's a very bad idea to name your program test because test is a common UNIX program and a shell built-in, so if you run test it won't do the right thing (if you run ./test it will work).
You want to have all depend on the program you want to build, say mytest, and mytest should depend on the actual .o files:
all: mytest
mytest: $(SOURCE:.c=.o)
gcc -o $# $^
Next, you need to define a pattern rule that knows how to create an assembly file from a source file:
%.s : %.c
gcc -S -o $# $<
That, along with your other pattern rules, is all you need: make will figure it all out from that.
Finally, make has a built-in rule that tells it how to build object files directly from source files. It's best to get rid of this to force make to use your rules; add this to your makefile to delete it:
%.o : %.c

gcc / make - creating make files for creating assembly and linking

To perform an experiment I want to modify the assembly code of the OpenWRT Project (by inserting NOPs between the regular, meaningful code).
Thous I need to create the assembly files (.s files) by compiling with gcc's -S flag in the first run, execute a shell script modifying the assembly files and call the linker in the third step to create the executable binaries. Beside step 2, is there a way to accomplish steps 1 & 3 by an appropriate make file modification/configuration, i.e. create one make file for compiling (creating .s files) and another to conduct linking?
Thanks for enlightenment &
Happy a new year! :)
use this syntax:
target [target...] : [dependent ....]
[ command ...]
example:
%.S: %.c
$(CC) -S $# -c $<
%.o: %.S
$(CC) -o $# -c $<
which means to build the target foo.o make should build foo.S and for foo.S build foo.c
$# means target name
$< means targets first dependency

Makefile for using make as gcc

Is it possible to write universal Makefile which would get any target and act like a wrapper to gcc, but with parameters? For example, this means that
make 01.c
will have the same result as
g++ -o 01.out 01.c
make already has several "implicit rules" to do what you're trying.
For example, even with no makefile,
make 01.o
Will run:
c++ -c -o 01.o 01.cpp
If it finds a file called 01.cpp in your current directory. You can set the CXXFLAGS environment variable if you want to pass more flags. If you're really set on using g++ rather than the system compiler, you can set CXX=g++, too.
Yes - You using implicit rules.
Summat like (if memory serves me right)
.cpp.o:
$(CCC) $(CFLAGS) $< -o $#
Maybe in the set of default implicit rules
You can use a wildcard - %.
However, the thing specified on the commandline is the target, not the source - what you want, not what you have.
It looks like what you want is approximately:
%.out: %.c
g++ -o $# $<
This means: to make (something).out, first make sure you have (something).c, then run g++ -o (something).out (something).c
$# is always the target file, and $< is the first prerequisite.
You will need to run make 01.out, not make 01.c

GNU Make Pattern Rule on MacOS X

I'm struggling with makefiles on OS X Lion. I'm trying to use % pattern rule to compile all my .c files into objects in current dir. I'm using rule:
%.o : %.c
$(CC) -c $(CFLAGS) $< -o $#
But make says that no targets. I know that % pattern it is feature of gMake but -v says that I've got GNU make installed. I've also tried old style:
.cpp.o:
gcc $^ -o $#
But it is do not working to. What I'm doing wrong? Thanks.
If that's your entire Makefile, then indeed, it contains no targets. Invoke it with make file.o or add a phony target all which lists the names of the files you want to have built. It could be as simple as
.PHONY: all
all: $(patsubst %.cpp,%.o,$(wildcard *.cpp))
What you have are pattern rules which specify "if you want to build a target of type *.o, here's how to do that" but no actual targets which specify "this is a file we want to build".
By the by, GNU Make already knows how to compile C files, so you don't really need to define that, unless you have a specific need to override the built-in pattern rule.

How to Overwrite a variable in makefile from terminal

I have created a simple makefile i.e.
COMMON=hello
all:
gcc $(COMMON).c -o $(COMMON).o
The directory in which I am running the makefile contains three files: hello.c add.c multiply.c factorial.c and subtraction.c.
When I am compiling this in the terminal using the make command, the hello gets printed. Now I want to make changes in the program such that when I write "make add" or "make multiply" or "make factorial", the corresponding program will compile.
Just supply it on the command line.
make COMMON=bye
If the target is predictable from file names in the current directory, you don't really need a Makefile at all, because Make already knows how to make multiply from multiply.c.
.PHONY: all
all: hello add multiply factorial
If you really want an explicit recipe, try something like this.
%: %.c
gcc -o $# $^

Resources