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


116

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

/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에 대한 경험이 거의 없으며 이것을 달성하기 위해 무엇을 검색 해야할지 잘 모르겠습니다.

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



6
@aaa : OP가 각 소스 파일을 명시 적으로 나열 할 필요가없는 솔루션을 원한다고 생각합니다.
Cascabel

7
나는 내가 가지고있는 각 소스 파일을 지정하고 싶지 않고 그 매뉴얼을 전에 읽어 보려고했지만 그것이 혼란스럽고 이해하기 어렵다는 것을 알았다. 건식 한 기술 매뉴얼보다는 내가 기대하는 바를 잘 설명하고있는 실제 예제에서 훨씬 더 잘 배운다.
Austin Hyde

괜찮아. 그러나 make 문서는 좋은 예제와 함께 훌륭합니다 (기술 매뉴얼을 시도하지 않습니다). 패턴 규칙을 찾고 있습니다 : gnu.org/software/make/manual/make.html#Pattern-Rules
Anycorn

11
내가 원하는 것과 조금 더 비슷해 보입니다. IMHO, make 매뉴얼은 make가 중간 수준 인 개발자를 대상으로하는 것으로 보이며 그 이상으로 매우 크고 심층적이므로 약간 건조합니다. 아마도 너무 많을 것입니다.
Austin Hyde

답변:


180

질문의 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을 사용하십시오. 을 사용하면 매우 유용합니다.


11
아, 당신은 나를 초로 이겼습니다. 그러나 나는 제안한다 OBJ_FILES = $(patsubst src/%.cpp,obj/%.o,$(CPP_FILES)).
Beta

1
나는 그것이 작동하기 위해 이것을 변경 $<해야 했다 : $^main.exe의 규칙 이어야하며 obj/%.o: src/%cpp.

1
@bobah '.'가 누락되었습니다. cpp에 대한 개체 규칙에서
regomodo

1
특수 변수는 makefile이 특정하고 검색하기 어렵 기 때문에 설명 할 가치가있을 것입니다. gnu.org/software/make/manual/html_node/Automatic-Variables.html
Blake

2
나는 이것이 오래된 질문이라는 것을 알고 있지만 내 프로젝트에 따라 약간 수정했지만 작동하지 않습니다. 내 makefile은 다음과 같습니다. pastebin.com/4CksG9Wc 콘솔에 있습니다.make: *** No rule to make target '/main.o', needed by 'bin/main'. Pare.
Mateus Felipe

5

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

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

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

슬래시를 의미 했습니까? 귀하의 예는 전통적으로 슬래시로 간주되는 것을 보여줍니다. 특히, 사람은 "바로 기대어" "앞으로"로 간주하고 고려 남아있는 사람은 "다시"로
에반 테란

예, 맞습니다. "슬래시"만 의미합니다. 게시물을 업데이트했습니다.
xesf 2014-06-18
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.