makefile not generating executeble files - linux

I am fairly new at makefile. I am trying to create a makefile that compiles yu.c and link yu.c to get a executable file called yu.
Below is the code i have. I am using make -f mymakefile to run the file and each time i run it, only gcc -c yuFile.c is done.
Where am I wrong?
CC=gcc
yu.o: yuFile.c
${CC} -c yuFile.c
yu: yuFile.o
${CC} yu -o yuFile.o
run-c: yu
./yu
clean:
rm -f "*.o" core

make with no target specified makes the first target in the file, so in your case it is equivalent to make yu.o.
Typically, you make the first target all so that everything is built:
all: yu
.PHONY: all
(Note that the .PHONY prevents make from doing nothing if there's a file named all already).
Worth pointing out: you've got your arguments reversed in the yu target. It should be
yu: yuFile.o
${CC} yuFile.o -o yu
or more generically
yu: yuFile.o
${CC} $^ -o $#
($^ means all prereqs, and $# means the target, as documented in Automatic Variables).

The first target is the one picked when no argument is specified.
The standard is to have an 'all' target first:
all: yu
Also, your 'yu' target is incorrect.
yo: yufile.o
$(CC) -o $# $^
should work

Related

Makefile pattern rule not working properly

Long story short, it seems like pattern rules are not behaving correctly.
Assume you have simple Makefile like this,
%.o:
gcc $< -o $#
echo from %.o
and if you type make asd, which clearly doesn't match %.o pattern, it will actually match asd.o and performe recipe for it.
[user]$ make asd
gcc -o asd.o
gcc: fatal error: no input files
compilation terminated.
make: *** [Makefile:2: asd.o] Error 1
So you get this output.
But even stranger thing is that if you explicitly disable the builtin rules by --no-builtin-rules flag, it won't match.
[user]$ make --no-builtin-rules asd
make: *** No rule to make target 'asd'. Stop.
I have no idea why enabling or disabling builtin rule should do anything about pattern matching, so does anyone have idea why this is happening?
P.S. I'm using GNU Make 4.3 in Arch Linux (don't know kernel version).
which clearly doesn't match %.o pattern
You've specified that to create asd.o you have no dependencies so it will try to create it from your recipe directly.
If you have dependencies, like "to create asd.o there must be an asd.c file", then specify that by adding a dependency:
%.o: %.c
gcc $< -c -o $#
#echo from $#
Note: I added -c to make it into a plain object file, not an executable.
If you now do make --no-builtin-rules asd.o and if you don't have asd.c, it will print:
$ make --no-builtin-rules asd.o
make: *** No rule to make target 'asd.o'. Stop.
If you on the other hand do have asd.c, it'll use your recipe to create asd.o:
$ make --no-builtin-rules asd.o
gcc asd.c -o asd.o
from asd.o
You may want to add a rule for creating an actual executable too - and if you don't want the built-in rules, you can create an empty target for .SUFFIXES:
.SUFFIXES:
%: %.o
gcc -o $# $<
echo from $#
%.o: %.c
gcc $< -c -o $#
#echo from $#
Now, it'll first create asd.o and then link that into asd if you do make asd:
$ make asd
gcc asd.c -c -o asd.o
from asd.o
gcc -o asd asd.o
echo from asd
from asd
rm asd.o

Linux make command is deleting a source file

I have inherited a project file that has a Makefile in it that is doing something I have never seen before--It is injecting a rm command. I cannot find any reason for the rm command, so I am missing something very obvious or very esoteric.
Thanks
The results of running make are:
bison --defines --xml --graph=calc.gv -o calc.c calc.y
Bison flags =
cc -c -o calc.o calc.c
Making BASE = calc
cc -o calc calc.o
Done making BASE
rm calc.c <======== WHERE IS THIS COMING FROM?
The Makefile is:
BASE = calc
BISON = bison
XSLTPROC = xsltproc
all: $(BASE)
%.c %.h %.xml %.gv: %.y
$(BISON) $(BISONFLAGS) --defines --xml --graph=$*.gv -o $*.c $<
#echo "Bison flags = " $(BISONFLAGS)
$(BASE): $(BASE).o
#echo "Making BASE = " $(BASE)
$(CC) $(CFLAGS) -o $# $^
#echo "Done making BASE"
run: $(BASE)
#echo "Type arithmetic expressions. Quit with ctrl-d."
./$<
html: $(BASE).html
%.html: %.xml
$(XSLTPROC) $(XSLTPROCFLAGS) -o $# $$($(BISON) --print-datadir)/xslt/xml2xhtml.xsl $<
CLEANFILES = $(BASE) *.o $(BASE).[ch] $(BASE).output $(BASE).xml $(BASE).html $(BASE).gv
clean:
#echo "Running clean" $(CLEANFILES)
rm -f $(CLEANFILES)
See https://www.gnu.org/software/make/manual/make.html#Chained-Rules:
The second difference is that if make does create b in order to update something else, it deletes b later on after it is no longer needed. Therefore, an intermediate file which did not exist before make also does not exist after make. make reports the deletion to you by printing a rm -f command showing which file it is deleting.

specifying the filename in a makefile

I'm new to this and trying to create a makefile where I could, for example, run:
make -f mymakefile testfile
and the makefile would find testfile.java (which exists in the directory I'm running from), compile it, and run the code.
Instead, I must be confused with how automatic variables work and after working all afternoon I still get the error:
make: Nothing to be done for `testfile'.
Any help would be appreciated and my code is below:
JC=javac
JVM=java
JFLAGS= -g
RM = rm -f
CFLAGS =
CXX = gcc
NAME = *
.SUFFIXES: .java .class
all: run
NAME:
$(CXX) $(CFLAGS) -o $^ $#
echo $(NAME)
$(NAME).class: $(NAME)
$(JC) $(JFLAGS) $(NAME).java
run: $(NAME).class
$(JVM) $(NAME)
.PHONY: clean
clean:
$(RM) $(NAME).class
I've tried just having it echo 'testfile' to better understand how automatic variables work, but I couldn't get that to work correctly either.
The arguments on the make command line select the targets to build. You can't pass values to variables in the same way you would with a shell script (like you're trying to do with "NAME".)
If you really want to pass a value for a variable, the command would be:
NAME=testfile make -f mymakefile
You can use pattern rules to create rules from arbitrary names. For example:
%.bin : %.cpp
$(CXX) $(CXXFLAGS) -o $# $<
When you call make test.bin, this matches pattern rule %.bin, where % matches test. Then automatic variables $< substitutes the source file and $# substitutes the target file. What actually runs is something like g++ -O3 -o test.bin test.cpp.

Compiling C++ and C files in one makefile

I have a makefile that looks like this:
CS := a.c b.c
CPPS := foo.cpp bar.cpp
SOURCES := $(CS) $(CPPS)
OBJS := $(CS:%.c=$(OBJSDIR)/%.o) $(CPPS:%.cpp=$(OBJSDIR)/%.o)
I want to create a single rule to compile them all. But the only option I can think of is this:
$(OBJSDIR)/%.o: %.cpp
$(GXX) $(GXXFLAGS) -c $< -o $#
But of course it doesn't work because some of the object files don't have a matching C++ source file.
Any idea?
suppose you have a.cc, b.cc and c.cc, and on the other side, d.c, e.c and f.c
program_objs = a.o b.o c.o d.o e.o f.o
program: $(program_objs)
$(CC) $(LDFLAGS) -o $# $(program_objs)
You don't need anything more, as make will automatically detect which files are c++ and which ones are plain c and will select the proper compiler.
in case you want something special, not included in makefile, you can add some suffixes (file types) with the rule:
.SUFFIXES: .a .b .o
and then use the following rules to compile them to .o
.a.o:
$(COMPILER_A) $(COMPILER_A_FLAGS) -c $# -o $<
.b.o:
$(COMPILER_B) $(COMPILER_B_FLAGS) -c $# -o $<
and let makefile select the proper compiler (the one stored in variables COMPILER_A or COMPILER_B) to do the work.
Of course, you can compile something to a .o file with an explicit rule, as in:
a.o: a.cc
g++ -o a.o -c a.cc
b.o: b.cc
g++ -o b.o -c b.cc
c.o: c.cc
g++ -o c.o -c c.cc
d.o: d.c
gcc -o d.o -c d.c
e.o: e.c
gcc -o e.o -c e.c
f.o: f.c
gcc -o f.o -c f.c
Note #1:
Some sugestions have been made on GNU make % pattern to construct implicit rules for targets. Below is a rewritting of the implicit rules above to do the same thing:
%.o: %.a
$(COMPILER_A) $(COMPILER_A_FLAGS) -c $# -o $<
%.o: %.b
$(COMPILER_B) $(COMPILER_B_FLAGS) -c $# -o $<
As always, $# means the target of the rule and $< (you can use also $* for the file name without any matching suffixes) the left needed file. For a complete list of automatic variables that can be used, I suggest you to read your make manual. Take into account that the old suffix syntax is reversed from the new one (the target suffix appears last in the old syntax, the new syntax being more similar to a normal makefile rule with the target on the left side of the colon)
I want to create a single rule to compile them all.
As Etan Reisner said in the comment section, make already has implicit rules to compile .c and .cpp file, so the real answer to your question is:
Do not write anything to compile your object files.
That said, you should now remove those two variables: $(GXX) and $(GXXFLAGS).
To provide flags to cc or gcc one should use the CFLAGS built-in variable.
To provide flags to g++ one should use the CXXFLAGS built-in variable.
To provide flags to the preprocessor (cpp) one should use the CPPFLAGS variable.
Since you're mixing C and C++ source files, you should use the CXX variable as the linker command.

Makefiles with source files in different directories

I have a project where the directory structure is like this:
$projectroot
|
+---------------+----------------+
| | |
part1/ part2/ part3/
| | |
+------+-----+ +---+----+ +---+-----+
| | | | | | |
data/ src/ inc/ src/ inc/ src/ inc/
How should I write a makefile that would be in part/src (or wherever really) that could comple/link on the c/c++ source files in part?/src ?
Can I do something like
-I$projectroot/part1/src -I$projectroot/part1/inc -I$projectroot/part2/src ...
If that would work, is there an easier way to do it. I've seen projects where there is a makefile in each of the corresponding part? folders. [in this post I used the question mark like in bash syntax]
The traditional way is to have a Makefile in each of the subdirectories (part1, part2, etc.) allowing you to build them independently. Further, have a Makefile in the root directory of the project which builds everything. The "root" Makefile would look something like the following:
all:
+$(MAKE) -C part1
+$(MAKE) -C part2
+$(MAKE) -C part3
Since each line in a make target is run in its own shell, there is no need to worry about traversing back up the directory tree or to other directories.
I suggest taking a look at the GNU make manual section 5.7; it is very helpful.
If you have code in one subdirectory dependent on code in another subdirectory, you are probably better off with a single makefile at top-level.
See Recursive Make Considered Harmful for the full rationale, but basically you want make to have the full information it needs to decide whether or not a file needs to be rebuilt, and it won't have that if you only tell it about a third of your project.
The link above seems to be not reachable. The same document is reachable here:
aegis.sourceforge.net (archived)
lcgapp.cern.ch
The VPATH option might come in handy, which tells make what directories to look in for source code. You'd still need a -I option for each include path, though. An example:
CXXFLAGS=-Ipart1/inc -Ipart2/inc -Ipart3/inc
VPATH=part1/src:part2/src:part3/src
OutputExecutable: part1api.o part2api.o part3api.o
This will automatically find the matching partXapi.cpp files in any of the VPATH specified directories and compile them. However, this is more useful when your src directory is broken into subdirectories. For what you describe, as others have said, you are probably better off with a makefile for each part, especially if each part can stand alone.
You can add rules to your root Makefile in order to compile the necessary cpp files in other directories. The Makefile example below should be a good start in getting you to where you want to be.
CC=g++
TARGET=cppTest
OTHERDIR=../../someotherpath/in/project/src
SOURCE = cppTest.cpp
SOURCE = $(OTHERDIR)/file.cpp
## End sources definition
INCLUDE = -I./ $(AN_INCLUDE_DIR)
INCLUDE = -I.$(OTHERDIR)/../inc
## end more includes
VPATH=$(OTHERDIR)
OBJ=$(join $(addsuffix ../obj/, $(dir $(SOURCE))), $(notdir $(SOURCE:.cpp=.o)))
## Fix dependency destination to be ../.dep relative to the src dir
DEPENDS=$(join $(addsuffix ../.dep/, $(dir $(SOURCE))), $(notdir $(SOURCE:.cpp=.d)))
## Default rule executed
all: $(TARGET)
#true
## Clean Rule
clean:
#-rm -f $(TARGET) $(OBJ) $(DEPENDS)
## Rule for making the actual target
$(TARGET): $(OBJ)
#echo "============="
#echo "Linking the target $#"
#echo "============="
#$(CC) $(CFLAGS) -o $# $^ $(LIBS)
#echo -- Link finished --
## Generic compilation rule
%.o : %.cpp
#mkdir -p $(dir $#)
#echo "============="
#echo "Compiling $<"
#$(CC) $(CFLAGS) -c $< -o $#
## Rules for object files from cpp files
## Object file for each file is put in obj directory
## one level up from the actual source directory.
../obj/%.o : %.cpp
#mkdir -p $(dir $#)
#echo "============="
#echo "Compiling $<"
#$(CC) $(CFLAGS) -c $< -o $#
# Rule for "other directory" You will need one per "other" dir
$(OTHERDIR)/../obj/%.o : %.cpp
#mkdir -p $(dir $#)
#echo "============="
#echo "Compiling $<"
#$(CC) $(CFLAGS) -c $< -o $#
## Make dependancy rules
../.dep/%.d: %.cpp
#mkdir -p $(dir $#)
#echo "============="
#echo Building dependencies file for $*.o
#$(SHELL) -ec '$(CC) -M $(CFLAGS) $< | sed "s^$*.o^../obj/$*.o^" > $#'
## Dependency rule for "other" directory
$(OTHERDIR)/../.dep/%.d: %.cpp
#mkdir -p $(dir $#)
#echo "============="
#echo Building dependencies file for $*.o
#$(SHELL) -ec '$(CC) -M $(CFLAGS) $< | sed "s^$*.o^$(OTHERDIR)/../obj/$*.o^" > $#'
## Include the dependency files
-include $(DEPENDS)
If the sources are spread in many folders, and it makes sense to have individual Makefiles then as suggested before, recursive make is a good approach, but for smaller projects I find it easier to list all the source files in the Makefile with their relative path to the Makefile like this:
# common sources
COMMON_SRC := ./main.cpp \
../src1/somefile.cpp \
../src1/somefile2.cpp \
../src2/somefile3.cpp \
I can then set VPATH this way:
VPATH := ../src1:../src2
Then I build the objects:
COMMON_OBJS := $(patsubst %.cpp, $(ObjDir)/%$(ARCH)$(DEBUG).o, $(notdir $(COMMON_SRC)))
Now the rule is simple:
# the "common" object files
$(ObjDir)/%$(ARCH)$(DEBUG).o : %.cpp Makefile
#echo creating $# ...
$(CXX) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $# $<
And building the output is even easier:
# This will make the cbsdk shared library
$(BinDir)/$(OUTPUTBIN): $(COMMON_OBJS)
#echo building output ...
$(CXX) -o $(BinDir)/$(OUTPUTBIN) $(COMMON_OBJS) $(LFLAGS)
One can even make the VPATH generation automated by:
VPATH := $(dir $(COMMON_SRC))
Or using the fact that sort removes duplicates (although it should not matter):
VPATH := $(sort $(dir $(COMMON_SRC)))
I think it's better to point out that using Make (recursive or not) is something that usually you may want to avoid, because compared to today tools, it's difficult to learn, maintain and scale.
It's a wonderful tool but it's direct use should be considered obsolete in 2010+.
Unless, of course, you're working in a special environment i.e. with a legacy project etc.
Use an IDE, CMake or, if you're hard cored, the Autotools.
(edited due to downvotes, ty Honza for pointing out)
I was looking for something like this and after some tries and falls i create my own makefile, I know that's not the "idiomatic way" but it's a begining to understand make and this works for me, maybe you could try in your project.
PROJ_NAME=mono
CPP_FILES=$(shell find . -name "*.cpp")
S_OBJ=$(patsubst %.cpp, %.o, $(CPP_FILES))
CXXFLAGS=-c \
-g \
-Wall
all: $(PROJ_NAME)
#echo Running application
#echo
#./$(PROJ_NAME)
$(PROJ_NAME): $(S_OBJ)
#echo Linking objects...
#g++ -o $# $^
%.o: %.cpp %.h
#echo Compiling and generating object $# ...
#g++ $< $(CXXFLAGS) -o $#
main.o: main.cpp
#echo Compiling and generating object $# ...
#g++ $< $(CXXFLAGS)
clean:
#echo Removing secondary things
#rm -r -f objects $(S_OBJ) $(PROJ_NAME)
#echo Done!
I know that's simple and for some people my flags are wrong, but as i said this is my first Makefile to compile my project in multiple dirs and link all of then together to create my bin.
I'm accepting sugestions :D
RC's post was SUPER useful. I never thought about using the $(dir $#) function, but it did exactly what I needed it to do.
In parentDir, have a bunch of directories with source files in them: dirA, dirB, dirC. Various files depend on the object files in other directories, so I wanted to be able to make one file from within one directory, and have it make that dependency by calling the makefile associated with that dependency.
Essentially, I made one Makefile in parentDir that had (among many other things) a generic rule similar to RC's:
%.o : %.cpp
#mkdir -p $(dir $#)
#echo "============="
#echo "Compiling $<"
#$(CC) $(CFLAGS) -c $< -o $#
Each subdirectory included this upper-level makefile in order to inherit this generic rule. In each subdirectory's Makefile, I wrote a custom rule for each file so that I could keep track of everything that each individual file depended on.
Whenever I needed to make a file, I used (essentially) this rule to recursively make any/all dependencies. Perfect!
NOTE: there's a utility called "makepp" that seems to do this very task even more intuitively, but for the sake of portability and not depending on another tool, I chose to do it this way.
Hope this helps!
Recursive Use of Make
all:
+$(MAKE) -C part1
+$(MAKE) -C part2
+$(MAKE) -C part3
This allows for make to split into jobs and use multiple cores
I suggest to use autotools:
//## Place generated object files (.o) into the same directory as their source files, in order to avoid collisions when non-recursive make is used.
AUTOMAKE_OPTIONS = subdir-objects
just including it in Makefile.am with the other quite simple stuff.
Here is the tutorial.

Resources