2010-07-08 13 views
4

J'ai refactorisé mes makefiles, avec l'aide de Beta, Paul R et Sjoerd (merci les gars!).Makefile Makeover - Presque complet, je veux des commentaires

Ci-dessous mon produit DÉPART:

#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 

... et le sous makefile:

#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)/ 

Avec l'aide des utilisateurs ci-dessus et trouver quelques trucs chouettes sur mon propre comme bien (comme l'utilisation de caractères génériques), j'ai refactorisé les makefiles fortement, plus des commentaires ajoutés pour la postérité.

Voici le résultat de haut niveau:

#################################################### 
## ------------------------------- 
## - 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 

Voici le résultat sous-makefile:

#################################################### 
## ------------------------------- 
## - 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] 

... au fond, je suis assez satisfait, tout fonctionne, propre et bien documenté , mais je voulais voir si quelqu'un d'autre a des suggestions de choses que je devrais changer pour "les meilleures pratiques", etc. J'essaie d'apprendre autant que possible! Merci d'avance!!

Cheers, Jason

Répondre

3

(je ne vais pas entrer dans le débat récurrent/non récurrent à nouveau dit Nuff..)

Pourquoi copier tous ces fichiers? Je comprends que vous ne voulez pas coder en dur une carte de votre structure de répertoire dans le submake, mais vous pouvez gagner beaucoup de temps et d'ennuis en donnant l'accès submake aux fichiers originaux, soit par lien symbolique:

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 

ou en passant un paramètre à la 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 

va de même pour param_test. Je pense que cela vous permet réellement de faire disparaître MOLECULE_UT_SOURCES et PARAM_UT_SOURCES, et bon débarras. (J'ai omis les répertoires de données, car je ne sais pas ce que fait réellement ce code - peut-être a-t-il besoin d'un régime restrictif, ou modifie-t-il ses fichiers d'entrée?). partout où vous voyez la redondance, vous pouvez l'enlever et rendre le fichier makefile plus facile à lire.Par exemple,

$(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] 

peut devenir

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

Je récursive d'appeler make repenser, et au lieu @include les submakefiles dans le makefile principal. Il est beaucoup plus facile de faire fonctionner correctement les dépendances, et cela vous permet d'utiliser plusieurs cœurs pour construire (en utilisant -j). Jetez un oeil à Recursive Make Considered Harmful pour tous les détails sanglants.

Aussi, jetez un oeil à ces questions:
What is your experience with non recursive make?
Recursive make friend or foe

+0

L'implémentation d'une marque non récursive vaut la confusion pour un projet avec moins de 200 fichiers? Une autre préoccupation est que la plupart des gens de mon groupe sont des ingénieurs chimistes avec de légères connaissances en informatique, donc si je devais le faire, je devrais le rendre aussi compréhensible/maintenable que possible ... ce qui semble être le cas difficile ... –

+1

En fait, c'est assez facile. Les sous-makefiles sont très simples, tout le code de la chaudière est dans le makefile principal. Cela réduit beaucoup de duplication. Une fois configuré, l'ajout de nouveaux fichiers objets ou exécutables est trivial. L'ajout d'un nouveau sous-répertoire n'est pas beaucoup plus difficile. En outre, vous pouvez avoir seulement 200 fichiers maintenant, mais cela ne fera que monter. C'est plus facile de faire le changement maintenant. – KeithB

2

Ce n'est pas la réponse que vous cherchez, mais avez-vous envisagé d'utiliser la suite "autotools" (automake, autoconf, etc.)?

Une fois que vous avez compris, c'est vraiment merveilleux de travailler avec. Et il a beaucoup plus de fonctionnalités que Make pure. Fonctionnalités telles que la vérification des bibliothèques nécessaires à la construction, la compilation croisée, etc.