다른 디렉토리에 소스 파일이있는 Makefile
디렉토리 구조가 다음과 같은 프로젝트가 있습니다.
$projectroot
|
+---------------+----------------+
| | |
part1/ part2/ part3/
| | |
+------+-----+ +---+----+ +---+-----+
| | | | | | |
data/ src/ inc/ src/ inc/ src/ inc/
part / src에 있거나 또는 실제로 c / c ++ 소스 파일에서 컴파일 / 링크 할 수있는 makefile을 어떻게 작성해야합니까? / src?
-I $ projectroot / part1 / src -I $ projectroot / part1 / inc -I $ projectroot / part2 / src와 같은 작업을 수행 할 수 있습니까?
그것이 효과가 있다면 더 쉬운 방법이 있습니까? 해당하는 각 부분에 makefile이있는 프로젝트를 보았습니까? 폴더. [이 포스트에서 나는 bash 구문에서와 같이 물음표를 사용했다]
전통적인 방법은이 것입니다 Makefile
하위 디렉토리 (각각 part1
, part2
당신은 독립적으로 구축 할 수 등). 또한 Makefile
프로젝트의 루트 디렉토리에 모든 것을 빌드하십시오. "루트" Makefile
는 다음과 같습니다.
all:
+$(MAKE) -C part1
+$(MAKE) -C part2
+$(MAKE) -C part3
make 대상의 각 행은 자체 쉘에서 실행되므로 디렉토리 트리 또는 다른 디렉토리로의 순회에 대해 걱정할 필요가 없습니다.
GNU make 매뉴얼 섹션 5.7을 살펴 보는 것이 좋습니다 . 매우 도움이됩니다.
한 서브 디렉토리에 다른 서브 디렉토리의 코드에 종속 된 코드가있는 경우 최상위 레벨의 단일 makefile을 사용하는 것이 좋습니다.
참조 유해 고려 재귀 만들기 전체 근거에 대한,하지만 기본적으로는 make가 그것을 다시 작성 여부 파일 요구 사항을 결정하는 데 필요한 모든 정보를 갖고 싶어, 그리고 당신 만의 대략 세 번째를 말한다면 것을 필요가 없습니다 당신의 프로젝트.
위의 링크에 접근 할 수없는 것 같습니다. 동일한 문서를 여기에서 찾을 수 있습니다 :
VPATH 옵션이 유용 할 수 있는데, 이는 소스 코드를 찾을 디렉토리를 지정합니다. 그래도 각 포함 경로에 대해 -I 옵션이 필요합니다. 예를 들면 :
CXXFLAGS=-Ipart1/inc -Ipart2/inc -Ipart3/inc
VPATH=part1/src:part2/src:part3/src
OutputExecutable: part1api.o part2api.o part3api.o
그러면 VPATH 지정 디렉토리에서 일치하는 partXapi.cpp 파일을 자동으로 찾아서 컴파일합니다. 그러나 이것은 src 디렉토리가 서브 디렉토리로 분리 될 때 더 유용합니다. 다른 사람들이 말했듯이, 특히 각 부분이 독립적 일 수 있다면 각 부분에 대한 makefile을 사용하는 것이 좋습니다.
다른 디렉토리에서 필요한 cpp 파일을 컴파일하기 위해 루트 Makefile에 규칙을 추가 할 수 있습니다. 아래의 Makefile 예제는 원하는 곳으로가는 좋은 출발점이되어야합니다.
CC = g ++ 목표 = cppTest OTHERDIR = .. / .. / someotherpath / in / project / src 소스 = cppTest.cpp 소스 = $ (OTHERDIR) /file.cpp ## 최종 소스 정의 INCLUDE = -I./ $ (AN_INCLUDE_DIR) INCLUDE = -I. $ (OTHERDIR) /../ inc ## 더 포함 VPATH = $ (OTHERDIR) OBJ = $ (가입 $ (addsuffix ../obj/, $ (dir $ (SOURCE))), $ (notdir $ (SOURCE : .cpp = .o)) ## 의존 목적지를 src 디렉토리에 대해 ../.dep로 수정 DEPENDS = $ (가입 $ (addsuffix ../.dep/, $ (dir $ (SOURCE))), $ (notdir $ (SOURCE : .cpp = .d)) ## 기본 규칙 실행 모두 : $ (TARGET) @진실 ## 깨끗한 규칙 깨끗한: @ -rm -f $ (대상) $ (OBJ) $ (DEPENDS) ## 실제 목표를 만들기위한 규칙 $ (대상) : $ (OBJ) @echo "=============" @echo "대상 연결 $ @" @echo "=============" @ $ (CC) $ (CFLAGS) -o $ @ $ ^ $ (LIBS) @echo-링크 완료- ## 일반 컴파일 규칙 % .o : % .cpp @mkdir -p $ (디렉토리 $ @) @echo "=============" @echo "$ <"컴파일 @ $ (CC) $ (CFLAGS) -c $ <-o $ @ ## cpp 파일의 객체 파일 규칙 ## 각 파일의 오브젝트 파일은 obj 디렉토리에 있습니다 ## 실제 소스 디렉토리에서 한 단계 위 ../obj/%.o : % .cpp @mkdir -p $ (디렉토리 $ @) @echo "=============" @echo "$ <"컴파일 @ $ (CC) $ (CFLAGS) -c $ <-o $ @ # "other directory"에 대한 규칙 "other"디렉토리마다 하나씩 필요합니다. $ (OTHERDIR) /../ obj / %. o : % .cpp @mkdir -p $ (디렉토리 $ @) @echo "=============" @echo "$ <"컴파일 @ $ (CC) $ (CFLAGS) -c $ <-o $ @ ## 의존성 규칙 만들기 ../.dep/%.d : % .cpp @mkdir -p $ (디렉토리 $ @) @echo "=============" $ *. o의 @echo Building 의존성 파일 @ $ (SHELL) -ec '$ (CC) -M $ (CFLAGS) $ <| sed "s ^ $ *. o ^ .. / obj / $ *. o ^"> $ @ ' ## "기타"디렉토리에 대한 종속성 규칙 $ (OTHERDIR) /../. dep / %. d : % .cpp @mkdir -p $ (디렉토리 $ @) @echo "=============" $ *. o의 @echo Building 의존성 파일 @ $ (SHELL) -ec '$ (CC) -M $ (CFLAGS) $ <| sed "s ^ $ *. o ^ $ (OTHERDIR) /../ obj / $ *. o ^"> $ @ ' ## 의존성 파일 포함 -포함 $ (DEPENDS)
If the sources are spread in many folders, and it makes sense to have individual Makefiles then as suggested before, recursive make is a good approach, but for smaller projects I find it easier to list all the source files in the Makefile with their relative path to the Makefile like this:
# common sources
COMMON_SRC := ./main.cpp \
../src1/somefile.cpp \
../src1/somefile2.cpp \
../src2/somefile3.cpp \
I can then set VPATH
this way:
VPATH := ../src1:../src2
Then I build the objects:
COMMON_OBJS := $(patsubst %.cpp, $(ObjDir)/%$(ARCH)$(DEBUG).o, $(notdir $(COMMON_SRC)))
Now the rule is simple:
# the "common" object files
$(ObjDir)/%$(ARCH)$(DEBUG).o : %.cpp Makefile
@echo creating $@ ...
$(CXX) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
And building the output is even easier:
# This will make the cbsdk shared library
$(BinDir)/$(OUTPUTBIN): $(COMMON_OBJS)
@echo building output ...
$(CXX) -o $(BinDir)/$(OUTPUTBIN) $(COMMON_OBJS) $(LFLAGS)
One can even make the VPATH
generation automated by:
VPATH := $(dir $(COMMON_SRC))
Or using the fact that sort
removes duplicates (although it should not matter):
VPATH := $(sort $(dir $(COMMON_SRC)))
I think it's better to point out that using Make (recursive or not) is something that usually you may want to avoid, because compared to today tools, it's difficult to learn, maintain and scale.
It's a wonderful tool but it's direct use should be considered obsolete in 2010+.
Unless, of course, you're working in a special environment i.e. with a legacy project etc.
Use an IDE, CMake or, if you're hard cored, the Autotools.
(edited due to downvotes, ty Honza for pointing out)
RC's post was SUPER useful. I never thought about using the $(dir $@) function, but it did exactly what I needed it to do.
In parentDir, have a bunch of directories with source files in them: dirA, dirB, dirC. Various files depend on the object files in other directories, so I wanted to be able to make one file from within one directory, and have it make that dependency by calling the makefile associated with that dependency.
Essentially, I made one Makefile in parentDir that had (among many other things) a generic rule similar to RC's:
%.o : %.cpp @mkdir -p $(dir $@) @echo "=============" @echo "Compiling $<" @$(CC) $(CFLAGS) -c $< -o $@
Each subdirectory included this upper-level makefile in order to inherit this generic rule. In each subdirectory's Makefile, I wrote a custom rule for each file so that I could keep track of everything that each individual file depended on.
Whenever I needed to make a file, I used (essentially) this rule to recursively make any/all dependencies. Perfect!
NOTE: there's a utility called "makepp" that seems to do this very task even more intuitively, but for the sake of portability and not depending on another tool, I chose to do it this way.
Hope this helps!
all:
+$(MAKE) -C part1
+$(MAKE) -C part2
+$(MAKE) -C part3
This allows for make
to split into jobs and use multiple cores
I was looking for something like this and after some tries and falls i create my own makefile, I know that's not the "idiomatic way" but it's a begining to understand make and this works for me, maybe you could try in your project.
PROJ_NAME=mono
CPP_FILES=$(shell find . -name "*.cpp")
S_OBJ=$(patsubst %.cpp, %.o, $(CPP_FILES))
CXXFLAGS=-c \
-g \
-Wall
all: $(PROJ_NAME)
@echo Running application
@echo
@./$(PROJ_NAME)
$(PROJ_NAME): $(S_OBJ)
@echo Linking objects...
@g++ -o $@ $^
%.o: %.cpp %.h
@echo Compiling and generating object $@ ...
@g++ $< $(CXXFLAGS) -o $@
main.o: main.cpp
@echo Compiling and generating object $@ ...
@g++ $< $(CXXFLAGS)
clean:
@echo Removing secondary things
@rm -r -f objects $(S_OBJ) $(PROJ_NAME)
@echo Done!
I know that's simple and for some people my flags are wrong, but as i said this is my first Makefile to compile my project in multiple dirs and link all of then together to create my bin.
I'm accepting sugestions :D
I suggest to use autotools
:
//##
Place generated object files (.o) into the same directory as their source files, in order to avoid collisions when non-recursive make is used.
AUTOMAKE_OPTIONS = subdir-objects
just including it in Makefile.am
with the other quite simple stuff.
Here is the tutorial.
참고URL : https://stackoverflow.com/questions/1139271/makefiles-with-source-files-in-different-directories
'IT story' 카테고리의 다른 글
Java를 사용하여 텍스트를 클립 보드에 복사 (0) | 2020.07.14 |
---|---|
부트 스트랩 4 센터 수직 및 수평 정렬 (0) | 2020.07.14 |
C에서 변수 선언 배치 (0) | 2020.07.14 |
Django 모델에 목록을 저장하는 가장 효율적인 방법은 무엇입니까? (0) | 2020.07.14 |
iPad / iPhone 호버 문제로 인해 사용자가 링크를 두 번 클릭 (0) | 2020.07.14 |