Search code examples
makefilegnu-make

How to change the compile flags based on the build type while keeping the build recipe same in Makefile


I have a recipe to build the targets in my Makefile. What I want to do is change the compiler flags based on whether the user selects the debug build or the release build. To do this, I tried using a target-specific variable called FLAGS which gets assigned appropriately when the user builds the debug or the release target. However, the main target recipe is not able to view the values of the FLAGS variable.

My Makefile looks like:

CXX = g++ 
CXX_FLAGS = -pedantic -Wall -Wextra                                                                                                                            
TARGET_FLAGS = $(CXX_FLAGS) -shared -fPIC

OPT_FLAGS = -Ofast -march=native
DBG_FLAGS = -g3 -Og -ggdb

SRC = $(wildcard ./src/*/impl.cpp)
INCLPATH = ./headers
OBJECTS = $(patsubst ./src/%/impl.cpp,./build/%.o,$(SRC))
TARGET = lfds.so

.PHONY: release
release: FLAGS = $(OPT_FLAGS) $(TARGET)

.PHONY: debug
debug: FLAGS = $(DBG_FLAGS) $(TARGET)

$(TARGET): $(OBJECTS)
        echo "Hi $(FLAGS)"
        $(CXX) -I$(INCLPATH) $(TARGET_FLAGS) $(FLAGS) $^ -o $@
./build/%.o: ./src/%/impl.cpp
        echo "Hi $(FLAGS)"
        $(CXX) -I$(INCLPATH) $(CXX_FLAGS) $(FLAGS) -c $< -o $@

.PHONY: clean
clean:
        rm -rf $(OBJECTS)
        rm $(TARGET)

When I run make debug and make release, the echo commands prints Hi , which tells me that the variable FLAGS was never assigned. Does anyone know why this is happening? Note that I don't want to build two different targets one for debug and one for release, rather I want a single target which get built with different flags based on what the user wants.


Solution

  • There was a syntax mistake my Makefile. As per the syntax, the target-specific variables should be set in a different line and the dependencies should be specified in a different line. The updated Makefile works correctly. Here is the updated version:

    CXX = g++                                                                                                                                                      
    CXX_FLAGS = -pedantic -Wall -Wextra
    TARGET_FLAGS = $(CXX_FLAGS) -shared -fPIC
    
    OPT_FLAGS = -Ofast -march=native
    DBG_FLAGS = -g3 -Og -ggdb
    
    SRC = $(wildcard ./src/*/impl.cpp)
    INCLPATH = ./headers
    OBJECTS = $(patsubst ./src/%/impl.cpp,./build/%.o,$(SRC))
    TARGET = lfds.so
    
    .PHONY: release
    release: FLAGS = $(OPT_FLAGS)
    release: $(TARGET)
    
    .PHONY: debug
    debug: FLAGS=$(DBG_FLAGS)
    debug: $(TARGET)
    
    $(TARGET): $(OBJECTS)
            @echo "Hi $(FLAGS)"
            $(CXX) -I$(INCLPATH) $(TARGET_FLAGS) $(FLAGS) $^ -o $@
    ./build/%.o: ./src/%/impl.cpp
            @echo "Hi $(FLAGS)"
            $(CXX) -I$(INCLPATH) $(CXX_FLAGS) $(FLAGS) -c $< -o $@
    
    .PHONY: clean
    clean:
            rm -rf $(OBJECTS)
            rm $(TARGET)