Saya sangat baru di makefile dan saya ingin membuat direktori menggunakan makefile. Direktori proyek saya seperti ini
+--Project
+--output
+--source
+Testfile.cpp
+Makefile
Saya ingin meletakkan semua objek dan keluaran ke folder keluaran masing-masing. Saya ingin membuat struktur folder yang akan menjadi seperti ini setelah kompilasi.
+--Project
+--output
+--debug (or release)
+--objs
+Testfile.o
+Testfile (my executable file)
+--source
+Testfile.cpp
+Makefile
Saya mencoba dengan beberapa pilihan, tetapi tidak berhasil. Tolong bantu saya membuat direktori menggunakan make file. Saya memposting Makefile saya untuk pertimbangan Anda.
#---------------------------------------------------------------------
# Input dirs, names, files
#---------------------------------------------------------------------
OUTPUT_ROOT := output/
TITLE_NAME := TestProj
ifdef DEBUG
TITLE_NAME += _DEBUG
else
ifdef RELEASE
TITLE_NAME += _RELEASE
endif
endif
# Include all the source files here with the directory tree
SOURCES := \
source/TestFile.cpp \
#---------------------------------------------------------------------
# configs
#---------------------------------------------------------------------
ifdef DEBUG
OUT_DIR := $(OUTPUT_ROOT)debug
CC_FLAGS := -c -Wall
else
ifdef RELEASE
OUT_DIR := $(OUTPUT_ROOT)release
CC_FLAGS := -c -Wall
else
$(error no build type defined)
endif
endif
# Put objects in the output directory.
OUT_O_DIR := $(OUT_DIR)/objs
#---------------------------------------------------------------------
# settings
#---------------------------------------------------------------------
OBJS = $(SOURCES:.cpp=.o)
DIRS = $(subst /,/,$(sort $(dir $(OBJS))))
DIR_TARGET = $(OUT_DIR)
OUTPUT_TARGET = $(OUT_DIR)/$(TITLE_NAME)
CC_FLAGS +=
LCF_FLAGS :=
LD_FLAGS :=
#---------------------------------------------------------------------
# executables
#---------------------------------------------------------------------
MD := mkdir
RM := rm
CC := g++
#---------------------------------------------------------------------
# rules
#---------------------------------------------------------------------
.PHONY: all clean title
all: title
clean:
$(RM) -rf $(OUT_DIR)
$(DIR_TARGET):
$(MD) -p $(DIRS)
.cpp.o:
@$(CC) -c $< -o $@
$(OBJS): $(OUT_O_DIR)/%.o: %.cpp
@$(CC) -c $< -o $@
title: $(DIR_TARGET) $(OBJS)
Terima kasih sebelumnya. Tolong bimbing saya jika saya membuat kesalahan juga.
output/debug', needed by
direktori target '. Berhenti." Tapi saya tidak akan khawatir tentang itu sekarang. akan tetap berpegang pada aturan dasar. :). Terima kasih telah membimbing. Dan saya menjalankan "make" hanya dari direktori tingkat atas.directories
tanpa menyebabkannya selalu membangun kembali ..Menurut pendapat saya, direktori tidak boleh dianggap sebagai target makefile Anda, baik secara teknis maupun desain. Anda harus membuat file dan jika pembuatan file membutuhkan direktori baru, maka diam-diam buat direktori di dalam aturan untuk file yang relevan.
Jika Anda menargetkan file biasa atau "berpola", cukup gunakan
make
variabel internal$(@D)
, yang berarti "direktori tempat target saat ini berada" (cmp. Dengan$@
untuk target). Sebagai contoh,Kemudian, Anda secara efektif melakukan hal yang sama: membuat direktori untuk semua
$(OBJS)
, tetapi Anda akan melakukannya dengan cara yang tidak terlalu rumit.Kebijakan yang sama (file adalah target, direktori tidak pernah) digunakan dalam berbagai aplikasi. Misalnya,
git
sistem kontrol revisi tidak menyimpan direktori.Catatan: Jika Anda akan menggunakannya, mungkin berguna untuk memperkenalkan variabel kemudahan dan memanfaatkan
make
aturan perluasan.sumber
Atau, Cium.
Ini akan membuat semua direktori setelah Makefile diurai.
sumber
$(info $(shell mkdir -p $(DIRS)))
Tanpa$(info ...)
, output darimkdir
perintah akan ditempelkan ke Makefile , yang menyebabkan kesalahan sintaks paling baik. The$(info ...)
panggilan memastikan bahwa a) kesalahan (jika ada) yang terlihat kepada pengguna, dan b) bahwa fungsi panggilan mengembang apa-apa.make
di, dan di luar dirinya sendiri, menangani target direktori sama seperti target file. Jadi, mudah untuk menulis aturan seperti ini:Satu-satunya masalah adalah, bahwa stempel waktu direktori bergantung pada apa yang dilakukan pada file di dalamnya. Untuk aturan di atas, ini mengarah pada hasil sebagai berikut:
Ini jelas bukan yang Anda inginkan. Setiap kali Anda menyentuh file tersebut, Anda juga menyentuh direktori. Dan karena file tersebut bergantung pada direktori, akibatnya file tersebut tampak kedaluwarsa, memaksanya untuk dibangun kembali.
Namun, Anda dapat dengan mudah menghentikan putaran ini dengan memberi tahu make untuk mengabaikan stempel waktu direktori . Ini dilakukan dengan mendeklarasikan direktori sebagai prasyarat hanya-pesanan:
Ini dengan benar menghasilkan:
TL; DR:
Tulis aturan untuk membuat direktori:
Dan memiliki target untuk barang-barang di dalamnya bergantung pada direktori yang hanya dapat dipesan:
sumber
touch
mengubah data stat di direktori induk? Itu tidak masuk akal bagi saya. Mtime dir hanya bergantung pada nama file yang dikandungnya. Saya tidak dapat mereproduksi masalah Anda.Semua solusi termasuk yang diterima memiliki beberapa masalah seperti yang dinyatakan dalam komentar masing-masing. The diterima jawaban dengan @ jonathan-Leffler sudah cukup baik tetapi tidak memperhitungkan efek itu prasyarat belum tentu akan dibangun dalam rangka (selama
make -j
misalnya). Namun hanya memindahkandirectories
prasyarat dariall
untukprogram
memprovokasi pembangunan kembali pada setiap menjalankan AFAICT. Solusi berikut tidak memiliki masalah itu dan AFAICS berfungsi sebagaimana mestinya.sumber
Saya baru saja menemukan solusi yang cukup masuk akal yang memungkinkan Anda menentukan file yang akan dibangun dan direktori dibuat secara otomatis. Pertama, tentukan variabel
ALL_TARGET_FILES
yang menyimpan nama file dari setiap file yang akan dibuat oleh makefile Anda. Kemudian gunakan kode berikut:Begini cara kerjanya. Saya mendefinisikan sebuah fungsi
depend_on_dir
yang mengambil nama file dan menghasilkan aturan yang membuat file bergantung pada direktori yang berisi dan kemudian mendefinisikan aturan untuk membuat direktori itu jika perlu. Kemudian saya menggunakanforeach
untukcall
fungsi ini pada setiap nama file daneval
hasilnya.Perhatikan bahwa Anda memerlukan versi GNU make yang mendukung
eval
, yang menurut saya adalah versi 3.81 dan lebih tinggi.sumber
mengingat Anda adalah seorang pemula, saya akan mengatakan jangan mencoba melakukan ini dulu. itu pasti mungkin, tetapi akan memperumit Makefile Anda tidak perlu. tetap berpegang pada cara sederhana sampai Anda lebih nyaman dengan make.
Meskipun demikian , salah satu cara untuk membangun direktori yang berbeda dari direktori sumber adalah VPATH ; Saya lebih suka aturan pola
sumber
Kemandirian OS sangat penting bagi saya, jadi
mkdir -p
bukan pilihan. Saya membuat rangkaian fungsi ini yang digunakaneval
untuk membuat target direktori dengan prasyarat pada direktori induk. Ini memiliki manfaat yangmake -j 2
akan berfungsi tanpa masalah karena dependensi ditentukan dengan benar.Misalnya, menjalankan di atas akan membuat:
sumber
Lihat https://www.oreilly.com/library/view/managing-projects-with/0596006101/ch12.html
Saat saya menggunakan Ubuntu, saya juga perlu menambahkan ini di bagian atas Makefile saya:
sumber