Header in subfolder not found - linux

my compiler does not found a header in a subfolder included in a cpp file
#include "comm\ComPublic.h"
My master makefile :
SUB_POUET=Pouet \
PouetTech \
PouetPrivate
all: $(SUB_POUET)
PouetTech:
#(cd PouetTech && $(MAKE))
Pouet:
#(cd Pouet && $(MAKE))
PouetPrivate:
#(cd PouetPrivate && $(MAKE))
.PHONY: clean mrproper $(SUB_POUET)
clean:
#(cd $(SUB_POUET) && $(MAKE) $#)
mrproper: clean
#(cd $(SUB_POUET) && $(MAKE) $#)
Sub-makefile1 :
include ../Definitions.mif
SRC=$(wildcard *.cpp)
OBJ_FILES=$(addprefix $(OBJECTS_DIR)/,$(notdir $(SRC:.cpp=.o)))
INCLUDES=-I../PouetTech -I../../libs/MPSSE -I../../libs/FTDI/$(OS) -I../shared -I../../libs/libmodbus-3.0.6/src
CXXFLAGS+=$(INCLUDES)
all: $(OBJ_FILES)
$(OBJECTS_DIR)/%o: %cpp | objects_dir
$(CXX) -o $# -c $< $(CXXFLAGS)
objects_dir:
mkdir -p $(OBJECTS_DIR)
.PHONY: clean mrproper
clean:
rm -rf *.o
Sub-makefile 2
include ../Definitions.mif
SRC=$(wildcard *.cpp)
OBJ_FILES=$(addprefix $(OBJECTS_DIR)/,$(notdir $(SRC:.cpp=.o)))
INCLUDES=-I../PouetTech -I../Pouet -I../shared
CXXFLAGS+=$(INCLUDES)
all: $(OBJ_FILES)
$(OBJECTS_DIR)/%o: %cpp | objects_dir
$(CXX) -o $# -c $< $(CXXFLAGS)
objects_dir:
mkdir -p $(OBJECTS_DIR)
.PHONY: clean mrproper
clean:
rm -rf *.o
Sub-makefile 3 is identical to 2.
And my folder are like this:
src
|_makefile
|_Pouet
| |_makefile
|_PouetTech
| |_makefile
|_PouetPrivate
| |_makefile
|_shared
|_comm
|_ComPublic.h
The problem appears during the 3rd makefile (PouetPrivate), but the folder "shared" is included in the makefile.
If I add -I../shared/comm to the makefile and change the include to #include "ComPublic.h" it works. But I dont want to include manually all folder in the makefile.
It's probable just a simple mistake, but I dont have much experience in makefile
Furthermore, its working fine when using mingw / msys under windows or Visual Studio
Edit : and I have the same issue with another subfolder of "comm"

If the include directive in your source is #include "comm\ComPublic.h" as you've written, the problem is simply that you're using the Windows path delimeter \. Linux (and g++) want / and won't recognise the path.
Fortunately, Visual C++ will accept both delimiters so / can be used throughtout.

Related

Linux make command is deleting a source file

I have inherited a project file that has a Makefile in it that is doing something I have never seen before--It is injecting a rm command. I cannot find any reason for the rm command, so I am missing something very obvious or very esoteric.
Thanks
The results of running make are:
bison --defines --xml --graph=calc.gv -o calc.c calc.y
Bison flags =
cc -c -o calc.o calc.c
Making BASE = calc
cc -o calc calc.o
Done making BASE
rm calc.c <======== WHERE IS THIS COMING FROM?
The Makefile is:
BASE = calc
BISON = bison
XSLTPROC = xsltproc
all: $(BASE)
%.c %.h %.xml %.gv: %.y
$(BISON) $(BISONFLAGS) --defines --xml --graph=$*.gv -o $*.c $<
#echo "Bison flags = " $(BISONFLAGS)
$(BASE): $(BASE).o
#echo "Making BASE = " $(BASE)
$(CC) $(CFLAGS) -o $# $^
#echo "Done making BASE"
run: $(BASE)
#echo "Type arithmetic expressions. Quit with ctrl-d."
./$<
html: $(BASE).html
%.html: %.xml
$(XSLTPROC) $(XSLTPROCFLAGS) -o $# $$($(BISON) --print-datadir)/xslt/xml2xhtml.xsl $<
CLEANFILES = $(BASE) *.o $(BASE).[ch] $(BASE).output $(BASE).xml $(BASE).html $(BASE).gv
clean:
#echo "Running clean" $(CLEANFILES)
rm -f $(CLEANFILES)
See https://www.gnu.org/software/make/manual/make.html#Chained-Rules:
The second difference is that if make does create b in order to update something else, it deletes b later on after it is no longer needed. Therefore, an intermediate file which did not exist before make also does not exist after make. make reports the deletion to you by printing a rm -f command showing which file it is deleting.

how to write recipe for the makefile in yocto

I am trying to add this package called sane-airscan to my yocto build. My experience with yocto is very basic.I do not know how to write a recipe for this one
This is the MakeFile for the above mentioned one
# USER-SETTABLE VARIABLES
#
# The following variables can be overridden by user (i.e.,
# make install DESTDIR=/tmp/xxx):
#
# Name Default Description
# ---- ------- -----------
# DESTDIR Destination directory for make install
# PREFIX Non-standard: appended to DESTDIR
# CC gcc C compiler
# CPPFLAGS C preprocessor flags
# CFLAGS -O2 -g -W -Wall -Werror C compiler flags
# LDFLAGS Linker flags
# COMPRESS gzip Program to compress man page, or ""
# MANDIR /usr/share/man/ Where to install man page
CC = gcc
COMPRESS = gzip
CFLAGS = -O2 -g -W -Wall -Werror
MANDIR = /usr/share/man/
PKG_CONFIG = /usr/bin/pkg-config
# These variables are not intended to be user-settable
OBJDIR = objs/
BINDIR = /usr/bin
CONFDIR = /etc/sane.d
LIBDIR := $(shell $(PKG_CONFIG) --variable=libdir sane-backends)
BACKEND = libsane-airscan.so.1
DISCOVER = airscan-discover
LIBAIRSCAN = $(OBJDIR)/libairscan.a
MAN_DISCOVER = $(DISCOVER).1
MAN_DISCOVER_TITLE = "SANE Scanner Access Now Easy"
MAN_BACKEND = sane-airscan.5
MAN_BACKEND_TITLE = "AirScan (eSCL) and WSD SANE backend"
DEPENDS := avahi-client avahi-glib libjpeg libsoup-2.4 libxml-2.0
DEPENDS += libpng
# Sources and object files
SRC = $(wildcard airscan-*.c) sane_strstatus.c
OBJ = $(addprefix $(OBJDIR), $(SRC:.c=.o))
# Obtain CFLAGS and LDFLAGS for dependencies
airscan_CFLAGS = $(CFLAGS)
airscan_CFLAGS += -fPIC
airscan_CFLAGS += $(foreach lib, $(DEPENDS), $(shell pkg-config --cflags $(lib)))
airscan_LIBS := $(foreach lib, $(DEPENDS), $(shell pkg-config --libs $(lib))) -lm
airscan_LDFLAGS = $(LDFLAGS)
airscan_LDFLAGS += $(airscan_LIBS)
airscan_LDFLAGS += -Wl,--version-script=airscan.sym
# This magic is a workaround for libsoup bug.
#
# We are linked against libsoup. If SANE backend goes unloaded
# from the memory, all libraries it is linked against also will
# be unloaded (unless main program uses them directly).
#
# Libsoup, unfortunately, doesn't unload correctly, leaving its
# types registered in GLIB. Which sooner or later leads program to
# crash
#
# The workaround is to prevent our backend's shared object from being
# unloaded when not longer in use, and these magical options do it
# by adding NODELETE flag to the resulting ELF shared object
airscan_LDFLAGS += -Wl,-z,nodelete
$(OBJDIR)%.o: %.c Makefile airscan.h
mkdir -p $(OBJDIR)
$(CC) -c -o $# $< $(CPPFLAGS) $(airscan_CFLAGS)
.PHONY: all clean install man
all: tags $(BACKEND) $(DISCOVER) test test-decode
tags: $(SRC) airscan.h test.c test-decode.c
-ctags -R .
$(BACKEND): $(OBJDIR)airscan.o $(LIBAIRSCAN) airscan.sym
$(CC) -o $(BACKEND) -shared $(OBJDIR)/airscan.o $(LIBAIRSCAN) $(airscan_LDFLAGS)
$(DISCOVER): $(OBJDIR)discover.o $(LIBAIRSCAN)
$(CC) -o $(DISCOVER) discover.c $(CPPFLAGS) $(airscan_CFLAGS) $(LIBAIRSCAN) $(airscan_LIBS) -fPIE
$(LIBAIRSCAN): $(OBJ) Makefile
ar cru $(LIBAIRSCAN) $(OBJ)
install: all
mkdir -p $(DESTDIR)$(PREFIX)$(BINDIR)
mkdir -p $(DESTDIR)$(PREFIX)$(CONFDIR)
mkdir -p $(DESTDIR)$(PREFIX)$(CONFDIR)/dll.d
install -s -D -t $(DESTDIR)$(PREFIX)$(BINDIR) $(DISCOVER)
cp -n airscan.conf $(DESTDIR)$(PREFIX)$(CONFDIR)
cp -n dll.conf $(DESTDIR)$(PREFIX)$(CONFDIR)/dll.d/airscan
install -s -D -t $(DESTDIR)$(PREFIX)$(LIBDIR)/sane $(BACKEND)
mkdir -p $(DESTDIR)$(PREFIX)/$(MANDIR)/man5
install -m 644 -D -t $(DESTDIR)$(PREFIX)$(MANDIR)/man1 $(MAN_DISCOVER)
install -m 644 -D -t $(DESTDIR)$(PREFIX)$(MANDIR)/man5 $(MAN_BACKEND)
[ "$(COMPRESS)" = "" ] || $(COMPRESS) -f $(DESTDIR)$(PREFIX)$(MANDIR)/man1/$(MAN_DISCOVER)
[ "$(COMPRESS)" = "" ] || $(COMPRESS) -f $(DESTDIR)$(PREFIX)$(MANDIR)/man5/$(MAN_BACKEND)
clean:
rm -f test $(BACKEND) tags
rm -rf $(OBJDIR)
man: $(MAN_DISCOVER) $(MAN_BACKEND)
$(MAN_DISCOVER): $(MAN_DISCOVER).md
ronn --roff --manual=$(MAN_DISCOVER_TITLE) $(MAN_DISCOVER).md
$(MAN_BACKEND): $(MAN_BACKEND).md
ronn --roff --manual=$(MAN_BACKEND_TITLE) $(MAN_BACKEND).md
test: $(BACKEND) test.c
$(CC) -o test test.c $(BACKEND) -Wl,-rpath . ${airscan_CFLAGS}
test-decode: test-decode.c $(LIBAIRSCAN)
$(CC) -o test-decode test-decode.c $(CPPFLAGS) $(airscan_CFLAGS) $(LIBAIRSCAN) $(airscan_LIBS)
I tried generating recipe using devtool but not success with it. Can anybody help me write a recipe for this one. Thanks in advance
I'm the sane-airscan author :-), but I don't know anything about yocto. So, what is your problem?

Why does "make all" seem to skip "all:" rule?

I am trying to analyze the following makefile and reproduce its "behavior" step by step.
Although I type "make all" it seems this makefile skips the "all:" line and jumps straight to "build/*.o" (hence the echo's).
The file and its corresponding output:
TOOLCHAIN ?= arm-none-eabi-
SOURCES = Demo/main.c \
Demo/startup.c \
Demo/Drivers/rpi_gpio.c \
Demo/Drivers/rpi_irq.c \
Source/tasks.c \
Source/list.c \
Source/portable/GCC/RaspberryPi/port.c \
Source/portable/GCC/RaspberryPi/portisr.c \
Source/portable/MemMang/heap_4.c
OBJECTS = $(patsubst %.c,build/%.o,$(SOURCES))
INCDIRS = Source/include Source/portable/GCC/RaspberryPi \
Demo/Drivers Demo/
CFLAGS = -Wall $(addprefix -I ,$(INCDIRS))
CFLAGS += -D RPI2
CFLAGS += -march=armv7-a -mtune=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4
ASFLAGS += -march=armv7-a -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard
LDFLAGS =
.PHONY: all clean
all: $(MOD_NAME)
echo "in all"
$(MOD_NAME): $(OBJECTS)
echo "in mod name"
ld -shared $(LDFLAGS) $< -o $#
build/%.o: %.c
echo -e "\nin build/*.o:*.c\n"
mkdir -p $(dir $#)
$(TOOLCHAIN)gcc -c $(CFLAGS) $< -o $#
build/%.o: %.s
echo -e "in build/*.o:*.s\n"
mkdir -p $(dir $#)
$(TOOLCHAIN)as $(ASFLAGS) $< -o $#
all: kernel7.list kernel7.img kernel7.syms kernel7.hex
echo -e"in kernel all\n"
$(TOOLCHAIN)size kernel7.elf
kernel7.img: kernel7.elf
$(TOOLCHAIN)objcopy kernel7.elf -O binary $#
echo -e "in kernel7.img\n"
kernel7.list: kernel7.elf
echo -e "kernel7.list\n"
$(TOOLCHAIN)objdump -D -S kernel7.elf > $#
kernel7.syms: kernel7.elf
echo -e "kernel7.syms\n"
$(TOOLCHAIN)objdump -t kernel7.elf > $#
kernel7.hex : kernel7.elf
echo -e "kernel7.hex\n"
$(TOOLCHAIN)objcopy kernel7.elf -O ihex $#
kernel7.elf: $(OBJECTS)
echo -e "kernel7.elf\n"
$(TOOLCHAIN)ld $^ -static -Map kernel7.map -o $# -T Demo/raspberrypi.ld
clean:
rm -f $(OBJECTS)
rm -f kernel7.list kernel7.img kernel7.syms
rm -f kernel7.elf kernel7.hex kernel7.map
rm -rf build
echo -e "cleaning \n"
I tried to replicate this behaviour myself with a tiny piece of code. But it doesn't seem to work:
SOURCES = Demo/Drivers/rpi_irq.c \
Demo/Drivers/rpi_gpio.c
OBJECTS = $(patsubst %.c,build/%.o,$(SOURCES))
.PHONY: all clean
all: $(MOD_NAME)
echo "making all"$(SOURCES)
$(MOD_NAME): $(OBJECTS)
echo "MOD_NAME"
build/%.o:%.c
mkdir -p $(dir $#)
arm-none-eabi-gcc -march=armv7-a -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=har $< -o $#
As you can see thanks to the echo's my code just doesn't even build my source code. I'd expect it to go from all->MOD_NAME->build. (This is all the output I get)
So my questions are:
How does the makefile I am analyzing manage to go straight to build/*.o?
Why does my implementation, which I think should do the same doesn't even compile my source code?
The Makefile that you copied contains 2 rules for "all".
The first depends on $(MOD_NAME) which might be empty.
The second rule depends on multiple files "kernel7.*" which themselves depend on "kernel7.elf".
Finally "kernel7.elf" depends on $(OBJECTS).
This last rule is responsible that all your source files will be compiled.
The first rule with $(MOD_NAME) does not need to cause any compilation at all.
In your own Makefile you only have a rule for "all" depending on $(MOD_NAME).
If $(MOD_NAME) is empty in your Makefile as well, you do not have any dependency for "all" at all.
If "all" does not depend on anything, no source files will be compiled.
To solve your problem you need to provide some content for $(MOD_NAME).
all is trying to build $(MOD_NAME), which has dependencies of $(OBJECTS), which it is trying to build.
There are two all's here, which is a problem.

/bin/sh: Syntax Error: end of file unexpected

I am getting an error when running the following makefile with make -f makefile2 install (apart install the rest is working):
all:myapp
#which compiler
CC = gcc
#Where to install
INSTDIR = /usr/local/bin
#where are include files kept
INCLUDE = .
#Options for development
CFLAGS = -g -Wall -ansi
#Options for release
# CFLAGS = -O -Wall -ansi
myapp: main.o 2.o 3.o
$(CC) -o myapp main.o 2.o 3.o
main.o: main.c a.h
$(CC) -I$(INCLUDE) $(CFLAGS) -c main.c
2.o: 2.c a.h b.h
$(CC) -I$(INCLUDE) $(CFLAGS) -c 2.c
3.o: 3.c b.h c.h
$(CC) -I$(INCLUDE) $(CFLAGS) -c 3.c
clean:
-rm main.o 2.o 3.o
install: myapp
#if [ -d $(INSTDIR) ]; \
then \
cp myapp $(INSTDIR);\
chmod a+x $(INSTDIR)/myapp;\
chmod og-w $(INSTDIR)/myapp;\
echo "Installed in $(INSTDIR)";\
else
echo "Sorry, $(INSTDIR) does not exist";\
fi
I'm getting the following error:
error /bin/sh: 7: Syntax error: end of file unexpected
make: *** [install] Error 2
From what I understand it is a white space/tabulation/non unix character problem in the last lines of the makefile (after install:). But even trying to delete all spaces and replacing with tabulation I didn't manage to run the makefile properly. The code comes directly from a programming book I'm reading and is an example. Any help appreciated!
You're missing a trailing slash on your else under the install rule. It should be:
install: myapp
#if [ -d $(INSTDIR) ]; \
then \
cp myapp $(INSTDIR);\
chmod a+x $(INSTDIR)/myapp;\
chmod og-w $(INSTDIR)/myapp;\
echo "Installed in $(INSTDIR)";\
else\
echo "Sorry, $(INSTDIR) does not exist";\
fi

Makefiles with source files in different directories

I have a project where the directory structure is like this:
$projectroot
|
+---------------+----------------+
| | |
part1/ part2/ part3/
| | |
+------+-----+ +---+----+ +---+-----+
| | | | | | |
data/ src/ inc/ src/ inc/ src/ inc/
How should I write a makefile that would be in part/src (or wherever really) that could comple/link on the c/c++ source files in part?/src ?
Can I do something like
-I$projectroot/part1/src -I$projectroot/part1/inc -I$projectroot/part2/src ...
If that would work, is there an easier way to do it. I've seen projects where there is a makefile in each of the corresponding part? folders. [in this post I used the question mark like in bash syntax]
The traditional way is to have a Makefile in each of the subdirectories (part1, part2, etc.) allowing you to build them independently. Further, have a Makefile in the root directory of the project which builds everything. The "root" Makefile would look something like the following:
all:
+$(MAKE) -C part1
+$(MAKE) -C part2
+$(MAKE) -C part3
Since each line in a make target is run in its own shell, there is no need to worry about traversing back up the directory tree or to other directories.
I suggest taking a look at the GNU make manual section 5.7; it is very helpful.
If you have code in one subdirectory dependent on code in another subdirectory, you are probably better off with a single makefile at top-level.
See Recursive Make Considered Harmful for the full rationale, but basically you want make to have the full information it needs to decide whether or not a file needs to be rebuilt, and it won't have that if you only tell it about a third of your project.
The link above seems to be not reachable. The same document is reachable here:
aegis.sourceforge.net (archived)
lcgapp.cern.ch
The VPATH option might come in handy, which tells make what directories to look in for source code. You'd still need a -I option for each include path, though. An example:
CXXFLAGS=-Ipart1/inc -Ipart2/inc -Ipart3/inc
VPATH=part1/src:part2/src:part3/src
OutputExecutable: part1api.o part2api.o part3api.o
This will automatically find the matching partXapi.cpp files in any of the VPATH specified directories and compile them. However, this is more useful when your src directory is broken into subdirectories. For what you describe, as others have said, you are probably better off with a makefile for each part, especially if each part can stand alone.
You can add rules to your root Makefile in order to compile the necessary cpp files in other directories. The Makefile example below should be a good start in getting you to where you want to be.
CC=g++
TARGET=cppTest
OTHERDIR=../../someotherpath/in/project/src
SOURCE = cppTest.cpp
SOURCE = $(OTHERDIR)/file.cpp
## End sources definition
INCLUDE = -I./ $(AN_INCLUDE_DIR)
INCLUDE = -I.$(OTHERDIR)/../inc
## end more includes
VPATH=$(OTHERDIR)
OBJ=$(join $(addsuffix ../obj/, $(dir $(SOURCE))), $(notdir $(SOURCE:.cpp=.o)))
## Fix dependency destination to be ../.dep relative to the src dir
DEPENDS=$(join $(addsuffix ../.dep/, $(dir $(SOURCE))), $(notdir $(SOURCE:.cpp=.d)))
## Default rule executed
all: $(TARGET)
#true
## Clean Rule
clean:
#-rm -f $(TARGET) $(OBJ) $(DEPENDS)
## Rule for making the actual target
$(TARGET): $(OBJ)
#echo "============="
#echo "Linking the target $#"
#echo "============="
#$(CC) $(CFLAGS) -o $# $^ $(LIBS)
#echo -- Link finished --
## Generic compilation rule
%.o : %.cpp
#mkdir -p $(dir $#)
#echo "============="
#echo "Compiling $<"
#$(CC) $(CFLAGS) -c $< -o $#
## Rules for object files from cpp files
## Object file for each file is put in obj directory
## one level up from the actual source directory.
../obj/%.o : %.cpp
#mkdir -p $(dir $#)
#echo "============="
#echo "Compiling $<"
#$(CC) $(CFLAGS) -c $< -o $#
# Rule for "other directory" You will need one per "other" dir
$(OTHERDIR)/../obj/%.o : %.cpp
#mkdir -p $(dir $#)
#echo "============="
#echo "Compiling $<"
#$(CC) $(CFLAGS) -c $< -o $#
## Make dependancy rules
../.dep/%.d: %.cpp
#mkdir -p $(dir $#)
#echo "============="
#echo Building dependencies file for $*.o
#$(SHELL) -ec '$(CC) -M $(CFLAGS) $< | sed "s^$*.o^../obj/$*.o^" > $#'
## Dependency rule for "other" directory
$(OTHERDIR)/../.dep/%.d: %.cpp
#mkdir -p $(dir $#)
#echo "============="
#echo Building dependencies file for $*.o
#$(SHELL) -ec '$(CC) -M $(CFLAGS) $< | sed "s^$*.o^$(OTHERDIR)/../obj/$*.o^" > $#'
## Include the dependency files
-include $(DEPENDS)
If the sources are spread in many folders, and it makes sense to have individual Makefiles then as suggested before, recursive make is a good approach, but for smaller projects I find it easier to list all the source files in the Makefile with their relative path to the Makefile like this:
# common sources
COMMON_SRC := ./main.cpp \
../src1/somefile.cpp \
../src1/somefile2.cpp \
../src2/somefile3.cpp \
I can then set VPATH this way:
VPATH := ../src1:../src2
Then I build the objects:
COMMON_OBJS := $(patsubst %.cpp, $(ObjDir)/%$(ARCH)$(DEBUG).o, $(notdir $(COMMON_SRC)))
Now the rule is simple:
# the "common" object files
$(ObjDir)/%$(ARCH)$(DEBUG).o : %.cpp Makefile
#echo creating $# ...
$(CXX) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $# $<
And building the output is even easier:
# This will make the cbsdk shared library
$(BinDir)/$(OUTPUTBIN): $(COMMON_OBJS)
#echo building output ...
$(CXX) -o $(BinDir)/$(OUTPUTBIN) $(COMMON_OBJS) $(LFLAGS)
One can even make the VPATH generation automated by:
VPATH := $(dir $(COMMON_SRC))
Or using the fact that sort removes duplicates (although it should not matter):
VPATH := $(sort $(dir $(COMMON_SRC)))
I think it's better to point out that using Make (recursive or not) is something that usually you may want to avoid, because compared to today tools, it's difficult to learn, maintain and scale.
It's a wonderful tool but it's direct use should be considered obsolete in 2010+.
Unless, of course, you're working in a special environment i.e. with a legacy project etc.
Use an IDE, CMake or, if you're hard cored, the Autotools.
(edited due to downvotes, ty Honza for pointing out)
I was looking for something like this and after some tries and falls i create my own makefile, I know that's not the "idiomatic way" but it's a begining to understand make and this works for me, maybe you could try in your project.
PROJ_NAME=mono
CPP_FILES=$(shell find . -name "*.cpp")
S_OBJ=$(patsubst %.cpp, %.o, $(CPP_FILES))
CXXFLAGS=-c \
-g \
-Wall
all: $(PROJ_NAME)
#echo Running application
#echo
#./$(PROJ_NAME)
$(PROJ_NAME): $(S_OBJ)
#echo Linking objects...
#g++ -o $# $^
%.o: %.cpp %.h
#echo Compiling and generating object $# ...
#g++ $< $(CXXFLAGS) -o $#
main.o: main.cpp
#echo Compiling and generating object $# ...
#g++ $< $(CXXFLAGS)
clean:
#echo Removing secondary things
#rm -r -f objects $(S_OBJ) $(PROJ_NAME)
#echo Done!
I know that's simple and for some people my flags are wrong, but as i said this is my first Makefile to compile my project in multiple dirs and link all of then together to create my bin.
I'm accepting sugestions :D
RC's post was SUPER useful. I never thought about using the $(dir $#) function, but it did exactly what I needed it to do.
In parentDir, have a bunch of directories with source files in them: dirA, dirB, dirC. Various files depend on the object files in other directories, so I wanted to be able to make one file from within one directory, and have it make that dependency by calling the makefile associated with that dependency.
Essentially, I made one Makefile in parentDir that had (among many other things) a generic rule similar to RC's:
%.o : %.cpp
#mkdir -p $(dir $#)
#echo "============="
#echo "Compiling $<"
#$(CC) $(CFLAGS) -c $< -o $#
Each subdirectory included this upper-level makefile in order to inherit this generic rule. In each subdirectory's Makefile, I wrote a custom rule for each file so that I could keep track of everything that each individual file depended on.
Whenever I needed to make a file, I used (essentially) this rule to recursively make any/all dependencies. Perfect!
NOTE: there's a utility called "makepp" that seems to do this very task even more intuitively, but for the sake of portability and not depending on another tool, I chose to do it this way.
Hope this helps!
Recursive Use of Make
all:
+$(MAKE) -C part1
+$(MAKE) -C part2
+$(MAKE) -C part3
This allows for make to split into jobs and use multiple cores
I suggest to use autotools:
//## Place generated object files (.o) into the same directory as their source files, in order to avoid collisions when non-recursive make is used.
AUTOMAKE_OPTIONS = subdir-objects
just including it in Makefile.am with the other quite simple stuff.
Here is the tutorial.

Resources