Makefile Sözdizimini Anlamak: Yaygın Sorunlar ve Çözümler ('Eksik Operatör' ve 'Giriş Noktası Bulunamadı' dahil)

Makefile Sozdizimini Anlamak Yaygin Sorunlar Ve Cozumler Eksik Operator Ve Giris Noktasi Bulunamadi Dahil



Tıpkı bir kod dosyasının onu değerli kılmak için içerik olarak bir veya daha fazla kod satırı içermesi gibi, temel makefile de değişkenler, kurallar ve hedefler kullanılarak oluşturulur. Bunun dışında, sorunsuz bir makefile oluşturmak için gerekli olan başka faktörler de vardır. Bu kılavuzda, temel makefile sözdizimini ve makefile yazarken sık karşılaşılan sorunları tartışacağız ve bu sorunları çözmek için çözümler sunacağız.

Makefile Temel Söz Dizimini Anlamak

Makefile oluşturmaya başlamak için makefile'ın temel özelliklerini makefile kod örneğiyle açıklıyoruz. Yürütülebilir bir dosya elde etmek için makefile içeriğine aşağıdaki sözdizimi özelliklerini dahil etmek gerekir:







Değişken s: Makefile içerisinde kullanılması gereken temel veri saklama nesneleri. Bu değişkenler bir derleyiciyi, bayrakları, kaynak dosyalarını, nesne dosyalarını ve hedef dosyaları belirtmek için kullanılır. Aşağıdaki örnek makefile içinde toplam beş değişken vardır: CXX (bir C++ derleyicisi ayarlamak için), CXXFLAGSc (derleyici işaretleri), TARGET (hedef yürütülebilir dosya adı ayarlamak için), SRCS (bir kaynak kod dosyası ayarlamak için) , OBJS (kaynak kod dosyası aracılığıyla oluşturulan nesne dosyalarını içerecek şekilde).



Hedefler: Kaynaktan oluşturulması beklenen bir çıktı. Bu bir hedef dosya veya herhangi bir sembolik ad olabilir: 'tümü', 'TARGET' değişkeni aracılığıyla oluşturulması gereken varsayılan hedeftir, '$TARGET', 'OBJS' değişkenlerine bağlıdır ve 'temiz' hedef, hedefi kaldırır ve çalışma dizinindeki nesne dosyalarını.



Kurallar ve Oluşturma Komutları: Kaynak dosyadan veya bağımlılıklardan bir hedef oluşturmak için yürütülecek temel talimatlar kümesi. Örneğin, “%.o: %.cpp” kuralı, “cpp” uzantılı dosyanın “o” uzantılı bir nesne dosyası oluşturmak için kullanıldığını ve her iki dosyanın da aynı adı içerdiğini gösterir. Öte yandan build komutu $(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJS) bir nesne dosyasını ve yeni bir hedef dosyayı birbirine bağlamak için kullanılır. Aynı şekilde build komutu $(CXX) $(CXXFLAGS) -c $< -o $@ kaynak dosyayı bir nesne dosyasına derler.





Bağımlılıklar: Bir makefile oluşturmak istediğinizde bağımlılıklar her zaman oradadır. Örneğin, “hepsi” hedefi “TARGET” değişkenine, “TARGET” ise “OBJS” değişkenine bağlıdır. Aynı zamanda “OBJS” değişkeni “SRCS” değişkeni üzerinden kaynak dosyaya bağımlıdır.

Yorumlar: Bir dosyayı uzun süre sonra kullanmanız durumunda genellikle kod satırının amacını açıklamak için insanların anlayabileceği talimatlar kullanılır. Aşağıdaki makefile'da her satırı açıklamak için “#” işaretiyle başlayan yorumları kullanıyoruz.



CXX = g++
CXXBAYRAKLAR = -std =c++ on bir -Duvar
HEDEF = Yeni
SRCS = ana.cpp
OBJS = $ ( SRCS:.cpp=.o )
hepsi: $ ( HEDEF )
$ ( HEDEF ) : $ ( OBJ'ler )
$ ( CXX ) $ ( CXXBAYRAKLAR ) $ ( HEDEF ) $ ( OBJ'ler )
% .Ö: % .cpp
$ ( CXX ) $ ( CXXBAYRAKLAR ) -C $ < $ @
temiz:
rm -F $ ( HEDEF ) $ ( OBJ'ler )

Yaygın Sorunlar ve Çözümler

Herhangi bir makefile yazarken, sonunda istenen çıktıyı elde etmek için her küçük ayrıntıyı dikkate almak gerekir. Makefile oluştururken kullanıcılar tarafından sıklıkla karşılaşılan bazı genel sorunlar vardır. Bu bölümde bu sorunları tartışacağız ve olası çözümleri aşağıdaki gibi önereceğiz:

1: Değişkenleri Kullanmamak

Derleyicileri, hedefi, kaynak dosyalarını vb. ayarlamak için gerekli olduğundan, makefile'da değişkenlerin kullanılması şarttır. Karşılaşılabilecek en yaygın sorun, makefile'de herhangi bir değişkenin kullanılmamasıdır. Bu nedenle, önceki örnek makefile'da CXX, CXXFLAGSc(derleyici bayrakları), TARGET, SRCS ve OBJS gibi temel değişkenleri kullandığınızdan emin olun.

2: Eksik Ayırıcı Sorunu

Makefile yazarken girinti kurallarına çok dikkat etmek gerekir çünkü “make” komutunun yürütülmesi sırasında tab yerine boşluk kullanmak sizi “eksik ayırıcı” sorununa sürükleyecektir. Örneğin 13. satırda bir kuralın başına boşluk ekleyip sekmeyi kaldırıyoruz.

$ ( HEDEF ) : $ ( OBJ'ler )
$ ( CXX ) $ ( CXXBAYRAKLAR ) $ ( HEDEF ) $ ( OBJ'ler )

Make sorgusunu çalıştırdığımızda 13. satırda eksik ayırıcı hatası alıyoruz ve dosyanın çalışması duruyor. Bu sorunu önlemek için boşluk yerine “sekme” kullandığınızdan emin olun.

yapmak

Bu sorunu önlemek için aşağıdaki resimde gösterildiği gibi boşluk yerine 'sekme' kullandığınızdan emin olun:

$ ( HEDEF ) : $ ( OBJ'ler )
$ ( CXX ) $ ( CXXBAYRAKLAR ) $ ( HEDEF ) $ ( OBJ'ler )

3: “Giriş Noktası Bulunamadı” Sorunu

Bu hata, kaynak kod dosyasındaki “main()” işlevinin kullanımını kaçırdığınızda olduğu gibi makefile nedeniyle değil, çoğunlukla kaynak dosya nedeniyle oluşur. Örneğin, main() işlev tanımını basit, kullanıcı tanımlı bir işlev bildirimiyle değiştiririz.

#include
dahili gösteri ( ) {
karakter v;
std::cout << 'Bir değer girin: ' ;
std::cin >> içinde;
std::cout << içinde << std::endl;
geri dönmek 0 ;
}

Windows komut isteminde “make” komutunu çalıştırdığımızda “‘WinMain’e tanımsız referans” ile karşılaşıyoruz. Bunun nedeni derleyicinin C++ dosyasını çalıştırmaya başlamak için herhangi bir giriş noktası bulamamasıdır. Bu sorunu çözmek için 'göster'i 'ana' ile değiştirin.

4: Yanlış Uzantıların Kullanımı

Bazen kullanıcı makefile'da kullanılacak kaynak dosya için istemeden yanlış uzantıları kullanabilir. Yanlış uzantının kullanılması çalışma zamanı hatalarına yol açacaktır, yani hedef oluşturma kuralı yoktur. C++ dosyası için yürütülebilir dosyayı ve nesne dosyasını oluşturmak için bir makefile oluşturuyoruz. Yedinci satırda kaynak dosyayı “c” uzantılı olarak veriyoruz.

CXX := g++
CXXBAYRAKLAR := -std =c++ on bir -Duvar
HEDEF = yeni
SRCS = ana.c
OBJS = $ ( SRCS:.cpp=.o )
Hepsi: $ ( HEDEF )
$ ( HEDEF ) : $ ( OBJ'ler )

“Make” komutunu çalıştırmak bizi “No rule to make target ‘main.c’” hatasına yönlendiriyor. Bu sorunu önlemek için doğru kaynak dosya uzantısını kullandığınızdan emin olun.

yapmak

5: Eksik Bağımlılıklar

Bir makefile yazarken, istenen çıktıyı elde etmek için kaynak dosyanın tüm bağımlılıklarını dahil etmelisiniz. Örneğin C++ kod dosyamız bağımlılık olarak “myheader.h” dosyasını kullanıyor. Bu nedenle C++ kod dosyasında bundan şu şekilde bahsediyoruz:

#include
#include “myheader.h”
dahili gösteri ( ) {
karakter v;
std::cout << 'Bir değer girin: ' ;
std::cin >> içinde;
std::cout << içinde << std::endl;
geri dönmek 0 ;
}

Makefile içerisinde 9. satırda yazılan build kuralındaki “myheader.h” dosyasının kullanımını kasıtlı olarak görmezden geliyoruz.

% .Ö: % .cpp
$ ( CXX ) $ ( CXXBAYRAKLAR ) -C $ < $ @

Artık “make” komutunu kullanırken “Hepsi için yapılacak bir şey yok” hatasıyla karşılaşıyoruz.

yapmak

% .Ö: % .cpp başlığım.h
$ ( CXX ) $ ( CXXBAYRAKLAR ) -C $ < $ @

Bahsi geçen sorunu önlemek ve kaynak kodunu başarılı bir şekilde çalıştırmak için makefile'ın dokuzuncu satırında aşağıda gösterildiği gibi “myheader.h” dosya adını belirtin:

Çözüm

Bu kılavuzda, değişkenler, derleme komutları, kurallar vb. gibi gerekli içerikleri kullanarak makefile sözdizimini kapsamlı bir şekilde açıkladık. Sözdizimini daha açık bir şekilde detaylandırmak için kod örneği eklenmiştir. Sonunda, kullanıcının makefile oluştururken karşılaşabileceği bazı olağan sorunları ve bunların çözümlerini tartıştık.