I have the following directory structure:
.
..
./Graphic/
./Graphic/SymbolXLib
There are several other directories in this project but I won't list them for simplicities sake.I want a main makefile that drives the build of other Makefiles stored in their own directories. There are several project comming together, so I can't just move source around.
The main makefile is defined as:
[mehoggan#hogganz400 Core]$ cat ./Makefile
CORE_LIBS_DIR = libs
OBJS_DIR = obj/symb_obj
include ./Graphic/SymbolXLib/Makefile
The Graphic makefile is defined as:
#
# make BUILD_MODE={release|debug} OS_ARCH={32|64}
#
# default is 32-bit release build
#
BUILD_MODE = release
OS_ARCH = 64
OBJS_DIR = $(BUILD_MODE)$(OS_ARCH)
SRC = \
./Graphic/SymbolXLib/CartoCursor.cpp \
...
./Graphic/SymbolXLib/TextureConversion.cpp \
$(NULL)
CC = gcc -fPIC
OBJS = $(SRC:%.cpp=$(OBJS_DIR)/%.o)
COPTS = -m$(OS_ARCH) -O2
CDEFS = -DLINUXx86 \
-I../../../SharedArcGIS/Include/GraphicsPipeline/Display/SymbolX/SymbolXLib \
-I../../../SharedArcGIS/Include/System/Geometry/GeometryXLib \
-I../../../ArcSDE/pe/include \
-I../../../ArcSDE/shape/include
CFLAGS = $(COPTS) $(CDEFS) $(CINCS)
TARGET = libSymbolXLib.a
all : $(OBJS_DIR) $(OBJS_DIR)/$(TARGET)
$(OBJS_DIR) :
mkdir -p $(OBJS_DIR)
$(OBJS_DIR)/$(TARGET) : $(OBJS)
ar qc $# $^
$(OBJS_DIR)/%.o : %.cpp
$(CC) -c $(CFLAGS) -o $# $<
The response at the previous post (Previous Post) helped only if I moved alot of things around. I can't do this. So the question still remains, how do I get make to recognize the implicit build in a subdirectory from the main Makefile?
The error I am getting is
make: *** No rule to make target `release64/./Graphic/SymbolXLib/CartoCursor.o', needed by `release64/libSymbolXLib.a'. Stop.
I have to think you'd have far better success if you avoided include and instead use recursive make. In the top-level Makefile, something like:
graphic:
$(MAKE) -C Graphic
And the Makefile in Graphic/Makefile can have its sub-projects:
symbolxlib:
$(MAKE) -C SymbolXLib
and so on. You might need to add each of the targets to a default target or something similar to hang them all together on a single execution. You could give each of these targets an actual dependency (they should be .PHONY: if they don't have a dependency...) to rebuild them only when necessary or when commanded to by an upper-level target that touch(1)es "command files".
Alternatively, this paper recommends a different approach to avoid recursive make, but I've not yet read it -- and have found recursive make works well enough in projects I've been a part of that I don't mind recommending it.
Does this gnumake documentation help you?
Related
I am trying to write a makefile in a subdirectory of my eclipse makefile project.
MyProject \
test.cpp
Build\
Makefile
I am also trying to create a generic makefile. I am having trouble defining the targets since the build is not happening in the same directory as the source.
CC = g++
CC_FLAGS = -g3
EXEC = test
SOURCEDIR = ..
SOURCES = $(shell find $(SOURCEDIR) -name '*.c' -o -name '*.cpp')
OBJECTS = $(addsuffix .o,$(subst ../,,$(SOURCES)))
.DEFAULT_GOAL = all
$(EXEC): $(OBJECTS)
$(CC) $(OBJECTS) -o $(EXEC)
%.o: %.cpp
$(CC) -c $(CC_FLAGS) $< -o $#
.PHONY: clean
clean:
rm -f $(EXEC) $(OBJECTS)
.PHONY: all
all: $(EXEC)
Right now when I build I get the error...
make all
make: *** No rule to make target 'test.cpp.o', needed by 'test'. Stop.
Can anyone tell me why this is not working or recommend a better approach.
If you change your dependency from object to source as follows:
%.cpp.o: $(SOURCEDIR)/%.cpp
it seems to work.
In general I would prefer to NOT do anything in a build dir, because I personally expect a build dir is a temporary dir which can be removed completely for distribution which is not the case if the Makefile resists there. But this is a matter of taste.
Also I do not prefer to use all c/cpp you find as objects/sources in the make process. If you need to add files for different variants in your projects, you enter a nightmare to change all these things later.
And also as a hint: Typically objects are <basename>.o and not <basename>.cpp.o
And another one:
Users expect that the clean target also remove the executable. If not, you will never see a rebuild by simply do make clean; make, because the executable is in place and all dependencies are fulfilled.
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 have two different directories with two different C++ source codes each of them execute different program. Directories have their own Makefiles each of them builds scripts with certain environment variables set.
Now, I want to put both directories' contents into a single directory as I want to mix both C++ source codes in order to develop a new C++ source code that utilizes both programs capabilities.
So far, I placed all files in a single directory, and I can successfully build each of the original source codes when I place the corresponding Makefile. Now, I want to have a single Makefile that allows me to build each of the original source codes (without replacing the Makefile), and hopefully this would allow me to build the new mixed C++ source file...
I tried a trivial solution and I placed the contents of both Makefiles into a single Makefile and this didn't work ...
I think it is useful to post my two Makefiles
Here is the first one
# A simple $(MAKE)file to cause make to go look in the top directory. A simple
# convenience.
all: lib
$(MAKE) -C .. examples
lib:
$(MAKE) -C .. lib/libAria.so
%.so: ../lib/libAria.so %.cpp
$(MAKE) -C .. examples/$#
%: ../lib/libAria.so %.cpp
$(MAKE) -C .. examples/$#
%Static: ../lib/libAria.a %.cpp
$(MAKE) -C .. examples/$#
clean:
$(MAKE) -C .. cleanExamples
../lib/libAria.so: FORCE
$(MAKE) -C .. dirs lib/libAria.so
../lib/libAria.a: FORCE
$(MAKE) -C .. dirs lib/libAria.a
FORCE:
.PHONY: all FORCE clean lib
And the second Makefile is
LDLIBS = -lm
CXXFLAGS = -O3 -finline-functions -I. -I./qpoases/INCLUDE -I./qpoases/SRC
CFLAGS = -O3
CC = g++
OBJECTS = \
./qpoases/SRC/QProblemB.o \
./qpoases/SRC/Bounds.o \
./qpoases/SRC/Constraints.o \
./qpoases/SRC/SubjectTo.o \
./qpoases/SRC/Indexlist.o \
./qpoases/SRC/CyclingManager.o \
./qpoases/SRC/Utils.o \
./qpoases/SRC/MessageHandling.o \
./qpoases/solver.o \
integrator.o \
condensing.o \
gauss_newton_method.o
.PHONY: all
all: test libacado_exported_rti.a
test: ${OBJECTS} test.o
./qpoases/solver.o : ./qpoases/solver.hpp
integrator.o : acado.h
condensing.o : acado.h
gauss_newton_method.o : acado.h ./qpoases/solver.hpp
test.o : acado.h ./qpoases/solver.hpp
libacado_exported_rti.a: ${OBJECTS}
ar r $# $?
${OBJECTS} : ./qpoases/solver.hpp
.PHONY : clean
clean :
-rm -f *.o *.a ./qpoases/SRC/*.o ./qpoases/SRC/*.a test
I check all stackoverflow questions related to my question and the only closest situation to mine is a question titled (multiple makefiles in one directory);however, this is not exactly what I want to do...
Thanks a lot !
Why would you want to merge your source directories? I assume they are seperated for a reason. Instead, I'd leave them be and create a new make file in the directory above them that calls each of the sub makes files below it - either via includes or via shelling directly to each makefile. I would not mix the code just to make it "easier" to get inheritance or whatever working.
BTW, here's a link for you:Stack Overflow shows you how
I'm updating some Makefiles to move from Make 3.81 to 3.82. In multiple places, the original author used something like this to build static libs:
all: lib$(library).a($objects)
This seems to build each .o file in turn and insert it into the .a using ar:
g++ -O2 <snip> -o some_obj.o some_cpp.cpp
ar rv libsome_lib.a some_obj.o
etc...
This new make version, though, chokes with:
*** No rule to make target 'libsome_lib.a()', needed by 'all'
Am I safe to replace this shortcut with the way I'm used to doing this:
lib$(library).a: $(objects)
ar -rs lib$(library).a $objects
Thanks.
EDIT
Looks like I need a better Makefile education. Here's a larger excerpt from the original Makefile:
CXXFLAGS += -O2 -g -Wall -Wunused-parameter \
`pkg-config --cflags gthread-2.0 glibmm-2.4 gtkmm-2.4`
libs += `pkg-config --libs gthread-2.0 glibmm-2.4` -lc
%.d: %.cpp
$(SHELL) -ec '$(CXX) -M $(CPPFLAGS) $(CXXFLAGS) $< \
| sed '\''s/\($*\)\.o[ :]*/\1.o $# : /g'\'' > $#; \
[ -s $# ] || rm -f $#'
%.d: %.c
$(SHELL) -ec '$(CXX) -M $(CPPFLAGS) $(CXXFLAGS) $< \
| sed '\''s/\($*\)\.o[ :]*/\1.o $# : /g'\'' > $#; \
[ -s $# ] || rm -f $#'
from_sources = $(patsubst %.c,$(2),$(filter %.c, $(1))) $(patsubst %.cpp,$(2),$(filter %.cpp, $(1)))
sources = $(shell cat sources.inc)
objects = $(call from_sources,$(sources),%.o)
depends = $(call from_sources,$(sources),%.d)
library = some_lib
.PHONY: all clean fresh
all: lib$(library).a($(objects))
clean:
<SNIP>
if neq($(MAKECMDGOALS),clean)
include $(depends)
endif
When this runs under 3.81, I get all the .d dependences created, then make starts g++ing the obj files. Under 3.82, I get the .d files but no .o and make fails with "***No rule to make..."
This is the "archive member" syntax supported in gnu make. It's a bit too intimate with the tools for my tastes, but there it is. The original error may be caused by $(objects) being empty. But I'm really not sure. Here's some documentation:
http://www.gnu.org/software/make/manual/make.html#Archive-Members
11.1 Archive Members as Targets
An individual member of an archive file can be used as a target or
prerequisite in make. You specify the member named member in archive
file archive as follows:
archive(member)
This construct is available only in targets and prerequisites, not in recipes! Most programs that you might use in
recipes do not support this syntax and cannot act directly on archive
members. Only ar and other programs specifically designed to operate
on archives can do so. Therefore, valid recipes to update an archive
member target probably must use ar. For example, this rule says to
create a member hack.o in archive foolib by copying the file hack.o:
foolib(hack.o) : hack.o
ar cr foolib hack.o
In fact, nearly all archive member targets are updated in just this way and there is an implicit rule to
do it for you. Please note: The ācā flag to ar is required if the
archive file does not already exist.
Your way looks good, but there must be more to the old makefile if the old way worked at all.
Oh, and just for good form I'd suggest this:
lib$(library).a: $(objects)
ar -rs $# $^
EDIT
Don't feel bad about not understanding Make very well; it has quite a learning curve.
There is still not quite enough to go on here, but if sources.inc isn't too huge, you could try the following in 3.81 and 3.82 and look for differences:
experiment:
#echo sources: $(sources)
#echo objects: $(objects)
#echo depends: $(depends)
The evidence so far is that objects is empty under 3.82, but if the .d files are being rebuilt under 3.82 that suggests that depends is not empty, which is very strange.
Possibly, but you have no explicit rule for converting something like xyz.cpp to xyz.o, which you may need for your sources before trying to inject their objects into the library. There may be a suitable implicit rule for this so check first.
The first question I'd be asking is: what happened to $objects that caused you to try and target libsome_lib.a() (i.e., with nothing between the parentheses) in the first place?
To be honest, I tend to avoid these encompassing rules as much as possible, preferring explicit statements of dependencies (unless there are a lot of dependencies, of course). Yes, I know it makes the makefiles larger and marks me as at least a partial luddite, but I prefer to have things that just work over things that work cleverly.
Cut'n'paste is one of the strongest tools in my toolbox :-)
Here are my two questions:
I am now learning to manage my code with CVS, and I just want to make a repository for my C++ files, Makefile and bash and python scripts only, not the object files and executables. So I made several subdirectories under my project directory: src, bin, scripts, results and data.
I put C++ files and Makefile under ~/myproject/src, Bash and Python scripts under ~/myproject/scripts and object and executables under ~/myproject/bin. I am hoping only the files under src and scripts will be updated via CVS. I wonder how you organize your projects? Just hope to follow some good habits.
Since I put my C++ files and Makefile into ~/myproject/src and object and executable files into ~/myproject/bin, I have to specify the directories in Makefile. Here is what I am doing
Makefile:
...
BIN_DIR=/home/myproject/bin/
all: $(BIN_DIR)myexecutable TAGS
TAGS: *.cc *.h
etags --members --declarations -l c++ *.cc *.h
$(BIN_DIR)myexecutable: $(BIN_DIR)myobject.o
$(CXX) $(CXXFLAGS) -o $# $^ $(LDFLAGS)
Makefile.depend: *.h *.cc Makefile
$(CXX) -M $(CXXFLAGS) *.cc > Makefile.depend
clean:
\rm -f $(BIN_DIR)myexecutable $(BIN_DIR)*.o Makefile.depend TAGS`
However this will give error
make: *** No rule to make target /home/myproject/bin/myobject.o', needed by /home/myproject/bin/myexecutable'.
How to specify a different directory for object and executable files from C++ files in Makefile?
If you want to learn make, the GNU make manual is very good, both as a reference and a tutorial. You might want to consider using the patsubst command. The following is a chopped down version of one of my own makefiles that uses it:
OUT = bin/csvfix.exe
CC = g++
IDIR = inc
ODIR = obj
SDIR = src
INC = -Iinc -I../alib/inc
LIBS = ../alib/lib/alib.a -lodbc32
_OBJS = csved_atable.o \
csved_case.o \
csved_cli.o \
csved_command.o \
csved_date.o \
OBJS = $(patsubst %,$(ODIR)/%,$(_OBJS))
$(ODIR)/%.o: $(SDIR)/%.cpp
$(CC) -c $(INC) -o $# $< $(CFLAGS)
$(OUT): $(OBJS)
$(CC) -o $# $^ $(CFLAGS) $(LIBS)
strip $(OUT)
clean:
rm -f $(ODIR)/*.o $(OUT)
You can keep your files in different directories if you like, but that isn't necessary. Add a file or directory to the CVS repository once, and CVS will retain it indefinitely. From then on you can update it, check it in, whatever. If you don't add an object file to the repository, CVS won't touch it. If you want to add a whole directory tree, and you're in the habit of keeping objects there, just make clean before you do it.
Make is a wonderful tool, but it has some glaring faults. What you're describing is one of the classic problems: Make is good at using a source there to make something here, but not the other way around. Here are a couple of ways to do what you're trying to do.
A) Run make in your binary directory:
...
all: myexecutable TAGS
myexecutable: myobject.o
$(CXX) $(CXXFLAGS) -o $# $^ $(LDFLAGS)
VPATH = /home/myproject/src
...
cd ~/myproject/bin
make -f ../src/makefile
B) Put the objects on the bin directory by brute force:
$(BIN_DIR)%.o: %.cc
$(CXX) $(CXXFLAGS) -c -o $# $^
This will give you a problem with Makefile.depend, which you can approach several ways.
C) Learn some more advanced Make techniques. You probably shouldn't try this yet.
Your directory structure seems sensible.
I would make an explicit rule for executing the compiler, like
TARGET_DIR=bin
SRC_DIR=src
CXX=g++
CXXFLAGS=
ETC=
OBJS=$(TARGET_DIR)/test.o
all: $(OBJS)
$(TARGET_DIR)/%.o: $(SRC_DIR)/%.cc
$(CXX) -c -o $# $(CXXFLAGS) $(ETC) $<
Use automake and autoconf for building your project.
As for the structure of files just look at any big open-source C++ application. Any KDE application
will do fine for that matter. If you find an application that uses C++ and Python even better.
Why not go for eclipse, which is quite popular and handy for managing large projects. You can make a new project in eclipse, import-export code into the project from other projects, does version control for you as well etc. No need to write your make files, eclipse does it for you with your mentioned preferences in GUI.
If you are involved in a C++ project, just install the CDT plugin over eclipse and your are done.