Pb Makefile suite portage vers autre noyau
Fermé
CG14
-
Modifié par CG14 le 7/04/2011 à 11:06
mamiemando Messages postés 33088 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 30 avril 2024 - 13 avril 2011 à 23:44
mamiemando Messages postés 33088 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 30 avril 2024 - 13 avril 2011 à 23:44
A voir également:
- Pb Makefile suite portage vers autre noyau
- Windows 7 vers windows 10 - Guide
- Transferer photo android vers pc - Guide
- Qwerty vers azerty - Guide
- Vers quelle adresse web renvoie ce lien - Guide
- Cloner disque dur vers ssd - Guide
7 réponses
mamiemando
Messages postés
33088
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
30 avril 2024
7 751
12 avril 2011 à 21:46
12 avril 2011 à 21:46
En parallèle je suis en train de reconstituer complètement le Makefile à l'aide de l'outil de génération CMake. Je galère un peu car je découvre complète comment est généré le Makefile, mais j'y vais pas à pas. J'ai trouvé un tuto (in French) qui me semble pas mal pour commencer en complément de la doc officielle.
Ben à la base, c'est carrément toi qui l'écrit avec un bon vieil éditeur texte. Mais comme c'est un peu fastidieux, souvent on se repose sur un outil qui va le générer pour nous (automake, cmake...).
Ceci dit un makefile bien écrit peu compilé un projet C/C++ sans nécessiter de modifications particulières et sous réserve que le projet respecte une certaine arborescence.
J'ai vu que gcc et g++ n'utilise pas les même lib (normal), je n'ai pas encore trouvé pour le header mais je suppose que pour certain d'entre eux ils doivent être différents, ce qui pourrait m'expliquer pourquoi il y a plusieurs versions d'un même .h en dehors des différentes plateformes.
Théoriquement les headers C on une extension ".h" et les headers C++, selon les projets, une extension ".hpp" (boost...), ".h" (Qt) et dans le cas particulier de la STL pas d'extension.
Ainsi si tu veux inclure les headers de la STL il faut bien faire un "#include <vector>" et non "#include <vector.h>" (déprécié).
Selon la librairie les classes qu'elle fourni peuvent être dans un namespace isolé ou pas (par exemple std:: pour la STL et boost:: pour boost). Ainsi on écrira std::vector<int> au lieu de vector<int>.
Ceci peut être alléger avec un "using namespace std;" mais il ne faut jamais faire de "using namespace" dans un header.
Par contre je n'ai pas encore trouvé le moyen d'identifier comment gcc et g++ détermine le path d'accès aux includes qui leurs sont respectifs (j'aime bien comprendre comment cela se passe en dessous de ce qui se voit et de ce qui s'exécute ...).
Les headers sont tous dans /usr/include a priori, que ce soit pour le C ou le C++. Selon l'importance de la librairie elle peut être dans /lib ou /usr/lib. On peut retrouver avec quelles librairies un projet est lié dynamiquement grâce à ldd :
Ici on voit que ce programme utilise des morceaux écrits en C et d'autres en C++, qu'il utilise la librairie mathématique (libm.so), la librairie Perl Compatible Regular Expression (libpcre.so) etc...
Concrètement le programme est lié à libpcre.so mais grâce à un lien symbolique linux pointe sur la dernière version de la librairie (ce qui évite d'avoir à recompiler si celle-ci est mise à jour). La correction de ce lien est assuré lors des mises à jours par la commande ldconfig (appelée implicitement sous debian et les distributions qui en dérivent).
D'autres tuyaux ici :
http://www.mistra.fr/tutoriel-linux-compiler.html
Bonne chance
Ben à la base, c'est carrément toi qui l'écrit avec un bon vieil éditeur texte. Mais comme c'est un peu fastidieux, souvent on se repose sur un outil qui va le générer pour nous (automake, cmake...).
Ceci dit un makefile bien écrit peu compilé un projet C/C++ sans nécessiter de modifications particulières et sous réserve que le projet respecte une certaine arborescence.
J'ai vu que gcc et g++ n'utilise pas les même lib (normal), je n'ai pas encore trouvé pour le header mais je suppose que pour certain d'entre eux ils doivent être différents, ce qui pourrait m'expliquer pourquoi il y a plusieurs versions d'un même .h en dehors des différentes plateformes.
Théoriquement les headers C on une extension ".h" et les headers C++, selon les projets, une extension ".hpp" (boost...), ".h" (Qt) et dans le cas particulier de la STL pas d'extension.
Ainsi si tu veux inclure les headers de la STL il faut bien faire un "#include <vector>" et non "#include <vector.h>" (déprécié).
Selon la librairie les classes qu'elle fourni peuvent être dans un namespace isolé ou pas (par exemple std:: pour la STL et boost:: pour boost). Ainsi on écrira std::vector<int> au lieu de vector<int>.
Ceci peut être alléger avec un "using namespace std;" mais il ne faut jamais faire de "using namespace" dans un header.
Par contre je n'ai pas encore trouvé le moyen d'identifier comment gcc et g++ détermine le path d'accès aux includes qui leurs sont respectifs (j'aime bien comprendre comment cela se passe en dessous de ce qui se voit et de ce qui s'exécute ...).
Les headers sont tous dans /usr/include a priori, que ce soit pour le C ou le C++. Selon l'importance de la librairie elle peut être dans /lib ou /usr/lib. On peut retrouver avec quelles librairies un projet est lié dynamiquement grâce à ldd :
(mando@aldur) (~/cpp/app_dynamic_simulator/build) $ ldd app_dynamic_simulator linux-gate.so.1 => (0xb77a9000) libtorque_mando.so => not found libpcre.so.3 => /lib/libpcre.so.3 (0xb7756000) libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb7667000) libm.so.6 => /lib/i686/cmov/libm.so.6 (0xb7641000) libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7625000) libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb74de000) /lib/ld-linux.so.2 (0xb77aa000)
Ici on voit que ce programme utilise des morceaux écrits en C et d'autres en C++, qu'il utilise la librairie mathématique (libm.so), la librairie Perl Compatible Regular Expression (libpcre.so) etc...
Concrètement le programme est lié à libpcre.so mais grâce à un lien symbolique linux pointe sur la dernière version de la librairie (ce qui évite d'avoir à recompiler si celle-ci est mise à jour). La correction de ce lien est assuré lors des mises à jours par la commande ldconfig (appelée implicitement sous debian et les distributions qui en dérivent).
D'autres tuyaux ici :
http://www.mistra.fr/tutoriel-linux-compiler.html
Bonne chance
mamiemando
Messages postés
33088
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
30 avril 2024
7 751
Modifié par mamiemando le 8/04/2011 à 08:56
Modifié par mamiemando le 8/04/2011 à 08:56
Pourquoi n'utilises-tu pas directement un noyau fourni sous forme de paquet par ta distribution (ce qui te fournirait un noyau compilé) ?
Si tu tiens vraiment à compiler ton noyau, privilégie les sources fournies par les paquets de ta distribution. Et si vraiment tu veux autre chose, récupères les sur kernel.org et vérifie ta version de gcc.
Ce tutoriel est orienté pour debian donc le gestionnaire de paquets n'est pas aptitude dans ton cas et les noms de paquets peuvent différer légèrement (dev -> devel), mais dans l'idée ça ressemble à ceci :
http://www.mistra.fr/tutoriel-linux-compiler.html#h4-compiler-un-noyau
Bonne chance
Si tu tiens vraiment à compiler ton noyau, privilégie les sources fournies par les paquets de ta distribution. Et si vraiment tu veux autre chose, récupères les sur kernel.org et vérifie ta version de gcc.
Ce tutoriel est orienté pour debian donc le gestionnaire de paquets n'est pas aptitude dans ton cas et les noms de paquets peuvent différer légèrement (dev -> devel), mais dans l'idée ça ressemble à ceci :
http://www.mistra.fr/tutoriel-linux-compiler.html#h4-compiler-un-noyau
Bonne chance
Ce n'est pas le noyau que je veux recompiler mais une application en C++ qui tourne déjà sur la plateforme matérielle précédante.
Le noyau à déjà été recompilé avec les options qui me sont nécessaires et ce avec succès.
c'est juste le portage de mon appli qui me pose problème au niveau du Makefile pour l'accès aux bons fichiers d'includes ...
Le noyau à déjà été recompilé avec les options qui me sont nécessaires et ce avec succès.
c'est juste le portage de mon appli qui me pose problème au niveau du Makefile pour l'accès aux bons fichiers d'includes ...
mamiemando
Messages postés
33088
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
30 avril 2024
7 751
Modifié par mamiemando le 9/04/2011 à 12:50
Modifié par mamiemando le 9/04/2011 à 12:50
Bah quand on cherche le warning on tombe sur des trucs dans ce genre :
http://www.generation-nt.com/reponses/variadic-macros-entraide-197901.html
Commence par vérifier que des headers de noyaux concordent avec ta version de noyau :
Essaye de voir s'il vaut mieux corriger les sources ou simplement ignorer les warnings qui, soit dit en passant ne sont pas responsable du fait que ça ne compile pas (même si c'est en général pas bon signe quand il y a des warnings).
Par contre si tu copies colles le message d'erreur il y a des chances que tu tombes sur des informations intéressantes :
- fichier manquant à installer,
- erreur qui laisse penser qu'un #define choppé par un -D n'a pas été bien initialisé
- ou simplement, un message d'erreur à copier coller dans google pour essayer de voir comment d'autres l'ont résolu.
Bonne chance
http://www.generation-nt.com/reponses/variadic-macros-entraide-197901.html
Commence par vérifier que des headers de noyaux concordent avec ta version de noyau :
uname -a
Essaye de voir s'il vaut mieux corriger les sources ou simplement ignorer les warnings qui, soit dit en passant ne sont pas responsable du fait que ça ne compile pas (même si c'est en général pas bon signe quand il y a des warnings).
Par contre si tu copies colles le message d'erreur il y a des chances que tu tombes sur des informations intéressantes :
- fichier manquant à installer,
- erreur qui laisse penser qu'un #define choppé par un -D n'a pas été bien initialisé
- ou simplement, un message d'erreur à copier coller dans google pour essayer de voir comment d'autres l'ont résolu.
Bonne chance
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
mamiemando, merci pour tes conseils.
En parallèle je suis en train de reconstituer complètement le Makefile à l'aide de l'outil de génération CMake. Je galère un peu car je découvre complète comment est généré le Makefile, mais j'y vais pas à pas. J'ai trouvé un tuto (in French) qui me semble pas mal pour commencer en complément de la doc officielle.
J'ai vu que gcc et g++ n'utilise pas les même lib (normal), je n'ai pas encore trouvé pour le header mais je suppose que pour certain d'entre eux ils doivent être différents, ce qui pourrait m'expliquer pourquoi il y a plusieurs versions d'un même .h en dehors des différentes plateformes.
Par contre je n'ai pas encore trouvé le moyen d'identifier comment gcc et g++ détermine le path d'accès aux includes qui leurs sont respectifs (j'aime bien comprendre comment cela se passe en dessous de ce qui se voit et de ce qui s'exécute ...).
Si il y a encore quelques conseils je reste preneur.
En parallèle je suis en train de reconstituer complètement le Makefile à l'aide de l'outil de génération CMake. Je galère un peu car je découvre complète comment est généré le Makefile, mais j'y vais pas à pas. J'ai trouvé un tuto (in French) qui me semble pas mal pour commencer en complément de la doc officielle.
J'ai vu que gcc et g++ n'utilise pas les même lib (normal), je n'ai pas encore trouvé pour le header mais je suppose que pour certain d'entre eux ils doivent être différents, ce qui pourrait m'expliquer pourquoi il y a plusieurs versions d'un même .h en dehors des différentes plateformes.
Par contre je n'ai pas encore trouvé le moyen d'identifier comment gcc et g++ détermine le path d'accès aux includes qui leurs sont respectifs (j'aime bien comprendre comment cela se passe en dessous de ce qui se voit et de ce qui s'exécute ...).
Si il y a encore quelques conseils je reste preneur.
Merci a toi Mamiemando, l'ensemble de tes commentaires et précision vont m'être très utiles pour approfondir et mieux maîtriser ce que je fais.
En effet, j'avais bien le souvenir d'avoir constitué des Makefile à la main,il y a une vingtaine d'années quand je programmais, en C et en Fortran77 sous une version RT de HPUX portant le nom de Lynx OS(18 classeurs de doc pour HPUX et 5 de plus pour Lynx OS in French Please, le luxe quoi! Le prix aussi : pas loin de 10000€ l'OS). Je l'utilisais alors pour le dev de prog de tests et mesures de produits électroniques pour l'automobile. Le Makefile était beaucoup moins verbeux qu'aujourd'hui. Il n'y avait pas tout les utilitaires de maintenant, les modules et les librairies dynamiques étaient inexistantes. Lynx OS était pourtant une "F1" à l'époque et tournait sur 486DX2 en plateforme VXI. Ben 20 ans plus tard le code de la route est toujours le même mais le trafic a un peu augmenté, "tous les chemins mène au noyau" et tout les "panneaux" sont en English. Il va me falloir un petit temps d'adaptation et les "balises" que tu viens de m'indiquer vont dissiper un peu le brouillard dans lequel je me trouvais.
Encore merci et j'espère pouvoir marquer ce sujet comme résolu cette semaine.
En effet, j'avais bien le souvenir d'avoir constitué des Makefile à la main,il y a une vingtaine d'années quand je programmais, en C et en Fortran77 sous une version RT de HPUX portant le nom de Lynx OS(18 classeurs de doc pour HPUX et 5 de plus pour Lynx OS in French Please, le luxe quoi! Le prix aussi : pas loin de 10000€ l'OS). Je l'utilisais alors pour le dev de prog de tests et mesures de produits électroniques pour l'automobile. Le Makefile était beaucoup moins verbeux qu'aujourd'hui. Il n'y avait pas tout les utilitaires de maintenant, les modules et les librairies dynamiques étaient inexistantes. Lynx OS était pourtant une "F1" à l'époque et tournait sur 486DX2 en plateforme VXI. Ben 20 ans plus tard le code de la route est toujours le même mais le trafic a un peu augmenté, "tous les chemins mène au noyau" et tout les "panneaux" sont en English. Il va me falloir un petit temps d'adaptation et les "balises" que tu viens de m'indiquer vont dissiper un peu le brouillard dans lequel je me trouvais.
Encore merci et j'espère pouvoir marquer ce sujet comme résolu cette semaine.
mamiemando
Messages postés
33088
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
30 avril 2024
7 751
Modifié par mamiemando le 12/09/2011 à 15:18
Modifié par mamiemando le 12/09/2011 à 15:18
Sinon voici les fameux makefile automatiques dont je te parlais. Tu crées un workspace par exemple ~/cpp. Dedans tu crées
- un répertoire conf : contient la configuration communes aux différents projets
- un répertoire app_pouet : pour l'application pouet que tu écris (idem pour les autres application que tu écris)
- un répertoire lib_plop : pour la librairie plop (idem pour les autres librairies que tu écris).
- un répertoire stage (qui correspond aux applications en production)
Chaque application et chaque librairie a son propre makefile. Dedans il faut juste régler le nom de l'appli et les éventuelles libraires avec lesquelles linker.
Dans un répertoire app_* ou lib_* il faut que les sources soient dans le sous répertoire src/ et que les sources aient les extensions :
- C++ : hpp et cpp
- C++ : h et c
Tu peux éventuellement créer des sous-répertoires de sources dans src/.
conf/boost.mk
conf/common.mk
app_pouet/Makefile
lib_plop/Makefile
Utilisation
Tout recompiler :
Recompiler juste le nécessaire :
Rappel important : dans une makefile les débuts de ligne blancs doivent être des caractères "tabulation".
- un répertoire conf : contient la configuration communes aux différents projets
- un répertoire app_pouet : pour l'application pouet que tu écris (idem pour les autres application que tu écris)
- un répertoire lib_plop : pour la librairie plop (idem pour les autres librairies que tu écris).
- un répertoire stage (qui correspond aux applications en production)
Chaque application et chaque librairie a son propre makefile. Dedans il faut juste régler le nom de l'appli et les éventuelles libraires avec lesquelles linker.
Dans un répertoire app_* ou lib_* il faut que les sources soient dans le sous répertoire src/ et que les sources aient les extensions :
- C++ : hpp et cpp
- C++ : h et c
Tu peux éventuellement créer des sous-répertoires de sources dans src/.
conf/boost.mk
BOOST_EXEC_PREFIX = /usr/lib BOOST_CPPFLAGS = #-isystem /usr/include/boost BOOST_LDLIBS = -lboost_serialization CPPFLAGS += $(BOOST_CPPFLAGS) LDFLAGS += $(BOOST_LDFLAGS) LDLIBS += $(BOOST_LDLIBS)
conf/common.mk
proj_NAME = projet CC = gcc CXX = g++ CONFIG_GUESS = i686-pc-linux-gnu CXX_VERSION = g++-$(shell $(CXX) -dumpversion) RANLIB = ranlib AR = ar INSTALL = install -p # CPPFLAGS += -DNDEBUG CCFLAGS += -O2 -funroll-loops -fexceptions CXXFLAGS += -O2 -funroll-loops -W -Wall LDFLAGS += -time DEPFLAGS = -MM -MG -MP
app_pouet/Makefile
include ../conf/common.mk # Pour linker avec boost #include ../conf/boost.mk ############################################################################# # Custom flags ############################################################################# CXXFLAGS += -ftemplate-depth-100 #-DNDEBUG ############################################################################# # Le nom du binaire final NAME = app_pouet # Directories INC_DIR = ./src SRC_DIR = ./src BUILD_DIR = ./build STAGE_DIR = ../stage CPPFLAGS += -I$(STAGE_DIR)/include -I$(INC_DIR) CCFLAGS += -fPIC CXXFLAGS += -fPIC LDFLAGS += -L$(STAGE_DIR)/lib -Wl,-R$(STAGE_DIR)/lib # Pour linker avec la lprojet_plop LDLIBS += -lprojet_plop # Pour linker avec la librairie pcre (il faut installer libpcre3-dev) # SYSLIBS += -lpcre EXE_SRCS := \ $(shell find $(SRC_DIR) -follow -type f -name '*.cpp') \ $(shell find $(SRC_DIR) -follow -type f -name '*.c') # Le nom de l'exécutable EXES = $(NAME) ############################################################################## BUILD_EXES = $(patsubst %, $(BUILD_DIR)/%, $(EXES)) BUILD_EXE_OBJS= $(patsubst $(SRC_DIR)/%,$(BUILD_DIR)/%.o, $(basename $(EXE_SRCS))) BUILD_OBJS = $(BUILD_EXE_OBJS) BUILD_DEPS = $(BUILD_OBJS:.o=.d) BUILD_DEP_MK = $(BUILD_DIR)/depend.mk BUILD_SUBDIRS = $(sort $(dir $(BUILD_OBJS))) STAGE_EXES = $(patsubst $(BUILD_DIR)/bin/%,$(STAGE_DIR)/%, $(basename $(BUILD_EXES))) STAGE_BIN_DIRS = $(STAGE_DIR)/bin $(sort $(dir $(STAGE_EXES))) # Commands DEPEND.cpp = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(DEPFLAGS) COMPILE.cpp = $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c LINK.cpp = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(CXX_LDFLAGS) DEPEND.c = $(CC) $(CCFLAGS) $(CPPFLAGS) $(DEPFLAGS) COMPILE.c = $(CC) $(CCFLAGS) $(CPPFLAGS) -c LINK.c = $(CC) $(CCFLAGS) $(CPPFLAGS) $(LDFLAGS) ############################################################################## # # Rules # $(BUILD_DIR)/%.d : $(SRC_DIR)/%.cpp $(DEPEND.cpp) $< -MT $(@:.d=.o) -MF $@ $(BUILD_DIR)/%.d : $(SRC_DIR)/%.c $(DEPEND.c) $< -MT $(@:.d=.o) -MF $@ $(BUILD_DIR)/%.o : $(SRC_DIR)/%.cpp $(COMPILE.cpp) $< -o $@ $(BUILD_DIR)/%.o : $(SRC_DIR)/%.c $(COMPILE.c) $< -o $@ ############################################################################## # # Generic Targets # .PHONY: dump config depend all: $(BUILD_EXES) config: mkdir -p $(BUILD_DIR) $(BUILD_SUBDIRS) depend: $(BUILD_DEPS) rm -f $(BUILD_DEP_MK) for dep in $(BUILD_DEPS); do echo "-include $$dep" >> $(BUILD_DEP_MK); done depclean: rm -f $(BUILD_DEPS) objclean: rm -f $(BUILD_OBJS) clean: objclean distclean: objclean depclean rm -f $(BUILD_DEP_MK) rm -f $(BUILD_EXES) stage-exe: $(BUILD_EXES) $(INSTALL) -d $(STAGE_BIN_DIRS) for exe in $(patsubst $(BUILD_DIR)/%, %, $(BUILD_EXES)); do \ echo "installing $(STAGE_DIR)/bin/$$exe" ; \ $(INSTALL) $(BUILD_DIR)/$$exe $(STAGE_DIR)/bin/$$exe ; \ done stage: stage-exe unstage-exe: for exe in $(patsubst $(BUILD_DIR)/bin/%, %, $(BUILD_EXES)); do \ echo "removing $(STAGE_DIR)/bin/$$exe" ; \ rm -f $(STAGE_DIR)/bin/$$exe ; \ done unstage: unstage-exe ############################################################################## # # Custom Targets # $(BUILD_DIR)/$(EXES): $(BUILD_EXE_OBJS) $(LINK.cpp) -o $@ $(BUILD_EXE_OBJS) $(LDLIBS) $(SYSLIBS) ############################################################################## # # Dependencies # -include $(BUILD_DEP_MK)
lib_plop/Makefile
include ../conf/common.mk # Pour inclure un header situé dans ../conf #include ../conf/boost_standard.mk ############################################################################## # # Compilateur # CXX_LIBDIR = $(shell dirname $(shell $(CXX) -print-file-name=libstdc++.a)) CXX_LDFLAGS += -L$(CXX_LIBDIR) -Wl,-R$(CXX_LIBDIR) ############################################################################## # # Libs (sys & extern) # CPPFLAGS += -I$(SRC_DIR) LDFLAGS += LDLIBS += SYSLIBS += ############################################################################## # # Commands # DEPEND.cpp = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(DEPFLAGS) COMPILE.cpp = $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c LINK.cpp = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(CXX_LDFLAGS) DEPEND.c = $(CC) $(CCFLAGS) $(CPPFLAGS) $(DEPFLAGS) COMPILE.c = $(CC) $(CCFLAGS) $(CPPFLAGS) -c LINK.c = $(CC) $(CCFLAGS) $(CPPFLAGS) $(LDFLAGS) ############################################################################## NAME=plop # Directories INC_DIR = ./src SRC_DIR = ./src BUILD_DIR = ./build STAGE_DIR = ../stage CPPFLAGS += CCFLAGS += -fPIC CXXFLAGS += -fPIC $(BOOST_CPPFLAGS) LDFLAGS += -L$(STAGE_DIR)/lib -Wl,-R$(STAGE_DIR)/lib $(BOOST_LDFLAGS) LDLIBS += $(BOOST_LDLIBS) # Sources LIB_INCS := \ $(shell find $(INC_DIR)/ -follow -type f -name '*.h') \ $(shell find $(INC_DIR)/ -follow -type f -name '*.hpp') LIB_SRCS := \ $(shell find $(SRC_DIR)/ -follow -type f -name '*.c') \ $(shell find $(SRC_DIR)/ -follow -type f -name '*.cpp') LIB_A = lib$(proj_NAME)_$(NAME).a LIB_SO = lib$(proj_NAME)_$(NAME).so LIBS = $(LIB_A) $(LIB_SO) ############################################################################## BUILD_LIBS = $(patsubst %, $(BUILD_DIR)/%, $(LIBS)) BUILD_LIB_OBJS= $(patsubst $(SRC_DIR)/%,$(BUILD_DIR)/%.o, $(basename $(LIB_SRCS))) BUILD_OBJS = $(BUILD_LIB_OBJS) BUILD_DEPS = $(BUILD_OBJS:.o=.d) BUILD_DEP_MK = $(BUILD_DIR)/depend.mk BUILD_SUBDIRS = $(sort $(dir $(BUILD_OBJS))) STAGE_INCS = $(patsubst $(INC_DIR)/%,$(STAGE_DIR)/include/%, $(basename $(LIB_INCS))) STAGE_LIBS = $(patsubst $(BUILD_DIR)/%,$(STAGE_DIR)/lib/%, $(basename $(BUILD_LIBS))) STAGE_INC_DIRS = $(STAGE_DIR)/include $(sort $(dir $(STAGE_INCS))) STAGE_LIB_DIRS = $(STAGE_DIR)/lib $(sort $(dir $(STAGE_LIBS))) ############################################################################ # # Rules # $(BUILD_DIR)/%.d : $(SRC_DIR)/%.cpp $(DEPEND.cpp) $< -MT $(@:.d=.o) -MF $@ $(BUILD_DIR)/%.d : $(SRC_DIR)/%.c $(DEPEND.c) $< -MT $(@:.d=.o) -MF $@ $(BUILD_DIR)/%.o : $(SRC_DIR)/%.cpp $(COMPILE.cpp) $< -o $@ $(BUILD_DIR)/%.o : $(SRC_DIR)/%.c $(COMPILE.c) $< -o $@ ############################################################################## # # Generic Targets # .PHONY: dump config depend all: $(BUILD_LIBS) config: @echo "creating build dirs" mkdir -p $(BUILD_DIR) $(BUILD_SUBDIRS) $(BUILD_DIR)/doxygen/html depend: $(BUILD_DEPS) @echo "merging dependencies" rm -f $(BUILD_DEP_MK) for dep in $(BUILD_DEPS); do echo "-include $$dep" >> $(BUILD_DEP_MK); done depclean: rm -f $(BUILD_DEPS) objclean: rm -f $(BUILD_OBJS) clean: objclean distclean: objclean depclean rm -f $(BUILD_DEP_MK) rm -f $(BUILD_LIBS) $(BUILD_EXES) stage-include: @echo "creating stage include dirs..." $(INSTALL) -d $(STAGE_INC_DIRS) for header in $(patsubst $(INC_DIR)/%, %, $(LIB_INCS)); do \ echo "installing $(STAGE_DIR)/include/$$header" ; \ $(INSTALL) $(INC_DIR)/$$header $(STAGE_DIR)/include/$$header ; \ done stage-lib: $(BUILD_LIBS) @echo "creating stage lib dirs..." $(INSTALL) -d $(STAGE_LIB_DIRS) for lib in $(patsubst $(BUILD_DIR)/%, %, $(BUILD_LIBS)); do \ echo "installing $(STAGE_DIR)/lib/$$lib" ; \ $(INSTALL) $(BUILD_DIR)/$$lib $(STAGE_DIR)/lib/$$lib ; \ done stage: stage-lib stage-include unstage-include: for header in $(patsubst $(INC_DIR)/%, %, $(LIB_INCS)); do \ echo "removing $(STAGE_DIR)/include/$$header" ; \ rm -f $(STAGE_DIR)/include/$$header ; \ done unstage-lib: for lib in $(patsubst $(LIB_DIR)/%, %, $(BUILD_LIBS)); do \ echo "removing $(STAGE_DIR)/lib/$$lib" ; \ rm -f $(STAGE_DIR)/lib/$$lib ; \ done unstage: unstage-lib unstage-include ############################################################################## # # Custom Targets # $(BUILD_DIR)/$(LIB_A): $(BUILD_LIB_OBJS) @echo "linking $@" $(AR) -cr $@ $(BUILD_LIB_OBJS) $(RANLIB) $@ $(BUILD_DIR)/$(LIB_SO): $(BUILD_LIB_OBJS) @echo "linking $@" $(LINK.cpp) -shared -o $@ $(BUILD_LIB_OBJS) $(LDLIBS) $(SYSLIBS) dump: @echo $(LIB_SRCS) @echo $(BUILD_LIB_OBJS) ############################################################################## # # Dependencies # -include $(BUILD_DEP_MK)
Utilisation
Tout recompiler :
make clean depend all stage
Recompiler juste le nécessaire :
make depend all stage
Rappel important : dans une makefile les débuts de ligne blancs doivent être des caractères "tabulation".