Search code examples
makefiledependenciesheader-filesnvcc

GNU Makefile uses the same source file for all object files


File structure:

cpp
|   Makefile
|
|   obj
|___include
|   |   a.cuh
|   |   b.cuh
|   |   c.cuh
|
|___src
|   |   a.cu
|   |   b.cu
|   |   c.cu

I don't have much experience with GNU make. The following was written based on different search results on Stackoverflow. The $@ variable correctly gets the name of each object file from the list, however $< variable only gets the first item in the list of source file names (as per the manual, but that is what all the stack overflow answers I found are using 1, 2, 3).

NVCC=nvcc

LIB       = lib.dll

SRC_DIR   = src
INC_DIR   = include
OBJ_DIR   = obj

CU_FILES  = $(wildcard $(SRC_DIR)/*.cu)

CUH_FILES = $(wildcard $(INC_DIR)/*.cuh)

CUO_FILES = $(addprefix $(OBJ_DIR)/,$(notdir $(CU_FILES:.cu=.obj)))

$(LIB): $(CUO_FILES)
    $(NVCC) --shared $^ -o $@

$(CUO_FILES): $(CU_FILES) $(CUH_FILES)
    $(NVCC) -dc $< -o $@

Solution

  • What you wrote is probably not what you want. Your rule:

    $(CUO_FILES): $(CU_FILES) $(CUH_FILES)
        $(NVCC) -dc $< -o $@
    

    means that each object file depends on all source files ad all header files.

    What you need here is a pattern rule saying that obj/foo.obj depends on src/foo.cu and include/foo.cuh:

    obj/%.obj: src/%.cu include/%.cuh
        $(NVCC) -dc $< -o $@
    

    Note that you can simplify a bit the CUO_FILES assignment:

    CUO_FILES = $(patsubst $(SRC_DIR)/%.cu,$(OBJ_DIR)/%.obj,$(CU_FILES))