2010-07-08 6 views
4

저는 베타, 폴 R 및 Sjoerd (덕분에 얘들 아!)의 도움으로 메이크 파일을 크게 리팩터링했습니다.메이크 파일 화장 - 거의 완료, 피드백 받기

#Nice, wonderful makefile written by Jason 
CC=g++ 
CFLAGS=-c -Wall 
BASE_DIR:=. 
SOURCE_DIR:=$(BASE_DIR)/source 
BUILD_DIR:=$(BASE_DIR)/build 
TEST_DIR:=$(BASE_DIR)/build/tests 
MAKEFILE_DIR:=$(BASE_DIR)/makefiles 
DATA_DIR:=$(BASE_DIR)/data 
DATA_DIR_TESTS:=$(DATA_DIR)/tests 
MOLECULE_UT_SOURCES := $(SOURCE_DIR)/molecule_test/main.cc \ 
    $(SOURCE_DIR)/molecule_manager.h \ 
    $(SOURCE_DIR)/molecule_manager.cpp \ 
    $(SOURCE_DIR)/molecule_manager_main.h \ 
    $(SOURCE_DIR)/molecule_manager_main.cpp \ 
    $(SOURCE_DIR)/molecule_reader.h \ 
    $(SOURCE_DIR)/molecule_reader.cpp \ 
    $(SOURCE_DIR)/molecule_reader_psf_pdb.h \ 
    $(SOURCE_DIR)/molecule_reader_psf_pdb.cpp \ 
    $(SOURCE_DIR)/parameter_manager_lj_molecule.h \ 
    $(SOURCE_DIR)/parameter_manager_lj_molecule.cpp \ 
    $(SOURCE_DIR)/parameter_manager.h \ 
    $(SOURCE_DIR)/parameter_manager.cpp \ 
    $(SOURCE_DIR)/parser.h \ 
    $(SOURCE_DIR)/parser.cpp \ 
    $(SOURCE_DIR)/common.h 
MOLECULE_UT_DATA := \ 
    $(DATA_DIR_TESTS)/molecule_test/par_oxalate_and_friends.inp \ 
    $(DATA_DIR_TESTS)/molecule_test/dicarboxy-octane_4.pdb \ 
    $(DATA_DIR_TESTS)/molecule_test/dicarboxy-octane_4.psf 
PARAM_UT_SOURCES := $(SOURCE_DIR)/parameter_test/main.cc \ 
    $(SOURCE_DIR)/parameter_manager_lj_molecule.h \ 
    $(SOURCE_DIR)/parameter_manager_lj_molecule.cpp \ 
    $(SOURCE_DIR)/parameter_manager.h \ 
    $(SOURCE_DIR)/parameter_manager.cpp \ 
    $(SOURCE_DIR)/parser.h \ 
    $(SOURCE_DIR)/parser.cpp \ 
    $(SOURCE_DIR)/common.h 
PARAM_UT_DATA := $(DATA_DIR_TESTS)/molecule_test/par_oxalate_and_friends.inp 

molecule_test : molecule_test_prepare_sources molecule_test_prepare_makefiles \ 
    molecule_test_prepare_data_files 
    @$(shell cd $(TEST_DIR)/molecule_unit_test/; \ 
    make ./bin/molecule_test) 

molecule_test_prepare_sources: molecule_test_dir 
    @echo Copying sources... 
    @cp --preserve $(MOLECULE_UT_SOURCES) \ 
    $(TEST_DIR)/molecule_unit_test/source 

molecule_test_prepare_makefiles: $(MAKEFILE_DIR)/Makefile.molecule_test 
    @cp --preserve $(MAKEFILE_DIR)/Makefile.molecule_test \ 
    $(TEST_DIR)/molecule_unit_test/Makefile 

molecule_test_prepare_data_files: 
    cp --preserve $(MOLECULE_UT_DATA) $(TEST_DIR)/molecule_unit_test/bin/ 

molecule_test_dir: 
    @if test -d $(BUILD_DIR); then \ 
     echo Build exists...; \ 
     else \ 
     echo Build directory does not exist, making build dir...; \ 
    mkdir $(BUILD_DIR); \ 
     fi 
    @if test -d $(TEST_DIR); then \ 
     echo Tests exists...; \ 
     else \ 
     echo Tests directory does not exist, making tests dir...; \ 
    mkdir $(TEST_DIR); \ 
     fi 
    @if test -d $(TEST_DIR)/molecule_unit_test; then \ 
     echo Molecule unit test directory exists...; \ 
     else \ 
     echo Molecule unit test directory does \ 
     not exist, making build dir...; \ 
     mkdir $(TEST_DIR)/molecule_unit_test; \ 
     fi 
    @if test -d $(TEST_DIR)/molecule_unit_test/source; then \ 
     echo Molecule unit test source directory exists...; \ 
     else \ 
     echo Molecule unit test source directory does \ 
     not exist, making build dir...; \ 
     mkdir $(TEST_DIR)/molecule_unit_test/source; \ 
     fi 
    @if test -d $(TEST_DIR)/molecule_unit_test/obj; then \ 
     echo Molecule unit test object directory exists...; \ 
     else \ 
     echo Molecule unit test object directory does \ 
     not exist, making object dir...; \ 
     mkdir $(TEST_DIR)/molecule_unit_test/obj; \ 
     fi 
    @if test -d $(TEST_DIR)/molecule_unit_test/bin; then \ 
     echo Molecule unit test executable directory exists...; \ 
     else \ 
     echo Molecule unit test executable directory does \ 
     not exist, making executable dir...; \ 
     mkdir $(TEST_DIR)/molecule_unit_test/bin; \ 
     fi 

param_test : param_test_prepare_sources param_test_prepare_makefiles \ 
    param_test_prepare_data_files 
    @$(shell cd $(TEST_DIR)/param_unit_test/; \ 
    make ./bin/param_test) 

param_test_prepare_sources: param_test_dir 
    @echo Copying sources... 
    @cp --preserve $(PARAM_UT_SOURCES) $(TEST_DIR)/param_unit_test/source 

param_test_prepare_makefiles: $(MAKEFILE_DIR)/Makefile.param_test 
    @cp --preserve $(MAKEFILE_DIR)/Makefile.param_test \ 
    $(TEST_DIR)/param_unit_test/Makefile 

param_test_prepare_data_files: 
    cp --preserve $(PARAM_UT_DATA) $(TEST_DIR)/param_unit_test/bin/ 

param_test_dir: 
    @if test -d $(BUILD_DIR); then \ 
     echo Build exists...; \ 
     else \ 
     echo Build directory does not exist, making build dir...; \ 
    mkdir $(BUILD_DIR); \ 
     fi 
    @if test -d $(TEST_DIR); then \ 
     echo Tests exists...; \ 
     else \ 
     echo Tests directory does not exist, making tests dir...; \ 
    mkdir $(TEST_DIR); \ 
     fi 
    @if test -d $(TEST_DIR)/param_unit_test; then \ 
     echo Param unit test directory exists...; \ 
     else \ 
     echo Param unit test directory does \ 
     not exist, making build dir...; \ 
     mkdir $(TEST_DIR)/param_unit_test; \ 
     fi 
    @if test -d $(TEST_DIR)/param_unit_test/source; then \ 
     echo Param unit test source directory exists...; \ 
     else \ 
     echo Param unit test source directory does \ 
     not exist, making build dir...; \ 
     mkdir $(TEST_DIR)/param_unit_test/source; \ 
     fi 
    @if test -d $(TEST_DIR)/param_unit_test/obj; then \ 
     echo Param unit test object directory exists...; \ 
     else \ 
     echo Param unit test object directory does \ 
     not exist, making object dir...; \ 
     mkdir $(TEST_DIR)/param_unit_test/obj; \ 
     fi 
    @if test -d $(TEST_DIR)/param_unit_test/bin; then \ 
     echo Param unit test executable directory exists...; \ 
     else \ 
     echo Param unit test executable directory does \ 
     not exist, making executable dir...; \ 
     mkdir $(TEST_DIR)/param_unit_test/bin; \ 
     fi 

... 그리고 서브 메이크 :

#Nice, wonderful makefile written by Jason 
CC=g++ 
CFLAGS=-c -Wall 
SOURCE_DIR:=./source 
OBJ_DIR:=./obj 
EXE_DIR:=./bin 

$(EXE_DIR)/molecule_test : $(OBJ_DIR)/main.o \ 
    $(OBJ_DIR)/parameter_manager_lj_molecule.o \ 
    $(OBJ_DIR)/parameter_manager.o $(OBJ_DIR)/parser.o \ 
    $(OBJ_DIR)/molecule_manager.o $(OBJ_DIR)/molecule_manager_main.o \ 
    $(OBJ_DIR)/molecule_reader.o \ 
    $(OBJ_DIR)/molecule_reader_psf_pdb.o 
    @$(CC) $(OBJ_DIR)/main.o $(OBJ_DIR)/parameter_manager.o \ 
    $(OBJ_DIR)/parser.o $(OBJ_DIR)/parameter_manager_lj_molecule.o \ 
    $(OBJ_DIR)/molecule_manager.o $(OBJ_DIR)/molecule_manager_main.o \ 
    $(OBJ_DIR)/molecule_reader.o \ 
    $(OBJ_DIR)/molecule_reader_psf_pdb.o \ 
    -o molecule_test 
    @mv molecule_test $(EXE_DIR)/ 

$(OBJ_DIR)/main.o: $(SOURCE_DIR)/parameter_manager.h \ 
    $(SOURCE_DIR)/parameter_manager_lj_molecule.h \ 
    $(SOURCE_DIR)/molecule_manager.h \ 
    $(SOURCE_DIR)/molecule_manager_main.h \ 
    $(SOURCE_DIR)/molecule_reader.h \ 
    $(SOURCE_DIR)/molecule_reader_psf_pdb.h \ 
    $(SOURCE_DIR)/common.h $(SOURCE_DIR)/main.cc 
    $(CC) $(CFLAGS) $(SOURCE_DIR)/main.cc 
    @mv main.o $(OBJ_DIR)/ 

$(OBJ_DIR)/molecule_reader.o: $(SOURCE_DIR)/parameter_manager.h \ 
    $(SOURCE_DIR)/parameter_manager_lj_molecule.h \ 
    $(SOURCE_DIR)/molecule_manager.h \ 
    $(SOURCE_DIR)/molecule_manager_main.h \ 
    $(SOURCE_DIR)/molecule_reader.h \ 
    $(SOURCE_DIR)/common.h 
    $(CC) $(CFLAGS) $(SOURCE_DIR)/molecule_reader.cpp 
    @mv molecule_reader.o $(OBJ_DIR)/ 

$(OBJ_DIR)/molecule_reader_psf_pdb.o: $(SOURCE_DIR)/parameter_manager.h \ 
    $(SOURCE_DIR)/parameter_manager_lj_molecule.h \ 
    $(SOURCE_DIR)/molecule_manager.h \ 
    $(SOURCE_DIR)/molecule_manager_main.h \ 
    $(SOURCE_DIR)/molecule_reader.h \ 
    $(SOURCE_DIR)/molecule_reader_psf_pdb.h \ 
    $(SOURCE_DIR)/common.h 
    $(CC) $(CFLAGS) $(SOURCE_DIR)/molecule_reader_psf_pdb.cpp 
    @mv molecule_reader_psf_pdb.o $(OBJ_DIR)/ 

$(OBJ_DIR)/molecule_manager.o: $(SOURCE_DIR)/molecule_manager.h \ 
    $(SOURCE_DIR)/common.h 
    $(CC) $(CFLAGS) $(SOURCE_DIR)/molecule_manager.cpp 
    @mv molecule_manager.o $(OBJ_DIR)/ 

$(OBJ_DIR)/molecule_manager_main.o: $(SOURCE_DIR)/molecule_manager.h \ 
    $(SOURCE_DIR)/molecule_manager_main.h \ 
    $(SOURCE_DIR)/common.h 
    $(CC) $(CFLAGS) $(SOURCE_DIR)/molecule_manager_main.cpp 
    @mv molecule_manager_main.o $(OBJ_DIR)/ 

$(OBJ_DIR)/parameter_manager_lj_molecule.o: $(SOURCE_DIR)/common.h \ 
    $(SOURCE_DIR)/parameter_manager.h \ 
    $(SOURCE_DIR)/parser.h 
    $(CC) $(CFLAGS) $(SOURCE_DIR)/parameter_manager_lj_molecule.cpp 
    @mv parameter_manager_lj_molecule.o $(OBJ_DIR)/ 

$(OBJ_DIR)/parameter_manager.o: $(SOURCE_DIR)/common.h 
    $(CC) $(CFLAGS) $(SOURCE_DIR)/parameter_manager.cpp 
    @mv parameter_manager.o $(OBJ_DIR)/ 

$(OBJ_DIR)/parser.o: $(SOURCE_DIR)/parser.h 
    @$(CC) $(CFLAGS) $(SOURCE_DIR)/parser.cpp 
    @mv parser.o $(OBJ_DIR)/ 

$(OBJ_DIR)/common.o: $(SOURCE_DIR)/common.h 
    $(CC) $(CFLAGS) $(SOURCE_DIR)/common.h 
    mv common.h.gch $(OBJ_DIR)/ 

위의 사용자로부터 약간의 도움으로 내 자신에 대한 몇 가지 멋진 트릭 등을 파악 아래

내 STARTING 제품입니다 잘 (와일드 카드 사용과 같이) 메이크 파일을 심하게 리팩토링했으며, 후손을 위해 덧붙였다. 모든 것이 작동하고, 기본적으로 내가 꽤 만족 스럽습니다 ... 깨끗한

#################################################### 
## ------------------------------- 
## - Monte Carlo Source Submake - 
## ------------------------------- 
## 
## Author: Jason R. Mick 
## Date: July 7, 2010 
## Company: Wayne State University 
## 
## CHANGE LOG 
## Author  Date   Description 
## 
## 
## 
#################################################### 

################################ 
# These lines set up some basic vars 
# such as compiler, flags, and dirs. 
################################ 
CC=g++ 
CFLAGS=-c -Wall 
SOURCE_DIR:=./source 
INCDIRS := -I$(SOURCE_DIR) 
OBJ_DIR:=./obj 
EXE_DIR:=./bin 

################################ 
#This line tells make what directories to search in for rules... 
################################ 
VPATH = $(SOURCE_DIR) 

################################ 
# INFO on the "magic" here: 
#$^ is all the prerequisite (.o files), [email protected] is target, and % is wildcard 
################################ 
$(EXE_DIR)/molecule_test : $(OBJ_DIR)/main.o \ 
    $(OBJ_DIR)/parameter_manager_lj_molecule.o \ 
    $(OBJ_DIR)/parameter_manager.o $(OBJ_DIR)/parser.o \ 
    $(OBJ_DIR)/molecule_manager.o $(OBJ_DIR)/molecule_manager_main.o \ 
    $(OBJ_DIR)/molecule_reader.o \ 
    $(OBJ_DIR)/molecule_reader_psf_pdb.o 
    $(CC) $^ -o [email protected] 

################################ 
# These are extra includes for the general 
# rule at the end.... 
################################ 
$(OBJ_DIR)/main.o $(OBJ_DIR)/molecule_reader.o \ 
    $(OBJ_DIR)/molecule_reader_psf_pdb.o: \ 
    molecule_manager.h \ 
    molecule_manager_main.h \ 
    parameter_manager.h \ 
    parameter_manager_lj_molecule.h 

$(OBJ_DIR)/molecule_manager_main.o: molecule_manager.h 

$(OBJ_DIR)/parameter_manager_lj_molecule.o: parser.h 

$(OBJ_DIR)/molecule_reader_psf_pdb.o: molecule_reader.h 

################################ 
# Special rule for main object 
################################ 
$(OBJ_DIR)/main.o: $(SOURCE_DIR)/main.cc \ 
    molecule_reader.h \ 
    molecule_reader_psf_pdb.h common.h 
    $(CC) $(CFLAGS) $(INCDIRS) $< -o [email protected] 

################################ 
# The GENERAL RULE for objects... 
# INFO on the "magic" here: 
#$< is the first prerequisite (.cpp file), [email protected] is target, and % is wildcard 
################################ 
$(OBJ_DIR)/%.o: $(SOURCE_DIR)/%.cpp $(SOURCE_DIR)/%.h $(SOURCE_DIR)/common.h 
    $(CC) $(CFLAGS) $(INCDIRS) $< -o [email protected] 

, 잘 문서화 : 하위 메이크 결과 다음

#################################################### 
## ------------------------------- 
## - Monte Carlo Source Makefile - 
## ------------------------------- 
## 
## Author: Jason R. Mick 
## Date: July 7, 2010 
## Company: Wayne State University 
## 
## CHANGE LOG 
## Author  Date   Description 
## 
## 
## 
#################################################### 

################################# 
# These lines set up some basic vars 
# such as compiler, flags, and dirs. 
################################# 
CC=g++ 
CFLAGS=-c -Wall 
BASE_DIR:=. 
SOURCE_DIR:=$(BASE_DIR)/source 
BUILD_DIR:=$(BASE_DIR)/build 
TEST_DIR:=$(BASE_DIR)/build/tests 
MAKEFILE_DIR:=$(BASE_DIR)/makefiles 
DATA_DIR:=$(BASE_DIR)/data 
DATA_DIR_TESTS:=$(DATA_DIR)/tests 

################################# 
# Note use of wildcards to catch *.h and *.cpp files and all the sub_classes 
# ... for future unit tests/classes, follow this approach, please 
################################# 
MOLECULE_UT_SOURCES := $(SOURCE_DIR)/molecule_test/main.cc \ 
    $(SOURCE_DIR)/molecule_manager* \ 
    $(SOURCE_DIR)/molecule_reader* \ 
    $(SOURCE_DIR)/parameter_manager* \ 
    $(SOURCE_DIR)/parser* \ 
    $(SOURCE_DIR)/common.h 
MOLECULE_UT_DATA := \ 
    $(DATA_DIR_TESTS)/molecule_test/par_oxalate_and_friends.inp \ 
    $(DATA_DIR_TESTS)/molecule_test/dicarboxy-octane_4.* 
PARAM_UT_SOURCES := $(SOURCE_DIR)/parameter_test/main.cc \ 
    $(SOURCE_DIR)/parameter_manager* \ 
    $(SOURCE_DIR)/parser* \ 
    $(SOURCE_DIR)/common.h 
PARAM_UT_DATA := $(DATA_DIR_TESTS)/molecule_test/par_oxalate_and_friends.inp 

################################# 
# Use sub-make inside subdirectory on test target 
# NOTE: @ silences output of this call... 
################################# 
molecule_test : molecule_test_prepare_sources molecule_test_prepare_makefiles \ 
    molecule_test_prepare_data_files 
    @$(MAKE) -C $(TEST_DIR)/molecule_unit_test/ ./bin/molecule_test 

################################# 
# NOTE: this target uses --preserve to keep base source modification date 
# to prevent unnecessary rebuilds 
################################# 
molecule_test_prepare_sources: molecule_test_dir 
    @echo Copying sources... 
    @cp --preserve $(MOLECULE_UT_SOURCES) \ 
    $(TEST_DIR)/molecule_unit_test/source 

molecule_test_prepare_makefiles: $(MAKEFILE_DIR)/Makefile.molecule_test 
    @cp --preserve $(MAKEFILE_DIR)/Makefile.molecule_test \ 
    $(TEST_DIR)/molecule_unit_test/Makefile 

molecule_test_prepare_data_files: 
    @cp --preserve $(MOLECULE_UT_DATA) $(TEST_DIR)/molecule_unit_test/bin/ 

################################# 
# NOTE: This mkdir command uses -p flag to create any missing parent dirs. 
# If all dirs already exist, it also returns no error... 
################################# 
molecule_test_dir: 
    mkdir -p $(TEST_DIR)/molecule_unit_test/source 
    mkdir -p $(TEST_DIR)/molecule_unit_test/obj 
    mkdir -p $(TEST_DIR)/molecule_unit_test/bin 

param_test : param_test_prepare_sources param_test_prepare_makefiles \ 
    param_test_prepare_data_files 
    @$(MAKE) -C $(TEST_DIR)/param_unit_test/ ./bin/param_test 

param_test_prepare_sources: param_test_dir 
    @echo Copying sources... 
    @cp --preserve $(PARAM_UT_SOURCES) $(TEST_DIR)/param_unit_test/source 

param_test_prepare_makefiles: $(MAKEFILE_DIR)/Makefile.param_test 
    @cp --preserve $(MAKEFILE_DIR)/Makefile.param_test \ 
    $(TEST_DIR)/param_unit_test/Makefile 

param_test_prepare_data_files: 
    @cp --preserve $(PARAM_UT_DATA) $(TEST_DIR)/param_unit_test/bin/ 

param_test_dir: 
    mkdir -p $(TEST_DIR)/param_unit_test/source 
    mkdir -p $(TEST_DIR)/param_unit_test/obj 
    mkdir -p $(TEST_DIR)/param_unit_test/bin 

것 :

여기에 최고 수준의 결과입니다 그러나 나는 다른 이들이 "모범 사례"등으로 바꿔야하는 것들에 대한 제안을하고 싶었는지보고 싶었다. 나는 할 수있는 한 많이 배우려고 노력하고있다 !! 미리 감사드립니다 !! 내가 재귀 적으로 만들 호출 재고 것

건배, 제이슨

답변

3

(나는 다시 재귀/비 재귀 적 논쟁을 체결하지 않을 것이다 '안 그런가 말했다..)

왜이 파일들을 모두 복사해야합니까? submake에서 디렉토리 구조의 맵을 하드 코딩하고 싶지는 않지만 심볼릭 링크를 통해 submake 액세스를 제공하여 많은 시간과 문제를 줄일 수 있다는 것을 이해합니다.

molecule_test_prepare_sources: molecule_test_dir 
    @echo linking to sources... 
    @ln -s $(SOURCE_DIR) $(TEST_DIR)/molecule_unit_test/source 

molecule_test_prepare_makefiles: $(MAKEFILE_DIR)/Makefile.molecule_test 
    @ln -s $< $(TEST_DIR)/molecule_unit_test/Makefile 

또는 submake에 매개 변수를 전달하여이 :

param_test : param_test_prepare_sources param_test_prepare_makefiles \ 
    param_test_prepare_data_files 
    @$(MAKE) -C $(TEST_DIR)/param_unit_test/ SOURCE_DIR=$(SOURCE_DIR) \ 
     ./bin/param_test # and then use SOURCE_DIR in the submake 

동일 param_test 간다. 나는 이것이 실제로 MOLECULE_UT_SOURCES와 PARAM_UT_SOURCES, 그리고 좋은 속임수를 없앨 수 있다고 생각한다. (이 코드가 실제로 무엇을하는지 모르기 때문에 데이터 디렉토리를 생략했습니다. 제한된 다이어트가 필요하거나 입력 파일이나 기타 사항을 수정했을 수 있습니다.)

마지막으로 스타일의 문제로 이중화를 볼 수있는 곳이면 어디서든 제거하고 makefile을 읽기 쉽게 만들 수 있습니다.예를 들어,

$(EXE_DIR)/molecule_test : $(OBJ_DIR)/main.o \ 
    $(OBJ_DIR)/parameter_manager_lj_molecule.o \ 
    $(OBJ_DIR)/parameter_manager.o $(OBJ_DIR)/parser.o \ 
    $(OBJ_DIR)/molecule_manager.o $(OBJ_DIR)/molecule_manager_main.o \ 
    $(OBJ_DIR)/molecule_reader.o \ 
    $(OBJ_DIR)/molecule_reader_psf_pdb.o 
    $(CC) $^ -o [email protected] 

이 당신이 찾고있는 대답하지

OBJECTS := main \ 
    parameter_manager_lj_molecule \ 
    parameter_manager parser \ 
    molecule_manager molecule_manager_main \ 
    molecule_reader \ 
    molecule_reader_psf_pdb 

OBJECTS := $(patsubst %,$(OBJ_DIR)/%.o, $(OBJECTS) 

$(EXE_DIR)/molecule_test : $(OBJECTS) 
    $(CC) $^ -o [email protected] 
6

, 메인 메이크에서 대신 @include submakefiles. 의존성을 올바르게 작동시키는 것이 훨씬 쉽고, 구축을 위해 여러 개의 코어를 사용할 수 있습니다 (-j 사용). 모든 피투성이의 세부 사항을 보려면 Recursive Make Considered Harmful을보십시오.

또한

,이 질문에 대해 살펴 :
What is your experience with non recursive make?
Recursive make friend or foe

+0

200 개 미만의 파일이있는 프로젝트에 대한 혼란스러운 가치를 재귀 적으로 만들지 않습니까? 또 다른 관심사는 내 그룹의 사람들이 대부분 컴퓨터 스캐너 가벼운 화학 엔지니어 들이기 때문에 가능한 한 이해할 수있는/유지할 수있는 것으로 만들어야한다는 것입니다. 힘든 ... –

+1

사실, 그 꽤 쉽습니다. 서브 메이크 파일은 매우 간단하며 모든 보일러 플레이트 코드는 메인 메이크 파일에 있습니다. 그것은 많은 중복을 줄입니다. 설정이 끝나면 새로운 오브젝트 파일이나 실행 파일을 추가하는 것은 쉽지 않습니다. 새로운 서브 디렉토리를 추가하는 것은 그다지 어렵지 않습니다. 또한 현재 200 개의 파일 만있을 수 있지만 그 파일은 위로 올라갈 것입니다. 이제 스위치를 쉽게 만들 수 있습니다. – KeithB

2

될 수 있지만 "autotools를"스위트 (automake는, autoconf를, 등)를 사용하여 고려 했는가?

일단 문제가 생기면 작업하는 것이 좋습니다. 그리고 그것은 순수한 Make보다 더 많은 기능을 가지고 있습니다.