I have a project with following structure:
$ tree
.
├── bin
├── include
│ └── reader.h
├── Makefile
├── obj
└── src
├── main.cpp
└── reader.cpp
4 directories, 4 files
I want to have .cpp file in src/, headers in include/ , compile object files in obj/ and executables in bin/. I use GNU make in version 4.1, g++ in version 7.2.0 and Ubuntu 17.10. When I try to build it (I try to use ideas from here, slightly modified) I get following error:
$ make
make: Circular obj/main.o <- obj/main.o dependency dropped.
make: Circular obj/reader.o <- obj/main.o dependency dropped.
make: Circular obj/reader.o <- obj/reader.o dependency dropped.
g++ -c -o obj/obj/reader.o include/reader.h
In file included from <command-line>:0:0:
/usr/include/stdc-predef.h:1:0: fatal error: can’t create precompiled header obj/obj/reader.o: No such file or directory
/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
compilation terminated.
Makefile:15: recipe for target 'obj/reader.o' failed
make: *** [obj/reader.o] Error 1
I am new to makefiles, so I guess it's something very basic. How can I fix this?
EDIT I forgot about Makefile`. Here we go:
IDIR = include
OBJDIR = obj
CXX = g++
CXXFLAGS = -g -Wall -std=c++14 -I$(IDIR)
DEPS = reader.h
_DEPS = reader.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
_OBJ = main.o reader.o
OBJ = $(patsubst %,$(OBJDIR)/%,$(_OBJ))
$(OBJDIR)/%.o: $(OBJ) $(DEPS)
$(CXX) -c -o $(OBJDIR)/$# $< $(CFLAGS)
main: $(OBJ)
$(CXX) -o $# $^ $(CXXFLAGS)
EDIT2 After changing language to English I understood the warnings I had.
I deleted redundant $(OBJDIR) part from $(OBJDIR)/%.o directive and ended up with something like this:
IDIR = include
OBJDIR = obj
CXX = g++
CXXFLAGS = -g -Wall -std=c++14 -I$(IDIR)
DEPS = reader.h
_DEPS = reader.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
_OBJ = main.o reader.o
OBJ = $(patsubst %,$(OBJDIR)/%,$(_OBJ))
$(OBJDIR)/%.o: $(OBJ) $(DEPS)
$(CXX) -c -o $# $< $(CFLAGS)
main: $(OBJ)
$(CXX) -o $# $^ $(CXXFLAGS)
and new errors:
$ make
make: Circular obj/main.o <- obj/main.o dependency dropped.
make: Circular obj/reader.o <- obj/main.o dependency dropped.
make: Circular obj/reader.o <- obj/reader.o dependency dropped.
g++ -c -o obj/main.o obj/reader.o
g++: warning: obj/reader.o: linker input file unused because linking not done
g++ -o main obj/main.o obj/reader.o -g -Wall -std=c++14 -Iinclude
g++: error: obj/main.o: No such file or directory
Makefile:18: recipe for target 'main' failed
make: *** [main] Error 1
$(OBJDIR)/%.o: $(OBJ) $(DEPS) makes no sense. You're saying every object file depends on itself (and also all other object files). That's why make is complaining Circular obj/main.o <- obj/main.o dependency dropped.. $(OBJ) shouldn't be there.
$(CXX) -c -o $# $< $(CFLAGS) is broken because $< is the first prerequisite, which in this case is obj/reader.o. It's like you're trying to compile one object file into another, which makes no sense.
Also, why are you using $(CFLAGS) here? You're compiling C++, so it should be $(CXXFLAGS) (your code never sets CFLAGS anyway).
Your Makefile never mentions any cpp files. This cannot work.
I would throw away your Makefile and start with something simple:
CXXFLAGS = -g -Wall -std=c++14 -Iinclude
bin/main: obj/main.o obj/reader.o
$(CXX) -o $# $(LDFLAGS) $+ $(LDLIBS)
obj/main.o: src/main.cpp include/reader.h
obj/reader.o: src/reader.cpp include/reader.h
This should be all you need.
Related
I have a project with this structure
/project
Makefile
.gitignore
/bin
/src
file1.cpp
file2.cpp
file3.cpp
/include
definitions.h
/obj
I played around with the Makefile but I couldn't seem to get what I wanted, first I tried:
CC = g++
CFLAGS = -std=c++2b -Wno-parentheses -Iinclude/
All: build
obj/%.o: src/%.cpp
$(CC) $(CFLAGS) -c $^
build:
$(CC) $(CFLAGS) file1.o file2.o file3.o -o bin/main$(compiler)
but this returned the error
make: *** No rule to make target 'file1.o', needed by 'build'. Stop.
so I tried
CC = g++
CFLAGS = -std=c++2b -Wno-parentheses -Iinclude/
All: build
%.o: src/%.cpp
$(CC) $(CFLAGS) -c $^
build:
$(CC) $(CFLAGS) file1.o file2.o file3.o -o bin/main$(compiler)
and it compiled, putting all the .o files in the main directory, which is unideal. Furthermore, I can't run the binary file unless I specifically opened a terminal in the main directory and enter ./bin/maing++, opening a terminal in the bin folder and entering ./maing++ doesn't work, and so does running the .exe file manually, what did I do wrong? what I want is all the .o files made in obj/ and to be able to run the executable manually
UPDATE:
I changed the makefile to
CC = g++
CFLAGS = -std=c++2b -Wno-parentheses -Iinclude/ -Idoc/
SOURCES := $(wildcard src/*.cpp)
OBJECTS := $(patsubst src/%.cpp, obj/%.o, $(SOURCES))
All: build
obj/%.o: src/%.cpp
$(CC) $(CFLAGS) -c $< -o $#
build: $(OBJECTS)
$(CC) $(CFLAGS) $^ -o bin/is$(compiler)
this will put all obj files in the correct folder, its a simple program so running the executable would pop up a terminal window and print some text, I'm going to reiterate that I had to specifically open a terminal in the main directory and enter ./bin/maing++, opening a terminal in the bin folder and entering ./maing++ doesn't work, and so does running the .exe file manually
I am following along with the LLVM Kaleidoscope Tutorial (Ch. 3), and am encountering errors (undoubtedly from my Makefile) after attempting to link LLVM IR libraries. My Makefile and project structure:
CPP=clang++
CFLAGS=-g -Wall -std=c++14
LDFLAGS:=$(shell llvm-config --cxxflags --ldflags --system-libs --libs core)
EXEC=comp.out
SRCS:=$(shell find src -type f -name '*.cpp')
OBJS:=$(patsubst %.cpp,%.o,$(SRCS))
all: $(EXEC)
$(EXEC): $(OBJS)
$(CPP) $(CFLAGS) -o $# $^
src/%.o: src/%.cpp
$(CPP) $(CFLAGS) $(LDFLAGS) -o $# $<
src/ast/%.o: src/ast/%.cpp
$(CPP) $(CFLAGS) $(LDFLAGS) -o $# $<
.PHONY: clean
clean:
rm -f $(shell find src -type f -name '*.o')
rm -f $(EXEC)
.
└── src
├── main.cpp
├── [.cpp files]
│
├── ast
│ ├── [.cpp files]
│ │
│ └── include
│ └── [.h files]
│
└── include
└── [.h files]
When Making, I get the error:
clang++ -g -Wall -std=c++14 -I/usr/local/Cellar/llvm/12.0.1/include -std=c++14 -stdlib=libc++ -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -L/usr/local/Cellar/llvm/12.0.1/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM-12 src/IMRep.cpp -o src/IMRep.o
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang-12: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [Makefile:19: src/IMRep.o] Error 1
From the error above, main.cpp is never compiled before compilation errors out. It only gets to the src/IMRep.cpp file (not sure if that matters). If I add the -c flag to make it:
src/%.o: src/%.cpp
$(CPP) $(CFLAGS) $(LDFLAGS) -c $< -o $#
src/ast/%.o: src/ast/%.cpp
$(CPP) $(CFLAGS) $(LDFLAGS) -c $< -o $#
I am able to run the program successfully despite the plethora of warning messages saying the linker inputs/arguments are unused. These warnings are expected because -c only compiles and doesn't link.
And in main.cpp:
#include <iostream>
int main(int argc, char *argv[])
{
return 0;
}
So this question doesn't get flagged as a dupe:
[1]: main.cpp is included in OBJS
[2]: Added -c flag and receive many warnings about unused linker arguments/input (because -c is for compilation, not linkage)
[3]: I only use $< where there is one dependency and $^ where there are multiple
[4]: Can't apply the answer to this question
[5]: All files in SRCS and OBJS are the correct files. I verified this by making a 'verbose' rule and printing those values and make verbose
Which leads me to believe that I am not linking in these libraries correctly.
Your question is, in fact, a duplicate of the #2 answer there.
When you want to create an object file you MUST use the -c option. That's what the -c option means.
If you don't want "a plethora of warning messages saying the linker inputs/arguments are unused" then, you know, don't add the linker inputs and arguments when you generate object files! Those arguments are for linking, not compiling.
Your .o rules should be:
src/%.o: src/%.cpp
$(CPP) $(CFLAGS) -c $< -o $#
src/ast/%.o: src/ast/%.cpp
$(CPP) $(CFLAGS) -c $< -o $#
Just to point out you don't need both of the above pattern rules. If you want the object files to live in the same directory as the source files you can just write:
%.o: %.cpp
$(CPP) $(CFLAGS) -c $< -o $#
And, if you switched to using the standard make variables instead of using non-standard ones:
# CPP is the C preprocessor, not C++
CXX = clang++
# CFLAGS is flags for the C compiler, not C++
CXXFLAGS := -g -Wall -std=c++14 $(shell llvm-config --cxxflags core)
LDFLAGS := $(shell llvm-config --ldflags --system-libs --libs core)
then you wouldn't need to define your own pattern rule at all because make has a built-in rule which knows how to compile a C++ source file into an object file.
I'm programming on Xcode. I include SDL_image.h as
#include <SDL2/SDL_image.h>
and it says 'SDL2/SDL_image.h' file not found
I have installed and linked binary with libraries both SDL2.framework and SDL2_image.framework.
I used a Makefile to compile and there is an error: fatal error: 'SDL2/SDL_image.h' file not found
Here is my Makefile
# set the compiler
CC := clang
# set the compiler flags
CXXFLAGS = -std=c++14 -Wall -MMD -Werror=vla pkg-config --cflags --libs sdl2 `-L/Library/Frameworks/ sdl2-config --libs --cflags` -ggdb3 -O0 --std=c99 -Wall -l SDL2_image -lm
# add source files here
SRCS := main.cpp #file-name.c
# generate names of object files
OBJS := $(SRCS:.c=.o)
# name of executable
EXEC := sdl #name your executable file
# default recipe
all: $(EXEC)
showfont: showfont.c Makefile
$(CC) -o $# $#.c $(CFLAGS) $(LIBS)
glfont: glfont.c Makefile
$(CC) -o $# $#.c $(CFLAGS) $(LIBS)
# recipe for building the final executable
$(EXEC): $(OBJS) $(HDRS) Makefile
$(CC) -o $# $(OBJS) $(CFLAGS)
# recipe for building object files
#$(OBJS): $(#:.o=.c) $(HDRS) Makefile
# $(CC) -o $# $(#:.o=.c) -c $(CFLAGS)
# recipe to clean the workspace
clean:
rm -f $(EXEC) $(OBJS)
.PHONY: all clean
Im using this code in the makefile, all is going good but the last line.
My code folder looks like this:
Project/bin -> For executable files
Project/build -> For .o files
Project/include -> For .hpp files
Project/src -> For .cpp files
Makefile path: Project/Makefile
# Compiler #
CC = g++
DEBUG = -g
LFLAGS =
CFLAGS = -Wall
# Directories #
SRCDIR = src/
INCDIR = include/
BUILDDIR = build/
BINDIR = bin/
# Objects #
OBJ_NAMES = main.o dfa.o dfaException.o state.o
OBJS = $(addprefix $(BUILDDIR), $(OBJ_NAMES))
# Output #
TARGET = $(BINDIR)pract3
$(TARGET): $(OBJS)
$(CC) $(CCFLAGS) $(LFLAGS) $(OBJS) -o $(TARGET)
$(BUILDDIR)%.o: $(SRCDIR)%.cpp
$(CC) $(CCFLAGS) $(LFLAGS) -c $< -o $(BUILDDIR)$($(notdir $<):.cpp=.o)
The problem is in "$(BUILDDIR)$($(notdir $<):.cpp=.o)". What Im trying to do here is:
$< contains "src/mysrc.cpp" so with $(notdir $<) I get
"mysrc.cpp"
Now, I want to change the file extension to .o, so I use $($(notdir $<):.cpp=.o) And I should get "mysrc.o". But this part is not working:
g++ -c src/main.cpp -o build/
Assembler messages:
Fatal error: can't create build/: Permission denied
Makefile:25: recipe for target 'build/main.o' failed
make: *** [build/main.o] Error 1
I use $(BUILDDIR) To get "build/mysrc.o"
Why does $($(notdir $<):.cpp=.o) somehow delete the file name ?
And now that Im here. I've learned to use make some days ago. Is there something that I should improve here ?
$(notdir) operates on strings.
$(X:Y=Z) operates on the value of the X variable.
So follow your expansions when $< is src/mysrc.cpp
$($(notdir $<):.cpp=.o)
becomes
$(mysrc.cpp:.cpp=.o)
Is that how you would write that?
No, you would write $(<:.cpp=.o).
So invert your operations.
$(notdir $(<:.cpp=.o))
Or, even better and simpler than that just use $# since that's the target you are building and what you want to create.
$(CC) $(CCFLAGS) $(LFLAGS) -c $< -o $#
I've got this directory structure:
.\src contains all the source code (.h and .cpp)
.\bin should have all the .o and .bin
. has Makefile
This is my current Makefile:
CFLAGS = -Wall -pedantic -g
CC = g++
EXEC = flrfile
SRC_DIR = src
BIN_DIR = bin
SOURCES := $(wildcard $(SRC_DIR)/*.cpp)
OBJ := $(patsubst $(SRC_DIR)/%,%,$(SOURCES))
OBJ := $(patsubst %.cpp,%.o,$(OBJ))
OBJ := $(addprefix ../$(BIN_DIR)/,$(OBJ))
all: flrfile
../$(BIN_DIR)/%.o: $(SRC_DIR)/%.cpp $(SRC_DIR)/%.h
$(CC) $(CFLAGS) -c $(SRC_DIR)/%.cpp -o $#
$(EXEC): $(OBJ)
#mkdir -p $(BIN_DIR)
$(CC) $(CFLAGS) $(BIN_DIR)/$(OBJ) -o $(BIN_DIR)/$(EXEC)
.PHONY : clean
clean:
-rm -rf $(BIN_DIR)
When I run make I get this error:
g++ -Wall -pedantic -g -c src/%.cpp -o ../bin/FixedLengthFieldsRecord.o
g++: error: src/%.cpp: No such file or directory
g++: fatal error: no input files
compilation terminated.
make: *** [../bin/FixedLengthFieldsRecord.o] Error 4
Why is this? I have little to no understanding of Makefile to be honest...
The correct line for compiling should look like this:
$(BIN_DIR)/%.o: $(SRC_DIR)/%.cpp $(SRC_DIR)/%.h
$(CXX) -o $# -c $< $(CFLAGS)
Which means: "for every file matching the pattern "%.o" in $(BIN_DIR), compile it using the associated $(SRC_DIR)/%.cpp as argument (first dependency)
Additional comment: I suspect some missing dependencies: usually, a .c or cpp source file doesn't only depend on the corresponding header file, but might also include other headers from the project.