Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi directory makefile for project

This is how my directory looks like:

/project
    makefile
    /ceda_lib
        makefile
        files....
    /general
        makefile
        files....
    /CLI
        makefile
        files....
    /objects
         files.o 

Makefile(main):

1  #start other makefiles
2  
3 
4  o= ./objects
5  DEPS= Affine.hpp CEDA.hpp generalParameters.hpp generalFunctions.hpp
6  OBJ= $o/main.o $o/Affine.o $o/generalFunctions.o
7  CC=g++
8  CFLAGS= -Wall -g -I.
9  export CC
10 export CFLAGS
11 export DEPS
12 
13 all: 
14 ▸---+$(MAKE) -C general
15 ▸---+$(MAKE) -C ceda_lib 
16 ▸---+$(MAKE) -C CLI
17 
18 run: $(OBJ) $(DEPS)
19 ▸---$(CC) -o $@ $^

The other makefiles look like this:(update2)

  1 include ../makefile.variables
  2 
  3 OBJ = main.o
  4 all: $(OBJ)
  5 
  6 $(OBJ): %.o: %.cpp $(DEPS)
  7 ▸---$(CC) -o ../objects/$@ -c $< $(CFLAGS)

What I want to do is for all code in the 3 directories to be compiled and all objects to be stored in the /object directory. Then an executable will be created from the $DEPS and the contents of /object directory.

This makefile doesn't work sadly. Could you please find what I've done wrong and also could you suggest me ways to improve the code. (I'm quite new to makefiles).

Also this is the output whenever I try making the project:(Update2)

make: Entering directory '/home/george/Documents/CEDA'
make -C general
make[1]: Entering directory '/home/george/Documents/CEDA/general'
g++ -o ../objects/generalFunctions.o -c generalFunctions.cpp -Wall -g -I.
make[1]: Leaving directory '/home/george/Documents/CEDA/general'
make -C ceda_lib
make[1]: Entering directory '/home/george/Documents/CEDA/ceda_lib'
g++ -o ../objects/Affine.o -c Affine.cpp -Wall -g -I.
Affine.cpp:4:33: fatal error: generalParameters.hpp: No such file or directory
 #include "generalParameters.hpp"
                                 ^
compilation terminated.
makefile:7: recipe for target 'Affine.o' failed
make[1]: *** [Affine.o] Error 1
make[1]: Leaving directory '/home/george/Documents/CEDA/ceda_lib'
makefile:8: recipe for target 'All' failed
make: *** [All] Error 2
make: Leaving directory '/home/george/Documents/CEDA'

This is the makefile.variables

  1 #variables used by all makefiles in project directory
  2 
  3 PATH_TO_DIR = ~/Documents/CEDA
  4 c = $(PATH_TO_DIR)/ceda_lib
  5 g = $(PATH_TO_DIR)/general
  6 e = $(PATH_TO_DIR)/CLI         #e for executable
  7 
  8 DEPS= $c/Affine.hpp $c/CEDA.hpp $g/generalParameters.hpp $g/generalFunctions.hpp
  9 CC=g++
 10 CFLAGS= -Wall -g -I.
like image 379
alienCY Avatar asked Oct 18 '22 09:10

alienCY


1 Answers

Here:

OBJ= main.o

../objects/%.o: %.cpp $(DEPS)
    $(CC) -c $< $(CFLAGS)

This makefile contains one rule, which is a pattern rule, a way to build any file with a name like ../objects/foo.o. But it doesn't tell Make which object file it is to build. To be precise, a pattern rule cannot be the default rule.

The simplest way to fix this is with the addition of an ordinary rule:

../objects/$(OBJ):

Once you have this working you will have the object files, but there are still problems in the main makefile. The run rule will not build an executable, and if you want to execute that rule you will have to invoke it on the command line, it won't follow automatically.

You are attempting recursive use of Make -- which is tricky -- before you've mastered the basics. I suggest you try using the makefile to build the object files, then try to build the executable using the command line, then look carefully at the command you used and rewrite the run rule.

Once you get that far, other improvements are possible. (Make is a powerful tool, but it has a long learning curve.)

EDIT: If it isn't working at all, try something simpler first.

Pick a source file in ceda_lib, like, I don't know main.cpp. Verify that the source file exists and that the corresponding object file (main.o) does not. Edit the makefile (in ceda_lib/) to this:

main.o: main.cpp
    $(CC) -c $< $(CFLAGS)

Then within ceda_lib/, try make and see what happens.

If it builds main.o, then delete main.o, and then from project/ try make -C ceda_lib, and see what happens. If that builds ceda_lib/main.o, then we can move on to more advanced makefiles.

like image 57
Beta Avatar answered Oct 21 '22 03:10

Beta