I have to work in a C project and i have problem with the make. The file structure is:
dir
--/bin
--/src
all the sources files (.c)
--/includes
all the includes (.h)
makefile
makefile is:
CC = gcc
RES =
_OBJ = paciente.o utils.o obrasocial.o pacienteobrasocial.o orm.o
profespecialidad.o profesional.o especialidad.o turnos.o $(RES)
LINKOBJ = main.o utils.o $(RES)
MAINOBJ = main.o
MAINSRC= main.c
LIBS = -L"/usr/lib"
IDIR =/includes
INCS = -I$(IDIR)
BIN = tpfinalc
_DEPS = config.h utils.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
ODIR=/bin
CFLAGS = $(INCS) $(LIBS) -lpq
RM = rm -f
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
SDIR = /src
_SRC = especialidad.c obrasocial.c orm.c paciente.c
pacienteobrasocial.c profesional.c profespecialidad.c turnos.c utils.c
SRC = $(patsubst %,$(SDIR)/%,$(_SRC))
VPATH = src
.PHONY: all all-before all-after clean clean-custom
all: all-before tpfinalc all-after clean
$(BIN): $(OBJ)
$(CC) $(LINKOBJ) -o tpfinalc $(CFLAGS)
$(ODIR)/$(MAINOBJ): MAINSRC $(DEPS)
$(CC) -c MAINSRC -o $(ODIR)/$(MAINOBJ) $(CFLAGS)
$(ODIR)/%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
I guess that this should'be correct, but when I make my c files the console indicates that there isn't any rule to build bin/paciente.
Anyone have an idea why? Thanks You.
One error is that /includes is an absolute path which does not exist (same applies to all other paths here). What you need is a relative path: includes or, if you like typing, ./includes.
Another error is that you omit paths in the dependencies and rules, so that make never finds your files. E.g.:
$(ODIR)/%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
Should really be:
bin/%.o: src/%.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
All paths should be relative to the current directory, which is where your makefile is.
Related
Teacher gave us this makefile for compiling two C files and storing the objects into a directory called object. It compiles the programs fine however it doesn't store their objects into the directory, and it also doesn't even create the directory. Not sure what to do and could really use some help.
This is my make file
CC = clang
CFLAGS = -g -Wall
OBJDIR = object
HDRS = $(wildcard *.h)
SRCS = $(wildcard *.c)
OBJS = $(addprefix $(OBJDIR)/, $(SRCS:.c=.o))
.PHONY: all
all: client server
# WARNING: must have a tab before each definition
$(OBJDIR)/client.o: client.c $(HDRS) $(OBJDIR)
$(CC) $(CFLAGS) -c client.c -o object/client.o
$(OBJDIR)/server .o: server.c $(HDRS) $(OBJDIR)
$(CC) $(CFLAGS) -c server.c -o object/server.o
$(OBJDIR)/%.o: %.c $(HDRS) $(OBJDIR)
$(CC) $(CFLAGS) -c $*.c -o object/$*.o
$(OBJDIR):
mkdir $(OBJDIR)
.PHONY: clean
clean:
rm -f $(TARGET) $(OBJS)
All I had to do was add multiple targets to the makefile and change all to target the targets
CC = clang
CFLAGS = -g -Wall
# TODO: rename the target to something meaningful!
TARGET = client server
OBJDIR = object
HDRS = $(wildcard *.h)
SRCS = $(wildcard *.c)
OBJS = $(addprefix $(OBJDIR)/, $(SRCS:.c=.o))
.PHONY: all
all: $(TARGET)
# WARNING: *must* have a tab before each definition
$(TARGET): $(OBJDIR) $(OBJS)
$(CC) $(CFLAGS) $(OBJDIR)/protocol.o $(OBJDIR)/$#.o -o $#
$(OBJDIR)/%.o: %.c $(HDRS) $(OBJDIR)
$(CC) $(CFLAGS) -c $*.c -o object/$*.o
$(OBJDIR):
mkdir $(OBJDIR)
.PHONY: clean
clean:
rm -f $(TARGET) $(OBJS)
I'm performing blackbox testing using a set.h interface where I have no access to set.c, I've been provided with the object file set.o and I'm required to write a bunch of tests in a main.c file for the set. How do I create a makefile that would include set.o, set.h and main.c?
**I already have the set.o file so I don't have to regenerate it using set.c
I'm confused because I only know how to do this using the complete files.
Here's my template
CC = clang
CFLAGS = -g -Wall
PROG = example
HDRS = set.h
SRCS = main.c
OBJDIR = object
OBJS = $(OBJDIR)/main.o $(OBJDIR)/set.o
# compiling rules
$(PROG): $(OBJS) $(OBJDIR)
$(CC) $(CFLAGS) $(OBJS) -o $(PROG)
$(OBJDIR)/set.o: set.h $(HDRS) $(OBJDIR)
$(CC) $(CFLAGS) -c set.h -o $(OBJDIR)/set.o
$(OBJDIR)/main.o: main.c $(HDRS) $(OBJDIR)
$(CC) $(CFLAGS) -c main.c -o $(OBJDIR)/main.o
$(OBJDIR):
mkdir $(OBJDIR)
clean:
rm -f $(PROG) $(OBJS)
If you already have the set.o file there is no need to create a rule for it, just use it. Also note I got rid of the mkdir because if you already have a set.o, it should already be in objects/ right?
CC = clang
CFLAGS = -g -Wall
PROG = example
HDRS = set.h
SRCS = main.c
OBJDIR = object
OBJS = $(OBJDIR)/main.o
# compiling rules
$(PROG): $(OBJS)
$(CC) $(CFLAGS) $(OBJS) $(OBJDIR)/set.o -o $(PROG)
$(OBJDIR)/main.o: main.c $(HDRS)
$(CC) $(CFLAGS) -c main.c -o $(OBJDIR)/main.o
clean:
rm -f $(PROG) $(OBJS)
I am trying to make a Makefile for a big project.
The project structure is (I've ommitted the header files):
root/feature1/feat1.c
root/feature2/feat2.c
root/srcfile1.c
root/srcfile2.c
I wanted to start easy so I created a simpler project with the source files in the root dir.
I need to create all the object files in one directory, let's say, objdir.
The project structure of the simple project is:
root/main.c
root/word.c
By looking in other questions I have come up with this:
CC = gcc
FLAGS = -c
MKDIR_P = mkdir -p
OUT = words
OBJDIR = objdir
SRCDIR = .
_OBJS = main.o word.o
OBJS = $(patsubst %,$(OBJDIR)/%,$(_OBJS))
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) -c -o $# $<
all: directories program
directories: ${OBJDIR}
${OBJDIR}:
${MKDIR_P} ${OBJDIR}
program: $(OBJS)
$(CC) -o $# $^ $(LIBS)
clean:
rm -f $(OBJS)
When running it with make -f ./myMakefile all (changed the filename as in the same dir, there is Netbeans' Makefile), I am getting this output:
gcc -o objdir/main.o main.c
/tmp/ccatfAHu.o: In function `main':
main.c:(.text+0x15): undefined reference to `CreateWord'
main.c:(.text+0x26): undefined reference to `CreateWord'
collect2: error: ld returned 1 exit status
make: *** [objdir/main.o] Error 1
Giving the make all command, it tries to produce the targes directories and program.
The dir objdir is created and in it, there are the main.o and word.o files.
What am I doing wrong with the makefile of the simpleproject?
EDIT:
Added the -c flag at the $(OBJDIR)/%.o rule.
Removed the $(FLAGS) from $(CC) -o $# $^ $(FLAGS) $(LIBS).
Now, if we move to my project problem, I need to access all the source files from all the directories:
/repo-root
/repo-root/feature1/feat1.c
/repo-root/feature2/feat2.c
In this rule:
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) -o $# $<
you're missing the -c flag. Instead of building an object file, Make is trying to build an executable named objdir/main.o, and main.c doesn't have all of the needed code. Just do this:
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) -c -o $# $<
Try this
#source files to compile relative to the src dir
CSOURCE = main.c
CSOURCE += func1.c
SRCDIR = .
vpath %.c $(SRCDIR)/
CC = gcc
MKDIR_P = mkdir -p
OBJDIR = objdir
BINDIR = bindir
#list of objects
OBJS = $(addprefix $(OBJDIR)/, $(CSOURCE:.c=.o))
#output name for executable
APP = example
all: ${OBJDIR} $(OBJS) bin
#rule to create bin and objects dir
${BINDIR}:
${MKDIR_P} ${BINDIR}
${OBJDIR}:
${MKDIR_P} ${OBJDIR}
#rule to compile c files
$(OBJDIR)/%.o: %.c
$(CC) -c $< -o $#
#to create executable
bin: $(BINDIR) $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $(BINDIR)/$(APP)
#to clean executable and objects
clean:
rm -rf $(OBJS) $(BINDIR) $(OBJDIR)
Updated root make file, Use this in the root/ directory
WORKDIR = $(shell pwd)
MODULES = feature1 feature2
CSOURCE = main.c
CSOURCE += func1.c
SRCDIR = .
vpath %.c $(SRCDIR)/
CC = gcc
MKDIR_P = mkdir -p
OBJDIR = $(WORKDIR)/objdir
BINDIR = $(WORKDIR)/bindir
OBJS = $(addprefix $(OBJDIR)/, $(CSOURCE:.c=.o))
APP = example
all: ${OBJDIR} modules $(OBJS) bin
modules:
for mod in $(MODULES); do \
echo "Building $$mod ....."; \
$(MAKE) -C $(WORKDIR)/$$mod all; \
done
${BINDIR}:
${MKDIR_P} ${BINDIR}
${OBJDIR}:
${MKDIR_P} ${OBJDIR}
$(OBJDIR)/%.o: %.c
$(CC) -c $< -o $#
bin: $(BINDIR) $(OBJS)
$(CC) $(CFLAGS) $(OBJDIR)/*.o -o $(BINDIR)/$(APP)
clean:
rm -rf $(OBJS) $(BINDIR) $(OBJDIR)
feature make file, use this in the root/feature1 directory and root/feature2 directory
WORKDIR = $(shell cd ..; pwd)
CSOURCE = func2.c
SRCDIR = .
vpath %.c $(SRCDIR)/
CC = gcc
MKDIR_P = mkdir -p
OBJDIR = $(WORKDIR)/objdir
OBJS = $(addprefix $(OBJDIR)/, $(CSOURCE:.c=.o))
all: ${OBJDIR} $(OBJS)
${OBJDIR}:
${MKDIR_P} ${OBJDIR}
$(OBJDIR)/%.o: %.c
$(CC) -c $< -o $#
clean:
rm -rf $(OBJS) $(OBJDIR)
When you want to add new directory say feature3, you can just add it in main makefile module list and copy the feature1 makefile to feature3 and update source file list
Hope this helps
Thanks for the responses. I found that this worked — I don't know why though.
all: $(OUT)
$(OBJ_DIR)/%.o: %.c
$(CC) $(CCFLAGS) -o $# -c $< $(INCLUDES)
$(OUT): $(OBJ)
ar rcs $(OUT) $(OBJ)
cp DIMEFILEAPPSAUTH.h ../include
.PHONY: clean
Below is a makefile I have. I keep getting the error make: *** No rule to make target but cannot see what is wrong in this case. The ".c" files exist in the current directory. I'm not sure why makefile cannot see them — can you explain?
DimeFileAppsAuth/src> ls
db_get_DIMEFILEAPPSAUTH.c db_reset_query_DIMEFILEAPPSAUTH.c Makefile
db_add_DIMEFILEAPPSAUTH.c db_print_DIMEFILEAPPSAUTH.c db_update_DIMEFILEAPPSAUTH.c
db_delete_DIMEFILEAPPSAUTH.c db_reset_DIMEFILEAPPSAUTH.c
Running the make
DimeFileAppsAuth/src> make
make: *** No rule to make target `../obj/db_add_DIMEFILEAPPSAUTH.o', needed by `../lib/lib_dime_file_apps.a'. Stop.
The Makefile
# clear out all suffixes
.SUFFIXES:
# list only those we use
.SUFFIXES: .o .c
# define a suffix rule for .c -> .o
.c.o :
$(CC) $(CFLAGS) -c $<
FILE_DIVERSION=$(IMG_PROJ_HOME)/dime/basics/BasicsLink
INC_DIR =../include
LIB_DIR =../lib
OBJ_DIR =../obj
BIN_DIR =../bin
CUR_DIR = .
OUT = $(LIB_DIR)/lib_dime_file_apps.a
BIN_OUT = $(BIN_DIR)/test_run
# include directories
INCLUDES = -I$(INC_DIR) -I$(FILE_DIVERSION)/include -I$(ORACLE_HOME)/rdbms/public -I/usr/local/include
# library paths
LIBS = -L$(LIB_DIR) -ldime_direct -L$(FILE_DIVERSION)/lib -loutput_files -lquerylib -lsql_common -lsql_common -L$(ORACLE_HOME)/lib -lclntsh -L$(ORACLE_HOME)/lib `cat $(ORACLE_HOME)/lib/sysliblist` -L/usr/local/lib -lm
CC=gcc
CCFLAGS=-w -O2 -unused-variable -Wall -fPIC -c -g -rdynamic
_DEPS = DIMEFILEAPPSAUTH.h
DEPS = $(patsubst %,$(INC_DIR)/%,$(_DEPS))
_OBJ = db_add_DIMEFILEAPPSAUTH.o db_delete_DIMEFILEAPPSAUTH.o db_get_DIMEFILEAPPSAUTH.o db_get_SEQ_DIMEFILEAPPSAUTH.o db_print_DIMEFILEAPPSAUTH.o db_reset_DIMEFILEAPPSAUTH.o db_reset_query_DIMEFILEAPPSAUTH.o db_special_DIMEFILEAPPSAUTH.o db_update_DIMEFILEAPPSAUTH.o
OBJ = $(patsubst %,$(OBJ_DIR)/%,$(_OBJ))
_BIN = db_add_DIMEFILEAPPSAUTH.o db_delete_DIMEFILEAPPSAUTH.o db_get_DIMEFILEAPPSAUTH.o db_get_SEQ_DIMEFILEAPPSAUTH.o db_print_DIMEFILEAPPSAUTH.o db_reset_DIMEFILEAPPSAUTH.o db_reset_query_DIMEFILEAPPSAUTH.o db_special_DIMEFILEAPPSAUTH.o db_update_DIMEFILEAPPSAUTH.o test_this.o
BIN = $(patsubst %,$(BIN_DIR)/%,$(_BIN))
all: $(OUT)
$(OBJ_DIR)/%.o: %.c $(DEPS)
$(CC) $(CCFLAGS) -o $# $< $(INCLUDES)
$(OUT): $(OBJ)
ar rcs $(OUT) $(OBJ)
cp DIMEFILEAPPSAUTH.h ../include
exec: $(BIN) $(OUT)
$(CC) -o $(BIN_OUT) $(BIN) $(LIBS)
rm $(BIN_DIR)/*.o
.PHONY: clean
The make error occurs when it comes to this line "$(OUT): $(OBJ)". Please check whether the file named "db_add_DIMEFILEAPPSAUTH.o" exists in the directory "../obj"
Follow-up: Set up a development environment on Linux targeting Linux and Windows
The project dir looks like this:
/pps
/src
/obj
/bin
Makefile
And the content of Makefile is this:
OBJ_DIR = obj
SRC_DIR = src
BIN_DIR = bin
INCLUDE = -I./$(SRC_DIR)
LIBS =
_SRCS = print_current_dir.c test_main.c
_OBJS = print_current_dir.o test_main.o
SRCS = $(addprefix $(SRC_DIR)/,$(_SRCS))
OBJS = $(addprefix $(OBJ_DIR)/,$(_OBJS))
$(OBJ_DIR)/%.o: %.c %.h
$(CC) -c -o $(OBJ_DIR)/$# $< $(CFLAGS)
all: $(BIN_DIR)/pps-linux $(BIN_DIR)/pps-win32
$(BIN_DIR)/pps-linux: $(OBJS)
CC = cc
CFLAGS = -g -Wall $(INCLUDE) $(LIBS)
$(BIN_DIR)/pps-win32: $(OBJS)
CC = i586-mingw32msvc-cc
CFLAGS = -g -Wall $(INCLUDE) $(LIBS)
.PHONY: clean
clean:
rm -f $(OBJS) $(SRC_DIR)/~ core $(BIN_DIR)/*
The files print_current_dir.c and test_main.c are just for testing.
This makefile doesn't work:
$ make
make: *** No rule to make target `obj/print_current_dir.o', needed by `bin/pps-linux'. Stop.
I think the problem is with the %.o rule. I'm sure it is trivial, but I'm not very experienced with make.
Thank you.
This rule:
$(OBJ_DIR)/%.o: %.c %.h
specifies that obj/foo.o depends on foo.c, not src/foo.c. There is no foo.c, so this rule cannot be applied (hence the error message).
This should do the job:
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(SRC_DIR)/%.h