Question

Not sure if the title makes sense... so I'll elaborate a bit.

I'm toying with this makefile that uses gcc's auto-dependency list generator.

At the same time, I wanted to keep a nice sorted directory structure that separates source, headers, and resources.

The layout's nice and simple like so

  • MAIN
    • src
    • include
    • objects
    • dependencies

Now, the makefile dependency list generator atm is this:

$(DEP_PATH)%.d : $(SRC_PATH)%.c
    @${CC} $(CFLAGS) -MM -c $(INCLUDE) $< > $(DEP_PATH)$*.d
include $@

The idea here being that we generate the dependency rule, then include it to the make build.

and the result for say, foo1.o is:

foo1.o: src/foo1.c include/foo1.h include/foo2.h include/foo3.h

This would work fine if I labled all my objects to be found in the main directory... however since they in /main/objects instead... the make says it can't find the rule for /main/objects/foo1.o

Now, I tried this:

@echo "$(OBJ_PATH)" > $(DEP_PATH)$*.d
@${CC} $(CFLAGS) -MM -c $(INCLUDE) $< >> $(DEP_PATH)$*.d

Which the > feeds the object path to the new/overwritten file, then concatenates the GCC auto-dependency rule generation to it... but it adds the newline between the two sets.

I tried cat'ing two separate files with said info as well... but they also get the newlines.

Is there a nice way to prepend the dependency file w/out adding the newline?

Also, if you've got any real nice tutorials on makefiles, cat, and echo, I'd really appreciate it.

Thanks for any and all responses.

Was it helpful?

Solution

The answer to the question you asked is sed:

@${CC} blah blah blah | sed 's|^|$(OBJ_PATH)|' > $(DEP_PATH)$*.d

But you're going to have a different problem with this part:

include $@

The include directive is for Make itself, it is not a shell command (like $(CC)...). And $@ is an automatic variable, defined within the rule, not available to directives outside the rule. Instead, try something like this:

include $(DEP_PATH)/*.d

and take a look at Advanced Auto-Dependency Generation.

OTHER TIPS

While I imagine there are alternatives, possibly better ones... I think I found a solution to my problem.

I can pipe the echo into tr to remove the newline. So the resultant code is:

$(DEP_PATH)%.d : $(SRC_PATH)%.c
    @echo "$(OBJ_PATH)" | tr -d '\n' > $(DEP_PATH)$*.d
    @${CC} $(CFLAGS) -MM -c $(INCLUDE) $< >> $(DEP_PATH)$*.d
cat $@
include $@

Which does the following now...

1) For each .d, make sure the .c is there and up-to-date.

2) echo the object path, | (pipe) it to tr which will delete the newline, then > will make the result overwrite/create to the .d file

3) have $(CC) generate the dependency list... which unfortunately excludes the object file's intended location (which is why 1-2 lines exist)

4) simply concatenate the resulting file to the terminal (not needed, but I like seeing that this works now!)

5) have make include the resulting dependency list into the build.

Should be worth noting that in subsequent runs... I have this listed up top:

all: $(MAIN)
-include $(DEP)

which will check for the main executable and then include the dependency files if they're created. (the - is here to ignore errors should the files not be made yet... which is ok since my snippet from the begin will run after.)

Again, any suggestions and constructive criticisms are appreciated.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top