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)
규칙에는 대상 이름이 규칙이 구축하는 내용을 실제로 설명하지 않는 것과 동일한 문제가 있다.그렇기 때문에 만약 당신이 타이핑을 한다면make
Make는 그럴 이유가 없는데도 매번 목표를 다시 세울 것이다.작은 변화로 다음과 같은 해결책:
$(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 |