make: implicit rule to link c++ project

后端 未结 7 901
礼貌的吻别
礼貌的吻别 2020-12-31 04:52

I am working my way through a make tutorial. Very simple test projects I am trying to build has only 3 files: ./src/main.cpp ./src/implementation.cpp and

相关标签:
7条回答
  • 2020-12-31 05:12

    According to the make manual, you can use the implicit linking rule with multiple objects if one of these matches the executable name, eg:

    VPATH = src include
    CPPFLAGS = -I include
    
    main: implementation.o
    main.o: header.hpp
    implementation.o: header.hpp
    

    This will build an executable named main from both main.o and implementation.o.

    Note however that the builtin implicit rule uses the C compiler for linking, which will not link against the C++ std library by default, you will need to add the flag -lstdc++ to LDLIBS explicitly

    0 讨论(0)
  • 2020-12-31 05:15

    How about this for a minimal Makefile:

    SOURCES = src/main.cpp src/implementation.cpp
    
    CXX = g++
    CXXFLAGS = -g -W -Wall -Werror
    LDFLAGS = -g
    
    OBJECTS = $(SOURCES:.cpp=.o)
    
    prog: $(OBJECTS)
        $(CXX) $(LDFLAGS) -o $@ $^
    
    clean::
        $(RM) prog
    
    .cpp.o:
        $(CXX) -MD -MP $(CXXFLAGS) -o $@ -c $<
    
    clean::
        $(RM) src/*.o
    
    DEPENDS = $(SOURCES:.cpp=.d)
    
    -include $(DEPENDS)
    
    %.d:
        @touch $@
    
    clean::
        $(RM) src/*.d
    

    This assumes GNU make and gcc, but it adds proper dependency tracking, so there is no need to explicitly list the header file dependencies.

    0 讨论(0)
  • 2020-12-31 05:16

    There supposed to be an implicit rule for prog or I am missing something?

    There is no implicit rule. make cannot know how to build prog because it doesn’t know that prog is supposed to be an executable. make only uses the file name as a pattern to deduce the build rule. prog is a generic file name without extension so make doesn’t know how to treat it.

    0 讨论(0)
  • 2020-12-31 05:17

    Hmm...

    CXX = g++               # Just an example
    CXXFLAGS = -Wall -O2    # Just an example
    
    prog: main.o implementation.o
        $(CXX) $(CXXFLAGS) $^ -o $@
    
    main.o: header.hpp
    implementation.o: header.hpp
    

    should do the job. Why your variant isn't working is explained in Konrad Rudolph answer

    0 讨论(0)
  • 2020-12-31 05:22

    If you want to link c++ object files you can specify LINK.o to be LINK.cc at the top

    LINK.o := $(LINK.cc)
    

    You should then see c++ instead of cc in your make output

    0 讨论(0)
  • 2020-12-31 05:27

    The implicit rule for linking object files is:

    $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
    

    But $(LINK.o) uses $(CC), which is not quite correct for compiling C++ programs, so the easiest fix is:

    CC = $(CXX)
    
    0 讨论(0)
提交回复
热议问题