I am trying to make a project using a library named BigInt. My file structure is:
/Users/wen/Projects/challenge/fibonacci3/fibonacci3.cpp
/Users/wen/Projects/challenge/fibonacci3/Makefile
/Users/wen/Projects/include/bigint/<.cc files and .hh files>
/Users/wen/Projects/include/bigint/Makefile
The Fibonacci3 Makefile is as of
LD_FLAGS =
CC_FLAGS =
# Include libraries
include /Users/wen/Projects/include/bigint/Makefile
# Build object files
%.o: %.cc %.cpp $(library-cpp)
g++ -c -o $# $(CC_FLAGS)
# Link object files
fibonacci3: fibonacci3.o $(library-objects)
g++ -o $# $(LD_FLAGS)
and the bigint Makefile is as of (shortened)
# Mention default target.
all:
# Implicit rule to compile C++ files. Modify to your taste.
%.o: %.cc
g++ -c -O2 -Wall -Wextra -pedantic $<
# Components of the library.
library-cpp = \
BigUnsigned.cc \
BigInteger.cc \
BigIntegerAlgorithms.cc \
BigUnsignedInABase.cc \
BigIntegerUtils.cc \
library-objects = \
BigUnsigned.o \
BigInteger.o \
BigIntegerAlgorithms.o \
BigUnsignedInABase.o \
BigIntegerUtils.o \
library-headers = \
NumberlikeArray.hh \
BigUnsigned.hh \
BigInteger.hh \
BigIntegerAlgorithms.hh \
BigUnsignedInABase.hh \
BigIntegerLibrary.hh \
however, make reports that it could not find a rule for a header file?
make: *** No rule to make target `NumberlikeArray.hh', needed by `BigUnsigned.o'. Stop.
[Finished in 0.0s with exit code 2]
What is happening here? Headers are supposed to be included, not compiled, so why is make asking for one?
Thanks in advance!
Solution:
Instead of including the makefile, compile the sources in my own makefile. It worked! Thanks again.
The make program expects all files to be in the current directory. Since you include the second makefile into the current makefile, all files in that are relative to the current directory as well. You have to make sure that the files in the included makefile contains the correct paths.
Make gives this error when it cannot find a dependency; it then tries to build that dependency, but knows no rule to make this header file.
You might have mistyped the header file's name.
Related
I'm attempting to integrate an L2CAP server (in C - uses BlueKitchen's btstack) with a UDP server (in C++). To start, I've attempted to just add the code from the L2CAP server into the "main.cpp" file of the UDP server. I included all of the relevant C libraries and headers using extern "C" {...}. At first, I'd get errors on the include statements for the btstack files. I solved this by modifying the make file to include "INC = -I./directory/...". Next, I dealt with problems the g++ compiler found with the pasted C code (ex. adding spaces between literals and strings). After resolving those, it seems that none of the bstack files/functions are being linked properly as this is what I get when I attempt to "make":
"undefined reference to 'every single btstack function call in main.cpp'
My makefile. Note that a lot of this is probably unnecessary/does nothing. I was just trying anything and everything and borrowing lines from the btstack port makefile and seeing if they'd work.
CORE += \
btstack_chipset_bcm.c \
btstack_chipset_bcm_download_firmware.c \
btstack_control_raspi.c \
btstack_link_key_db_tlv.c \
btstack_run_loop_posix.c \
btstack_tlv_posix.c \
btstack_uart_posix.c \
btstack_slip.c \
hci_dump_posix_fs.c \
hci_transport_h4.c \
hci_transport_h5.c \
le_device_db_tlv.c \
main.c \
wav_util.c \
btstack_stdin_posix.c \
raspi_get_model.c \
rijndael.c
.INCLUDE : home/pi/udpDemo/inc/btstack-master/example/Makefile.inc
CC=g++
CFLAGS=-Wall -Wextra -pedantic -std=c++11
SRC=$(wildcard ./src/*.cpp)
OBJ=$(patsubst ./src/%.cpp, ./obj/%.o, $(SRC))
INC=-I./inc \
-I./inc/btsrc \
-I./inc/btsrc/ble \
-I./inc/btsrc/ble/gatt-service \
-I./inc/platform/embedded \
-I./inc/platform/posix \
-I./inc/chipset/bcm \
-I./inc/3rd-party/tinydir \
-I./inc/3rd-party/rijndael \
-I./inc/port/raspi \
-I./src
LDFLAGS += -lrt
VPATH += src
VPATH += inc/3rd-party/rijndael
VPATH += inc
VPATH += inc/btsrc \
VPATH += inc/btsrc/ble \
VPATH += inc/btsrc/ble/gatt-service \
VPATH += inc/platform/embedded \
VPATH += inc/platform/posix \
VPATH += inc/chipset/bcm \
VPATH += inc/3rd-party/tinydir \
VPATH += inc/3rd-party/rijndael \
VPATH += inc/port/raspi \
LIBS=
TARGET=test
bindir=/usr/local/bin
$(TARGET):$(OBJ)
$(CC) -o $# $^ $(CFLAGS)
$(OBJ):./obj/%.o:./src/%.cpp
$(CC) $(CFLAGS) -c $^ -o $# -I$(INC)
clean:
rm -rf $(TARGET) $(OBJ)
install:$(TARGET)
install -g root -o root $(TARGET) $(bindir)/$(TARGET)
uninstall:$(bindir)/$(TARGET)
rm $(bindir)/$(TARGET)
It looks like there are both makefile issues and compile issues here. Solving both at the same time is hard. Below is a simplified and commented (but untested) version of your makefile that might be a good starting point for you.
Your original makefile looks like it was including a lot of stuff from the btstack build system. It's usually not a good idea to mesh two separate projects together like that, both for technical and licensing reasons. The typical way to use third-party code is to compile that code into a library and then have your code link against that library. You'll have to consult the documentation for btstack for details on how to do that, I'm not familiar with that particular library.
# Which compiler to use
CC=g++
# Options to pass to the compiler
CFLAGS=-Wall -Wextra -pedantic -std=c++11
# Options to pass to the linker
LDFLAGS=-Wall -Wextra
LDFLAGS+=-lbtstack # Link with 'libbtstack.a'
LDFLAGS+=-L/path/to/btstack # Where to find the btstack libraries that were built separately
# Source files to compile (everything in 'src' directory)
SRC=$(wildcard src/*.cpp)
# Convert names of source files into their corresponding object files
OBJ=$(patsubst src/%.cpp, obj/%.o, $(SRC))
# Directories where headers are kept
INC=-Isrc
INC+=-I/path/to/btstack/headers
# Name of the program
TARGET=test
# Rule for linking the .o files together to build the program
$(TARGET): $(OBJ)
$(CC) $(LDFLAGS) -o $# $^
# Rule for making a .o file from a .cpp file
obj/%.o: src/%.cpp
$(CC) $(CFLAGS) -c $^ -o $# -I$(INC)
# Rule for deleting output and temporary files
clean:
rm -rf $(TARGET) $(OBJ)
This will compile all the .cpp files in your src directory and link them with libbtstack.a to create a program named test. After you build the btstack library, update the LDFLAGS and INC variables with the actual paths to the btstack library and headers, respectively.
I'm currently working on an SDL2 project and the directory is structured in the following way
./
|__assets
| |__*.png
|__src
| |__physcis
| |_*.cpp *.hpp
| |__textures
| |_obstacles
| |_*.cpp *.hpp
| |_constants
| |_*.cpp *.hpp
|
|__Makefile
Currently, my makefile has a very simple structure
Makefile:
ROOTDIR=src/
TXTURDIR = src/textures/constant/
OBSTACLEDIR = src/textures/obstacles/
PHYSDIR = src/physics/
OBJS = $(ROOTDIR)Main.cpp \
$(ROOTDIR)WindowInit.cpp \
$(ROOTDIR)Timer.cpp \
$(ROOTDIR)GameLoop.cpp \
$(PHYSDIR)Gravity.cpp \
$(TXTURDIR)Texture.cpp \
$(TXTURDIR)TextureContainer.cpp \
$(TXTURDIR)Ball.cpp \
$(TXTURDIR)Bob.cpp \
$(TXTURDIR)Text.cpp \
$(TXTURDIR)ScoreCounter.cpp \
$(TXTURDIR)FPSCounter.cpp
CC = g++
COMPILER_FLAGS = -g -o
LINKER_FLAGS = -lSDL2 -lSDL2_image -lSDL2_ttf
OUT = exe
all: $(OUT)
$(OUT): $(OBJS)
$(CC) $(COMPILER_FLAGS) $# $^ ${LINKER_FLAGS}
clean:
rm exe
Is there any way to speed my making process up by only compiling certain folders when there is a change and then linking compiled sections together afterwards?
Yes, this is the exact thing Makefiles are designed to do. Here's a set of changes to your existing Makefile that will do it:
Change your OBJS variable to refer to .o files instead of .cpp files. This turns your existing compilation rule into a link rule.
OBJS = $(ROOTDIR)Main.o \
$(ROOTDIR)WindowInit.o \
$(ROOTDIR)Timer.o \
# ... etc ...
Make already knows how to create .o files from the .cpp files, thanks to its built-in set of implicit rules. However, you do need to adjust your configuration variable names to what Make's implicit rules expect. Don't put the -o option in the compiler flags, Make will add that itself.
# _instead of_ setting CC, COMPILER_FLAGS, LINKER_FLAGS
CXX = g++
CXXFLAGS = -g
LIBS = -lSDL2 -lSDL2_image -lSDL2_ttf
Adjust the link rule to match the adjusted variable names. (You don't have a CPPFLAGS right now but you may want it in the future.)
$(OUT): $(OBJS)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $# $^ $(LIBS)
At the bottom of the file, add a set of rules without recipes, specifying the individual dependencies of each object file. This is how you arrange for things to get rebuilt when you change your header files, and it also works around a misfeature where sometimes Make will delete object files immediately after they are used. (For a project this size, it's easiest to keep track of which source files use which header files manually. When it gets big enough that you want to have the computer deal with that for you, look into automake.)
$(ROOTDIR)Main.o: $(ROOTDIR)Main.cpp foo.h bar.h
$(ROOTDIR)WindowInit.o: $(ROOTDIR)WindowInit.cpp foo.h bar.h
# ... etc ...
Change the clean target to clean up the object files as well (and while you're at it, use -rm -f instead of bare rm).
clean:
-rm -f $(OUT) $(OBJS)
Add a .PHONY annotation at the very bottom of the file: this is not strictly necessary but will prevent weird things from happening if you ever have a file named 'all' or 'clean' for some reason:
.PHONY: all clean
And that's it, you're done.
I need that a Makefile that someone else previously provided be able to compile .C files with .CPP files. At the time this Makefile was created, we didn’t have any .C files in the project, but that has changed so I modified the Makefile as follows:
GPP=g++
CPPSRCS= \
./CBDefault.cpp \
./testPFDefault.cpp \
./PFDefault.cpp \
./xapiDebug.cpp \
./init.cpp \
./tracePriorityManager.c \
CFLAGS= -O0 -g3 -Wall -c -fmessage-length=0 -std=c++0x -IASB -IALU
-Istub -IIKAN
OBJ_DIR=../build/pxy/obj
OBJS := $(foreach s,$(CPPSRCS:.cpp=.o),$(OBJ_DIR)/$(notdir $s))
PROG=../build/pxy/pxy
$(PROG): $(OBJS) | $(dir $(PROG))
$(GPP) -o $# $(OBJS)
$(OBJ_DIR):
mkdir -p $#
$(foreach src,$(CPPSRCS),$(eval $(OBJ_DIR)/$(notdir $(src:.cpp=.o)):
CSRC=$(src)))
$(OBJS): | $(OBJ_DIR)
$(GPP) $(CFLAGS) -c -o $# $(CSRC)
Adding tracePriorityManager.c to the list of CPPSRCS macros.
Compilation results in a long list of error messages with the following content:
../build/pxy/obj/tracePriorityManager.c:10:3607: warning: null
character(s) ignored
../build/pxy/obj/tracePriorityManager.c:10:3618: warning: null
character(s) ignored
../build/pxy/obj/tracePriorityManager.c:10: error: stray ?\1? in program
../build/pxy/obj/tracePriorityManager.c:10:3620: warning: null
character(s) ignored
Can you suggest a change in the Makefile that would fix the problem?
You should create a different variable for C sources and compile it with gcc and CFLAGS.
Look at your rule - it transforms *.cpp to *.o, but doesn't talk about *.c.
I resolved the issue another way:
I changed the name of the .c file to .cpp and encompassed the source file content in extern "C" { ..file content.. }
Also changed the file name in Makefile from .c to .cpp and resolved the issue.
Assuming that you share the same the ld and compile flags for both your c++ and c compilation.
CSRC = CSOURCE FILES
or just
CSRC := $(wildcard *.c)
OBJS += $(foreach s,$(CSRCS:.c=.o),$(OBJ_DIR)/$(notdir $s))
as far as I know g++ can compile gcc files without a problem.
Edit: need to use wildcard function to actually get the list of files.
my mistake about g++ and c. Only linking is not problematic. You will have to use another set files of OBJC and use gcc explicitly in another rule to compile them. Just make sure to sum all objects file in OBJ and link against g++.
I really suggest using implicit rules to compile c and c++ and just adding a rule for linking.
Regarding the characters warning. Im throwing a longshot guess, but might have it anything to with the charset expected from the file? Im not sure, but id try to copy paste the content to a new file on my computer and recompile it.
I have a script which generates multiple C++ .h and .cpp files, based on a configuration file. This script also generates a file called 'Makefile.inc', and this file contains a variable with the required object filenames, for the generated .cpp files.
Example of a Makefile.inc file (all paths are absolute):
MESSAGE_OBJS = \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/error-message.o \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/challenge-request-message.o \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/challenge-response-message.o \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/login-message.o \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/get-game-list-message.o \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/game-list-response-message.o \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/join-game-message.o \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/connect-to-game-message.o \
/scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/leave-game-message.o
Using the answer in this question as base, I created the following Makefile:
# Include the generated makefile for messages.
# This includes a variable with all message targets
include atlarge/messages/Makefile.inc
# Create a variable with all source targets
LIBOBJS = \
atlarge/exceptions.o \
atlarge/message-factory.o \
atlarge/envelope.o \
atlarge/client.o \
atlarge/user.o \
atlarge/atlarge-protocol.o \
atlarge/atlarge-gameserver.o \
$(MESSAGE_OBJS)
CXXFLAGS += -W -Wall -I. -g -O3 -MD \
`pkg-config jansson --cflags` \
`libgcrypt-config --cflags` \
`pkg-config glib-2.0 --cflags` \
-fPIC -DDEBUG -DENABLE_LOGGING
PREFIX = /usr/local
# TODO use pkg-config for jansson
LDLIBS += -lm -ljansson -latlarge-util `libgcrypt-config --libs` `pkg-config glib-2.0 --libs`
LDFLAGS += -shared -L/usr/local/lib
# Include automatically generated dependencies
-include $(LIBOBJS:.o=.d)
all: libatlarge.so
# If the message Makefile doesn't exist yet, generate it
atlarge/messages/Makefile.inc: atlarge/messages/messages.conf
python ../common/messagegen.py -o ./atlarge/messages/ atlarge/messages/messages.conf
libatlarge.so: $(LIBOBJS)
$(CXX) $(LDFLAGS) -o $# $^ $(LDLIBS)
clean:
#rm -f *.o
#rm -f atlarge/*.o
#rm -f atlarge/messages/*.o
#rm -f atlarge/messages/*.cpp
#rm -f atlarge/messages/*.h
#rm -f atlarge/messages/Makefile.inc
#rm -f atlarge/*.d
#rm -f atlarge/messages/*.d
#rm -f *.d
#rm -f ../common/*.d
#rm -f ../common/*.o
#rm -f *.a
#rm -f *.so
#rm -f tags
install: libatlarge.so
#install -m 0644 $^ $(PREFIX)/lib
#install -m 0755 -d $(PREFIX)/include/atlarge
#install -m 0755 -d $(PREFIX)/include/atlarge/messages
#install -m 0644 -D atlarge/*.h $(PREFIX)/include/atlarge
#install -m 0644 -D atlarge/messages/*.h $(PREFIX)/include/atlarge/messages
#ldconfig
#echo "Installed"
.PHONY: all clean install splint messages
As you can see, I first include the generated Makefile.inc. Then a variable with all library object files is defined, and this variable makes use of the variable declared in the generated Makefile.inc. After that some variables with compiler flags are declared.
To make use of Makefile remaking, I included a target rule for the generated Makefile.inc, so if the dependency of Makefile.inc (the configuration file) is newer than Makefile.inc, it gets regenerated, and Make will restart itself.
So this is the goal:
Check if Makefile.inc needs to be (re)generated.
Include it
Use the variable inside Makefile.inc in the $LIBOBJS variable in the main Makefile.
And this actually works. If I update the messages.conf file, Make detects that, and will run the python script. It will then restart itself, include the new Makefile.inc, and then proceed with compiling.
But here comes the part that doesn't work: if I don't update the messages.conf file, but only .h or .cpp files which are by default in the $LIBOBJS list, Make will not proceed to compile.
For example, if alter client.cpp and no other files, I get the following error:
make: `atlarge/exceptions.o' is up to date.
Well yeah, great you found out that exceptions.o is up to date, but I altered client.cpp, so why don't you start compiling that one? Why does make quit immediatly after seeing that the first target in LIBOBJS is up to date?
Who knows what's causing this, and what could be a solution? Is there maybe a better way to handle code generation with makefiles?
Thanks in advance.
NB: I also use dependency files generated by gcc, and that was working fine before I added the code generation, so I don't think that's a problem.
You need to move the all target to come BEFORE the include. Make always builds the first target it sees in the makefile unless you give a specific target on the command line. Since the include comes before any target, the first target defined in Makefile.inc will be the default target and when you run make that's the one that will be built. That's why it tries to build exceptions.o and then stops. If you run make all explicitly, it will work as you expect.
Where is the dependency for the object files on the source files
or the header files? There is an implicit rule which should
pick up the dependencies if the .cpp file is in the same
directory as the .o, but if they're not, you'll have to
provide your own, or use VPATH (see §4.5.1 in the manual). And
you also need to generate the dependencies for the includes, see
§4.1.4 in the manual.
I have a project for which I regularly modify headers and when I do so, and forget to make clean then make, I get all sorts of weird behavior. I'm currently using Qt Creator as my IDE, but I've seen this happen on a Qt-independent project. My project is getting fairly large, and having to rebuild every time I make a header change is becoming unproductive. Any thoughts?
For future reference:
If using the QMake system:
DEPENDPATH += . \
HeaderLocation1/ \
HeaderLocation2/ \
HeaderLocation2/HeaderSubLocation1/ \
HeaderLocation2/HeaderSubLocation2/ \
HeaderLocation2/HeaderSubLocation3/ \
HeaderLocation2/HeaderSubLocation4/ \
HeaderLocation2/HeaderSubLocation5/ \
HeaderLocation3/ \
HeaderLocation3/HeaderSubLocation1/ \
HeaderLocation3/HeaderSubLocation2/ \
Re-run qmake. This will generate a new Makefile which will have proper dependencies.
Example:
A file file.h looking like the following:
#include "some.h"
#include "header.h"
#include "files.h"
...
and file.cpp looking like the following:
#include "file.h"
...
and having in your .pro:
HEADERS += file.h some.h header.h files.h
SOURCES += file.cpp
will produce the following in the resulting Makefile:
file.o: ../src/file.cpp ../src/file.h \
../src/some.h \
../src/header.h \
../src/files.h
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o file.o ../src/file.cpp
Dont know anything about your IDE, and not sure if its relevant, and since you are not including your makefile - I'll just state the obvious - do you use any auto-generated dependencies?
For g++ I use the -MD flag, then in the makefile include $(wildcard bin/*.d) (depending on where your object file is created, mine are created in 'bin')
Also make sure to delete the dep file on a clean build
The solution is to have proper header dependency's in your makefile.
1) Use makedepend to generate the dependency files. You would add a target to your makefile which regenerates the dependency file, and you'd want to invoke that before actually doing your compilation.
2) GCC only: Use '-MMD' and '-MP' options on your compile line for .c/.cpp files. This causes GCC to generate a dependency file for input file. Then, you can include these in your makefile. The advantage here is that with those two options, as you add and remove headers, it should behave as you expect.
This is mainly caused by dependencies between files. So if you alter a .h file which is included in another, that file will also need to be recompiled. So either you need to reduce your includes, or do your coding in .h/.cpp form when possible to make changes in .cpp more often than .h.
Here is an excerpt from my own makefile generating and using dependency files automatically created during compilation. You would have to make an additional entry for cpp files
%.o : %.c
$(CC) -M $(CFLAGS) -o $*.P $<
#cp $*.P $*.d; \
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < $*.P >> $*.d; \
rm -f $*.P
$(CC) $(CFLAGS) -c $< -o $#
-include *.d
Dont forget to add delete *.d files on clean build