src /의 모든 .cpp 파일을 obj /의 .o로 컴파일 한 다음 ./의 바이너리에 연결할 수 있습니까? Makefile

내 프로젝트 디렉토리는 다음과 같습니다.

/project
    Makefile
    main
    /src
        main.cpp
        foo.cpp
        foo.h
        bar.cpp
        bar.h
    /obj
        main.o
        foo.o
        bar.o

나는 모든 컴파일하는 것입니다 할 내 메이크 싶은 무엇 .cpp의 파일 /src에 폴더를 .o에있는 파일 /obj폴더를 모든 링크 .o에있는 파일을 /obj최상위 폴더에 출력 바이너리로 /project.

나는 Makefiles에 대한 경험이 거의 없으며 이것을 달성하기 위해 무엇을 검색 해야할지 잘 모르겠습니다.

또한이 작업을 수행하는 “좋은”방법입니까, 아니면 내가하려는 작업에 대한보다 표준적인 접근 방식이 있습니까?



답변

질문의 Makefile 부분

일반화 할 필요가없는 한 아래 코드와 같은 것을 시도하지 않는 한 이것은 매우 쉽습니다 (하지만 공백 들여 쓰기를 g ++ 근처의 탭으로 대체).

SRC_DIR := .../src
OBJ_DIR := .../obj
SRC_FILES := $(wildcard $(SRC_DIR)/*.cpp)
OBJ_FILES := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRC_FILES))
LDFLAGS := ...
CPPFLAGS := ...
CXXFLAGS := ...

main.exe: $(OBJ_FILES)
   g++ $(LDFLAGS) -o $@ $^

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
   g++ $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<

자동 종속성 그래프 생성

대부분의 make 시스템의 “필수”기능입니다. GCC를 사용하면 다음을 추가하여 컴파일의 부작용으로 단일 패스로 수행 할 수 있습니다.-MMD 에 플래그 CXXFLAGS -include $(OBJ_FILES:.o=.d) 메이크 본체의 끝 :

CXXFLAGS += -MMD
-include $(OBJ_FILES:.o=.d)

이미 언급했듯이 항상 GNU Make Manual을 사용하십시오. 을 사용하면 매우 유용합니다.


답변

와일드 카드도 저에게도 효과가 있지만 디렉토리 변수를 사용하는 사람들을 위해 부수적 인 메모를하고 싶습니다. 폴더 트리에는 항상 슬래시 (백 슬래시 아님)를 사용하십시오. 그렇지 않으면 실패합니다.

BASEDIR = ../..
SRCDIR = $(BASEDIR)/src
INSTALLDIR = $(BASEDIR)/lib

MODULES = $(wildcard $(SRCDIR)/*.cpp)
OBJS = $(wildcard *.o)


답변