Kodu derlemek için Makefile ve CMake kullanma arasındaki fark


288

C / C ++ üzerinde kod ve kodu derlemek için bir (GNU) Makefile kullanın. Aynı şeyi CMake ile yapabilir ve bir MakeFile alabilirim. Ancak, kodu derlemek için Makefile ve CMake kullanma arasındaki fark nedir?


2
cmake ayrıca ninja kullanmak için dosya üretebilir
BЈовић

Yanıtlar:


403

Marka (veya daha doğrusu Makefile) bir yapı sistemidir - kodunuzu oluşturmak için derleyiciyi ve diğer oluşturma araçlarını çalıştırır.

CMake bir yapı sistemleri üretecidir. Makefiles üretebilir, Ninja derleme dosyaları üretebilir, KDEvelop veya Xcode projeleri üretebilir, Visual Studio çözümleri üretebilir. Aynı başlangıç ​​noktasından aynı CMakeLists.txt dosyası. Platformdan bağımsız bir projeniz varsa, CMake onu sistemden bağımsız hale getirmenin bir yoludur.

GNU Make tarafından yemin eden Visual Studio ve Unix geliştiricilerine alışkın olduğunuz Windows geliştiricileriniz varsa, CMake gidilecek yollardan biridir.

Projenizi çok platformlu veya yaygın olarak kullanılabilir kılmak istiyorsanız, CMake'i (veya başka bir yapı sistemi oluşturucusunu kullanmanızı öneririm, ancak CMake benim kişisel tercihimdir). CMake ayrıca bağımlılık algılama, kütüphane arayüz yönetimi veya CTest, CDash ve CPack ile entegrasyon gibi bazı güzel özellikler de sunar.

Bir yapı sistemi jeneratörü kullanmak, projenizi geleceğe daha dayanıklı hale getirir. Şimdi GNU-Make-you olsanız bile, daha sonra diğer platformlara (Windows veya gömülü bir şey olsun) genişlemeye karar verirseniz veya sadece bir IDE kullanmak isterseniz ne olur?


5
@rish Evet, özü bu. Bununla birlikte, Linux üzerinde programlamak için Makefiles'ten daha fazla yol olduğunu unutmayın - bkz. Örneğin QtCreator, KDEvelop, Ninja. Bunların her biri için, ya bir proje oluşturun ve bunu Makefile ile senkronize halde tutun ya da "CMake'i yeniden çalıştırın". Yanıtın belirttiği gibi, CMake'nin bağımlılık keşfi (örn. find_package()) Veya test / paketleme desteği gibi başka işlevleri de vardır .
Angew artık SO

3
CMake'in özyinelemeli olmayan dosyalar oluşturamayacağını okudum. Bu hala doğru mu?
Maxim Egorushkin

1
@Angew Özyinelemesiz , proje bir kez bağımlı proje ağacı ile çağrıldığında yapılır. Bir üst düzey makefile alt proje makefiles belirli bir sırayla çağırdığında özyinelemenin aksine .
Maxim Egorushkin

3
Bu CMake'in önemli bir zayıflığıdır - GNU make'in kırışıklıkları vardır, ancak öğrenmek için zaman ayırırsanız, son derece güçlü ve çok yönlüdür ve çok sayıda platformda çalışır. Analiz etmek için tam bir bağımlılık ağacına sahip olmamak büyük bir kusur, sadece 'zararlı olarak kabul edilen özyinelemeli marka' için google.
Erik Alapää

1
@ ErikAlapää Makaleyi ayrıntılı olarak okuyacağım, ancak ilk bakışta - özyineleme derinliğinin veriye dayalı olduğu özyinelemeli markadan bahsediyor gibi görünüyorlar (yani kaynak dizin derinliğine bağlıdır). CMake için durum böyle değil: proje yapısından bağımsız olarak, invokasyonların toplam derinliği her zaman 3'tür. Bazı bit yerine hepsi bir arada bir submakefile devredildiği sadece, ama yok değil herhangi bir şekilde proje yapısını yansıtmaktadır. Ayrıca, alt modeller gerçekten "bağımsız" değildir, bu nedenle aşırı / düşük bağımlılık sorununa maruz kalmazlar.
Angew artık SO

39

CMake'in "derleme oluşturucusu" olduğu ile ilgili açıklama yaygın bir yanlış anlamadır.

Teknik olarak yanlış değil; sadece NASIL çalıştığını açıklar, ama ne işe yaradığını açıklamaz.

Soru bağlamında, aynı şeyi yapıyorlar: bir grup C / C ++ dosyası alıp bir ikili dosyaya dönüştürün.

Peki, gerçek fark nedir?

  • CMake çok daha üst düzey. Daha az derleme kodu yazdığınız C ++ 'ı derlemek için tasarlanmıştır, ancak genel amaçlı derleme için de kullanılabilir. makebazı yerleşik C / C ++ kuralları da vardır, ancak çoğunlukla işe yaramazlar.

  • CMakeiki adımlı yapı yapar: bir düşük seviyeli inşa komut dosyası oluşturur ninjaveya makediğer birçok jeneratörler veya ve sonra çalıştırın. Normalde yığınlanan tüm kabuk komut dosyası parçaları Makefileyalnızca oluşturma aşamasında yürütülür. Böylece, CMakeyapı daha hızlı büyüklük emirleri olabilir.

  • Dilbilgisi CMakedış araçları için destek çok daha kolaydır yapmak en fazla .

  • Bir makeyapıyı inşa ettikten sonra nasıl yapıldığını unutur. Hangi kaynaklardan inşa edildi, hangi derleyici bayrakları? CMakeizler, size makebırakır. Kütüphane kaynaklarından biri önceki sürümüne beri kaldırıldıysa Makefile, makeonu yeniden olmayacaktır.

  • Modern CMake(3. sürümünden başlayarak) "hedefler" arasındaki bağımlılıklar açısından çalışır. Hedef hala tek bir otput dosyasıdır (ne yazık ki), ancak geçişli (CMake terimleriyle "genel" / "arayüz") bağımlılıklara sahip olabilir. Bu geçişli bağımlılıklar bağımlı paketlere maruz kalabilir veya gizlenebilir. CMakesizin için dizinleri de yönetecektir. İle make, bir dosya dosya ve yönetme dizinleri düzeyinde takılıp kalırsınız.

makeSon iki boşluğu kapatmak için bayrak dosyalarını kullanırken bir şey kodlayabilirsiniz , ancak kendi başınıza olursunuz. makebir Turing tam dili (hatta iki, bazen üç sayım Guile ) içerir ve hepsi korkunçtur.

Dürüst olmak gerekirse, bu nedir CMakeve make: onların dilleri oldukça korkunç - ortak noktası

  • Hiçbir türü yoktur;
  • diziler yok, sadece boşlukla ayrılmış dizeler, bu yüzden cehennemden kaçıyor;
  • normalde global değişkenleri ayarlayarak fonksiyonlara argümanlar iletirsiniz; (bu modern CMake'de ele alınıyor - değişkenler şimdi bir ad alanına sahip olabilir; bir hedef özellikleri için bir ad alanıdır)
  • tanımsız bir değişkene başvurmak varsayılan olarak sessizce yok sayılır;

ile başlamak.

Ama CMakesen çok daha az kod satırı yazıyorsun.


1
Burada bazı iyi bilgiler var, ancak bir açıklama tamamen yanlış: cmake bir LIST tipine sahip, çünkü uygun LIST fonksiyonları ile birçok yapı sistemi görevi için çok önemli, biraz fark var: cmake.org/cmake/help/git-master/command /list.html
solvingJ

Buna "tamamen" yanlış demezdim, ama düzelttiğiniz için teşekkürler.
Victor Sergienko
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.