gustavovelascoh
gustavovelascoh

Reputation: 1228

Using makefile file as prerequisite in a rule

I am inexperienced with make, and wanted to replicate a build structure provided by some third-party SDK and adapt it to my own compiler and project.

The thing is that I found that some rules are generated using the makefile as prerequisite, something like:

...
$(eval $(1): Makefile | $(dir $(1)).) \
...

or

$(OUTPUT_DIRECTORY)/%.inc: Makefile | $(OUTPUT_DIRECTORY)
    $(info Generating $@)
    $(NO_ECHO)$(call dump, $(call target_specific, INC_PATHS, $*)) > $@

Originally, their makefile is Capitalized (Makefile) and the one I am working on is lowercase (makefile). Anyway, When I try my current changes, this error appears:

*** No rule to make target 'Makefile', needed by '...'

I supposed that was due to the capitalization, so changed to lowercase in both places and tried again, but this time the error is that the makefile is treated as a C file (This is my guess...)

"makefile", line 1: error #171: expected a declaration
  -include makefile.local
                          ^

"makefile", line 67: error #8: missing closing quote
  ${CG_TOOL_ROOT}/include"
                         ^

"makefile", line 99: error #10: "#" not expected here
  .SUFFIXES: # ignore built-in rules
             ^

"makefile", line 100: error #10: "#" not expected here
  %.d:       # don't try to make .d files
             ^

"makefile", line 100: error #8: missing closing quote
  %.d:       # don't try to make .d files

What could be the issue here? Is there something I am missing?

EDIT 1: These are the files I am trying to use.

Nordic provides these as part of their SDK for development using arm-gcc for ARM platforms. There is a Makefile per project and there is a Makefile.common included in the main Makefile.

On the other side, I am trying to understand and replicate the same but for another proprietary compiler with different options and syntax (TI's cl430 for MSP430 platforms). From the original Makefile.common I removed some references to the gnu-arm suite and replace it with the proper compiling tools. In the makefile I also tried to replicate the same structure of the original but using my sources and options.

Just to make it clear, originals are capitalized, mine are lowercase.

EDIT 2:

After running make --debug --print-data-base I found this:

The error appears in the first attempt to build a file:

Updating goal targets....
 File 'default' does not exist.
   File 'test_project' does not exist.
     File '_build/test_project.out' does not exist.
       File '_build/test_project/<SOURCE_FILE>.c.o' does not exist.
      Must remake target '_build/test_project/<SOURCE_FILE>.c.o'.
Building file: "makefile"
Invoking: MSP430 Compiler
"cl430" -vmspx --use_hw_mpy=F5 <... a lot of options ...> --obj_directory="./_build"  "makefile"
"makefile", line 1: error #171: expected a declaration
  -include makefile.local
  ^
[ ... more errors ...]

However, from the debug and DB information, I found that the source file rule indeed requires makefile, and that makefile is not a target, but somehow it is trying to build it:

# Not a target:
makefile:
#  Implicit rule search has been done.
#  Last modified 2020-02-25 11:43:33.609423171
#  File has been updated.
#  Successfully updated.

_build/test_project/<SOURCE_FILE>.c.o: makefile | _build/test_project/.
#  Implicit rule search has been done.
#  Implicit/static pattern stem: '_build/test_project/<SOURCE_FILE>'
#  Modification time never checked.
#  File has been updated.
#  Failed to be updated.
# automatic
# @ := _build/test_project/<SOURCE_FILE>.c.o
# automatic
# % := 
# automatic
# * := _build/test_project/<SOURCE_FILE>
# automatic
# + := makefile
# automatic
# | := _build/test_project/.
# automatic
# < := makefile
# automatic
# ^ := makefile
# automatic
# ? := makefile
# variable set hash-table stats:
# Load=8/32=25%, Rehash=0, Collisions=1/30=3%
#  recipe to execute (from 'makefile.common', line 192):
    @echo 'Building file: "$<"'
    @echo 'Invoking: MSP430 Compiler'
    "${CG_TOOL_ROOT}/bin/cl430" -vmspx --use_hw_mpy=F5 <... a lot of options ...> "$(shell echo $<)"
    @echo 'Finished building: "$<"'
    @echo ' '

Upvotes: 1

Views: 1337

Answers (1)

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136256

That dependency on Makefile is to make sure that it rebuilds when Makefile has been changed. For example, if you change CFLAGS in Makefile or a rule to compile or link, this dependency triggers a rebuild (provided object files depend on Makefile, as they should). Without dependency on Makefile those changes won't cause a rebuild.

The error messages in the form of "makefile", line 1: error #171: expected a declaration suggest that makefile is passed as a source file to a C compiler that produces the error message.

The rules most likely do $(filter-out Makefile,$^). You need to replace all occurrences of Makefile to makefile.

*** No rule to make target 'Makefile', needed by '...' means that Makefile is still a prerequisite of some targets. You can find what those targets are by passing --debug --print-data-base command line options to make.

Upvotes: 3

Related Questions