windowsmakefilegnu-make

MINGW32-MAKE: *** No rule to make target '*.cpp.o', needed by 'module.dll'. Stop


I am trying to compile both C and C++ files into a DLL using a makefile but whenever I build I get the error MINGW32-MAKE: *** No rule to make target 'vendor\whatever*.cpp.o', needed by 'module.dll'. Stop.

All the files in the main source folder compile properly.

Im pretty sure the issue is with how I get all the .o files with patsubst and subst but I am unsure on how to fix it.

I know this is dumb but I have never used makefiles before.

.PHONY: build clean mkdir run print

CC     := gcc.exe
CXX    := g++.exe

CWD    := $(subst \,/,$(shell cd))
SRCDIR := $(CWD)/src
INCDIR := $(CWD)/inc
BINDIR := $(CWD)/build

SRC_C   := $(shell dir /a:-d /b/s $(shell cd)\src\\*.c)
SRC_C   := $(subst \,/,$(SRC_C))
CCFLAGS := -O2 -I "$(CWD)/vendor" -I "$(CWD)/inc"

LDLIBS  := -lws2_32 -lkernel32 -luser32 -ldwmapi -ld3d11 -ldxgi -ldxguid -lgid32 -ld3dcompiler
LDFLAGS := -s -shared -mconsole -static-libgcc -static-libstdc++
EXE     := module.dll

OBJECTS := $(SRC_C)
OBJECTS := $(subst \,/,$(OBJECTS))
OBJECTS := $(subst /src,,$(patsubst $(CWD)/%.c,$(BINDIR)/int/%.c.o,$(OBJECTS)))

build: $(EXE)

$(EXE): $(OBJECTS)
    $(CC) $(LDFLAGS) $(OBJECTS) -o $@ $(LDLIBS)

$(CWD)/int/%.c.o: $(SRC_C)/%.c
    $(shell echo $<)
    $(CC) -c -std=c99 $(CCFLAGS) -o $< $@

Edit: Simplified the makefile with the same issue


Solution

  • So I fixed it myself after a few hours of testing stuff.

    I took a template makefile and modified it to suit what I need

    .DEFAULT_GOAL = build
    
    CC  = gcc
    CXX = g++
    LD  = g++
    
    CCFLAGS = -O2 -I"vendor" -I"inc"
    LDFLAGS = -s -shared -mconsole -static-libgcc -static-libstdc++
    LDLIBS  = 
    
    ifeq ($(RENDERER),d3d11)
        CCFLAGS := $(CCFLAGS) -DRENDERER_USE_DIRECTX11
        LDLIBS  := $(LDLIBS) -ld3d11 -ldxgi -ldxguid -ld3dcompiler
    endif
    ifeq ($(RENDERER),d3d12)
        CCFLAGS = $(CCFLAGS) -DRENDERER_USE_DIRECTX12
    endif
    ifeq ($(RENDERER),glfw)
        CCFLAGS := $(CCFLAGS) -DRENDERER_USE_GLFW
    endif
    
    SRCDIR = src
    SRC_FILES := $(subst \,/, $(shell dir /a:-d /b/s $(shell cd)\src\\*.c)) $(subst \,/, $(shell dir /a:-d /b/s $(shell cd)\src\\*.cc))
    
    ifeq ($(BACKEND),imgui)
        SRC_FILES := $(SRC_FILES) $(subst \,/, $(shell dir /a:-d /b/s vendor\imgui\src\*.cpp))
        CCFLAGS   := $(CCFLAGS) -DRENDERER_USE_IMGUI
        LDLIBS    := $(LDLIBS) -lgdi32 -luser32 -ldwmapi
    endif
    ifeq ($(BACKEND),nuklear)
        SRC_FILES := $(SRC_FILES) $(subst \,/, $(shell dir /a:-d /b/s vendor\nuklear\src\*.c))
        CCFLAGS += -DRENDERER_USE_NUKLEAR
    endif
    SRC_FILES := $(subst $(subst \,/,$(shell cd))/,, $(SRC_FILES))
    
    INTDIR = build/int
    INT_FILES := $(SRC_FILES)
    INT_FILES := $(patsubst %.cc, $(INTDIR)/%.o, $(INT_FILES))
    INT_FILES := $(patsubst %.c, $(INTDIR)/%.o, $(INT_FILES))
    INT_FILES := $(patsubst %.cpp, $(INTDIR)/%.o, $(INT_FILES))
    INT_FILES := $(subst src/,, $(INT_FILES))
    
    OUTDIR = build/bin
    OUT_FILE = module.dll
    
    .PHONY: test
    test:
        @echo $(SRC_FILES)
        @echo $(INT_FILES)
    
    .PHONY: clean
    clean:
        $(RM) $(INT_FILES)
        $(RM) $(OUTDIR)/$(EXE)
    
    .PHONY: build
    build: $(OUTDIR)/$(OUT_FILE)
    
    $(OUTDIR)/$(OUT_FILE): $(INT_FILES)
         $(LD) $(LDFLAGS) $(INT_FILES) -o $@ $(LDLIBS)
    
    $(INTDIR)/%.o:  $(SRCDIR)/%.c
        $(CC) $(CCFLAGS) -c -o $@ $<
    $(INTDIR)/%.o:  $(SRCDIR)/%.cc
        $(CXX) $(CCFLAGS) -c -o $@ $<
    $(INTDIR)/%.o:  $(SRCDIR)/%.cpp
        $(CXX) $(CCFLAGS) -c -o $@ $<
    
    $(INTDIR)/vendor/nuklear/%.o:   vendor/nuklear/src/%.cpp
        $(CC) $(CCFLAGS) -c -o $@ $<
    
    $(INTDIR)/vendor/imgui/%.o: vendor/imgui/src/%.cpp
        $(CXX) $(CCFLAGS) -c -o $@ $<
    
    -include $(DEPENDS)
    

    I know its probably bad code but it works so :p