मेरे पास एक मेकफाइल स्वचालित रूप से स्रोत फ़ाइलों का पुनर्निर्माण कैसे हो सकता है जिसमें एक संशोधित हेडर फ़ाइल शामिल है? (C / C ++ में)


91

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

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 $@ $^

$(SOBJS) : $(SFILES)
    $(AS) $(ASFLAGS) $< -o $@

%.o: %.c
    @echo Compiling $<...
    $(CC) $(CFLAGS) -c -o $@ $<

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

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

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

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

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

जवाबों:


30

जैसा कि इस साइट पर पहले ही बताया जा चुका है, इस पृष्ठ को देखें: ऑटो-डिपेंडेंसी जेनरेशन

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

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


2
मुझसे गलती हो सकती है, लेकिन मुझे लगता है कि जीसीसी ने वास्तव में उस सेडान मुद्दे के आसपास कोशिश करने और पाने के लिए एक फीचर जोड़ा है। की जाँच करें gcc.gnu.org/onlinedocs/gcc-4.3.1/gcc/Preprocessor-Options.html विशेष रूप से -MP।
यूजीन मार्कोटे

हां, -एमपी जीसीसी 3 के बाद से मौजूद है, क्लैंग और आईसीसी में मौजूद है, और सेड की आवश्यकता से बचा जाता है। bruno.defraine.net/techtips/makefile-auto-d dependencies
gcc/

उत्तर में लिंक के नवीनतम संस्करण में जीसीसी झंडे का उपयोग करने वाले उदाहरण हैं।
मैडिसिनिस्ट

20

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

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

-include $(DEPS)

%.o: %.c
    $(CC) -c $(CFLAGS) -MM -MF $(patsubst %.o,%.d,$@) -o $@ $<

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

'-Include' के आरंभ में डैश, .d फ़ाइल को मौजूद नहीं होने पर जारी रखने के लिए कहता है (जैसे पहले संकलन पर)।

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


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

17

यह क्रिस डोड के उत्तर के बराबर है , लेकिन एक अलग नामकरण सम्मेलन का उपयोग करता है (और संयोग से sedजादू की आवश्यकता नहीं है । बाद के डुप्लिकेट से नकल की गई


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

depend: .depend

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

include .depend

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


4
आप स्रोत क्यों नहीं बख्शते? विशेष रूप से कई और पात्रों की आवश्यकता नहीं होती है और इसे "एसआरसीएस" के रूप में बाधित नहीं किया जाता है जो एक संक्षिप्त रूप में दिख सकता है।
हैलोगूडीबाई

@HelloGoodbye शैली का एक सा। मैंने हमेशा उपयोग किया है, और हमेशा देखा है, SRCSऔर OBJS। मैं ज्यादातर समय सहमत हूँ, लेकिन हर किसी को पता होना चाहिए कि वे क्या हैं।
sherrellbc

@sherrellbc क्या लोगों को "जानना चाहिए" और जो लोग वास्तव में जानते हैं, वे अक्सर दो अलग-अलग चीजें हैं: P
HelloGoodbye

7

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

%.o: %.c
        @echo Compiling $<...
        $(CC) $(CFLAGS) -c -o $@ $<

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

4

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

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

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

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


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

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

आह, वहाँ समस्या है: मैं विंडोज के तहत यह कर रहा हूँ।
निकोलस फ्लायंट

3

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


0

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

$ gcc --version gcc (GCC) 4.4.7 20120313 (रेड हैट 4.4.7-16)

तो यहाँ मेरा पूरा Makefile है जो मेरे लिए काम करता है; यह समाधानों का एक संयोजन है + ऐसा कुछ जिसका किसी और ने उल्लेख नहीं किया था (उदाहरण के लिए "। प्रत्यय प्रतिस्थापन नियम" .cc.o :):

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,$@) $<
    $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<

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

सूचना मैंने .cc का उपयोग किया है। ऊपर मेकफाइल .c फ़ाइलों के लिए समायोजित करना आसान है।

इन दो पंक्तियों के महत्व पर भी ध्यान दें:

$(CC) $(CFLAGS) $(INCLUDES) -c -MM -MF $(patsubst %.o,%.d,$@) $<
$(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<

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


0

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

जैसे, 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 $@ $<

-1

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.