2009-03-12 6 views
1

Makefile을 만드는 것에 대해 많이 알지 못하지만, 나는 make manual을 읽었으며 약간의 진전을 이루었습니다. Makefile이 작동하고 내가 원하는 것을합니다.어떻게이 Makefile을 향상시킬 수 있습니까?

내 상황은 일반적으로 웹 양식을 통해 마킹을 위해 TA에 보내고 컴파일해야하는 1 ~ 3 개의 서로 다른 프로그램이 필요합니다. 각 응용 프로그램의 구조는 'prog.c', 'prog_lib.h'및 'prog_lib.c'입니다. 과거에는 각 프로그램에 대해 별도의 디렉토리를 만들고 각 디렉토리에 별도의 Makefile을 만들어 내부에 포함 된 프로그램을 작성했습니다. 그런 다음 각 폴더를 타르 고 따로 제출하십시오.

최근에 TA는 모든 대상 파일이 하나의 디렉토리에 있고 여러 대상이 빌드 된 하나의 Makefile이 사용자의 개입 없이도 작동하도록 마킹 응용 프로그램을 만들 것을 요구했습니다.

더 많은 경험을 가진 사람이이 Makefile을 개선하고 내 상황이 일반적으로 어떻게 해결되는지 궁금합니다. 나는 다음 과제로 넘어갈 때해야 할 타이핑의 양을 줄이고 여러 장소를 업데이트해야한다.

여기 내 메이크입니다 : 내 경험에

ASSIGNMENT = 3 
TARNAME = Assignment$(ASSIGNMENT).tar.bz2 

CC = gcc 
CFLAGS = -O2 -Wall -ansi -pedantic -W # I like warnings 
LDFLAGS = -lm 
DEBUG = -g # to resolve symbols in GDB and valgrind 

FREQ_OUT = frequency_table 
FREQ_SOURCES = frequency_table.c frequency_table_lib.c 
FREQ_OBJECTS = frequency_table.o frequency_table_lib.o 

DECODE_OUT = decode 
DECODE_SOURCES = decode.c decode_lib.c 
DECODE_OBJECTS = decode.o decode_lib.o 

SOURCES = $(FREQ_SOURCES) $(DECODE_SOURCES) 
OBJECTS = $(FREQ_OBJECTS) $(DECODE_OBJECTS) 
OUT = $(FREQ_OUT) $(DECODE_OUT) 

.PHONY: info 
info: 
    @echo -e "make info\n" \ 
      "\tmake all \t\t\tMake all targets\n" \ 
      "\tmake frequency_table \t\tMakes frequency table\n" \ 
      "\tmake decode \t\t\tMakes decode\n" \ 
      "\tmake dist \t\t\tMakes tar archive of sources and Makefile\n" \ 
      "\tmake clean \t\t\tRemoves all the object files and executables\n" \ 
      "\tmake distclean \t\t\tPerforms clean and removes tar archive" 

.PHONY: all 
all: $(OUT) 

$(FREQ_OUT): $(FREQ_OBJECTS) 
    $(CC) $(CFLAGS) $(DEBUG) $(LDFLAGS) $(FREQ_OBJECTS) -o [email protected] 

$(DECODE_OUT): $(DECODE_OBJECTS) 
    $(CC) $(CFLAGS) $(DEBUG) $(LDFLAGS) $(DECODE_OBJECTS) -o [email protected] 

.o: 
    $(CC) -c $(CFLAGS) -o [email protected] $< 

.PHONY: dist 
dist: $(SOURCES) 
    @echo "Creating tar archive. See $(TARNAME)" 
    tar cvjf $(TARNAME) $(SOURCES) $(wildcard *_lib.h) Makefile 

.PHONY: clean 
clean: 
    rm -f $(OUT) $(OBJECTS) 

.PHONY: distclean 
distclean: clean 
    rm -f $(TARNAME) 
+0

코드에서 Makefile을 만드는 방법에 대해 잘 모르는 것 같습니다. – Lazer

답변

3

실제로는 $(CC) $(CFLAGS) $(DEBUG) $(LDFLAGS) $(FREQ_OBJECTS) -o [email protected] 행이 필요하지 않습니다. make는 이미 바이너리를 빌드하는 방법을 알고있다.

당신의 파일 이름이 다른 바이너리 (binary.c 및 binary_lib.c)에 대한 일정한 경우에, 당신은 또한에 대한 일반적인 규칙을 만들 수 있습니다

FOO := $(shell ls *_lib.c) 
BIN = $(FOO:%_lib.c=%) 

$(BIN) : % : %.o %_lib.o 

편집 : 어떻게 작동하는지은 다음과 같습니다

  1. FOO는
  2. BIN은 "_lib.c"접미사와 같은 목록이 제거 _lib.c로 끝나는 모든 파일의 목록입니다, 그래서 바이너리
  3. 을 목록입니다
  4. 마지막 줄이 당신의 make 규칙입니다. $ (BIN)의 각 푸 foo.o와 foo_lib.o 따라 규칙 상태
+0

이 코드는 실제로 작동하지만 정확히 작동하지 않는 이유는 아닙니다. 조금 더 명확히 해 주시겠습니까? 특히 $ (BIN) 라인. 유일한 목적은 어떤 목적을합니까? –

+0

설명해 주셔서 감사합니다. 나는이 방법을 사용하고 있으며 아주 잘 작동한다. –

+2

'ls'의 결과물을 파싱하는 것은 쉘 스크립트와 Makefiles에서 * 매우 * 나쁜 습관입니다. 'FOO : = $ (와일드 카드 * _lib.c)'가 훨씬 낫습니다. – MestreLion

2

, 당신은이 암시 적이다, 거기에 .o 대상을 필요가 없습니다.

또한, 암시 버전은 일반적으로 당신이 필요 수있는 -I경로 또는 -D매크로 옵션을 넣어해야하는 위치 인 $(CPPFLAGS)의 값이 포함되어 있습니다.

$(CFLAGS)에 포함 시키려면 빌드 대상 중 하나에 명시 적으로 지정하지 말아야합니다.

1

예 : 당신이 당신을 정말 확실하지 않으면

# CC, CFLAGS, etc. go here 

# Object variables go here 
MYPROG_OBJECTS = main.o someother.o 

# all, info, etc. targets go here 

# first actual target: 
myprog: $(MYPROG_OBJECTS) 
    <Do the linking stuff> 

# This will take care of the objects, sources are placed in src directory: 
%.o: src/%.c 
    <The usual compilation commands> 

# Automatic dependency magic: 
%.d: src/%.c 
    $(CC) -MM [email protected] $< 

-include (MYPROG_OBJECTS:%.o=%.d) 
3

은, '모든'대상 첫 번째 확인 사용자는 'make'다음에 무언가를 입력하여 프로젝트를 빌드해야합니다. '정보'목표는 좋지만 사실적입니다.

(기본 대상이 모두가 아닌 하나의 makefile이 있습니다 - 100 개 이상의 명령에 대한 소스 코드가있는 디렉토리에서 '모두 작성'을 기본값으로 설정하지 않으려 고합니다. 나는 두 가지를 만들고 싶습니다.'모두'가 있습니다. 그러나 그것은 매우 드문 경우입니다. 일반적으로 기본값은 'all'이어야합니다.

또한 '$ (FREQ_OUT)'또는 '$ (DECODE_OUT)'은 PHONY 대상이 아닙니다. 그들은 진짜 프로그램이지, 안 그래? 'all', 'info', 'dist', 'clean', 'realclean'등의 목표는 가짜입니다. 그러나 당신이 만드는 프로그램은 그렇지 않습니다.

+0

팁을 주셔서 감사 드리며 .PHONY 타겟이 맞는지 확인하십시오. 그 부분을 제거하고 예제를 업데이트했습니다. –

관련 문제