리눅스에서 gcc를위한 간단한 makefile을 어떻게 만드나요?


130

나는 세 개의 파일이 있습니다 program.c, program.h하고 headers.h.

program.c포함 program.h하고 headers.h.

gcc 컴파일러를 사용하여 Linux에서 이것을 컴파일해야합니다 . 이 작업을 수행하는 방법을 잘 모르겠습니다. Netbeans는 나를 위해 하나를 만들었지 만 비어 있습니다.


1
spin.atomicobject.com/2016/08/26/makefile-c-projects 에는 매우 우아하고 잘 문서화 된 솔루션이 있습니다 .
Casey

답변:


193

흥미롭게도, 소스 파일에 관한 규칙이 주어진 C 컴파일러를 사용하는 것이 기본값인지 몰랐습니다.

어쨌든 간단한 Makefile 개념을 보여주는 간단한 솔루션은 다음과 같습니다.

HEADERS = program.h headers.h

default: program

program.o: program.c $(HEADERS)
    gcc -c program.c -o program.o

program: program.o
    gcc program.o -o program

clean:
    -rm -f program.o
    -rm -f program

(공간 들여 쓰기 대신 탭이 필요하므로 복사 할 때 수정해야 함을 명심하십시오)

그러나 더 많은 C 파일을 지원하려면 각 파일에 대해 새로운 규칙을 만들어야합니다. 따라서 다음을 개선하십시오.

HEADERS = program.h headers.h
OBJECTS = program.o

default: program

%.o: %.c $(HEADERS)
    gcc -c $< -o $@

program: $(OBJECTS)
    gcc $(OBJECTS) -o $@

clean:
    -rm -f $(OBJECTS)
    -rm -f program

나는 보통 makefile에서 보이는 $ (CC)와 $ (CFLAGS)와 같은 변수를 생략함으로써 이것을 가능한 한 단순하게 만들려고 노력했다. 당신이 그것을 알아내는 데 관심이 있다면, 나는 당신에게 좋은 시작을 해주기를 바랍니다.

다음은 C 소스에 사용하려는 Makefile입니다. 자유롭게 사용하십시오 :

TARGET = prog
LIBS = -lm
CC = gcc
CFLAGS = -g -Wall

.PHONY: default all clean

default: $(TARGET)
all: default

OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))
HEADERS = $(wildcard *.h)

%.o: %.c $(HEADERS)
    $(CC) $(CFLAGS) -c $< -o $@

.PRECIOUS: $(TARGET) $(OBJECTS)

$(TARGET): $(OBJECTS)
    $(CC) $(OBJECTS) -Wall $(LIBS) -o $@

clean:
    -rm -f *.o
    -rm -f $(TARGET)

make 유틸리티의 와일드 카드 및 patsubst 기능을 사용하여 현재 디렉토리에 .c 및 .h 파일을 자동으로 포함합니다. 즉, 디렉토리에 새 코드 파일을 추가 할 때 Makefile을 업데이트 할 필요가 없습니다. 그러나 생성 된 실행 파일, 라이브러리 또는 컴파일러 플래그의 이름을 변경하려면 변수를 수정하면됩니다.

두 경우 모두 autoconf를 사용하지 마십시오. 부탁합니다! :)


7
기술적으로 정확하기 위해서는 .PHONY: clean all default커맨드 라인에서 사용되는 대상에 사용해야한다고 생각합니다 . 또한 Autoconf / Automake는 그렇게 나쁘지 않습니다. 물론, 그들은 끔찍하다고 느끼고 그들에게 익숙해지는 것은 벽돌 벽을 통해 머리를 강요하는 것만 큼 재미 있지만, 일을하고 잘 발달되어 있으며, 대부분의 기지를 휴대 할 수있을 정도로 덮을 것입니다. 당신이 그들의 끔찍한 디자인에 익숙해지면 결국 인생을 훨씬 쉽게 만들 것입니다.
Chris Lutz

나는 이것이 작동하는 것 같지만 터미널에서 "make"를 입력하면 프로그램이 실행되어야한다고 생각했다. 이것이 내가 얻는 것입니다 : gcc statsh.o -Wall -lm -o prog 그냥 make를 입력하고 프로그램을 실행할 수 있습니까?
user69514

어디에 openmp 플래그를 추가하겠습니까 -fopenmp
MySchizoBuddy

1
autoconf joey-adams를 사용하지 않는 이유는 무엇입니까?
Michal Gonda

7
누군가 왜 대시 앞에 대시가 있는지 궁금하다면 rm: stackoverflow.com/questions/2989465/rm-rf-versus-rm-rf
Tor Klingberg

25

예를 들어이 간단한 Makefile이면 충분합니다.

CC = gcc 
CFLAGS =-벽

모두 : 프로그램
프로그램 : program.o
program.o : program.c program.h 헤더 .h

깨끗한:
    rm -f 프로그램 program.o
실행 : 프로그램
    ./프로그램

<tab>공백이 아니라 청소 및 실행 후에 다음 줄에 있어야 합니다.

아래의 댓글 업데이트 적용


@ user69514 : make인수없이 일반적으로 소프트웨어 만 빌드 하십시오. 실행하려면 make run(이 답변에서 사용 가능하지만 반드시 모든 것은 아닙니다 Makefile) 직접 실행하십시오../program
MestreLion

14
all: program
program.o: program.h headers.h

충분하다. 나머지는 암시 적입니다


1
전체 프로그램이 단일 .c파일 인 경우에만 program:필요합니다. Sweet :)
MestreLion

10

가장 간단한 make 파일은

all : test

test : test.o
        gcc -o test test.o 

test.o : test.c
        gcc -c test.c

clean :
        rm test *.o

Makefile의 기능을 설명하기 위해 더 자세한 내용을 추가 할 수 있습니다
Federico

2
실제로 훨씬 더 간단하게 갈 수 있습니다. @anonymous 1 liner 참조
Mark Lakata

0

헤더 수와 개발 습관에 따라 gccmakedep을 조사 할 수 있습니다. 이 프로그램은 현재 디렉토리를 검사하고 각 .c / cpp 파일에 대한 헤더 종속성을 make 파일의 끝에 추가합니다. 두 개의 헤더와 하나의 프로그램 파일이 있으면 과잉입니다. 그러나 5 개 이상의 작은 테스트 프로그램이 있고 10 개의 헤더 중 하나를 편집하는 경우 수정에 의해 변경된 프로그램을 정확하게 다시 작성하도록 신뢰할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.