1

I am trying to modify a makefile that builds cpp to a c file, but I am running into some string substitution problem. I wonder if someone can point out the mistake.

here's a piece of the file:

SOURCES := \
lz4.c \
lz4frame.c \
lz4hc.cpp \
xxhash.c

OBJECTS := $(addprefix $(OBJ_DIR)/,$(subst .c,.o,$(SOURCES)))
DEPENDS := $(addprefix $(OBJ_DIR)/,$(subst .c,.d,$(SOURCES)))

all: $(OUT_DIR)/$(LIB_NAME)

clean:

rm -rf $(OBJ_DIR)
rm -rf $(OUT_DIR)

$(OUT_DIR)/$(LIB_NAME): $(OBJECTS)
    @rm -f $@
    $(AR) cr $@ $^

$(OBJECTS): $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
    @mkdir -p $(@D)
    $(CXX) -MMD -MF $(OBJ_DIR)/$*.d -MP -MT'$(OBJ_DIR)/$*.o $(OBJ_DIR)/$*.d' -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@

.PHONY: all clean

-include $(DEPENDS)

but when I typed make clean I get this:

 Makefile:38: target `Release64/obj/lz4hc.opp' doesn't match the target pattern

or when I try to build I get this:

g++-4.6 -MMD -MF ./Release64/obj/Release64/obj/lz4hc.opp.d -MP -MT'./Release64/obj/Release64/obj/lz4hc.opp.o ./Release64/obj/Release64/obj/lz4hc.opp.d' -c -I../../../include -I../../../thirdparty/include/lz4 -std=c++0x -fPIC -O2 -m64  -o Release64/obj/lz4hc.opp
g++-4.6: fatal error: no input files

compilation terminated.

I think the issue is with this line, but I can't figure out the problem:

OBJECTS := $(addprefix $(OBJ_DIR)/,$(subst .c,.o,$(SOURCES)))
DEPENDS := $(addprefix $(OBJ_DIR)/,$(subst .c,.d,$(SOURCES)))

thx!

gmmo
  • 2,577
  • 3
  • 30
  • 56

3 Answers3

2

Your sources variable is:

SOURCES := \
lz4.c \
lz4frame.c \
lz4hc.cpp \
xxhash.c

Note the filename lz4hc.cpp. Then you substitute .c with .o, that gives you a filename of lz4hc.opp which is exactly the error you see.

It's not clear if you really want a mix of C and C++ files, or if you just forgot to change the name of one of the files in the variable.

MadScientist
  • 92,819
  • 9
  • 109
  • 136
0

You can split C and C++ sources into separate lists, and use pattern rules to build your sources, e.g.:

SOURCES_C := \
lz4.c \
lz4frame.c \
xxhash.c
SOURCES_CPP:= lz4hc.cpp
SOURCES:=$(SOURCES_C) $(SOURCES_CPP)

OBJECTS_C := $(addprefix $(OBJ_DIR)/,$(subst .c,.o,$(SOURCES_C)))
OBJECTS_CPP:=$(addprefix $(OBJ_DIR)/,$(subst .cpp,.o,$(SOURCES_CPP)))
OBJECTS:=$(OBJECTS_C) $(OBJECTS_CPP)

DEPENDS_C := $(addprefix $(OBJ_DIR)/,$(subst .c,.d,$(SOURCES_C)))
DEPENDS_CPP := $(addprefix $(OBJ_DIR)/,$(subst .cpp,.d,$(SOURCES_CPP)))
DEPENTS:=$(DEPENDS_C) $(DEPENDS_CPP)

all: $(OUT_DIR)/$(LIB_NAME)

clean:
    $(RM) $(OBJECTS) $(DEPENDS)

$(OUT_DIR)/$(LIB_NAME): $(OBJECTS)
    @rm -f $@
    $(AR) cr $@ $^

%.o: %.c
    @mkdir -p $(@D)
    $(CC) -MMD -MF $(OBJ_DIR)/$*.d -MP -MT'$(OBJ_DIR)/$*.o $(OBJ_DIR)/$*.d' -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@

%.o: %.cpp
    @mkdir -p $(@D)
    $(CXX) -MMD -MF $(OBJ_DIR)/$*.d -MP -MT'$(OBJ_DIR)/$*.o $(OBJ_DIR)/$*.d' -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@

.PHONY: all clean

-include $(DEPENDS)
keltar
  • 17,711
  • 2
  • 37
  • 42
0

You have a file that ends in .cpp, but your subst commands only deal with names that end in .c. Try:

OBJECTS := $(addprefix $(OBJ_DIR)/,$(subst .c,.o,$(subst .cpp,.o,$(SOURCES))))
DEPENDS := $(addprefix $(OBJ_DIR)/,S(subst .c,.d,$(subst .cpp,.d,$(SOURCES))))
Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • Easier is to just use `basename`: `$(patsubst %,$(OBJ_DIR)/%.o,$(basename $(SOURCES)))` – MadScientist Apr 18 '15 at 15:05
  • @MadScientist: That will give you names like `lz4hc.cpp.o` -- probably not what you want. – Chris Dodd Apr 18 '15 at 19:02
  • No it won't. `basename` strips off the suffix, any suffix. – MadScientist Apr 18 '15 at 19:57
  • @MadScientist: not the `basename` on my machine or any other machine I've seen -- basename strips the directory off, and optionally can strip a specific suffix, but only one specific suffix. Try typing `basename foo.cpp` and see what you get... – Chris Dodd Apr 18 '15 at 23:12
  • Did you try my change? You're talking about the POSIX program `basename`. But in my example I'm using the GNU make function `basename`. See: http://www.gnu.org/software/make/manual/html_node/File-Name-Functions.html#index-basename : _Extracts all but the suffix of each file name in names. If the file name contains a period, the basename is everything starting up to (and not including) the last period._ – MadScientist Apr 19 '15 at 13:17