Src / 'deki tüm .cpp dosyalarını obj / içindeki .o'lara derleyip sonra ./ içinde ikili dosyaya bağlayabilir miyim?


116

Proje dizinim şuna benzer:

/project
    Makefile
    main
    /src
        main.cpp
        foo.cpp
        foo.h
        bar.cpp
        bar.h
    /obj
        main.o
        foo.o
        bar.o

Bütün derlemek olacaktır yapmak benim makefile istiyorum ne .cppdosyaları /srciçin klasöründe .odosyalar /objklasöründe, sonra tüm bağlantı .odosyaları /objüst düzey klasörde çıktı ikili içine /project.

Makefiles ile neredeyse hiç deneyimim yok ve bunu başarmak için ne arayacağımdan emin değilim.

Ayrıca, bunu yapmanın "iyi" bir yolu mu yoksa yapmaya çalıştığım şeye daha standart bir yaklaşım var mı?



6
@aaa: OP'nin her kaynak dosyanın açıkça listelenmesini gerektirmeyen bir çözüm istediğini tahmin ediyorum.
Cascabel

7
Sahip olduğum her kaynak dosyayı belirtmek istemiyorum ve bu kılavuzu daha önce okumaya çalıştım, ancak düzensiz ve anlaşılması zor buluyorum. Kuru teknik kılavuzlar yerine, beklediğim şeyi yapan ve iyi açıklanmış gerçek bir örnekten çok daha iyi öğreniyorum.
Austin Hyde

Tamam. Ancak, iyi örneklerle belgelemenin mükemmel olmasını sağlayın (teknik el kitabını denemeyin). kalıp kurallarını arıyorsunuz: gnu.org/software/make/manual/make.html#Pattern-Rules
Anycorn

11
İstediğim şeye biraz daha benziyor. Yine de, IMHO, yapma kılavuzu biraz kuru, çünkü make ile orta seviyedeki geliştiricilere daha çok hedefleniyor ve bunun ötesinde çok büyük ve derinlemesine. Belki çok fazla.
Austin Hyde

Yanıtlar:


180

Sorunun Makefile parçası

Genellemeniz gerekmediği sürece bu oldukça kolaydır (ancak boşluk girintisini g ++ yakınındaki sekmelerle değiştirin)

SRC_DIR := .../src
OBJ_DIR := .../obj
SRC_FILES := $(wildcard $(SRC_DIR)/*.cpp)
OBJ_FILES := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRC_FILES))
LDFLAGS := ...
CPPFLAGS := ...
CXXFLAGS := ...

main.exe: $(OBJ_FILES)
   g++ $(LDFLAGS) -o $@ $^

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
   g++ $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<

Otomatik bağımlılık grafiği oluşturma

Çoğu yapım sistemi için "olmazsa olmaz" özellik. Ekleyerek derleme bir yan etki olarak, tek bir geçişte yapılabilir içinde GCC ile -MMDbayrağı CXXFLAGSve -include $(OBJ_FILES:.o=.d) Makefile gövdenin ucuna:

CXXFLAGS += -MMD
-include $(OBJ_FILES:.o=.d)

Ve daha önce de bahsettiğimiz gibi, her zaman GNU Make Manual var, bu çok yardımcı oluyor.


11
Ah, beni saniyelerle yendin. Ama öneririm OBJ_FILES = $(patsubst src/%.cpp,obj/%.o,$(CPP_FILES)).
Beta

1
İşe bunun için bu değiştirmek zorunda: $<olmalı $^main.exe kurallarına karşı ve ben bir yazım hatası ile olduğunu düşünüyorum obj/%.o: src/%cpp.

1
@bobah Bir 'eksik.' cpp için nesneleriniz kuralı
regomodo

1
özel değişkenler, makefile'a özgü oldukları ve aranması zor oldukları için muhtemelen açıklamaya değer: gnu.org/software/make/manual/html_node/Automatic-Variables.html
Blake

2
Bunun eski bir soru olduğunu biliyorum ama projeme göre biraz değişiklik yaptım ama işe yaramıyor. İşte benim makefile: pastebin.com/4CksG9Wc Konsola giriyorum :make: *** No rule to make target '/main.o', needed by 'bin/main'. Pare.
Mateus Felipe

5

Joker karakter benim için de işe yarıyor, ancak dizin değişkenlerini kullananlar için bir yan not vermek istiyorum. Klasör ağacı için her zaman eğik çizgi kullanın (ters eğik çizgi değil), aksi takdirde başarısız olur:

BASEDIR = ../..
SRCDIR = $(BASEDIR)/src
INSTALLDIR = $(BASEDIR)/lib

MODULES = $(wildcard $(SRCDIR)/*.cpp)
OBJS = $(wildcard *.o)

eğik çizgi mi demek istedin? Örneğiniz, geleneksel olarak eğik çizgi olarak kabul edilen şeyi gösterir. Spesifik olarak, "sağa eğilenler" "ileri" olarak kabul edilir ve sol olanlar "geri" olarak kabul edilir
Evan Teran

Evet, haklısın, sadece "bölü" demek istiyorum. Gönderiyi güncelledim.
xesf
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.