catalogue_number
catalogue_number

Reputation: 335

Makefile cannot find the last prerequisite object

I'm trying to compile a large C++ project with source files in several subdirectories of src.

My Makefile looks like this:

# ---------- Compiler and linker directives ----------
CXX = g++-11

CXXFLAGS = -std=c++17 -fopenmp -MD -g -Wall -pedantic
# LDFLAGS = -Wl,--gc-sections


# Output directory after linking
BIN_PATH = ../bin
BUILD_PATH = ../build

# ------- System Include  --------------
# Change ~/include as necessary for your architecture
INC_FLAGS = -I../include -I/opt/homebrew/include



# -------- Establishing objects and sources ------

RATE_SRC = $(wildcard hartreefock/*.cpp) $(wildcard struct_hartreefock/*.cpp) $(wildcard numerical/*.cpp)
RATE_OBJ = $(addprefix $(BUILD_PATH)/,$(RATE_SRC:.cpp=.o)))

# ------------- Specific Include -----------
# RATE_HEADERS = $(wildcard hartreefock/*.hpp) $(wildcard struct_hartreefock/*.hpp) $(wildcard numerical/*.hpp)
RATE_DIR = hartreefock struct_hartreefock numerical

RATE_INC = $(addprefix -I,$(RATE_DIR))



# ---------- Libraries needed for linking ----------

# Change or remove ~/lib as necessary for your architecture
LIB_PATH = -L/opt/homebrew/lib 


# Generic .cc -> .o rule
$(BUILD_PATH)/%.o: %.cpp
    @mkdir -p $(@D)
    $(CXX) $(CXXFLAGS) $(INC_FLAGS) $(RATE_INC) $< -c -o $@

# ---------- Linking rules ----------

# Generic .o -> exec rule: uses all prerequisites (meant to be .o files)
ratecalc: $(RATE_OBJ)
    $(CXX) $(CXXFLAGS) $(INC_PATH) $(A_RATE_INC) $(LDFLAGS) $^ \
    $(LIB_PATH) -o $(BIN_PATH)/$@

# TODO
# simulate: 

echo: 
    echo "$(RATE_OBJ)"
    echo "$(BUILD_PATH)"


# Cleanup:
.PHONY: clean build_directories
clean:
    -rm -r $(BUILD_PATH)/**

Bizarrely, this seems to do the right thing until I get to one specific file:

make clean
make ratecalc
g++-11 -std=c++17 -fopenmp -MD -g -Wall -pedantic -I../include -I/opt/homebrew/include -Ihartreefock -Istruct_hartreefock -Inumerical struct_hartreefock/RateData.cpp -c -o ../build/struct_hartreefock/RateData.o
g++-11 -std=c++17 -fopenmp -MD -g -Wall -pedantic -I../include -I/opt/homebrew/include -Ihartreefock -Istruct_hartreefock -Inumerical numerical/Constant.cpp -c -o ../build/numerical/Constant.o
make: *** No rule to make target `../build/numerical/wignerSymbols.o)', needed by `ratecalc'.  Stop.

This is especially strange because Constant.cpp and wignerSymbols.cpp are in the same directory. Manually running with this target compiles the object file as needed,

make ../build/numerical/wignerSymbols.o
g++-11 -std=c++17 -fopenmp -MD -g -Wall -pedantic -I../include -I/opt/homebrew/include -Ihartreefock -Istruct_hartreefock -Inumerical numerical/wignerSymbols.cpp -c -o ../build/numerical/wignerSymbols.o

but this is not recognised as satisfying the dependency for the ratecalc rule.

It might be significant that wignerSymbols.cpp is the very last entry in RATE_OBJ, but to be honest I can't understand what's happening here.

For completeness: I'm using GNU make 3.81 on an M1 macbook air.

Upvotes: 0

Views: 94

Answers (1)

MadScientist
MadScientist

Reputation: 101051

Typo:

RATE_OBJ = $(addprefix $(BUILD_PATH)/,$(RATE_SRC:.cpp=.o)))

There is an extra close paren here, which you can see in your error message:

make: *** No rule to make target `../build/numerical/wignerSymbols.o)', ...

Upvotes: 1

Related Questions