I'm write the following make for experiment:
some_target fmake: foo.o
$(CC) -o $(TARGET) $(TARGET).c foo.c
$(CC) -o $(TARGET2) $(TARGET2).c
clean:
rm -f fmake test_second
CC=$(VAR2)
VAR2=gcc
TARGET=fmake
TARGET2=test_second
In this case recipes of default target are always execution. But if we swap some_target with fmake the recipes will executed such as we have fmake: foo.o as target and prerequisites. But I'm expected that make check the both some_target and fmake. Since there is no some_target in Makefile's directory we have that recipes are always execution. So, question is:
Is it true that
some_target fmake: foo.o
$(CC) -o $(TARGET) $(TARGET).c foo.c
$(CC) -o $(TARGET2) $(TARGET2).c
equivalent to
some_target: foo.o
$(CC) -o $(TARGET) $(TARGET).c foo.c
$(CC) -o $(TARGET2) $(TARGET2).c
fmake: foo.o
$(CC) -o $(TARGET) $(TARGET).c foo.c
$(CC) -o $(TARGET2) $(TARGET2).c
?
Yes, your last edit is true. The first form is identical in every way to the second form (when make sees the first form, it actually stores it internally as if you had written the second form)
Related
CC=g++
CFLAGS=-c -o
PROG=craps
LIBSRCS=craps.cpp craps_game.cpp craps_helper.cpp craps_io.cpp
LIBOBJS=$(patsubst %.cpp, %.o, $(LIBSRCS))
LIBCRAPS=craps
CXXFLAGS=-I./ -fpic
LDFLAGS=-L./
all: $(PROG)
$(PROG): $(LIBSRCS)
$(CC) $(LDFLAGS) -l$(PROG) -o $(PROG) $(PROG).o
$(LIBCRAPS): $(LIBOBJS)
$(CC) -shared -o lib$(LIBCRAPS).so $(LIBOBJS)
%.o: %.cpp
$(CC) $(CXXFLAGS) -c -o $# $
depend:
${CC} -MM ${PROG}.cpp ${LIBSCRS} > depends.mak
include depends.mak
Why executable file not compiled and generated?
All o files generated with no error.
Why this line $(CC) $(LDFLAGS) -l$(PROG) -o $(PROG) $(PROG).o does not run ? what is wrong ?
You misunderstood my comment. I'm saying this this:
PROG=craps LIBSRCS=craps.cpp craps_game.cpp craps_helper.cpp craps_io.cpp
is wrong. You can't assign two variables on the same line, in a makefile. These variables must look like this:
PROG=craps
LIBSRCS=craps.cpp craps_game.cpp craps_helper.cpp craps_io.cpp
I'm asking, is the latter how your actual makefile looks, or is the example you provided here just inaccurate.
Also these rules both have incorrect newlines:
$(PROG):
$(LIBSRCS) $(CC) $(LDFLAGS) -l$(PROG) -o $(PROG) $(PROG).o
$(LIBCRAPS):
$(LIBOBJS) $(CC) -shared -o lib$(LIBCRAPS).so $(LIBOBJS)
You are adding the prerequisite lists $(LIBSRCS) and $(LIBOBJS) into the recipe (shell commands) used to build the target. Prerequisites must be on the same line as the target. These should look like this:
$(PROG): $(LIBSRCS)
$(CC) $(LDFLAGS) -l$(PROG) -o $(PROG) $(PROG).o
$(LIBCRAPS): $(LIBOBJS)
$(CC) -shared -o lib$(LIBCRAPS).so $(LIBOBJS)
This is your problem, below
Finally, you can't have both the program and the target have the same name:
PROG=craps
LIBCRAPS=craps
You can only create one target with a given name so the value of both these variables cannot be craps. Maybe you wanted:
PROG = craps
LIBCRAPS = libcraps.so
Assuming the makefile you've quoted here is identical to what you're running, you must be getting warnings like this from make when you run this makefile:
Makefile:15: warning: overriding recipe for target 'craps'
Makefile:12: warning: ignoring old recipe for target 'craps'
These warnings are why you are not seeing the compile rule invoked: the library rule is overriding it just as the warning says.
Also, you should have the program depend on the library (since it links it) and the object file $(PROG).o because currently make doesn't know it needs to be built. And you don't need to have it depend on all the source files. You want something like:
$(PROG): $(LIBCRAPS) $(PROG).o
$(CC) $(LDFLAGS) -l$(PROG) -o $(PROG) $(PROG).o
If I have 3 files, function.h, function.c and my_program.c which calls a method in function.h all in the same directory, what would be the best way to write a makefile so that I end up with a my_program.bc that would actually run when I type in lli my_program.bc? (I need to run a user defined pass that would insert stuff into the functions - should I run the pass on function.bc and test.bc, or should I link before running the pass?)
I've tried llvm-link function.bc my_program.bc with no luck. I feel I'm either missing something simple or going about the whole thing wrong.
Current terrible none-working makefile:
.PHONY: all clean
CC = clang
CFLAGS = -std=gnu99 -D_POSIX_C_SOURCE=200809L -g -Wall
IRFLAGS = -O3 -emit-llvm
TARGET = test
DEPS = functions.h
all: $(TARGET)
bc: test2
%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
%.bc: %.c $(DEPS)
$(CC) $(IRFLAGS) -c -o $# $<
test2: test.bc functions.bc
llvm-link -o test2.bc $< functions.bc
test: test.o functions.o
$(CC) $(CFLAGS) -o $# $^
clean:
$(RM) $(TARGET) *.o *.bc
Why not just write a normal Makefile to produce the desired executable,
then use wllvm?
Shameless plug for wllvm:
https://github.com/SRI-CSL/whole-program-llvm
I do not use lli, so I would be interested to hear about how it resolved
any reliance on stdlibc that your program may have.
I have a makefile that works that looks like this:
TARGET:=prog
SOURCES:=a.c b.c
CFLAGS:=-Wall -g -O2
OBJECTS:=$(SOURCES:%.c=%.o)
$(TARGET): $(OBJECTS)
gcc -o $# $^
%.o: %.c
gcc $(CFLAGS) -c -o $# $<
clean:
rm -f $(TARGET) $(OBJECTS)
The only variables that the user needs to change are the target name and the sources required to build it. The objects that need to be generated are automatically determined from the sources. I would like to extend this to support multiple targets, each with its own list of sources. I'm having trouble getting the syntax right, though. This is the general idea:
TARGETS:=prog1 prog2
SOURCES_prog1:=a.c b.c
SOURCES_prog2:=a.c c.c
CFLAGS:=-Wall -g -O2
OBJECTS_$#=$(SOURCES_$#:%.c=%.o)
$(TARGETS): $(OBJECTS_$#)
gcc -o $# $^
%.o: %.c
gcc $(CFLAGS) -c -o $# $<
clean:
rm -f $(TARGET) $(OBJECTS)
But I can't get the object list to be generated correctly. I'm also unsure how to write the clean rule to clean all of the objects. Is this possible?
There are two primary ways that I see to do this.
The first involves dynamically creating the target/prerequisite mappings using the $(eval) function.
TARGETS:=prog1 prog2
SOURCES_prog1:=a.c b.c
SOURCES_prog2:=a.c c.c
CFLAGS:=-Wall -g -O2
$(TARGETS):
gcc -o $# $^
$(foreach t,$(TARGETS),$(eval OBJECTS_$t := $(SOURCES_$t:.c=.o))$(eval $t: $(OBJECTS_$t)))
The second involves using Secondary Expansion.
TARGETS:=prog1 prog2
SOURCES_prog1:=a.c b.c
SOURCES_prog2:=a.c c.c
CFLAGS:=-Wall -g -O2
.SECONDEXPANSION:
$(TARGETS): $$(OBJECTS_$$#)
gcc -o $# $^
$(foreach t,$(TARGETS),$(eval OBJECTS_$t := $(SOURCES_$t:.c=.o)))
In either case the clean target becomes:
clean:
rm -f $(TARGETS) $(foreach t,$(TARGETS),$(OBJECTS_$t))
I wrote this Makefile to move all .o of the project inside a directory 'obj' in the main folder.
Directories
.:
actor/ lib/ Controller.cpp Controller.h Controller.o doc.txt main.cpp main.o Makefile uno VRP*
./actor:
Customer.cpp Customer.h Customer.o Depot.cpp Depot.h Depot.o Route.cpp Route.h Route.o Vehicle.cpp Vehicle.h Vehicle.o
./lib:
Search.cpp Search.h Search.o Utils.cpp Utils.h Utils.o VRP.cpp VRP.h VRP.o
Makefile
CXX=g++
RM=rm -rf
BIN_NAME=VRP
CPPFLAGS=-s -O2 -std=gnu++11 -Wall
SRCS=$(wildcard *.cpp actor/*.cpp lib/*.cpp)
OBJS=$(subst .cpp,.o,$(SRCS))
all: $(OBJS_DIR) $(BIN_NAME)
$(OBJS_DIR):
mkdir $(OBJS_DIR)
$OBJS_DIR)/%.o : $(SRCS)
$(CXX) $(CPPFLAGS) -c $< -o $#
$(BIN_NAME) : $(OBJS)
$(CXX) -o $# $^
debug:
$(CXX) -g $(CPPFLAGS) -o $(BIN_NAME) $(OBJS)
.PHONY : all clean
clean:
$(RM) $(OBJS) $(OBJS_DIR)
dist-clean: clean
$(RM) $(BIN_NAME)
How can I make it works?
This line $OBJS_DIR)/%.o : $(SRCS) sets the prerequisites of every file that matches $OBJS_DIR)/%.o to all the files in $(SRCS) that's not even close to what you want. (It is also a typo. You are missing the opening ().
You can't write a single rule for what you are trying to do here you need three pattern rules (or one with a vpath/VPATH setup).
$(OBJS_DIR)/%.o: %.cpp
$(CXX) $(CPPFLAGS) -c $< -o $#
$(OBJS_DIR)/%.o: actor/%.cpp
$(CXX) $(CPPFLAGS) -c $< -o $#
$(OBJS_DIR)/%.o: lib/%.cpp
$(CXX) $(CPPFLAGS) -c $< -o $#
That being said you don't actually have any targets that match $(OBJS_DIR)/%.o since the value of $(OBJS) is Controller.o ... actor/Customer.o ... lib/Search.o. To fix that you also need:
OBJS=$(addprefix $(OBJS_DIR)/,$(patsubst %.cpp,%.o,$(notdir $(SRCS))))
$(notdir) to get just the filename from the source files.
$(patsubst) instead of $(subst) just for correctness (subst would have modified a Bar.cpp.cpp file to Bar.o.o).
$(addprefix) to add the $(OBJS_DIR) prefix to the bare object file names.
I want to have a neat makefile containing explicit dependencies but placing all .o objects in a separate directory to link it altogether later (in an another file).
The problem is that my make stops after compiling the first source and then stops with no error whatsoever.
CC=gcc
CFLAGS=-c -Wall -pedantic -std=c99
DIR=../obj
$(DIR)/CList.o : CList.c CList.h CList_aux.h Observation.h CList_View_aux.h
$(CC) $(CFLAGS) CList.c -o $#
$(DIR)/CList_aux.o : CList_aux.c CList.h CNode.h
$(CC) $(CFLAGS) CList_aux.c -o $#
$(DIR)/CList_View_aux.o : CList_View_aux.c CNode.h Observation.h
$(CC) $(CFLAGS) CList_View_aux.c -o $#
$(DIR)/CNode.o : CNode.c CNode.h CNode_aux.h Observation.h CList.h
$(CC) $(CFLAGS) CNode.c -o $#
$(DIR)/CNode_aux.o : CNode_aux.c CNode.h Observation.h
$(CC) $(CFLAGS) CNode_aux.c -o $#
$(DIR)/Observation.o : Observation.c Observation.h Observation_aux.h CNode.h
$(CC) $(CFLAGS) Observation.c -o $#
$(DIR)/Observation_aux.o : Observation.c Observation.h
$(CC) $(CFLAGS) Observation_aux.c -o $#
$(DIR)/Record.o : Record.c Record.h Observation.h
$(CC) $(CFLAGS) Record.c -o $#
By default, make builds the first target in the makefile. In this case, that is ${DIR}/CList.o.
You need a different first target, conventionally called all:
OBJECTS = \
$(DIR)/CList.o \
$(DIR)/CList_aux.o \
$(DIR)/CList_View_aux.o \
$(DIR)/CNode.o \
$(DIR)/CNode_aux.o \
$(DIR)/Observation.o \
$(DIR)/Observation_aux.o
all: ${OBJECTS}
Note that this works whether there are any object files in the ${DIR} or not; a wildcard looking for object files in the directory makes sure that those that have already been compiled once are up to date, but doesn't try building those which failed to compile previously, or simply aren't there.
If the Makefile is really just as much as you posted, then you're missing the all: rule. Without having an explicit all rule, make assumes that the first present rule is to be made, so it stops after that. In order to achieve what you want, add (append) this to the Makefile (change the final executable name respectively):
OBJECTS = $(wildcard $(DIR)/*.o)
all: $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(LD) $(LDFLAGS) -o $# $^