#----------------------------------------------------------------------- ------
# Choose a compiler & its options
#--------------------------------------------------------------------------
CC = gcc
OPTS = -W -O3
#--------------------------------------------------------------------------
# Add the debug flag to compile for use by a debugger
#--------------------------------------------------------------------------
#DEBUG=-g
#--------------------------------------------------------------------------
# Add the names of the directories
#--------------------------------------------------------------------------
SRCDIR= src
OBJDIR= obj
INCDIR= include
BINDIR= bin
#--------------------------------------------------------------------
# Add the rest of the source files. Don't forget to add the '\' character
# to continue the line. You don't need it after the last source file
#--------------------------------------------------------------------
SRCS=$(SRCDIR)/Lab12.c \ Function1.c \ Function2.c \ Function3.c \ Function4.c \ Function5.c
#--------------------------------------------------------------------
# You don't need to edit the next few lines. They define other flags
# used in the compilation of the source code
#--------------------------------------------------------------------
INCLUDE = $(addprefix -I,$(INCDIR))
OBJS=${SRCS:$(SRCDIR)/%.c=$(OBJDIR)/%.o}
CFLAGS = $(OPTS) $(INCLUDE) $(DEBUG)
#--------------------------------------------------------------------
# Add the name of the executable after the $(BINDIR)/
#--------------------------------------------------------------------
TARGET = $(BINDIR)/ Lab12
all: $(TARGET)
$(TARGET): $(OBJS)
${CC} ${CFLAGS} -o $# $(OBJS)
$(OBJS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $#
clean:
rm -f $(OBJS)
cleanall:
rm -f $(OBJS)
rm -f Lab12
#--------------------------------------------------------------------
# Add a target named cleanall that will remove the object files as well
# as the executable
#--------------------------------------------------------------------
I have all my "header" files in the include folder. I have all my source code in the src folder (Lab12.c , Function1.c, Function2.c ...). I keep getting this error when i use the make command.
Makefile:45: target Function1.c' doesn't match the target pattern
Makefile:45: target Function2.c' doesn't match the target pattern
Makefile:45: target Function3.c' doesn't match the target pattern
Makefile:45: target Function4.c' doesn't match the target pattern
Makefile:45: target ` Function5.c' doesn't match the target pattern
gcc -W -O3 -Iinclude -c -o Function1.c
gcc: no input files
make: *** [ Function1.c] Error 1
I cant quite figure out why it is behaving this way. All these files are in the src code folder so why isnt the system recognizing them?
SRCS=$(SRCDIR)/Lab12.c \ Function1.c \ Function2.c \ Function3.c \
seems wrong; you should try
SRCS=$(SRCDIR)/Lab12.c Function1.c Function2.c Function3.c
instead
UPDATE
If Function1.c and so on are in ยด$(SRCDIR)`, you must prepend the directory to these files, too. (comment from M Oehm)
Related
I have written a Makefile to generate a kernel image from both ASM and C sources however it fails to compile the C sources. I think the error is in using two object lists one for ASM and one for C. If there are other issues with the file please feel free to tell me.
Terminal Output
arm-none-eabi-as -I source/ source/maths.s -o build/maths.o
arm-none-eabi-as -I source/ source/tags.s -o build/tags.o
make: *** No rule to make target 'build/firstCFile.o', needed by 'build/output.elf'. Stop.
Makefile
# The toolchain to use. arm-none-eabi works, but there does exist
# arm-bcm2708-linux-gnueabi.
ARMGNU ?= arm-none-eabi
# The intermediate directory for compiled object files.
BUILD = build/
# The directory in which source files are stored.
SOURCE = source/
# The name of the output file to generate.
TARGET = bin/kernel.img
# The name of the assembler listing file to generate.
LIST = bin/kernel.list
# The name of the map file to generate.
MAP = bin/kernel.map
# The name of the linker script to use.
LINKER = kernel.ld
# The names of libraries to use.
LIBRARIES := csud
# The names of all object files that must be generated. Deduced from the
# assembly code files in source.
OBJECTS := $(patsubst $(SOURCE)%.s,$(BUILD)%.o,$(wildcard $(SOURCE)*.s))
OBJECTS2 := $(patsubst $(SOURCE)%.c,$(BUILD)%.o,$(wildcard $(SOURCE)*.c))
# Rule to make everything.
all: $(TARGET) $(LIST)
# Rule to remake everything. Does not include clean.
rebuild: all
# Rule to make the listing file.
$(LIST) : $(BUILD)output.elf
$(ARMGNU)-objdump -d $(BUILD)output.elf > $(LIST)
# Rule to make the image file.
$(TARGET) : $(BUILD)output.elf
$(ARMGNU)-objcopy $(BUILD)output.elf -O binary $(TARGET)
# Rule to make the elf file.
$(BUILD)output.elf : $(OBJECTS) $(OBJECTS2) $(LINKER)
$(ARMGNU)-ld --no-undefined $(OBJECTS) $(OBJECTS2) -L. $(patsubst %,-l %,$(LIBRARIES)) -Map $(MAP) -o $(BUILD)output.elf -T $(LINKER)
# Rule to make the object files.
$(BUILD)%.o: $(SOURCE)%.s
$(ARMGNU)-as -I $(SOURCE) $< -o $#
$(BUILD):
mkdir $#
I think you need a rule to make from the c source:
$(BUILD)%.o : $(SOURCE)%.c
$(ARMGNU)-gcc -c -I $(SOURCE) $< -o $#
I'm following this guide about makefile, but I didn't understand at all the last example and I can't get my makefile work, as I obtain the error make: *** No rule to make target "obj/date.o", needed by "Whatsapp". Stop.
Here is my makefile:
IDIR = ../include
CC = gcc
CFLAGS = -I$(IDIR)
ODIR = obj
LDIR = ../lib
LIBS = -lncurses
# Keep the alphabetical order!
_DEPS = \
constants.h\
date.h\
inOut.h\
languages.h\
message.h\
mycurses.h\
mysocket.h\
text.h\
time.h\
user.h\
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
# Keep the alphabetical order!
_OBJ = \
date.o\
inOut.o\
languages.o\
main.o\
message.o\
mycurses.o\
mysocket.o\
text.o\
time.o\
user.o\
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
# these two lines should tell the compilator that my .o files depend by .c files, don't they?
$(ODIR)/%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
Whatsapp: $(OBJ)
$(CC) -o $# $^ $(CFLAGS) $(LIBS)
.PHONY: clean
clean:
rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~
Obviously, all my *.c are in the current folder, so really I don't know what I am missing.
Just for more clarity, here is the content of the current folder:
urbijr#urbijr-VirtualBox:/media/sf_Whatsapp_CLIENT$ ls
constants.h indexbook.txt languages.c makefile message.h mycurses.h text.c time.h
date.c inOut.c languages.h message.c message.txt mysocket.c text.h user.c
date.h inOut.h main.c message_for_user.txt mycurses.c mysocket.h time.c user.h
Your dependencies are not as you have specified in your makefile. The line below specifies that all include files should be in the directory $(IDIR).
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
This is set as ../include, but it seems you have all the header files in the same directory. Either move them to ../include or change IDIR to . (the current directory).
You'll also need to create the output directory (obj) as make won't do this automatically.
I want to compile and link my Project. I have Problems with linking of the target. It is the first time I`m using a makefile.
I think there may be a Problem with the $OBJ or call of the gcc.
I got the following error message:
C:\Projekte\playground\Modultest>make all
gcc -O0 -g -Wall -fmessage-length=0 -fprofile-arcs -ftest-coverage ./CUnit/headers ./CUnit/sources ./stub ./source ./test --coverage -o CUnit-Target
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: cannot find ./CUnit/headers: Permission denied
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: cannot find ./CUnit/sources: Permission denied
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: cannot find ./stub: Permission denied
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: cannot find ./source: Permission denied
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: cannot find ./test: Permission denied
collect2.exe: error: ld returned 1 exit status
makefile:54: recipe for target 'CUnit-Target' failed
make: *** [CUnit-Target] Error 1
I have no spaces in the path.
This is my makefile
# makefile to generate UNIT-tests
# define the C compiler to use
CC = gcc
# define any compile-time flags
CFLAGS = -O0 -g -Wall -fmessage-length=0 -fprofile-arcs -ftest-coverage
# define any directories containing header files other than /usr/include
# TODO
HEADERS = ./CUnit/headers \
./CUnit/sources \
./stub \
./source \
./test
SOURCES = ./CUnit/sources \
./stub \
./source \
./test
#TODO Linkerflags
LFLAGS = --coverage -o
# define any libraries to link into executable:
# if I want to link in libraries (libx.so or libx.a) I use the -llibname
# option, something like (this will link in libmylib.so and libm.so:
LIBS =
# TODO define the C source files
TST_SRCS = min.c max.c
SRCS = CUnit.c Automated.c Basic.c Console.c CUCurses.c CUError.c Cunit_intl.c \
MyMem.c TestDB.c TestRun.c Util.c wxWidget.c \
$(TST_SRCS)
# define the C object files
#
# This uses Suffix Replacement within a macro:
# $(name:string1=string2)
# For each word in 'name' replace 'string1' with 'string2'
#OBJ = $(SRCS:%.c=%.o)
#OBJ = $(TST_SRCS:%.c=%.o)
OBJ=$(join($(dir $(SOURCES))), $(notdir $(SRCS:%.c=%.o)))
# define the executable file
TARGET = CUnit-Target
all: $(TARGET)
$(TARGET): $(OBJ)
$(CC) $(CFLAGS) $(HEADERS) $(OBJ) $(LFLAGS) $(TARGET)
#echo build finished
#execute tests
#Cunit.exe
# create coverage files
# TODO SRCS max.c min.c ?
# gcov -b -c -f max min
clean:
$(RM) *.o *~ $(MAIN)
# DO NOT DELETE THIS LINE -- make depend needs it
I am trying to use the mongo C driver in a Trivia server program I am making to use it to track login information scores etc.
It took me a decent amount of time to figure out how to compile the stuff in a makefile but I was able to include mongoc.h so things like mongoc_client work fine. As soon as I try to actually use a function though, such as mongoc_init I get
> undefined reference to `mongoc_init'
I feel like things should be linked though since the mongoc.h include all other header files and it looks like it is linking properly. Here is my makefile - I'm not sure what to do or even what information to provide to solve this issue.
client:
make -f makefile.client
server:
make -f makefile.server
clean:
rm -f *~ *.o tserve core tclient core *.tar *.zip *.gzip *.bzip *.gz
^ Makefile
C = gcc
CFLAGS = -g -Wall
LDFLAGS = -lpthread
INFO = -L/usr/local/lib -I/usr/local/include/libmongoc-1.0 -I/usr/local/include/libbson-1.0 -lmongoc-1.0 -lbson-1.0
all: tserve
csapp.o: csapp.c csapp.h
$(CC) $(CFLAGS) -c csapp.c
tserve.o: tserve.c readq.h csapp.h
$(CC) $(CFLAGS) -c tserve.c $(INFO)
readq.o: readq.c readq.h csapp.h
$(CC) $(CFLAGS) -c readq.c
tserve: tserve.o readq.o csapp.o
^ makefile.server
C = gcc
CFLAGS = -g -Wall
LDFLAGS = -lpthread
all: tclient
csapp.o: csapp.c csapp.h
$(CC) $(CFLAGS) -c csapp.c
tclient.o: tclient.c csapp.h
$(CC) $(CFLAGS) -c tclient.c
tclient: tclient.o csapp.o
^ makefile.client
If it is worth noting - the system is question had the driver installed using the following code
system("wget https://github.com/mongodb/mongo-c-driver/releases/download/1.0.2/mongo-c-driver-1.0.2.tar.gz");
system("tar -xzf mongo-c-driver-1.0.2.tar.gz");
system("rm mongo-c-driver-1.0.2.tar.gz");
if (chdir("mongo-c-driver-1.0.2"))
perror("error:");
system("./configure --prefix=/usr --libdir=/usr/lib64");
system("make");
system("sudo make install");
the code is also at https://www.github.com/decix/TriviaServer
the following file is expected to be named Makefile.mak
# note: with very minor changes this should work for most C projects
# irregardless of the OS being used
SHELL := /bin/sh
.PHONY: all clean
#
# macro for all *.c files
# (NOTE:
# (the following 'wildcard' will pick up ALL .c files
# (like FileHeader.c and FunctionHeader.c
# (which should not be part of the build
# (so be sure no unwanted .c files in directory
# (or change the extension
#
SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
DEP := $(SRC:.c=.d)
INC := $(SRC:.c=.h)
CC := /usr/bin/gcc
MAKE := /usr/bin/make
name := tserve
CFLAGS := -c -g -std=c11 -Wall -Wextra -pedantic-errors
#CPPFLAGS += =MD
# when #(DEBUG) is used in the compile/link steps,
# them max info for the gdb debugger is generated
DEBUG := -ggdb3
LDFLAGS := -L/lib -L/usr/lib -L/usr/local/lib
LIBS := -lpthread -lmongoc-1.0 -lbson-1.0
INC := -I/usr/local/include/libmongoc-1.0 -I/usr/local/include/libbson-1.0
name := tserve
all: $(name)
#
# link the .o files into the executable
# using the linker flags
# -- explicit rule
#
$(name): $(OBJ)
#
# ======= $(name) Link Start =========
$(CC) $(LDFLAGS) -o $# $(OBJ) $(LIBS)
# ======= $(name) Link Done ==========
#
#
#create dependancy files
# -- inference rule
#
%.d: %.c Makefile.mak
#
# ========= START $< TO $# =========
$(CC) -M $(CPPFLAGS) $< > $#.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $# : ,g' < $#.$$$$ > $#; \
rm -f $#.$$$$
# ========= END $< TO $# =========
#
# compile the .c file into .o files using the compiler flags
# -- inference rule
#
%.o: %.c %.d
#
# ========= START $< TO $# =========
$(CC) $(CCFLAGS) -c $< -o $# -I. $(INC)
# ========= END $< TO $# =========
#
clean:
# ========== CLEANING UP ==========
rm -f *.o
rm -f $(name).map
rm -f $(name)
rm -f *.d
# ========== DONE ==========
ifneq "$(MAKECMDGOALS)" "clean"
-include $(DEP)
endif
You only use the INFO variable, which contains -lmongoc-1.0 -lbson-1.0 (which is what you need), to build tserve.o. In this build step, the linker is not involved, so the -l options are not evaluated and don't do anything. Instead, you need to specify them when you build tserve.
You could solve this by supplying a recipe for tserve that does this, such as
tserve: tserve.o readq.o csapp.o
$(CC) $(LDFLAGS) $(INFO) -o $# $+
...but it would be better, in my opinion, to split INFO and put the parts into the variables that the predefined rules use for the relevant purposes. Then your whole Makefile could be replaced with
# C compiler
CC = gcc
# C compiler flags
CFLAGS = -g -Wall
# C preprocessor flags
CPPFLAGS = -I/usr/local/include/libmongoc-1.0 -I/usr/local/include/libbson-1.0 -pthread
# Linker flags
LDFLAGS = -L/usr/local/lib -pthread
# Libraries
LDLIBS = -lmongoc-1.0 -lbson-1.0
all: tserve
csapp.o: csapp.c csapp.h
tserve.o: tserve.c readq.h csapp.h
readq.o: readq.c readq.h csapp.h
tserve: tserve.o readq.o csapp.o
The .o files will then be built through implicit rules that generate them from corresponding .c files and use CPPFLAGS and CFLAGS, saving you the trouble of specifying the recipes explicitly -- the rules only exist to track dependencies -- and the linking step uses an implicit rule that uses LDFLAGS and LDLIBS. Note that I supplied -pthread in both CPPFLAGS and LDFLAGS because it is relevant for both the preprocessor and the linker.
For further information, see the bit about implicit rules in the GNU make manual, and speaking of dependency tracking, you may find this article about automating it enlightening.
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