Makefile overwrite old files automatically [duplicate] - makefile

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do you force a makefile to rebuild a target
I'm using a slightly modified version of zedshaw's makefile, but when I run it it doesn't recompile .o files.
I just spent 2 hours debugging only to find out make was looking at the existing object files and simply not recompiling them.
How do I force make to recompile $(OBJECTS) in future? Is there a way to do it without adding the clean target before all?
Edit: For clarity: Make is supposed to recompile automatically if something in the source has been changed, this isn't working for the $(OBJECTS) so I either need to force recompiling them or find out why it's not doing it itself.
Edit 2: After copying the whole folder and diffing it at different times I realized that make was correctly seeing all but one dependency. The problem is in the following point:
tests: LDLIBS += $(TARGET)
tests: $(TESTS)
Make doesn't recognize things under LDLIBS as dependencies so I added:
$(TESTS): $(TARGET)
Which resolved the issue. Since Jens called it in the comments I'm going to mark his answer as accepted.
CFLAGS=-g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG $(OPTFLAGS)
LDLIBS=-ldl $(OPTLIBS)
PREFIX?=/usr/local
SOURCES=$(wildcard src/**/*.c src/*.c)
OBJECTS=$(patsubst %.c,%.o,$(SOURCES))
TEST_SRC=$(wildcard tests/*_tests.c)
TESTS=$(patsubst %.c,%,$(TEST_SRC))
TARGET=build/liblcthw.a
SO_TARGET=$(patsubst %.a,%.so,$(TARGET))
# The Target Build
all: cls $(TARGET) $(SO_TARGET) tests
dev: CFLAGS=-g -Wall -Isrc -Wall -Wextra $(OPTFLAGS)
dev: all
$(TARGET): CFLAGS += -fPIC
$(TARGET): build $(OBJECTS)
ar rcs $# $(OBJECTS)
ranlib $#
$(SO_TARGET): $(TARGET) $(OBJECTS)
$(CC) -shared -o $# $(OBJECTS)
build:
#mkdir -p build
#mkdir -p bin
# The Unit Tests
.PHONY: tests
tests: LDLIBS += $(TARGET)
tests: $(TESTS)
sh ./tests/runtests.sh
valgrind:
VALGRIND="valgrind --log-file=/tmp/valgrind-%p.log" $(MAKE)
# The Cleaner
clean: cls
rm -rf build $(OBJECTS) $(TESTS)
rm -f tests/tests.log
find . -name "*.gc*" -exec rm {} \;
rm -rf `find . -name "*.dSYM" -print`
# The Install
install: all
install -d $(DESTDIR)/$(PREFIX)/lib/
install $(TARGET) $(DESTDIR)/$(PREFIX)/lib/
# The Checker
BADFUNCS='[^_.>a-zA-Z0-9](str(n?cpy|n?cat|xfrm|n?dup|str|pbrk|tok|_)|stpn?cpy|a?sn?printf|byte_)'
check:
#echo Files with potentially dangerous functions.
#egrep $(BADFUNCS) $(SOURCES) || true
# Clear screen for unspammy terminals
cls:
clear

How do I force make to recompile?
Two options:
touch all source files
If you are using GNU make, make --always-make

Related

Makefile can't find input files in specified directory

I am working with the following Makefile:
CFLAGS=-g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG $(OPTFLAGS)
LIBS=-ldl $(OPTLIBS)
PREFIX?=/usr/local
SOURCES=$(wildcard src/lcthw/*.c src/*.c)
OBJECTS=$(patsubst %.c,%.o,$(SOURCES))
TEST_SRC=$(wildcard tests/*_tests.c)
TESTS=$(patsubst %.c,%,$(TEST_SRC))
TARGET=build/libYOUR_LIBRARY.a
SO_TARGET=$(patsubst %.a,%.so,$(TARGET))
all: $(TARGET) $(SO_TARGET) tests
dev: CFLAGS=-g -Wall -Isrc -Wall -Wextra $(OPTFLAGS)
dev: all
$(TARGET): CFLAGS += -fPIC
$(TARGET): build $(OBJECTS)
ar rcs $# $(OBJECTS)
ranlib $#
$(SO_TARGET): $(TARGET) $(OBJECTS)
$(CC) -shared -o $# $(OBJECTS)
build:
#mkdir -p build
#mkdir -p bin
# The Unit Tests
.PHONY: tests
tests: CFLAGS += $(TARGET)
tests: $(TESTS)
sh ./tests/runtests.sh
valgrind:
VALGRIND="valgrind --log-file=/tmp/valgrind-%p.log" $(MAKE)
# The Cleaner
clean:
rm -rf build $(OBJECTS) $(TESTS)
rm -f tests/tests.log
find . -name "*.gc*" -exec rm {} \;
rm -rf `find . -name "*.dSYM" -print`
install: all
install -d $(DESTDIR)/$(PREFIX)/lib/
install $(TARGET) $(DESTDIR)/$(PREFIX)/lib/
And I'm having trouble with this line:
$(CC) -shared -o $# $(OBJECTS)
I am getting the error:
cc: fatal error: no input files
when I try and run any of the following commands: make, make all and make dev. Why can't my makefile find the .c files in the directories I specified?
You need to specify the full paths in this line:
SOURCES=$(wildcard src/lcthw/.c src/.c)
OTW this becomes a constraint on where you can run the make command from. Possibly what's happening is that the wildcards are not being expanded since the directory you are sitting in, $(CURDIR) , makes it hard for it to see these paths.
You should try printing these variables from inside your makefile, by doing:
$(info source=$(SOURCES))
And if your .obj files are placed in a different location than the sources, then you need to account for that by including that place in the $(OBJECTS) as well.

makefile skips making the build directory

I want all my build files stored in a build directory inside the project root folder. Though, I don't want to have to rebuild all of the files if I add a debug flag. Thus, I have two directories .build_release and .build_debug. Then I make a symbolic link from build to the proper directory.
I want all of this to be handled by make. Here is my makefile:
## setup
ifdef DEBUG
BUILDDIR=.build_debug
else
BUILDDIR=.build_release
endif
BLACKLIST:=bayesP obsDataStats test3 test bayesPsamplesBR test2 tuneSp \
toyFeatures2Multi getCov getDist isConnected mergeClusters sample \
toyFeatures0 toyFeatures1 toyFeatures2 toyFeatures3 toyFeatures4 \
toyFeatures6 toyFeatures7 wnsFeatures0 wnsFeatures1 wnsFeatures2
## make code
PROGS:=$(shell find ./src/ -maxdepth 1 -name "*.cpp" -exec grep -l "int main" {} \;)
PROGS:=$(notdir $(basename $(PROGS)))
PROGS:=$(filter-out $(BLACKLIST),$(PROGS))
CPP_SRC:=$(wildcard src/*.cpp)
CPP_SRC:=$(notdir $(basename $(CPP_SRC)))
CPP_SRC:=$(filter-out $(PROGS) $(BLACKLIST),$(CPP_SRC))
PROGS:=$(PROGS:=.bin)
PROGS:=$(PROGS:%=$(BUILDDIR)/%)
CPP_SRC:=$(CPP_SRC:%=src/%.cpp)
CPP_OBJ:=$(CPP_SRC:src/%.cpp=$(BUILDDIR)/%.o)
LIB=$(BUILDDIR)/libspatialDecisionMaking.so
## test code
CPP_SRC_TEST:=$(wildcard src/test/*.cpp)
CPP_SRC_TEST:=$(notdir $(basename $(CPP_SRC_TEST)))
CPP_SRC_TEST:=$(filter-out $(BLACKLIST),$(CPP_SRC_TEST))
PROGS_TEST:=$(CPP_SRC_TEST:%=$(BUILDDIR)/test/%.bin)
CPP_OBJ_TEST:=$(CPP_SRC_TEST:%=$(BUILDDIR)/test/%.o)
CPP_SRC_TEST:=$(CPP_SRC_TEST:%=src/test/%)
## options
CC=g++-4.9
ifdef DEBUG
CPP_FLAGS=-std=c++11 -ggdb
else
CPP_FLAGS=-std=c++11 -O3
endif
LD_FLAGS=-Isrc -L$(BUILDDIR) -lgsl -larmadillo -fPIC -fopenmp
## rules
all: | $(BUILDDIR) $(LIB) $(PROGS) build
test: | $(BUILDDIR)/test $(LIB) $(PROGS_TEST) build
build: $(BUILDDIR)
ln -rfs $(BUILDDIR) build
$(BUILDDIR)/test: $(BUILDDIR)
mkdir $(BUILDDIR)/test
$(BUILDDIR):
mkdir $(BUILDDIR)
$(BUILDDIR)/%.bin: src/%.cpp $(LIB)
$(CC) $(CPP_FLAGS) -o $# $< $(LD_FLAGS) -l$(LIB:$(BUILDDIR)/lib%.so=%)
ln -rfs $# $(#:%.bin=%)
$(LIB): $(CPP_OBJ)
$(CC) $(CPP_FLAGS) -o $# $^ $(LD_FLAGS) -shared
$(BUILDDIR)/%.o: src/%.cpp $(BUILDDIR)/%.d
$(CC) $(CPP_FLAGS) -c $< -o $# $(LD_FLAGS)
$(BUILDDIR)/%.d: src/%.cpp
$(CC) $(CPP_FLAGS) -MM $< -MT $(#:%.d=%.o) > $# $(LD_FLAGS)
%.cpp:
%.hpp:
# include dependencies
-include $(CPP_OBJ:%.o=%.d)
clean:
rm -rf $(BUILDDIR)
Though, it seems to skip making $(BUILDDIR). I delete the directories before I run make every time and it goes directly to building the dependency makefiles based on the rules for target $(BUILDDIR)/%.d. However, it naturally complains when trying to build the dependencies because $(BUILDDIR) doesn't exist.
Any ideas why it would be skipping the recipe for making $(BUILDDIR)?
As I have one more question on SO than answers, so I had to find a question to answer :) , and you seemed to not like the answer that was already there, so OK, even though your question was not "minimal", I spent an hour to work on it.
Your Makefile is not bad generally, but it does not follow a number of "good practices". Once I tidied everything up, all the problems disappeared. I hope it helps you to learn from this example - how I changed your original makefile to follow good practices.
The only little problem left, is that build is always relinked every time. This is because normally Make does not "depend" on variable values (such as DEBUG), only on files. It is possible to fix that (in this small case it does not matter much, but maybe later you will need this solution), by creating "dependable variables". See my answer at
How do I force a target to be rebuilt if a variable is set?
Below is the complete working makefile, I put comments on changes outside the code.
## setup
use := when you can
ifdef DEBUG
BUILDDIR:=.build_debug
else
BUILDDIR:=.build_release
endif
do not use find to list files, better declare files explicitly
PROGS:=\
prog0 \
prog1 \
CPP_SRC:=\
spam \
eggs \
CPP_SRC_TEST:=\
spam_test \
eggs_test \
split off link targets, so only the target is created in a rule:
PROG_LINKS:=$(addprefix $(BUILDDIR)/, $(PROGS))
PROGS:=$(PROGS:=.bin)
PROGS:=$(PROGS:%=$(BUILDDIR)/%)
CPP_SRC:=$(CPP_SRC:%=src/%.cpp)
CPP_OBJ:=$(CPP_SRC:src/%.cpp=$(BUILDDIR)/%.o)
LIB:=$(BUILDDIR)/libspatialDecisionMaking.so
PROGS_TEST:=$(CPP_SRC_TEST:%=$(BUILDDIR)/test/%.bin)
PROGS_TEST_LINKS:=$(addprefix $(BUILDDIR)/test, $(CPP_SRC_TEST))
## options
CC=g++-4.9
you are confusing CPP_FLAGS and LD_FLAGS, I put correct flags in each
also, your method of finding your shared library, is too complicated, I made it simple
CPP_FLAGS:= -std=c++11 -Isrc -fPIC -fopenmp
ifdef DEBUG
CPP_FLAGS+= -ggdb
else
CPP_FLAGS+= -O3
endif
LD_FLAGS:= -L$(BUILDDIR) -lgsl -larmadillo
## rules
you have too many dependencies - list only those that are conceptually needed for the target at hand, and recurse
all: | $(PROGS) $(PROG_LINKS) build
test: | $(PROGS_TEST) $(PROGS_TEST_LINKS) build
link file does not depend on the link target in any way
in your case, it depends on the value of DEBUG really, but like I said above, it is not super-easy to implement that, so I skipped it here and have a phony instead, which relinks all the time
.PHONY: build
build:
ln -srf $(BUILDDIR) $#
this is the best way to handle directory creation
%/.:
mkdir -p $(#D)
unfortunately, this is needed, because mkdir -p is not re-entrant and subject to race conditions
$(BUILDDIR)/test/.: | $(BUILDDIR)/.
.SECONDEXPANSION:
$(PROGS_TEST_LINKS) $(PROG_LINKS): %: | %.bin
ln -sr $| $#
all non-trivial recipes should depend on this makefile, change Makefile to whatever is correct (there is a more complicated way, to handle this automatically)
$(BUILDDIR)/%.bin: src/%.cpp $(LIB) Makefile | $$(#D)/.
$(CC) $(CPP_FLAGS) -o $# $< $(LD_FLAGS) $(LIB)
$(LIB): $(CPP_OBJ) Makefile | $$(#D)/.
$(CC) $(CPP_FLAGS) -o $# $(CPP_OBJ) $(LD_FLAGS) -shared
this is the most efficient way to handle "automatic" dependency generation - it invokes the preprocessor only once, not twice as in your original makefile
I put this in quotes, because the whole method of automatic dependencies, is subtly flawed and cannot work in all cases - but in your simple case it is very unlikely you will run into that subtle flaw
Yes I am violating the good practice I mentioned above - only target created in rule. If one understands what a good practice is for, and still thinks better to violate it, then OK.
$(BUILDDIR)/%.o: src/%.cpp Makefile | $$(#D)/.
$(CC) $(CPP_FLAGS) -MMD -MP -c $< -o $# $(LD_FLAGS)
# include dependencies
-include $(CPP_OBJ:%.o=%.d)
clean:
rm -rf $(BUILDDIR)
The .d, .o, and .bin files logically depend on $(BUILDDIR), so tell make that's the case
$(BUILDDIR)/%.d: src/%.cpp | $(BUILDDIR)

Makefile: How write a rule that is only executed when a certain shared object library doesn't exist?

I am trying to write a rule, which should only execute if a certain shared object library doesn't exist
$(OUTDIR)/libv8-$(ARCH).so: v8
v8: # to be able to build V8 only with "make v8"
cd V8; bash V8Update.sh
However, V8Update.sh is executed every time. Here is the full Makefile:
CC=g++
V8INCLUDEDIR=V8/build/v8/include
CFLAGS=-c -Wall -std=c++0x -fPIC -I$(V8INCLUDEDIR) -I/usr/include -I/usr/include/c++/4.6 \
-I/usr/include/c++/4.6/backward -I/usr/include/c++/4.6/x86_64-linux-gnu -I/usr/include/x86_64-linux-gnu \
-I/usr/lib/gcc/x86_64-linux-gnu/4.6/include -I/usr/lib/gcc/x86_64-linux-gnu/4.6/include-fixed \
-I/usr/local/include -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include/
DEPS=ProxyTypes.h $(V8INCLUDEDIR)/v8.h $(V8INCLUDEDIR)/v8-debug.h $(V8INCLUDEDIR)/v8stdint.h
ARCH=x64 # TODO: Add support for building 32-bit libraries.
LDFLAGS=-shared -lglib-2.0 -L/usr/lib/x86_64-linux-gnu/ #-Wl,--no-undefined
SOURCES=Exports.cpp FunctionTemplateProxy.cpp HandleProxy.cpp ObjectTemplateProxy.cpp Utilities.cpp V8EngineProxy.cpp \
ValueProxy.cpp
OBJECTS=$(patsubst %,$(OUTDIR)/%,$(SOURCES:.cpp=.o))
LIBRARY=libV8_Net_Proxy.so
.PHONY: all v8 release debug makeoutdir clean copybin
all: debug copybin
v8: # to be able to build V8 only with "make v8"
cd V8; bash V8Update.sh
release: OUTDIR=bin/Release
debug: OUTDIR=bin/Debug
release debug:
$(MAKE) -S makeoutdir $(LIBRARY) OUTDIR=$(OUTDIR)
makeoutdir:
mkdir -p $(OUTDIR)
clean:
rm bin/ -rf
# rm V8/build -rf
copybin:
cp -a bin/Debug/*.so ../bin/Debug
$(LIBRARY): $(OUTDIR)/libv8-$(ARCH).so $(OBJECTS)
$(CC) $(LDFLAGS) -lv8-$(ARCH) -L$(OUTDIR) -o $(patsubst %,$(OUTDIR)/%,$#) $(OBJECTS)
$(OUTDIR)/libv8-$(ARCH).so: v8
$(OUTDIR)/%.o: %.cpp $(DEPS)
$(CC) $(CFLAGS) -o $# $<
What am I doing wrong here?
It should be
v8: $(OUTDIR)/libv8-$(ARCH).so
$(OUTDIR)/libv8-$(ARCH).so:
cd V8; bash V8Update.sh
You can't depend on phony target - it will be executed every time (and that is a feature, btw).

What's the proper lib variable for a makefile?

Running into trouble with libraries in makefiles again. Every time I try to get back into C make gives me a pain with libs.
make -pf /dev/null says the correct vars should be LDLIBS and LOADLIBES but the following doesn't alter the run command at all:
LOADLIBES=testing
LDFLAGS=testing
LDLIBS=testing
Needless to say this gives me errors because the -L flags don't end up in the command. Anyone know what's going on?
Full makefile below (Derivitave of Z Shaw's makefile)
OPTLIBS=$(xml2-config --libs)
OPTFLAGS=$(xml2-config --cflags)
STD=c99
CFLAGS=-std=$(STD) -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG $(OPTFLAGS)
LDLIBS=-ldl $(OPTLIBS)
PREFIX?=/usr/local
SOURCES=$(wildcard src/**/*.c src/*.c)
OBJECTS=$(patsubst %.c,%.o,$(SOURCES))
TEST_SRC=$(wildcard tests/*_tests.c)
TESTS=$(patsubst %.c,%,$(TEST_SRC))
TARGET=build/lib.a
SO_TARGET=$(patsubst %.a,%.so,$(TARGET))
# The Target Build
all: cls $(TARGET) $(SO_TARGET) tests
dev: CFLAGS=-std=$(STD) -g -Wall -Isrc -Wall -Wextra $(OPTFLAGS)
dev: all
$(TARGET): CFLAGS += -fPIC
$(TARGET): build $(OBJECTS)
ar rcs $# $(OBJECTS)
ranlib $#
$(SO_TARGET): $(TARGET) $(OBJECTS)
$(CC) -shared -o $# $(OBJECTS)
build:
#mkdir -p build
#mkdir -p bin
# The Unit Tests
$(TESTS): $(TARGET)
.PHONY: tests
tests: LDLIBS += $(TARGET)
tests: $(TESTS)
sh ./tests/runtests.sh
valgrind:
VALGRIND="valgrind --log-file=/tmp/valgrind-%p.log" $(MAKE)
# The Cleaner
clean: cls
rm -rf build $(OBJECTS) $(TESTS)
rm -f tests/tests.log
find . -name "*.gc*" -exec rm {} \;
rm -rf `find . -name "*.dSYM" -print`
# The Install
install: all
install -d $(DESTDIR)/$(PREFIX)/lib/
install $(TARGET) $(DESTDIR)/$(PREFIX)/lib/
# The Checker
BADFUNCS='[^_.>a-zA-Z0-9](str(n?cpy|n?cat|xfrm|n?dup|str|pbrk|tok|_)|stpn?cpy|a?sn?printf|byte_)'
check:
#echo Files with potentially dangerous functions.
#egrep $(BADFUNCS) $(SOURCES) || true
# Clear screen for unspammy terminals
cls:
ifdef TERM
clear
endif
You aren't using LDFLAGS, etc in your link command. Make that something along the lines of:
$(SO_TARGET): $(TARGET) $(OBJECTS)
$(CC) -shared $(LDFLAGS) -o $# $(OBJECTS) $(LDLIBS)
It tells the linker to link the dl library, which is located at /usr/lib/libdl.so. -l is the switch to add a library, dl is the name of it (without the lib prefix or .so extension).
This library includes functions for dynamically loading shared libraries.

Makefiles: Get .cpp from one directory and put the compiled .o in another directory

I'm working on a cross-platform 2D engine for mobile devices (Windows Mobile 6 and Android). My Windows version is pretty much ready, but I still need to make sure the same functionality is available on Android.
What I want is one Makefile in the root of the project and several Makefile's for the project itself and the test applications.
Makefile
---Engine
------Makefile
------src
------bin
------intermediate
---Tests
------TestOne
---------Makefile
---------src
---------bin
---------intermediate
------TestTwo
---------Makefile
---------src
---------bin
---------intermediate
I'm basing my attempts on the following Makefile:
include ../makeinclude
PROGS = test1
SOURCES = $(wildcard *.cpp)
# first compile main.o and start.o, then compile the rest
OBJECTS = main.o start.o $(SOURCES:.cpp=.o)
all: $(PROGS)
clean:
rm -f *.o src
test1: $(OBJECTS)
$(LD) --entry=_start --dynamic-linker system/bin/linker -nostdlib -rpath system/lib -rpath $(LIBS) -L $(LIBS) -lm -lc -lui -lGLESv1_CM $^ -o ../$#
acpy ../$(PROGS)
.cpp.o:
$(CC) $(CFLAGS) -I $(GLES_INCLUDES) -c $*.cpp $(CLIBS)
However, I'm not very good with these things. What I want is for it to take the .cpp's that are in the src folder, compile them to .o and put them in the intermediate folder and, finally, compile the .o's to the compiled exe and put it in the bin folder.
I've managed to get clean to work like this:
cd intermediate && rm -f *.o
However, I can't get it to retrieve the .cpp's, compile them and put them in the intermediate folder.
I've looked at several other Makefiles, but none do the things I want to do.
Any help is appreciated.
There's more than one way to do this, but the simplest is to run in TestOne, making Intermediate/foo.o out of Src/foo.cpp and test1 out of Intermediate/foo.o, like this:
# This makefile resides in TestOne, and should be run from there.
include makeinclude # Adjust the path to makeinclude, if need be.
PROG = bin/test1
SOURCES = $(wildcard Src/*.cpp)
# Since main.cpp and start.cpp should be in Src/ with the rest of
# the source code, there's no need to single them out
OBJECTS = $(patsubst Src/%.cpp,Intermediate/%.o,$(SOURCES))
all: $(PROG)
clean:
rm -f Intermediate/*.o bin/*
$(PROG): $(OBJECTS)
$(LD) $(BLAH_BLAH_BLAH) $^ -o ../$#
$(OBJECTS): Intermediate/%.o : Src/%.cpp
$(CC) $(CFLAGS) -I $(GLES_INCLUDES) -c $&lt $(CLIBS) -o $#

Resources