I recently got feedback that my Makefile doesn't call the required flags. This is a snippet of my Makefile.
CXX = g++
CXXFLAGS = -Wall
all: testFacility testCode testRunway testSiteNumber airport distance
testFacility: testFacility.cpp Facility.o gcdistance.o
$(CXX) -o $# $^
Does the flag "-Wall" get called when I type Make?
No, it needs to be referenced directly:
$(CXX) $(CXXFLAGS) -o $# $^
You probably want to define something to compile all those .cpp files too:
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $# $<
testFacility: testFacility.o Facility.o gcdistance.o
$(CXX) $(CXXFLAGS) -o $# $^
Related
I have one Makefile to build an executable and a library. Executable consists of a lot of source files and library consists of one .cpp file. The difference between compilation of executable and library is -fPIC option.
There is a compilation rule:
%.o : %.cpp
$(CXX) -c $(CXXFLAGS) $< -o $#
all: $(TARGET) $(TARGET_LIB)
$(TARGET): $(OBJS)
$(CXX) $(LDFLAGS) -o $# $^
$(TARGET_LIB): $(LIBOBJS)
$(CXX) $(LDFLAGS) -fPIC -shared -o $# $^
I tried to add compilation rule for library and got this:
lib.o : lib.cpp
$(CXX) -fPIC -c $(CXXFLAGS) $< -o $#
%.o : %.cpp
$(CXX) -c $(CXXFLAGS) $< -o $#
all: $(TARGET) $(TARGET_LIB)
$(TARGET): $(OBJS)
$(CXX) $(LDFLAGS) -o $# $^
$(TARGET_LIB): $(LIBOBJS)
$(CXX) $(LDFLAGS) -fPIC -shared -o $# $^
Unfortunately, only lib is compiled in this case. Second rule is omitted.
How can I use a rule for one file and different rule for group of other files?
If you just run make without a target, the first target gets built. So just put all back at the top and it should work fine.
I am trying to write a makefile that can create one executable per main function.
I have a list of files: main1.cpp, main2.cpp, and main3.cpp. They each contain an int main() function. Obviously I can't build these into one exec, which is not the goal here, so how can I build each one of these into its own executable? This is one solution:
main1: main1.cpp
$(CC) -o $# $^
main2: main2.cpp
$(CC) -o $# $^
main3: main3.cpp
$(CC) -o $# $^
But there MUST be a better way to do this. Is there some type of looping feature to makefiles that will make this process easier? Like a for loop?
A mixture of wildcard, patsubst and static pattern rules, plus the standard make variables for C++ compilation and linking:
SRCS := $(wildcard main*.cpp)
EXES := $(patsubst %.cpp,%,$(SRCS))
$(EXES): %: %.cpp
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $# $< $(LDLIBS)
But as make knows already how to make all this you could as well get rid of your Makefile and just type make main1...
While it's not a very sophisticated makefile, your solution is fine for three simple programs. You could make it more generic and support building all three targets at the same time with an "all" target.
all: main1 main2 main3
main1: main1.cpp
$(CC) -o $# $^
main2: main2.cpp
$(CC) -o $# $^
main3: main3.cpp
$(CC) -o $# $^
The file tree in my C++ project is like this:
project/
source/
main.cpp (with int main() function)
a.cpp
a.h
b.cpp
...
obj/
Makefile
But when I compile it, it throws an error: "In function _start': (.text+0x20): undefined reference to main'"
My makefile is:
EXECUTABLE = name_of_program
CXX = g++
CXXFLAGS = -Wall -Isource
LIBS =
SRC_DIR = source
OBJ_DIR = obj
SRC = $(wildcard $(SRC_DIR)/*.cpp)
OBJ = $(SRC:$(SRC_DIR)/%.cpp=$(OBJ_DIR)/%.o)
.PHONY: all clean
all: $(EXECUTABLE)
$(EXECUTABLE): $(OBJ)
$(CXX) -o $# $^ $(LIBS)
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) $(CXXFLAGS) -o $# $<
$(CXX) $(CXXFLAGS) -o $# -c $<
clean:
rm $(OBJ)
Which things should I correct in order to make it compile correctly? I know it's a compiler error but I'm sure it's about Makefile.
I don't have enough of your source to reproduce the problem, but by inspection, it looks like you have an extra line here:
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) $(CXXFLAGS) -o $# $<
$(CXX) $(CXXFLAGS) -o $# -c $<
Remove the first line so you don't try to link each object file independently.
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) $(CXXFLAGS) -o $# -c $<
I am trying to write a makefile to compile and generate only object files from the source code. I have this so far:
CC=g++
CFLAGS=-c -Wall -std=c++11
SOURCES=$(wildcard *.h)
OBJECTS=$(SOURCES:.cpp=.o)
all: $(OBJECTS)
$(OBJECTS):
$(CC) $(CFLAGS) $< -o $#
when I call it, it prints:
make: Nothing to be done for `all'.
Obviously I am making a mistake, but I don't know which one, because I am seeing in the GNU make documentation page a very similar example.
Any help would be very appreciated.
Replace: SOURCES=$(wildcard *.h) with SOURCES=$(wildcard *.cpp)
and:
$(OBJECTS):
$(CC) $(CFLAGS) $< -o $#
with:
%.o: %.cpp
$(CC) $(CFLAGS) $< -o $#
This means that each {file}.o is depend on existence of {file}.cpp.
I've been doing a lot of reading on how to write makefiles to build an application on Linux but I'm massively confused about the many different ways to apparently achieve the same goal.
This is what I have come up with so far to build an archive.
SHELL = /bin/sh
CXX = g++
DEBUG = -g
CXXFLAGS = -std=c++11 -Wall -pedantic #-Wextra
CPPFLAGS = -I. \
-I./include
SOURCES = foo1.cpp \
foo2.cpp \
foo3.cpp
OBJECTS = $(SOURCES:.cpp=.o)
The following rule successfully compiles each source file into an object file and then creates an archive:
libfoo.a: $(OBJECTS)
ar rvcs $# $(OBJECTS)
%.o: src/%.cpp ./include/%.h
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $# $<
This also does the same thing:
libfoo.a: $(OBJECTS)
ar rvcs $# $(OBJECTS)
$(OBJECTS) : %.o:src/%.cpp
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $# $<
However, this fails with an error that there is no rule to make target 'foo1.o:%.h
libfoo.a: $(OBJECTS)
ar rvcs $# $(OBJECTS)
$(OBJECTS) : %.o:src/%.cpp %.o:%.h
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $# $<
Can someone please explain why it doesn't work and which approach is best?
The first option lists the header files as dependencies but the second option doesn't. That is my motivation for the third option.
How do I list the headers as dependencies using options 2 or 3?
TIA
The feature you're using in try #2 and try #3 is static pattern rules and the syntax looks like this:
<targets...> : <target-pattern> : <prerequisites...>
There can only be two colons, not three. You should write your try #3 above as:
$(OBJECTS) : %.o : src/%.cpp %.h
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $# $<
Note one critical thing: this rule will FAIL if you ever create any .cpp file which does not have an associated .h file. Just sayin'.