Is is possible to instruct g++ to search a folder recursively for header files? In my example I would like g++ to search
/ARDrone_SDK_2_0_1/ARDroneLib/Soft/
and all subdirectories for header files. Can this be done? Here's a simple Makefile example:
C=g++
CFLAGS=-c -Wall
LDFLAGS=
INC1=/ARDrone_SDK_2_0_1/ARDroneLib/Soft/ <- can this be recursive?
INCDIRS= -I${INC1}
SOURCES=src/dronevid.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=build/dronevid
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $#
.cpp.o:
$(CC) $(CFLAGS) $(INCDIRS) $< -o $#
The question is a little confusing because you're conflating two different tools, make and g++.
There is no way to get g++ search all subdirectories of a given directory. Every directory you want to use to find an included file must be individually specified on the command line with a -I flag.
If you want to, you can get make to construct those arguments and put them on your command line. Assuming you're using GNU make, and a UNIX-like system that supports the find command, you can do something like this:
INCDIRS := $(addprefix -I,$(shell find /ARDrone_SDK_2_0_1/ARDroneLib/Soft -type d -print))
I should just say up-front, this is not really a good idea. You don't know what order those directories will show up in, and you don't know if there are multiple copies of the same header file in different directories that might cause problems.
Generally the way headers in subdirectories are expected to work is that you add the top-level directory to the compile line, then use relative paths in the #include line in your code. Something like:
#include <subdir/subsubdir/header.h>
Then add:
-I/top/level/dir
to the g++ compile line.
Related
I am creating a custom Makefile to to build a C++ Linux application. I have my cpp source files in a folder called src on the same level as the Makefile. So far I have been able to build my object files with the following :
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp | $(OBJ_DIR)
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $#
Now my project is starting to get a bit more complicated and I want subdirectories within src , such as src/common , and also, not every file is a cpp file now but also a c file.
I guess having a separate Makefile for each subdirectory is the best way but I am trying to keep this simple for now with just one Makefile.
I tried the following but doesn't work
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(SRC_DIR)/common/%.cpp $(SRC_DIR)/common/%.c | $(OBJ_DIR)
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $#
I could have the Makefile do a shell find to find all cpp and c files but also trying to avoid this.
I'd appreciate any recommendations.
This:
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(SRC_DIR)/common/%.cpp $(SRC_DIR)/common/%.c | $(OBJ_DIR)
cannot work; what it says that if make wants to build some file $(OBJ_DIR)/XXX.o and there is no explicit rule, then if and only if ALL the prerequisites $(SRC_DIR)/XXX.cpp, $(SRC_DIR)/common/XXX.cpp, and $(SRC_DIR)/common/XXX.c exist or can be created by make, then the rule will match.
If the same target could be built from multiple different prerequisites you must create multiple rules, one per prerequisite.
Also, it doesn't make sense to compile both C files (.c) and C++ files (.cpp) using the same recipe. C++ compilers use the variables CXX and CXXFLAGS and C compilers use the variables CC and CFLAGS.
As for avoiding find, you can't avoid informing make what files you want to be compiled, in some manner. You either have to list them in your makefile explicitly, or else use some method to generate them dynamically. There's no way around this. You don't have to use find if you don't want to; for example if you know that all the files will be either one or two directories down you could use wildcard, like:
SRCS := $(wildcard $(SRC_DIR)/*.cpp $(SRC_DIR)/*.c $(SRC_DIR)/*/*.cpp $(SRC_DIR)/*/*.c)
I'm tying to write a makefile, that should compile (and link) my program. For my program I have to use a bigger Libray with many .h and .cpp files, which comes in a specified filestructure(many other subdirectories)(I'm not allowed to change that stucture)
My main.cpp is included in the first directory which also includes the makefile. This.cpp file includes headers out of the bigger library. And here comes the problem, when i try to "make" the terminal says:" fatal error: .. .h: File or Directory not found" #include ".. .h"
BTW: I'm using Ubuntu 18.04.1 with Gcc and gnu-make
Sooo... I tried several things the last 5 days.
I tried to do it with a dependfile like this:
SRC = datei1.c datei2.c datei3.c datei4.c datei5.c
CC = /usr/bin/gcc
DEPENDFILE = .depend
dep: $(SRC)
$(CC) -MM $(SRC) > $(DEPENDFILE)
-include $(DEPENDFILE)
(Not sure if i made it the right way)
I was thinking of just including every single header file with include, but that would be waaay to much!
I guess the most powerful and useful thing till now was this URL:
Makefile: How to correctly include header file and its directory?.
That nearly described perfectly my problem, but it was just useful to include one single header file and not the whole library.
I guess it could be helpful to know how to correctly include a library. (Maybe try some ways over the PATH?)
Folder Sructure:
myproj
|
|____Makefile
|____main.cpp
|____init.cpp
|____end.cpp
|____init.h
|____end.h
|____Dependencies
|____biggerlib
|____src
|____include
|____biggerLib1
|____biggerLib2
|____biggerLib
|____biggerLibrary.h
|____Lib2.h
|____Lib3.h
|____AnotherDirWithFiles1
|____AnotherDirWithFiles2
|____AnotherDirWithFiles3
|____etc.
#include in file:
#include "biggerLib/biggerLibrary.h"
I really do'nt know what to do anymore!
#Compiler directory
CC = gcc
#directories
SDCC = /home/myname/myproj/Dependencies/biggerlib/src
SDCH = /home/myname/myproj/Dependencies/biggerlib/include/biggerLib # normally ere are a few files and more directories!
#Dependenfile
#DEPENDFILE = .depend
#dep: $(SDCC)
# $(CPP) -MM $(SDCC) > $(DEPENDFILE)
#-include $(DEPENDFILE)
#C-Flags for object-compiling
CFLAGS = -c -I$(SDCH)/.. #ugly!
#Deps including every single one? too much work!
#DEPS = $(SDCH)/biggerlibfile.h
#Libs for Compiler
#LIBS = -lSDCH
#Loading object list
include objects.mk
#Main-target (linking)
$(NAME) : $(OBJECTS)
$(CC) -o $(NAME) #$+ $(LIBS)
#Object-targets
%.o : %.cpp #$(DEPENDFILE) #$(DEPS)
$(CC) -o $# $< $(CFLAGS)
Edit:
The single header file is working, but how do i include all the other header files in the even deeper directories? do I really need to include them all the same way? I need to include every Header behind "include".
I hope u guys understand my problem!:)
Looking forward to your suggestions and tips!
I'm trying to clean up my project a little and I want to put object files and include files in a separate folder and be able to compile another makefile in my a different testing subdirectory. I would like to do this so that the make file in the testing directory doesn't have to know about the objects in the the above directory: I have been struggling all day trying to figure out make and compilation.
Not sure what I'm doing wrong but in addition to this question I would be appreciative of any information to straighten out my thinking about make and g++ so in the future I know where to look.
Anyways I have 2 Questions both with regards to my project layout:
Project
inc/
-- header files
-obj/
--object files
-source
-make file for project that compiles objects in obj directory (makefile0)
-testing/
--test1/
---test.cc
---makefile1
Question 1
So I want to include the header files in the inc directory in test.cc and then just focus on compiling test.cc like I would if I included a standard library header file. Right now I need to make reference to the object in ../../obj/ in makefile1 and would like to ignore that. and just do something simple like
g++ -I ../../inc/ -c test.cc
How is it possible to do this?
Question 2
In makefile0, for each source file I have to append a $(OBJ) or $(INC) to the front of any file I have in those folders and wondering if there is anyway to clean up my make file an do something like
Spinless2DFieldIndex.o: Spinless2DFieldIndex.cc Utils.o Dispersion.h
instead of
$(ODIR)/Spinless2DFieldIndex.o: Spinless2DFieldIndex.cc $(ODIR)/Utils.o $(INC)/Dispersion.h
The following should work:
Project/Makefile
objdir := obj/
vpath %.cc source
vpath %.o $(objdir)
CPPFLAGS := -Iinc -MMD -MP
.PHONY: all
all: testing/test1/test
include source/Makefile
include testing/test1/Makefile
Project/source/Makefile
override objects := $(objdir)obj.o
$(objects): $(objdir)%.o: %.cc
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(OUTPUT_OPTION) $<
clean:: ; $(RM) $(objects) $(objects:.o=.d)
-include $(objects:.o=.d)
Project/testing/test1/Makefile
override dir := $(dir $(lastword $(MAKEFILE_LIST)))
$(dir)test: obj.o
clean:: ; $(RM) $(dir)test $(dir)test.d
-include $(dir)test.d
This should allow for a certain amount of modularity, although the asymmetry in the makefiles betrays the fact that your idea of having a separate obj directory while at the same time wanting to have the test executables in their own directory is perhaps not the best way to organize things. Personally I use a more configure style of makefile that recreates the project tree in the current working directory which helps separate the source from the build.
I have a number of C++ files distributed in several folders.
a_library/
file1.cpp
file2.cpp
category1/
file3.cpp
file4.cpp
They are guaruanteed to be uniquely named. I want to compile all those C++ files to seperate Object-files in the obj/ directory.
I have a list of all source-files with relative path, and their corresponding destination-names.
a_library/file1.cpp
a_library/file2.cpp
a_library/category1/file3.cpp
a_library/category1/file4.cpp
obj/file1.obj
obj/file2.obj
obj/file3.obj
obj/file4.obj
How can I make a rule that will convert a C++ file from the first list to a object-file from the second one?
These attempts do not work:
obj/%.obj: %:cpp
# ...
%.obj: %.cpp
# ...
.cpp.obj:
# ...
I would like to not write rules like this:
obj/%.obj: a_library/%.cpp
# ...
obj/%.obj: a_library/category1/%.cpp
# ...
Try setting VPATH:
VPATH = a_library:a_library/category1
obj/%.o: %.cpp
$(CXX) -c $(CPPFLAGS) $(CFLAGS) $(CXXFLAGS) -o $# $<
And to add complete file list (I would recommend you explicitely list the files, do not use $(wildcard ...) function) and linking of the application:
files := main.cpp $(wildcard a_library/*.cpp) a_library/category1/file.cpp
obj/application: $(patsubst %.cpp,obj/%.o,$(notdir $(files)))
$(CXX) $(CFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $# $+
The $(wildcard) has an annoying tendency to pick up anything in the directories, like one-off test files or temporaries (if they happen to have a fitting name: ~file.cpp).
One solution I can think of: just build them inplace with a simple rule and then make a "collection phase" moving the ".o" files to a single folder.
Make a "collect_objs" target which depends on your $(OBJS) and then your "main" target must depend on "collect_objs".
The traversal can be done using shell
dirs := $(shell find ./ -type d)
collect_objs: $(dirs)
for d in $+; do \
mv *.o YourDestDir/*.o
done
Of course, this implies using UnxUtils package (with 'find' and 'mv') or Cygwin since you are on Windows.
The other option is to generate the targets for each of your .c/.cpp file explicitly, using some tool. Grab python, traverse source directories and for each .c/.cpp file write
obj/file_name.o:
gcc -c path/fo/file_name.c -o obj/file_name.o
Use cmake to make the build configuration for you.
Some time ago I set up a simple example project on github.
The standard way is to have a Makefile in each folder and call recursively with include
This was my first two hits on 10^100:
http://owen.sj.ca.us/~rk/howto/slides/make/slides/makerecurs.html
http://www.gnu.org/savannah-checkouts/gnu/make/manual/html_node/Recursion.html
Not strictly related to this question as it doesn't have to do with Make, though I'd like to show how I compile my projects now, 3 years later. Craftr is a Python based meta build system that encourages indirect out-of-tree builds (eg. a build in the working tree). Building object files and cresting a static library is as easy as
# craftr_module(my_project)
from craftr import *
from craftr.ext.platform import cxx, ar
objects = cxx.compile(
sources = path.platform('**/*.cpp'),
)
lib = ar.staticlib(
output = 'myproj',
inputs = [objects],
)
Running craftr -eb will result with the following structure of build products
Craftfile
file1.c
file2.c
category1/
file3.c
file4.c
build/
my_project/
obj/
file1.o
file2.o
category1/
file3.o
file4.o
libmyproj.a
New to C++; Basic understanding of includes, libraries and the compile process. Did a few simple makefiles yet.
My current project involves using an informix DB api and i need to include header files in more than one nonstandard dirs. How to write that ? Havent found anything on the net, probably because i did not use good search terms
This is one way what i tried (not working). Just to show the makefile
LIB=-L/usr/informix/lib/c++
INC=-I/usr/informix/incl/c++ /opt/informix/incl/public
default: main
main: test.cpp
gcc -Wall $(LIB) $(INC) -c test.cpp
#gcc -Wall $(LIB) $(INC) -I/opt/informix/incl/public -c test.cpp
clean:
rm -r test.o make.out
You have to prepend every directory with -I:
INC=-I/usr/informix/incl/c++ -I/opt/informix/incl/public
You need to use -I with each directory. But you can still delimit the directories with whitespace if you use (GNU) make's foreach:
INC=$(DIR1) $(DIR2) ...
INC_PARAMS=$(foreach d, $(INC), -I$d)
Make's substitutions feature is nice and helped me to write
%.i: src/%.c $(INCLUDE)
gcc -E $(CPPFLAGS) $(INCLUDE:%=-I %) $< > $#
You might find this useful, because it asks make to check for changes in include folders too