Gnu Makefile - Manipulace závislostí

hlasů
12

Jaký přístup do C ++ programátoři na použití na platformě Unix pro vytváření a správu souborů Makefile?

Byl jsem pomocí ručně vyrobené Makefiles pro své projekty, ale nemají zvládnout změny souborů záhlaví a jiné závislosti. I googled kolem a našel dobré řešení zde .

Ale já jsem narazil na problém tady v sed příkazu -

    sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
        -e '/^$$/ d' -e 's/$$/ :/' < $*.d >> $*.P; \

Problém je s 3. výrazem „-e‚s / * \ $$ //‘. Tak to nefunguje. Jeho měl odstranit koncové zpětné lomítko. Chápu, že tam musí být dvojí dolaru tam, protože to je součástí Makefile. Může mi někdo říct, co špatně?

Zde je kompletní Makefile -

CC=g++
CFLAGS=-g -Wall
LIBS=-lpthread

OBJS=file1.o file2.o
TARGET=testProg

$(TARGET) : $(OBJS)
        $(CC) -o $@ $^ $(CFLAGS) $(LIBS)

%.o : %.cpp
        $(CC) -MMD -c -o $@ $< $(CFLAGS)
        @cp $*.d $*.P; \
            sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
                -e '/^$$/ d' -e 's/$$/ :/' < $*.d >> $*.P; \
            rm -f $*.d

-include $(OBJS:%.o=%.P)

clean :
        rm -f $(TARGET) $(OBJS)

all : $(TARGET)

Na rozdíl od řešení tohoto problému, také bych rád nějaké tipy / odkazy na mé 1. otázku.

Položena 30/09/2009 v 22:18
zdroj uživatelem
V jiných jazycích...                            


12 odpovědí

hlasů
25

gcc / g ++ lze generovat závislosti pro vás s -Mrodinou možností. Níže uvedené funguje podle zadání, jak vytvářet .dependssoubory daný zdrojový soubor. Tím -include $(DEPS)$ (Deps) je uznávána jako cíl, a bude vybudováno / vytvořena při změně zdrojové soubory.

CXX      = g++
CXXFLAGS = -Wall -O3
LDFLAGS  =

TARGET = testcpp
SRCS   = main.cc x.cc foo.cc
OBJS   = $(SRCS:.cc=.o)
DEPS   = $(SRCS:.cc=.depends)


.PHONY: clean all

all: $(TARGET)

$(TARGET): $(OBJS)
        $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) -o $(TARGET)

.cc.o:
        $(CXX) $(CXXFLAGS) -c $< -o $@

%.depends: %.cc
        $(CXX) -M $(CXXFLAGS) $< > $@

clean:
        rm -f $(OBJS) $(DEPS) $(TARGET)

-include $(DEPS)
Odpovězeno 02/10/2009 v 17:35
zdroj uživatelem

hlasů
8

  1. Používám tento přístup příliš a lze ji nechválí velmi málo. A píšu své makefiles rukou a znovu jim hodně na nové projekty.
  2. .v výraz „s / * \\ $ //“ bude pracovat mimo kontext značky. V rámci makefile to nefunguje, protože Ujistěte se pokusí interpretovat „$ /“ před předáním výsledku k plášti. Proto je nutné použít „S / * \\ $$ //“ (všimněte si navíc $) v rámci makefile, ale to nebude fungovat mimo kontextu značky (takže testování se jedná o mírnou bolest).



EDIT:

Snažil jsem se soubor Makefile, a že sed prohlášení se zdá, aby se odstranily koncové zpětná lomítka v pohodě. Zkuste něco jednodušší, takto:

obrácené lomítko:
    @echo "\\"> $ @

Test: zpětné lomítko
    @echo bez sed:
    @cat zpětné lomítko
    @echo s sed:
    @sed -e 's / * \\ $$ //' <lomítko



EDIT: Dobře, teď jsem závislý. Můžete zkusit tyto pokusy a sdělte nám výsledky?

Změnit poslední znak 'Z': s /.$/ z /
Změna koncové zpětné lomítko na 'z': s / \\ $ / z /
Změna koncové zpětné lomítko na 'z': sm \\ $ MZM
Odstranit koncové zpětné lomítko: s / \\ $ //
Smazat mezery a koncové zpětné lomítko: s / * \\ $ //
Zkuste všechny tyto uvnitř i vně značky s ‚$‘ a ‚$$‘.
Odpovězeno 30/09/2009 v 22:50
zdroj uživatelem

hlasů
3

V make souboru cokoliv List v závislosti linky je závislost hlavičkové soubory nebo jiné soubory hotelu.

BSD návod na make Poznámka: můžete automaticky generovat hlavičky závislost info s -mm spínačem GCC.

Odpovězeno 30/09/2009 v 22:22
zdroj uživatelem

hlasů
2

Musím být něco chybí. Proč ne vytvářet závislost soubory pracovat pro vás?

Odpovězeno 01/10/2009 v 14:06
zdroj uživatelem

hlasů
1

V sestavení systému Mozilly používáme -MD přepínač GCC generovat soubory závislost: http://mxr.mozilla.org/mozilla-central/source/configure.in#7134 a pak budeme používat skript s názvem mddepend.pl ke kontrole pro odstraněnými hlavičkové soubory, takže odstranění záhlaví prostě způsobuje přestavět, není chybu: http://mxr.mozilla.org/mozilla-central/source/config/rules.mk#2066 http: //mxr.mozilla. org / mozilla-střed / source / build / unix / mddepend.pl

Že skript generuje soubor .all.pp obsahující všechny závislostí, s další foo.o: FORCEzávislostí uvízl v chybějících hlavičkové soubory. Potom jsme prostě -include soubor .all.pp v rules.mk vpravo dole tam.

Odpovězeno 01/10/2009 v 20:58
zdroj uživatelem

hlasů
1

Makedepend nástroj je instalován na mnoha systémech a mohou být velmi užitečné pro získávání informací o závislostech.

Zde je příklad Makefile, který používá includesměrnice (plus malý Perl magie) začlenit výstup z makedepend:

# the name of the executable that we'll build
TARGET = foo_prog
# our .cc source files
SRCS = foo.cc main.cc

# the .o versions of our source files
OBJS := $(patsubst %.cc, %.o, $(filter %.cc, $(SRCS)))
# some flags for compiling
CXXFLAGS = -Wall -Werror

# In order to build $(TARGET), we first build each of the $(OBJS).
# Then we use the given command to link those $(OBJS) into our
# $(TARGET) executable.  $^ is a shortcut for $(OBJS).  $@ is a
# shortcut for $(TARGET).
#
# The default compile rule will compile each of the $(OBJS) for us.
$(TARGET): $(OBJS)
        $(CXX) $(CXXFLAGS) $^ -o $@

# Use "make clean" to remove all of the support files.
clean:
        rm -f $(OBJS) $(TARGET) Makefile.depend *~

# This automatically uses the 'makedepend' utility to add any
# dependencies that our source files have, namely .h files.  This way,
# if the .h files change, the code will be re-compiled.
include Makefile.depend
Makefile.depend: $(SRCS)
        makedepend -f- -Y $(SRCS) 2> /dev/null | \
        perl -p -e "s/(^.*?:)/Makefile.depend \1/" > Makefile.depend

Pokud jsou oba foo.cca main.ccjsou závislé na foo.h, pak se obsah Makefile.dependbude vypadat následovně:

Makefile.depend foo.o: foo.h
Makefile.depend main.o: foo.h

Konečným výsledkem je, že informace o závislost z makedependvstřikuje do Makefile jako řadu pravidel. Je to podobné jako v přístupu pomocí .dsouboru pro každý .ccsoubor , ale uchovává informace o závislostech v jednom souboru namísto roztroušených po celém místě.

Odpovězeno 01/10/2009 v 14:35
zdroj uživatelem

hlasů
1

Raději používat cmake, i když to není nezbytně řešení vašeho problému.

Je to projekt, jazyk pro popis, který bude generovat Makefiles, Visual Studio projektu Eclipse projektu, KDevelop, etc pro vás. Všechny závislosti jsou pro tebe udělal:

CMakeLists.txt

add_executable(my_exe file1.c file2.c)
target_link_libraries(my_exe my_library)
add_subdirectory(lib)

V lib / CMakeLists.txt

add_library(my_library file3.c file4.c)

To vytváří my_exe z file1.c file2.c propojeny proti my_library. Připadá mi to mnohem jednodušší. Má také věci, jako je balíček objev:

find_package(Qt4)
Odpovězeno 30/09/2009 v 23:13
zdroj uživatelem

hlasů
0

I začátek tip, že jsem našel užitečné při budování závislost soubory je zahrnout soubor závislost jako cíl v generované pravidla:

file.d file.o : file.c header.h header2.h ...

Tak makese regeneruje závislosti v případě, že zdroj nebo na kteroukoli záhlaví změní. Včetně falešné cíle pro záhlaví (GCC -MP), by pak mělo umožnit stabilní sestavení, kdy jsou hlavičky odstraněny - za absense požadovaného záhlaví zůstává chyba kompilace, není chyba make závislost.

Za předpokladu, že soubory závislost jsou generovány do stejného adresáře jako soubory objektů, následující by měl fungovat pro GCC na Unix:

-include $(OBJ:.o=.d)

$(OBJDIR)/%d : $(SRCDIR)/%.cpp
        mkdir -p $(@D)
        echo -n "$@ " > $@.tmp
        $(CXX) $(CPPFLAGS) -MM -MP -MT $(@:.d=.o) $< >> $@.tmp
        mv $@.tmp $@

(z paměti)

Odpovězeno 30/03/2017 v 14:07
zdroj uživatelem

hlasů
0

S modernější verzi GCC, můžete přidat příznak -MP mít GCC generovat prázdné pravidla pro vlastní záhlaví.

Odpovězeno 22/07/2013 v 15:08
zdroj uživatelem

hlasů
0

Namísto SED skripty, použijte volbu -MT gcc upravit cíl generovaných pravidel závislost. Tento blog post má více informací.

Odpovězeno 02/10/2010 v 20:40
zdroj uživatelem

hlasů
0

Používám BSD dělat (pmake?), Který dělá spoustu práce pro mě (můj jazyk je C, ale myslím, že žádný rozdíl zde). To je můj obyčejný ‚local.prog.mk‘ Nikdy jsem ho změnit:

.PHONY: tags .depend

# .depend depends only on $(SRCS) in bsd.dep.mk, so we can't track changes of
# header's own dependencies properly. so .depend is .PHONY target here.

CSTD    ?=c99
WARNS   ?=9
.if !empty(PC_LIST)
PC_CF   !=pkg-config --cflags $(PC_LIST)
PC_LD   !=pkg-config --libs   $(PC_LIST)
.endif
CFLAGS  +=$(PC_CF) -fgnu89-inline
.if !defined(NO_DEBUG)
CFLAGS  +=-O0 -ggdb3
.endif
LDFLAGS +=$(PC_LD)
CTAGS   =exctags

NO_MAN=
NO_OBJ=
CLEANFILES+=$(PROG).core

.include <bsd.prog.mk>
$(PROG): $(SUBDIR)
build: clean cleandepend depend all
run: $(PROG)
    ./$(PROG)

Poznámka: Zahrnutí ‚bsd.prog.mk‘ - to zvládá všechno, stavět, závisí čisté cíle. Specifické pro projekt BSDmakefiles jsou jednoduché:

.SILENT:

PROG    =hello
SRCS    =hello.c world.c
PC_LIST =gtk+-2.0 gnet-2.0

.include "../local.prog.mk"

proto:
    cproto -siv `pkg-config --cflags $(PC_LIST)` $(SRCS) > prototypes
CLEANFILES+=prototypes

Jen jsem dělat závisí pokaždé, když jsem vložit / odstranit veškeré direktivy #include.

Odpovězeno 30/09/2009 v 23:48
zdroj uživatelem

hlasů
0

Můžete použít qmake generovat Makefiles pro projekt i v případě, že projekt není pomocí Qt.

Odpovězeno 30/09/2009 v 22:46
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more