I have an issue with my makefile which says No rule to make target /obj/%.o, needed by /bin/exec. Stop. But from what I understand I have it:
# define the C compiler to use
CC = gcc
# define any compile-time flags
# add -DDEBUG for debug mode
CFLAGS = -Wall
# define any directories containing header files
INCLUDES = -I/includes
# define src folder
SRC_FOLDER = /src
# define src files
SRC = $(wildcard $(SRC_FOLDER)/%.cpp)
# define object folder
OBJ_FOLDER = /obj
# define obj files
OBJ = $(patsubst %.cpp, %.o, $(SRC))
# define binary path
BIN_FOLFER = /bin
# define the executable file
MAIN = $(BIN_FOLFER)/exec
# compile object files
$(OBJ_FOLDER)/%.o: $(SRC_FOLDER)/%.cpp
$(CC) $(CFLAGS) $< -o $#
# build
$(MAIN): $(OBJ_FOLDER)/%.o
$(CC) $(CFLAGS) $^ -o $#
# cleaning
.PHONY: clean
clean:
rm -f $(OBJ_FOLDER)/%.o
I am sorry for any possible major errors in the makefile, this is my first makefile. What am I doing wrong?
$(MAIN): $(OBJ_FOLDER)/%.o
requests %.o exactly. The % does not act as pattern here, because it does not appear on both sides of the rule. You need to use the $(OBJ) variable there. But it first need to be fixed, because you are only replacing the extension, but you need to replace the directory too.
Finish the $(OBJ) variable (as Lutin already said) (ok, but I modified it a bit; I presume you only want the direct descendants of the directory):
SRC = $(wildcard $(SRC_FOLDER)/*.cpp)
OBJ = $(patsubst $(SRC_FOLDER)/%.cpp, $(OBJ_FOLDER)/%.o, $(SRC))
Fix the rule to actually use the $(OBJ) variable:
$(MAIN): $(OBJ)
Oh, and you most probably don't want SRC_FOLDER, OBJ_FOLDER and BIN_FOLDER to start with / as that puts them in the filesystem root it's not where your project lives. And with the patterns above they should not end with slash either.
It works with that:
SRC = $(wildcard $(SRC_FOLDER)*/*.cpp $(SRC_FOLDER)*.cpp)
OBJ = $(patsubst $(SRC_FOLDER)%.cpp, $(OBJ_FOLDER)%.o, $(SRC))
Related
so ive got a make file here and my project currently has a master.c and slave.c which both have main functions. therefore i just want to filter the slave.c file out of the building process. so I used fliter-out when defining the source files. but when run make the project keeps turning up with the "multiple definitions of main" error. why is this when filter-out should be hiding the slave.c file?
########################################################################
####################### Makefile Template ##############################
########################################################################
#Compiler settings - Can be customized.
CC = gcc
CXXFLAGS = -std=c11 -Wall
LDFLAGS =
# Makefile settings - Can be customized.
APPNAME = master
SUBAPPNAME = slave
EXT = .c
SRCDIR = .
OBJDIR = .
############## Do not change anything from here downwards! #############
SRC := $(filter-out slave.c, $(wildcard $(SRCDIR)/*$(EXT)))
OBJ := $(SRC:$(SRCDIR)/%$(EXT)=$(OBJDIR)/%.o)
DEP := $(OBJ:$(OBJDIR)/%.o=%.d)
#UNIX-based OS variables & settings
RM = rm
DELOBJ = $(OBJ)
# Windows OS variables & settings
DEL = del
EXE = .exe
WDELOBJ = $(SRC:$(SRCDIR)/%$(EXT)=$(OBJDIR)\\%.o)
########################################################################
####################### Targets beginning here #########################
########################################################################
all: $(APPNAME)
# Builds the app
$(APPNAME): $(OBJ)
$(CC) $(CXXFLAGS) -o $# $^ $(LDFLAGS)
# Creates the dependecy rules
%.d: $(SRCDIR)/%$(EXT)
#$(CPP) $(CFLAGS) $< -MM -MT $(#:%.d=$(OBJDIR)/%.o) >$#
# Includes all .h files
-include $(DEP)
# Building rule for .o files and its .c/.cpp in combination with all .h
$(OBJDIR)/%.o: $(SRCDIR)/%$(EXT)
$(CC) $(CXXFLAGS) -o $# -c $<
################### Cleaning rules for Unix-based OS ###################
# Cleans complete project
.PHONY: clean
clean:
$(RM) $(DELOBJ) $(DEP) $(APPNAME)
# Cleans only all files with the extension .d
.PHONY: cleandep
cleandep:
$(RM) $(DEP)
# Clean only all files with the extension .o
.PHONY: cleanobj
cleanobj:
$(RM) $(DELOBJ)
# Cleans both files with .d and .o extensions
.PHONY: cleanod
cleanod:
$(RM) $(DELOBJ) $(DEP)
The call
SRC := $(filter-out slave.c, $(wildcard $(SRCDIR)/*$(EXT)))
is just a string operation, that is, make is unaware of the underlying file tree and tries to throw out the string slave.c from the liste yoursrcdir/slave.c yoursrcdir/master.c which obviously fails. Although you may disagree at first, this is a good thing because the semantic of filter operations on filetrees is by no means universal or easy to document or transport. Therefore make just looks at the presented strings and decides on the character-for-character comparison which to take and which to drop.
That said, the rewrite to
SRC := $(filter-out $(SRCDIR)/slave.c, $(wildcard $(SRCDIR)/*$(EXT)))
will do the trick in your case.
For wider reaching functionality look up the two functions abspath and realpath to get file names in a canonical format, which prevent filter et.al. from stumbling on differences in OS nomenclature.
I am very new at make. Thus far I've managed to create the following using some of GNU manual and tutorials found online. I'd like for make to place all of the created object files into the directory 'obj.' I've been able to successfully create this directory, but I cannot figure out how to place the files in it. Any suggestions or tips are appreciated. Also, on a general note, is there a good source for learning how to work with make besides the GNU documentation?
# specify compiler
CC := gcc
# set compiler flags
CFLAGS := -M -Igen/display -Igen/logic -Iman -Ilib/include -pipe -march=native -ftime-report
# set linker flags
LDFLAGS := -lglut32 -loglx -lopengl32 -Llib
# specify separate directory for objects
OBJDIR := obj
# include all sources
SOURCES := $(wildcard gen/display/*.c gen/logic/*.c man/*.c)
# create objects from the source files
OBJECTS := $(patsubst %.c,%.o,$(SOURCES))
# specify the name and the output directory of executable
EXECUTABLE := win32/demo
# all isn't a real file
all: $(EXECUTABLE)
# compile
%.o: %.c
#mkdir -p $(#D)
$(CC) $(CFLAGS) -c $< -o $(OBJDIR)/$#
# link
$(EXECUTABLE): $(OBJECTS)
$(CC) $^ $(LDFLAGS) -o $#
# clean objects
clean:
#$(RM) -rf $(OBJDIR)
.PHONY: all clean
Any time you see a rule where the output generated does not go to the file $#, you know it's not right. Make will set the $# automatic variable to the file name that it expects to be created and if the recipe does something different, the makefile will not work.
Your rule sends the file to $(OBJDIR)/$#, not $#, so it's not right.
So, you need to write your pattern rule like this:
%.o: %.c
#mkdir -p $(#D)
$(CC) $(CFLAGS) -c $< -o $#
If that doesn't work you'll need to provide more information such as an example of the compile line make invokes, what errors you see, etc.
I've been able to successfully create this directory, but I cannot
figure out how to place the files in it.
There are two parts writing to doing that explicitly.
First, and most fundamental, is that if you want make to create a file, you have to give it a rule for doing so. You do have a pattern rule that could, in principle, have that effect ...
%.o: %.c
# ...
... but in practice, that rule cannot ever be matched to files in the obj/ directory because your sources are not in that directory. This might be more effective:
$(OBJDIR)/%.o: %.c
#mkdir -p $(#D)
$(CC) $(CFLAGS) -c $< -o $#
Note in particular how now the target of the rule matches the artifact actually produced by that rule.
Second, you must have a requirement to build the target of the rule, usually by having it be a dependency of some other rule. Observe that your variable defining the object files contributing to $(EXECUTABLE) does not rely on objects from the obj/ directory. It is generated by this pattern substitution ...
OBJECTS := $(patsubst %.c,%.o,$(SOURCES))
... which generates object names with the same path as the corresponding sources. You probably want something more like this:
OBJECTS := $(patsubst %.c,$(OBJDIR)/%.o,$(SOURCES))
You will note how that also corresponds to the change presented in the previous point.
But that's a lot of work for little gain. You would not have to modify your clean target very much to do without it there. You could write your file in a somewhat simpler and more conventional form and still get output into a separate directory by leveraging the VPATH feature of GNU (and some other) make.
I am a newbie in creating makefiles, and would be glad if someone could help me.
I have created several header files (for function declarations) and corresponding .c programs (8 in total), for the function definitions (including the main function). These are listed in the .../include/ directory. Additionally, I have created another directory for the storing the output files : .../bin/ after compilation. I tried to link the .o files, but was unsuccessful. I have attached a small piece of the makefile code (similar one taken from the internet) :
CC = g++
CFLAGS = -Wall -O3
INC_DIR := /media/sf_~share/151*/Codes/include
OBJ_DIR := /media/sf_~share/151*/Codes/obj
INC_FILES := $(wildcard $(INC_DIR)/%.c)
OBJ_FILES := $(patsubst $(INC_DIR)/%.c, $(OBJ_DIR)/%.o, $(INC_FILES))
all : $(APP)
$(APP) : $(OBJ_FILES)
$(CC) $(CFLAGS) -o $# $^
$(OBJ_DIR)/%.o : $(INC_DIR)/%.c
$(CC) $(CFLAGS) -o $# $<
clean:
rm -f *.o $(APP)
I would be glad if someone could either suggest me a different code, or rectify this as it is.
There are a few mistakes in your Makefile:
Wildcard usage
You should use *.c rather than %.c for wildcard expansion, like this:
INC_FILES := $(wildcard $(INC_DIR)/*.c)
Patsubst usage
You don't need to specify the full pattern $(INC_DIR)/%.c for patsubst, instead, simply use:
OBJ_FILES := $(patsubst %.c, %.o, $(INC_FILES))
Missing $(APP) value
I don't know if you simply forgot to add this to the sample or not, but since $(APP) is an empty string, the makefile says:
make: Nothing to be done for `all'.
Adding APP := program triggers a build for all the *.c files in include.
I'm at my wits end here because of this extremely stupid error I'm getting from my makefile.
I finally gave up stripped the makefile down to just two lines:
%.o: %.c
gcc -c -o $# $< -I../inc
Command: make . The output:
make: *** No targets. Stop.
The spaces at the beginning are real tabs instead of spaces. The c files are in the same directory. If instead of %.o I give, say, file1.o and file1.c instead of %.c, all is well (file1.o gets created). I see plenty of examples on the 'net that use the % operator, though. If I include a clean: target, it is promptly found, like so:
%.o: %.c
gcc -c -o $# $< -I../inc
clean:
echo "this is clean!"
Command: make . The output:
echo "this is clean!"
this is clean!
Please help me out here as I'm totally clueless about what's wrong with my targets. In the second sample (the one with clean target), I guess the clean target is found and acted upon as the first one is 'invalid' somehow.
Looks like you forgot to write a target. You have just written rules of how to compile, but not what to do with those objects. I mean, I miss something like:
my_executable_file: *.o
gcc -o my_executable_file *.o
EDIT:
What is set before is true, you need a target. But as you want only to compile, your target should be something like:
OBJECTS = file.o #and whatever objects you need, as a list separated by commas
And then your target:
my_objects: $(OBJECTS)
So putting it all together:
OBJECTS = file.o #and whatever objects you need, as a list separated by commas
my_objects: $(OBJECTS)
%.o: %.c
gcc -c -o $# $< -I../inc
Below is the Makefile that will enable to any number of targets to compile
OBJ := file.o
all: $(OBJ)
%.o: %.c
gcc -c -o $# $< -I../inc
clean:
echo "this is clean!"
Here, OBJ will be the list of the files that you want to compile , like here it is file.c
Add the file name you want to compile to OBJ, when make is called it will build the target all first which depends on the OBJ.
To build OBJ the gcc command is used.
When an explicit target is not given to make, then the first (non-pattern?) target in the Makefile is used. In the case above, it is the clean target.
I see your intention to make only .o files (can be needed for creation of libraries).
You can modify your Makefile to build only .o files or build only executable by using the same Makefile
For the below directory structure (using tree command)
# tree .
.
|-- include
| `-- head.h
|-- Makefile
|-- obj
`-- src
`-- main.c
Makefile
# GNU Makefile #
# Some Variables #
CC := gcc
RM := rm
MV := mv
# Phony Targets #
.PHONY: clean
.PHONY: move
# Path for Source, Object and Include #
SRC_PATH := ./src/
OBJ_PATH := ./obj/
INCLUDE_PATH := ./include/
# Source and Object File Names #
SRC := $(SRC_PATH)main.c
OBJ := $(SRC:c=o) # Substitutes all SRC but with .c as .o (main.c becomes main.o) #
# Executable Name #
TARGET := exe
# Building Binary - use 'make' #
binary: $(TARGET) move
$(TARGET): $(OBJ)
$(CC) -o $(TARGET) $^
# Building only Object Files - use 'make object_only' #
object_only : $(OBJ) move
$(OBJ): $(SRC)
$(CC) -c -o $# $< -I $(INCLUDE_PATH)
# This rule is for moving .o files to ./obj directory (More Organised) #
move:
$(MV) $(SRC_PATH)*.o $(OBJ_PATH)
# For Cleaning - use 'make clean' #
clean:
echo "Cleaning Up!"
$(RM) -rfv $(TARGET) $(OBJ_PATH)*.o $(SRC_PATH)*.o # Delete .o and executable #
Execution:
To build only object files use
$ make object_only
To build object files and executable, use
$ make
I would like to store all paths to headers in separate file. I'm going to generate file with paths dynamically, to avoid re-creating Makefile whenever paths change.
Is that possible?
Yes, you can generate the file, let's call it paths.inc, so it looks like, for example:
INCLUDEPATH=path1:path2
and then include the file in your main Makefile
include paths.inc
and use the variable defined in it: ${INCLUDEPATH}
Makefile
paths_mk := paths.mk
-include $(paths_mk)
$(paths_mk) :
# Rule to generate paths.mk
include_flags = $(include_paths:%=-I%)
CPPFLAGS += $(include_flags)
%.o : %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -o $# -c $<
paths.mk
# Auto-generated file.
include_paths := ...