CFLAGS ve CPPFLAGS


104

CFLAGS'nin (veya C ++ için CXXFLAGS) derleyici için olduğunu, CPPFLAGS'ın ise önişlemci tarafından kullanıldığını anlıyorum.

Ama yine de farkı anlamıyorum.

#İnclude ile eklenen bir başlık dosyası için bir dahil etme yolu belirtmem gerekiyor - çünkü #include bir önişlemci yönergesi, önemsediğim tek şey önişlemci (CPPFLAGS) mi?

Hangi koşullarda derleyiciye fazladan bir içerme yolu vermem gerekir?

Genel olarak, önişlemci gerekli üstbilgi dosyalarını bulur ve içerirse, neden ekstra içerme dizinleri hakkında bilgi verilmesi gerekir? CFLAGS ne işe yarar?

(Benim durumumda, aslında bunların HER İKİSİNİN programımı derlememe izin verdiğini buldum, bu da kafa karışıklığına katkıda bulunuyor ... Hedefime ulaşmak için CFLAGS VEYA CPPFLAGS kullanabilirim (en azından autoconf bağlamında). Ne verir?)


Yanıtlar:


156

Bir C programını derlemek için örtük yapma kuralı şudur:

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

burada $()söz dizimi değişkenleri genişler. Her ikisi de CPPFLAGSve CFLAGSdahil etme yollarını tanımlamak için kullandığınız derleyici çağrısında kullanıldığında, kişisel bir zevk meselesidir. Örneğin foo.c, mevcut dizindeki bir dosyaysa

make foo.o CPPFLAGS="-I/usr/include"
make foo.o CFLAGS="-I/usr/include"

ikisi de derleyicinizi tam olarak aynı şekilde arayacaktır, yani

gcc -I/usr/include -c -o foo.o foo.c

İkisi arasındaki fark, aynı içerme yoluna ihtiyaç duyan birden fazla diliniz olduğunda devreye girer, örneğin, bar.cppdaha sonra denerseniz

make bar.o CPPFLAGS="-I/usr/include"
make bar.o CFLAGS="-I/usr/include"

o zaman derlemeler olacak

g++ -I/usr/include -c -o bar.o bar.cpp
g++ -c -o bar.o bar.cpp

C ++ örtük kuralı CPPFLAGSdeğişkeni de kullandığından .

Bu fark size hangi bayrağın kullanılacağı konusunda iyi bir rehber sağlar - bayrağın koyduğu tüm diller için kullanılmasını istiyorsanız, CPPFLAGSbelirli bir dil içinse koyun CFLAGS, CXXFLAGSvb. İkinci türün örnekleri arasında standart uyumluluk veya uyarı bayrakları bulunur - -std=c99C ++ derleyicinize geçmek istemezsiniz !

Makefile dosyanızda böyle bir şeyle karşılaşabilirsiniz.

CPPFLAGS=-I/usr/include
CFLAGS=-std=c99
CXXFLAGS=-Weffc++

1
Tek başına cppkullanarak çalışamayacağınızı CPPFLAGSve herhangi bir makul sonuç bekleyemeyeceğinizi unutmayın, çünkü -std=c99hangi sembollerin tanımlandığını etkiler (özellikle özellik testi makroları yerine). Bunun yerine ihtiyacınız var $(CC) $(CPPFLAGS) $(CFLAGS) -E.
Jed

10

CPPFLAGSMakro belirtmek için kullanmak biridir #includedizinleri.

Hem CPPFLAGSve CFLAGSsizin durumunuzda çalışma nedeniyle make(1) kuralı önişlemeyi ve (her iki makrolar komutu kullanılır böylece) bir komuta derleme hem birleştirir.

.Formu kullanıyorsanız içerme dizini olarak belirtmenize gerek yoktur #include "...". Ayrıca standart derleyici içerme dizinini belirtmenize de gerek yoktur. Diğer tüm içerme dizinlerini belirtmeniz gerekir.


Bu daha mantıklı, ancak o zaman CFLAGS'ın ne yaptığını hala göremiyorum. Sizin de ima ettiğiniz gibi, daha karmaşık projelerde derleme ön işlemeden ayrı bir adımda yapılırsa, ön işleme başarılı olur, ancak CFLAGS CPPFLAGS'nin önişlemci için eklediği yolların aynısını eklemezse derleme başarısız olur mu? Önişlemci #include yönergelerini zaten işlediyse derleyicinin include yollarıyla ne yaptığını anlamıyorum sanırım?
EBM

4
@EB Önceden işlenmiş dosyaları derliyorsanız, yolları dahil etmek gereksizdir - gerekli başlıklar önceden işlenmiş kaynağa zaten eklenmiştir ( gcc -EBir dosya üzerinde çalıştırdığınızda çıktıya bir göz atın - #includes yoktur). Çoğu modern derleyici, ön işleme ve derleme adımlarını birleştirir, böylece bu konuda endişelenmenize gerek kalmaz.
Scott Wales


0

Örtük kurallardan bahsedenlere eklemek için, make'in neyin örtük olarak tanımlandığını ve env için şunu kullanarak görmek en iyisidir:

make -p

Örneğin:

%.o: %.c
    $(COMPILE.c) $(OUTPUT_OPTION) $<

hangi genişler

COMPILE.c = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c

Bu aynı zamanda # environmentverileri de yazdıracaktır . Burada, diğer yararlı bilgilerin yanı sıra GCC'nin dahil etme yolunu bulacaksınız.

C_INCLUDE_PATH=/usr/include

Yapmada, arama söz konusu olduğunda, yollar çoktur, ışık birdir ... veya bu etkiye sahip bir şey.

  1. C_INCLUDE_PATHsistem genelinde, kabuğunuzun içine ayarlayın *.rc.
  2. $(CPPFLAGS) önişlemci için yol içerir.
  3. Make için genel bir arama yolu eklemeniz gerekiyorsa, şunu kullanın:
VPATH = my_dir_to_search

... veya daha spesifik

vpath %.c src
vpath %.h include

make genel arama yolu olarak VPATH kullanır, bu nedenle dikkatli kullanın. Bir dosya VPATH'de listelenen birden fazla konumda mevcutsa, make listedeki ilk örneği alacaktır.

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.