0

I have a project that I would like to convert from recursive to non recursive make. The structure looks like the following

+--app
|  +-- Makefile
+--lib1
|  +-- Makefile
|  +-- x.c
|  +-- y.c
|
+--lib2
|  +-- Makefile
|  +-- x.c

What I am trying to do is after a build is have a structure like this

+--app
|  +-- build/
|  |  +-- debug(or release or test)/
|  |  |  +-- lib1/
|  |  |  |  +-- *.o
|  |  |  |  +-- *.d
|  |  |  +-- lib2/
|  |  |  |  +-- *.o
|  |  |  |  +-- *.d
|  |
|  +-- target/
|  | +-- main.bin
|  |
|  +-- Makefile
|
+--lib1
|  +-- module.mk
|  +-- x.c
|  +-- y.c
|
+--lib2
|  +-- module.mk
|  +-- x.c

The main idea is that the build folder contains all object and dependency files and and target has the program file that should be loaded.

The issue that I am having is that make will never want to create this structure. When I define my rules make will only run implicit rules and not my defined rules.

I have read every resource on non-recursive make and right now it just has not clicked yet. Any help is much appreciated.

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
  • Let me suggest you my non-recursive template library: https://github.com/igagis/prorab it has tutorials. If you need help, I can help you to apply it to your project. – igagis Jan 11 '17 at 14:51
  • We are not a "provide me code!" community. If you have a **specific** question, state it along with what you have done so far. And don't use irrelevant tags. This is not related to embedded systems. – too honest for this site Jan 11 '17 at 14:59
  • This is related to embedded systems in that this is used to generate the binary needed for a embedded processor. We are currently working on moving away from a dedicated IDE to a more streamlined approach agnostic to IDE. – user7404994 Jan 12 '17 at 00:26

1 Answers1

1

For build results to have the same directory structure like that of the sources, the pattern rules must be in the form of:

${obj_dir}/%.o : ${src_dir}/%.c

Where % part includes all the subdirectories. The object file must also depend on its directory for make to build the directory first:

.SECONDEXPANSION:
${obj_dir}/%.o : ${src_dir}/%.c | $$(dir $$@)
${obj_dir}/% : mkdir -p $@ 

Depending on the target, one source file can be compiled with/without multi-threading, as position-independent/non-position-independent code, etc.. One way to cope with that is to have separate top-level object file directories (in addition to debug/release top-level directory), e.g.:

${obj_dir}/obj
${obj_dir}/obj-pic
${obj_dir}/obj-mt
${obj_dir}/obj-mt-pic

Once you have these rules working correctly and try a parallel build you will notice that mkdir -p fails when two of them race to create /a/b/a and /a/b/b. The fix is:

${obj_dir}/% : while ! mkdir -p $@; do echo -n ""; done
Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271