2008-11-18 4 views
80

मेरे पास निम्न मेकफ़ाइल है जिसका उपयोग मैं एक प्रोग्राम (एक कर्नेल, वास्तव में) बनाने के लिए करता हूं जिस पर मैं काम कर रहा हूं। यह खरोंच से है और मैं प्रक्रिया के बारे में सीख रहा हूं, इसलिए यह सही नहीं है, लेकिन मुझे लगता है कि इस स्तर पर मेरे लेखन के स्तर के मेकफ़ाइल के लिए पर्याप्त शक्तिशाली है।मेरे पास मेकफ़ाइल स्वचालित रूप से स्रोत फ़ाइलों का पुनर्निर्माण कैसे कर सकता है जिसमें संशोधित हेडर फ़ाइल शामिल है? (सी/सी ++ में)

AS = nasm 
CC = gcc 
LD = ld 

TARGET  = core 
BUILD  = build 
SOURCES  = source 
INCLUDE  = include 
ASM   = assembly 

VPATH = $(SOURCES) 

CFLAGS = -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions \ 
      -nostdinc -fno-builtin -I $(INCLUDE) 
ASFLAGS = -f elf 

#CFILES  = core.c consoleio.c system.c 
CFILES  = $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 
SFILES  = assembly/start.asm 

SOBJS = $(SFILES:.asm=.o) 
COBJS = $(CFILES:.c=.o) 
OBJS = $(SOBJS) $(COBJS) 

build : $(TARGET).img 

$(TARGET).img : $(TARGET).elf 
    c:/python26/python.exe concat.py stage1 stage2 pad.bin core.elf floppy.img 

$(TARGET).elf : $(OBJS) 
    $(LD) -T link.ld -o [email protected] $^ 

$(SOBJS) : $(SFILES) 
    $(AS) $(ASFLAGS) $< -o [email protected] 

%.o: %.c 
    @echo Compiling $<... 
    $(CC) $(CFLAGS) -c -o [email protected] $< 

#Clean Script - Should clear out all .o files everywhere and all that. 
clean: 
    -del *.img 
    -del *.o 
    -del assembly\*.o 
    -del core.elf 

इस makefile साथ मेरा मुख्य मुद्दा यह है कि जब मैं एक हेडर फाइल को संशोधित कि एक या अधिक सी फ़ाइलों में शामिल हैं, सी फ़ाइलों का पुनर्निर्माण नहीं कर रहे हैं। मैं अपनी सभी सी फाइलों के लिए अपनी सभी हेडर फाइलों पर निर्भरता रखकर इसे आसानी से ठीक कर सकता हूं, लेकिन जब भी मैं हेडर फ़ाइल बदलता/जोड़ता हूं, तो यह प्रभावी रूप से परियोजना के पूर्ण पुनर्निर्माण का कारण बनता है, जो बहुत ही सुंदर नहीं होगा।

जो मैं चाहता हूं केवल सी फाइलों के लिए है जो में हैडर फ़ाइल जिसे मैं पुनर्निर्मित करने के लिए बदलता हूं, और पूरी परियोजना को फिर से लिंक करने के लिए। मैं सभी हेडर फ़ाइलों को लक्ष्य की निर्भरता के कारण जोड़कर लिंक कर सकता हूं, लेकिन मैं यह नहीं समझ सकता कि सी फाइलों को अमान्य कैसे बनाया जाए जब उनकी हेडर फाइलें नई हों।

मैंने सुना है कि जीसीसी के पास यह संभव बनाने के लिए कुछ कमांड हैं (इसलिए मेकफ़ाइल किसी भी तरह से पता लगा सकता है कि किन फ़ाइलों को पुनर्निर्मित करने की आवश्यकता है) लेकिन मैं अपने जीवन के लिए वास्तविक कार्यान्वयन उदाहरण नहीं ढूंढ सकता । क्या कोई समाधान पोस्ट कर सकता है जो इस व्यवहार को मेकफ़ाइल में सक्षम करेगा?

संपादित करें: मुझे स्पष्ट करना चाहिए, मैं अलग-अलग लक्ष्यों को रखने और प्रत्येक लक्ष्य रखने की अवधारणा से परिचित हूं। आपको हेडर फ़ाइलों की आवश्यकता है। जब भी मैं कहीं हेडर फ़ाइल शामिल करता हूं, तो मुझे मेकफ़ाइल संपादित करने की आवश्यकता होती है, जो दर्द का थोड़ा सा होता है। मैं ऐसे समाधान की तलाश में हूं जो हेडर फ़ाइल निर्भरताओं को अपने आप प्राप्त कर सके, जो कि मैं निश्चित रूप से निश्चित हूं कि मैंने अन्य परियोजनाओं में देखा है।

उत्तर

25

जैसा कि पहले ही इस साइट पर कहीं और कहे अनुसार, इस पृष्ठ को देखें: http://make.paulandlesley.org/autodep.html

संक्षेप में, जीसीसी स्वचालित रूप से जो मिनी makefile ग फ़ाइल की निर्भरता युक्त टुकड़े कर रहे हैं आप के लिए निर्भरता फ़ाइलें, .D बना सकते हैं आप संकलित हर बार जब आप .c फ़ाइल बदलते हैं और इसे संकलित करते हैं, तो .d फ़ाइल अपडेट हो जाएगी।

जीसीसी को -एम ध्वज जोड़ने के अलावा, आपको मेकफ़ाइल में .d फ़ाइलों को शामिल करने की आवश्यकता होगी (जैसे क्रिस ने लिखा था)। पृष्ठ में कुछ और जटिल समस्याएं हैं जिन्हें sed का उपयोग करके हल किया गया है, लेकिन आप उन्हें अनदेखा कर सकते हैं और .d फ़ाइलों को दूर करने के लिए "साफ करें" करते हैं जब भी कोई हेडर फ़ाइल बनाने में सक्षम न होने के बारे में शिकायत करते हैं जो अब नहीं मौजूद।

+2

मुझे गलत हो सकता है, लेकिन मुझे लगता है कि जीसीसी ने वास्तव में उस प्रस्ताव को हल करने के लिए एक सुविधा जोड़ा है। Http://gcc.gnu.org/onlinedocs/gcc-4.3.1/gcc/Preprocessor-Options.html विशेष रूप से -एमपी देखें। –

+0

हां, -एमपी 3 के बाद से मौजूद है, क्लैंग और आईसीसी में मौजूद है, और sed की आवश्यकता को voids। http://bruno.defraine.net/techtips/makefile-auto- निर्भरता-with-gcc/#comment-50775 – hmijail

6

आपको प्रत्येक सी फ़ाइल के लिए व्यक्तिगत लक्ष्य बनाना होगा, और फिर हेडर फ़ाइल को निर्भरता के रूप में सूचीबद्ध करना होगा। आप अभी भी अपने सामान्य लक्ष्यों का उपयोग कर सकते हैं और सिर्फ बाद में .h निर्भरता जगह है, तो जैसे:

%.o: %.c 
     @echo Compiling $<... 
     $(CC) $(CFLAGS) -c -o [email protected] $< 

foo.c: bar.h 
# And so on... 
3

से अधिक और ऊपर @mipadi क्या कहा, आप भी एक रिकॉर्ड उत्पन्न करने के लिए '-M' विकल्प के उपयोग तलाश कर सकते हैं निर्भरताओं का। आप उन्हें एक अलग फ़ाइल (शायद 'depend.mk') में भी उत्पन्न कर सकते हैं जिसे आप मेकफ़ाइल में शामिल करते हैं। या आप 'make depend' नियम ढूंढ सकते हैं जो मेकफ़ाइल को सही निर्भरताओं के साथ संपादित करता है (Google शब्द: "इस पंक्ति को न हटाएं" और निर्भर)।

3

असल में, आपको हेडर फ़ाइलों को बदलने पर ऑब्जेक्ट फ़ाइलों को पुनर्निर्माण करने के लिए मेकफ़ाइल नियमों को गतिशील रूप से बनाने की आवश्यकता है। यदि आप जीसीसी और gnumake का उपयोग करते हैं, यह काफी आसान है; बस कुछ ऐसा डालें:

$(OBJDIR)/%.d: %.c 
     $(CC) -MM -MG $(CPPFLAGS) $< | sed -e 's,^\([^:]*\)\.o[ ]*:,$(@D)/\1.o $(@D)/\1.d:,' >[email protected] 

ifneq ($(MAKECMDGOALS),clean) 
include $(SRCS:%.c=$(OBJDIR)/%.d) 
endif 

आपके मेकफ़ाइल में।

+2

मैं इन सबसे छुटकारा इस बात को समझ, सिवाय इसके कि (एक तरफ fromt वह -MM और -MG झंडे नया किया जा रहा है) मुझे समझ नहीं आता क्या regex गुप्त पाठ के 'लाइन देख रहा है। यह मुझे टीम के साथी खुश करने वाला नहीं है ...^_^मैं इसे आजमाउंगा और देख सकता हूं कि मेरे पास कोई परिणाम है या नहीं। –

+0

sed "स्ट्रीम एडिटर" के लिए छोटा है जो फ़ाइल का उपयोग करने के बिना टेक्स्ट की स्ट्रीम को संशोधित कर सकता है। यह एक मानक यूनिक्स उपकरण है और छोटे और तेज़ है इसलिए इसका उपयोग अजीब या पर्ल से अधिक बार किया जाता है। –

+0

आह, समस्या है: मैं इसे विंडोज के तहत कर रहा हूं। –

16

यह Chris Dodd's answer के बराबर है, लेकिन एक अलग नामकरण परंपरा (का उपयोग करता है और संयोग से sed जादू। a later duplicate से कॉपी किया गया आवश्यकता नहीं है।


आप एक जीएनयू संकलक का उपयोग कर रहे हैं, तो संकलक को इकट्ठा कर सकते हैं । आप के लिए निर्भरता की एक सूची Makefile टुकड़ा:

depend: .depend 

.depend: $(SOURCES) 
     rm -f ./.depend 
     $(CC) $(CFLAGS) -MM $^>>./.depend; 

include .depend 

वहाँ भी उपकरण makedepend है, लेकिन मैं कभी नहीं पसंद आया यह जितना gcc -MM

+3

आप SOURCES का जादू क्यों नहीं करते? विशेष रूप से कई और पात्रों की आवश्यकता नहीं है और "एसआरसीएस" के रूप में अपमानित नहीं है जो एक संक्षिप्त शब्द की तरह दिख सकता है। – HelloGoodbye

-1

मेरा मानना ​​है कि mkdep कमांड आप चाहते हैं। यह वास्तव में #include लाइनों के लिए .c फ़ाइलों को स्कैन करता है और उनके लिए एक निर्भरता पेड़ बनाता है। मेरा मानना ​​है कि ऑटोमैक/ऑटोकॉन्फ परियोजनाएं डिफ़ॉल्ट रूप से इसका उपयोग करती हैं।

19

आप जोड़ सकते हैं एक कमांड 'निर्भर बनाने' के रूप में दूसरों ने कहा है लेकिन क्यों निर्भरता बनाने के लिए जीसीसी नहीं मिलता है और एक ही समय में संकलन:

DEPS := $(COBJS:.o=.d) 

-include $(DEPS) 

%.o: %.c 
    $(CC) -c $(CFLAGS) -MM -MF $(patsubst %.o,%.d,[email protected]) -o [email protected] $< 

'-MF' पैरामीटर स्टोर करने के लिए एक फ़ाइल निर्दिष्ट करता है

'अंतर्निहित' की शुरुआत में डैश बताता है कि .d फ़ाइल मौजूद नहीं है (उदाहरण के लिए पहले संकलन पर) जारी रखें।

नोट -ओ विकल्प के संबंध में जीसीसी में एक बग प्रतीत होता है। यदि आप obj/_file__c.o कहने के लिए ऑब्जेक्ट फ़ाइल नाम सेट करते हैं तो उत्पन्न _file_.d में अभी भी _file_.o, obj/_file_c.o नहीं होगा।

+13

यह मेरे लिए काम नहीं किया। जैसे मेकफ़ाइल उत्पन्न हुआ और इसे चलाया: 'g ++ -c -Wall -Werror -MM -MF main.d -o main.o main.cpp' मुझे main.d फ़ाइल मिली, लेकिन main.o 0 बाइट्स था। हालांकि -एमएमडी झंडा वास्तव में ऐसा करने लगता है जो आवश्यक था। तो मेरा कामकाजी मेकफ़ाइल नियम बन गया: '$ (सीसी) -सी $ (सीएफएलएजीएस) -एमएमडी -ओ $ @ $ <' –

0

कोई भी जवाब मेरे लिए काम नहीं किया। जैसे मार्टिन फिडो के जवाब से पता चलता है कि जीसीसी निर्भरता फ़ाइल बना सकता है, लेकिन जब मैंने कोशिश की कि यह बिना किसी चेतावनी या त्रुटियों के मेरे लिए खाली (शून्य बाइट्स) ऑब्जेक्ट फाइलें उत्पन्न कर रहा है। यह एक जीसीसी बग हो सकता है। मैं पर

$ जीसीसी --version जीसीसी (जीसीसी) कर रहा हूँ 4.4.7 20,120,313 (रेड हैट 4.4.7-16)

तो यहाँ मेरा पूरा Makefile कि मेरे लिए काम करता है,

CC = g++ 
CFLAGS = -Wall -g -std=c++0x 
INCLUDES = -I./includes/ 

# LFLAGS = -L../lib 
# LIBS = -lmylib -lm 

# List of all source files 
SRCS = main.cc cache.cc 

# Object files defined from source files 
OBJS = $(SRCS:.cc=.o) 

# # define the executable file 
MAIN = cache_test 

#List of non-file based targets: 
.PHONY: depend clean all 

## .DEFAULT_GOAL := all 

# List of dependencies defined from list of object files 
DEPS := $(OBJS:.o=.d) 

all: $(MAIN) 

-include $(DEPS) 

$(MAIN): $(OBJS) 
    $(CC) $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS) $(LFLAGS) $(LIBS) 

#suffix replacement rule for building .o's from .cc's 
#build dependency files first, second line actually compiles into .o 
.cc.o: 
    $(CC) $(CFLAGS) $(INCLUDES) -c -MM -MF $(patsubst %.o,%.d,[email protected]) $< 
    $(CC) $(CFLAGS) $(INCLUDES) -c -o [email protected] $< 

clean: 
    $(RM) *.o *~ $(MAIN) *.d 

सूचना मैं .cc इस्तेमाल किया .. इसके बाद के संस्करण Makefile आसान है: यह समाधान + कुछ है कि किसी और (उदाहरण के लिए "प्रत्यय प्रतिस्थापन नियम" से उल्लेख नहीं किया गया था .cc.o :) के रूप में निर्दिष्ट का एक संयोजन है .c फ़ाइलों के लिए समायोजित करने के लिए।

भी महत्वपूर्ण इन दो पंक्तियों के महत्व को नोट करने के लिए:

$(CC) $(CFLAGS) $(INCLUDES) -c -MM -MF $(patsubst %.o,%.d,[email protected]) $< 
$(CC) $(CFLAGS) $(INCLUDES) -c -o [email protected] $< 

तो जीसीसी एक बार कहा जाता है पहले एक निर्भरता फ़ाइल का निर्माण करने, और फिर वास्तव में एक .cc फ़ाइल संकलित करता है। और इसलिए प्रत्येक स्रोत फ़ाइल के लिए।

0

सरल समाधान: .c से .o संकलन नियम के लिए मेकफ़ाइल का उपयोग हेडर फ़ाइल (ओं) पर निर्भर होना चाहिए और निर्भरता के रूप में आपके प्रोजेक्ट में जो कुछ भी प्रासंगिक है।

उदा।, Makefile में कहीं:

DEPENDENCIES=mydefs.h yourdefs.h Makefile GameOfThrones.S07E01.mkv 

::: (your other Makefile statements like rules 
::: for constructing executables or libraries) 

# Compile any .c to the corresponding .o file: 
%.o: %.c $(DEPENDENCIES) 
     $(CC) $(CFLAGS) -c -o [email protected] $< 
संबंधित मुद्दे

 संबंधित मुद्दे