SRC, OBJ, BIN 하위 디렉터리를 사용하여 C 프로젝트의 Makefile을 생성하는 방법은?
몇 달 전에 나는 다음과 같은 일반론을 생각해 냈다.Makefile학교 과제:
# ------------------------------------------------
# Generic Makefile
#
# Author: yanick.rochon@gmail.com
# Date : 2010-11-05
#
# Changelog :
# 0.01 - first version
# ------------------------------------------------
# project name (generate executable with this name)
TARGET = projectname
CC = gcc -std=c99 -c
# compiling flags here
CFLAGS = -Wall -I.
LINKER = gcc -o
# linking flags here
LFLAGS = -Wall
SOURCES := $(wildcard *.c)
INCLUDES := $(wildcard *.h)
OBJECTS := $(SOURCES:.c=*.o)
rm = rm -f
$(TARGET): obj
@$(LINKER) $(TARGET) $(LFLAGS) $(OBJECTS)
@echo "Linking complete!"
obj: $(SOURCES) $(INCLUDES)
@$(CC) $(CFLAGS) $(SOURCES)
@echo "Compilation complete!"
clean:
@$(rm) $(TARGET) $(OBJECTS)
@echo "Cleanup complete!"
이것은 기본적으로 모든 것을 컴파일할 것이다..c그리고.h생성할 파일.o파일 및 실행 파일projectname모두 같은 폴더로
자, 이걸 좀 밀어보고 싶은데.다음 디렉토리 구조를 사용하여 C 프로젝트를 컴파일하기 위해 Makefile을 작성하려면 어떻게 해야 하는가?
./
./Makefile
./src/*.c;*.h
./obj/*.o
./bin/<executable>
즉, C 소스를 컴파일하여 C 소스를 컴파일하는 것을 원한다../src/로./obj/모든 것을 연결하여 실행 파일을./bin/.
나는 다른 Makefiles를 읽으려고 노력했지만 위의 프로젝트 구조에서 사용할 수 있도록 할 수는 없다. 대신, 프로젝트는 모든 종류의 오류로 컴파일되지 않는다.물론 완전한 IDE(Monodevelop, Anjuta 등)를 사용할 수도 있지만, 솔직히 gEdit와 good ol' 단말기를 고수하는 것이 더 좋다.
내게 작업 해결책을 줄 수 있는 전문가가 있는가, 아니면 어떻게 이 일을 할 수 있는지에 대한 명확한 정보를 줄 수 있는가?고마워!
** 업데이트(v4) **
최종 해결책:
# ------------------------------------------------
# Generic Makefile
#
# Author: yanick.rochon@gmail.com
# Date : 2011-08-10
#
# Changelog :
# 2010-11-05 - first version
# 2011-08-10 - added structure : sources, objects, binaries
# thanks to http://stackoverflow.com/users/128940/beta
# 2017-04-24 - changed order of linker params
# ------------------------------------------------
# project name (generate executable with this name)
TARGET = projectname
CC = gcc
# compiling flags here
CFLAGS = -std=c99 -Wall -I.
LINKER = gcc
# linking flags here
LFLAGS = -Wall -I. -lm
# change these to proper directories where each file should be
SRCDIR = src
OBJDIR = obj
BINDIR = bin
SOURCES := $(wildcard $(SRCDIR)/*.c)
INCLUDES := $(wildcard $(SRCDIR)/*.h)
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
rm = rm -f
$(BINDIR)/$(TARGET): $(OBJECTS)
@$(LINKER) $(OBJECTS) $(LFLAGS) -o $@
@echo "Linking complete!"
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
@$(CC) $(CFLAGS) -c $< -o $@
@echo "Compiled "$<" successfully!"
.PHONY: clean
clean:
@$(rm) $(OBJECTS)
@echo "Cleanup complete!"
.PHONY: remove
remove: clean
@$(rm) $(BINDIR)/$(TARGET)
@echo "Executable removed!"
먼저 당신의$(OBJECTS)규칙은 다음과 같은 이유로 문제가 있다.
- 무차별하게 모든 물체의 모든 원천을 만드는 거지
- (당신이 발견한 바와 같이) 잘못된 소스를 사용하는 경우가 많다.
file1.o그리고file2.o) - 객체에서 정지하는 대신 실행 파일을 작성하려고 시도하며,
- 대상의 이름().
foo.o)은 규칙이 실제로 만들어낼 것이 아니다.obj/foo.o).
나는 다음을 제안한다.
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $@
@echo "Compiled "$<" successfully!"
그$(TARGET)규칙에는 대상 이름이 규칙이 구축하는 내용을 실제로 설명하지 않는 것과 동일한 문제가 있다.그렇기 때문에 만약 당신이 타이핑을 한다면makeMake는 그럴 이유가 없는데도 매번 목표를 다시 세울 것이다.작은 변화로 다음과 같은 해결책:
$(BINDIR)/$(TARGET): $(OBJECTS)
$(LINKER) $@ $(LFLAGS) $(OBJECTS)
@echo "Linking complete!"
일단 순서가 잡히면 좀 더 정교한 종속성 처리를 고려할 수 있다. 헤더 파일 중 하나를 수정하면 이 makefile은 어떤 개체/실행 파일을 재구성해야 하는지 알 수 없다.하지만 그것은 다른 날을 기다릴 수 있다.
편집:
미안, 내가 그 중 일부를 빠뜨렸어.$(OBJECTS)위에 규칙; 수정했다. (코드 샘플 안에 "스트라이크"를 사용할 수 있으면 좋겠다.)
추가 가능-I컴파일러 플래그(CFLAGS)에 플래그를 지정하여 컴파일러가 소스 파일을 찾아야 하는 위치를 표시하고, -o 플래그를 사용하여 바이너리를 남겨 두어야 하는 위치를 표시:
CFLAGS = -Wall -I./src
TARGETPATH = ./bin
$(TARGET): obj
@$(LINKER) $(TARGETPATH)/$(TARGET) $(LFLAGS) $(OBJECTS)
@echo "Linking complete!"
오브젝트 파일을 에 드롭하려면obj디렉토리, 사용-o컴파일 시 옵션또한, 저것 좀 봐.$@그리고$< 자동 변수
예를 들어, 이 간단한 Makefile을 고려하십시오.
CFLAGS= -g -Wall -O3
OBJDIR= ./obj
SRCS=$(wildcard *.c)
OBJS=$(SRCS:.c=.o )
all:$(OBJS)
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $(OBJDIR)/$@
업데이트>
당신의 makefile을 보면, 나는 당신이 그 makefile을 사용하고 있다는 것을 알게 된다.-o깃발. 좋a. 계속 사용하려면 대상 디렉터리 변수를 추가하여 출력 파일을 쓸 위치를 지정하십시오.
나는 요즘 make file 쓰는 것을 그만뒀어. 만약 네가 계속 배우고 싶다면, 그렇지 않으면 넌 일식 CDT와 함께 나오는 좋은 makefile generator를 가지고 있어.빌드 트리에서 몇 가지 유지 보수성/여러 프로젝트 지원을 받으려면 다음을 살펴보십시오.
https://github.com/dmoulding/boilermake 나는 이것이 꽤 좋다는 것을 발견했다.
'programing' 카테고리의 다른 글
| Vue js 동적으로 구성 요소 가져오기 (0) | 2022.05.20 |
|---|---|
| Vue v-on:click.native in JSX? (0) | 2022.05.20 |
| 부동소수점비교 (0) | 2022.05.20 |
| 전처리기 매크로에서 "sizeof"를 사용하는 방법 (0) | 2022.05.20 |
| Laravel Passport 미들웨어 보호 경로 "인증되지 않음" 문제 (0) | 2022.05.20 |