Michael Assouline
Michael Assouline

Reputation: 21

Referencing a C code-defined macro within its makefile

I'm writing some embedded firmware using C with arm-gcc and Eclipse. Within my code is a FW version number defined as a macro. I want to have that version appended to the build target file automatically.

For the sake of the example, let's say this is my main.h file:

#ifndef MAIN_H__
#define MAIN_H__

#define FW_MAJOR_VERSION   1
#define FW_MINOR_VERSION   0

and the makefile:

TARGET     := fw_release
OUTPUT_DIR := out
...
generate_pkg:
   @gen_pkg $(OUTPUT_DIR)/$(TARGET)_pkg.zip

where gen_pkg is some script to generate a firmware update package.

This would generate a file path like this: out/fw_release_pkg.zip

Ideally, I would like something like this:

generate_pkg:
   @gen_pkg $(OUTPUT_DIR)/$(TARGET)_pkg_v$(FW_MAJOR_VERSION).$(FW_MINOR_VERSION).zip

which would generate a file path like this: out/fw_release_pkg_v1.0.zip

Now I know I can define the version within the makefile and reference that within the code (basically the other way around), but that has 2 problems:

  1. Every time I change the makefile it triggers a compilation of the entire code which takes a few minutes.

  2. I have two separate build configurations (release and debug), each using its own makefile, and that would require me to update the two separately.

Upvotes: 2

Views: 156

Answers (2)

user10678532
user10678532

Reputation:

Well, you'll have to parse main.h one way or another.

Assuming that you're using gcc or clang:

generate_pkg:   main.h
        @gen_pkg "$(OUTPUT_DIR)/$$(echo FW_MAJOR_VERSION/FW_MINOR_VERSION | $(CC) -P -E -include main.h -x c -)_pkg.zip"

If your main.h is more complicated than that, you'll have to add all your $(CFLAGS) and other default options to the $(CC) command.

Upvotes: 0

James McPherson
James McPherson

Reputation: 2556

The approach I'd take would be to define the version number elements in the Makefile, and burn those in to your code using cflags.

In the Makefile:

FW_VERSION_MAJOR=1
FW_VERSION_MINOR=1
FW_VERSION_MICRO=0a

FW_VERSION = $(FW_VERSION_MAJOR).$(FW_VERSION_MINOR).$(FW_VERSION_MICRO)

CFLAGS += -DFW_VERSION_MAJOR=$(FW_VERSION_MAJOR)
CFLAGS += -DFW_VERSION_MINOR=$(FW_VERSION_MINOR)
CFLAGS += -DFW_VERSION_MICRO=$(FW_VERSION_MICRO)

debug_build:
    $(CC) -DDEBUG=1 $(OBJECTS) -o $(OUTPUT)

release_build:
    $(CC) -DDEBUG=0 $(OBJECTS) -o $(OUTPUT)

Then it's a fairly easy matter to burn the correct version into your debug and non-debug pkg generation - and you only have to change the firmware version info in one place.

Upvotes: 3

Related Questions