-1

In Git, I have a master branch (release) and a dev branch (development) for a C project.

In the master branch, I want gcc to only be passed the compiler flag -Os (optimize for speed) and not -ftest-coverage -fprofile-arcs (when compiled, a .gcno file is created, when run, a .gcda file is created and when gcov executable, a .gcov file is created).

In the release branch, I only want the compiler to be passed the flag -Os.

I can add Makefile to .gitignore for 1 branch, but I would need to manually check everytime if Makefile has been changed after each push on the other branch.

I can also do nothing and be notified of a change in the Makefile when merging, but I would need to manually merge the file (keep one line of CFLAG+=... and discard the other), but this is error-prone.

How can I keep two separate versions of a Makefile on different branches with different requirements?

Makefile

BASE=notepad

# NEEDED FOR BOTH RELEASE AND TESTING
CFLAGS=-Wall

# ONLY NEEDED IF RELEASE
CFLAGS+=-Os

# ONLY NEEDED IF TESTING COVERAGE AND PROFILING
CFLAGS+=-ftest-coverage -fprofile-arcs

all: $(BASE).exe

$(BASE).exe: $(BASE).o

$(BASE).o: $(BASE).c
    gcc $(CFLAGS) -c $(BASE).c

clean:
    rm -f $(BASE).o $(BASE).exe # ALWAYS NEEDED
    rm -f *.gcda *.gcno *.gcov  # ONLY NEEDED IF -ftest-coverage -fprofile-arcs
2

Git cannot manage multiple versions, in the sense that it only records the history of your files, not different variants.

Branches are not a suitable mechanism for keeping track of different variants. You cannot have a file that only exists on one branch unless you manually delete the file on every merge.

Instead, your build process should be able to produce either variant.

  • In your Makefile, you can create different targets for a coverage-instrumented build and a release build. I'd recommend that these use different build directories so that you don't have to clean out all object files when switching between targets.

    GNU Make has many convenient features, such as the ability to scope variable assignments to a specific target:

    coverage: CFLAGS += -ftest-coverage -fprofile-arcs
    release:  CFLAGS += -Os
    
  • You could also query Git to discover the current branch. However, then the build will only work when checked out as a Git repository, and not e.g. when unpacked from a zip archive. This is generally a convenient but fragile solution, although it may be appropriate for a CI server.

(Also, note that -Os optimizes for small size, not speed, although the two can be related via cache effects. In particular, “-Os enables all -O2 optimizations that do not typically increase code size.”)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.