2011-12-21 35 views
9

Birkaç düzine kitaplık ve çeşitli çalıştırılabilir dosyalar geliştiren büyük ish kod örneğim var.CMake "proje" yönergesinin doğru kullanımı nedir?

Kod tabanı hiyerarşik olarak ayrıştırılır ve kütüphaneler hemen hemen her düzeyde oluşturulur.

Her kitaplığı oluşturmak için her bir dizine gittim ve bir CMakeLists.txt dosyası yerleştirdim.

Her CMakeLists.txt dosyasında "project (xxx)" yönergesini kullandım. Bu, benim için mantıklı kullanımı yaptığım PROJECT_NAME, PROJECT_SOURCE_DIR ve PROJECT_BINARY_DIR değişkenlerini tanımladı. Bununla birlikte, takımdan biri bu yaklaşımı hiç beğenmedi, çünkü bunu yapan başka herhangi bir gerçek dünya örneği bulamadı. Çoğu zaman KitWare örneklerini bu yaklaşımı kullanmıyor diye belirtiyor ve bu yüzden de yapmamalıyız.

Savunmaktan yana olduğu alternatif yaklaşım, bu değişkenleri "maket" in size verdiği gibi görünen her makefile yerleştirmektir.

Gerçekten onun noktasını göremiyorum ve onu başka türlü ikna etmede çok az adım atıyorum. Proje direktifini kullanmanın olumsuz taraflarına bu şekilde ışık tutabilir.

Kendimi kolektif bilgeliğine atarım?

+0

"PROJECT_NAME", "PROJECT_SOURCE_DIR" ve "PROJECT_BINARY_DIR" değişkenlerini nasıl kullanıyorsunuz? Ve bu kütüphaneler bağımsız mı yoksa sadece bir ana kütüphane/uygulamanın parçaları mı? –

+0

Bu değişkenleri kaynak kodu oluşturan makrolar içinde kullanıyorum. Diğer projelerin bunlardan güç üretmeye dayanabileceği $ {PROJECT_NAME} _SPDEF adında en üst düzey bir hedef oluşturuyorum. Oluşturulan kodu uygun konuma yerleştirmek için _DIR değişkenlerini de kullanıyorum. – ScaryAardvark

cevap

12

İlk olarak, <projectName>_BINARY_DIR ve <projectName>_SOURCE_DIR'u kullanmanıza olanak tanır, ancak bu ana avantaj değildir. CMake'e proje adı verirseniz, alt dizinlerin her biri için kendi dizinlerindeki yapı hedeflerini oluşturur. Bu, GNU Make, Eclipse CDT, XCode veya desteklenen diğer jeneratörlerden herhangi birini kullanıp kullanmadığınızı, alt projeleri tek tek oluşturabileceğiniz anlamına gelir. Örneğin, GNU ile her bir alt projenin kendi dizininden kendi tam inşa sistemine sahip olmasını sağlayın.

Geçerli proje adına PROJECT_NAME ve kök proje adı aracılığıyla CMAKE_PROJECT_NAME'a erişebilirsiniz.

Düzenleme: Projenin yapılıp yapılmadığına göre, aşağıdaki herhangi bir yapı hedefi için standart CMake davranışı olacağını fark ettim. Genel bilgi için burada kalacağım ama şu cevaba uygun değil:

Bir C++ kitaplığım varsayalım ve üç tane ikili yürütülebilir dosya oluşturabilirim; Main ve tests/test1 ve examples/ex1. Ben TÜM hedef ile CMake denen dizinde, make ex1 çalıştırın ya da dizinini examples/ olarak değiştirebilir ve bu dizinden make örneklerini oluşturabilirsiniz. Bu, dizin yapısında başka bir yerde olsalar bile tüm bağımlı projeleri ve kitaplıkları oluşturacaklardır, ancak Main veya tests/test1'u veya examples/ex1'a bağlı oldukları herhangi bir kitaplığı oluşturmayacaktır. Daha sonra ana dizinden çalıştırırsam, kaynaklarının değişmediği sürece examples/ex1'un bağlı olduğu kitaplıkların hiçbirini yeniden oluşturmaz.

+1

Yapı hiyerarşisinin herhangi bir seviyesine "cd" yapabilmenin ve "hepsini" yapabilmenin ve tüm eserlerin bu seviyeden inşa edilebilmesinin benim için büyük bir kazanım olduğunu. Teşekkürler. – ScaryAardvark

+0

@ScaryAardvark, farklı derleyiciler için farklı komutlar çalıştırma ve farklı işletim sistemleriyle farklı kodları otomatik olarak ekleme yeteneğidir, ayrıca birkaç kod satırıyla oldukça gelişmiş işlemler yapmak çok kolaydır. Herhangi bir platform/IDE/araç zinciri üzerinde iyi çalışan CMake ile 'zip' ile varlık sıkıştırmak. Ayrıca, ARM vb. Için çapraz derlemeyi çok kolay hale getirir. Ayrıca CMake'in yerleşik test sistemini de kontrol etmelisiniz, [CTest] (http://www.vtk.org/Wiki/CMake_Testing_With_CTest). Jenkins gibi CI sistemleri için CMake eklentileri de var. –

+0

Evet, buna aşinayım. Bir soru, cmake'nin aynı derleyicinin farklı sürümlerini nasıl ele aldığının bir sorusuydu ... yani, sadece sunstudio11 altında derlenebilen ve en çok sunstudio12'ye ihtiyaç duyan proje ağacının bir bölümümüz var. Bence bununla ilgili bir soru daha soracağım, ama teşekkürler :) – ScaryAardvark

0

Kitaplıklar gerçekten bağımsız projelerse, project komutunu kullanmak mantıklıdır. Ancak eğer olmasalardı, ben sadece onları CmakeLists.txt kökünüzde alt dizinler olarak eklerim. Şu anda işlenmekte olan dizinleri bilmeniz gerekiyorsa, CMAKE_CURRENT_SOURCE_DIR ve CMAKE_CURRENT_BINARY_DIR değişkenlerini kullanabilirsiniz.

+0

CMAKE_CURRENT_PROJECT var mı? Eğer varsa o zaman noktanızı görebilirim, ancak set() 'i bu değişkeni (ya da benzer bir şeyi) oluşturmak için kullanmam gerekiyorsa neden "proje" yi kullanmıyorsunuz ve benim için yaratılan tüm değişkenlere sahip oluyorsunuz. – ScaryAardvark

0

Bugün tam olarak bunun iyi bir örneğini buldum: Doxygen dokümantasyonunu eklemek.

Kişisel C++ projelerimi oluşturmak için CMake (ve Ninja) kullanıyorum. Oldukça eksiksiz ve belgelenmemiş çabalarıma bir miktar Doxygen belgesi eklemeye karar verdim. Ayrıca, diğer projelere de eklemenin, olabildiğince genel olarak nasıl yapılacağını anladığım kadarıyla düzgün olacağını düşündüm.

Başlamak için standart bir Doxygen şablonu oluşturdum ve yeniden adlandırdım.

cd my_projects/projectx 
doxygen -g Doxyfile 
mv Doxyfile Doxyfile.in 

.in uzantısına dikkat edin. Muhtemelen gerekli değil ama geleneksel olarak, eğer doğru anlarsam.

Daha sonra, CMakeLists.txt dosyasında, hedeflerimi tanımlamadan hemen önce aşağıdaki kod bloğunu ekledim (önemli olup olmadığından emin olmamakla birlikte, CMake bazen belirli komutların sırasına göre yanık oluyor).

FIND_PACKAGE(Doxygen) 
IF("${DOXYGEN_FOUND}" MATCHES "^YES$") 
    CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in 
        ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 
        @ONLY) 
    ADD_CUSTOM_TARGET( doc ALL 
         COMMAND ${DOXYGEN_EXECUTABLE} 
         ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 
         WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 
         COMMENT "Doxygenating..." 
         VERBATIM) 
ENDIF() 

Bu, doc adında yeni bir hedef oluşturur. ALL belirtmek varsayılan "all" hedefine ekler, ancak bu isteğe bağlıdır. @ONLY belirtmek, "$ {variable}" türündeki değişkenlerin CONFIGURE_FILE, sadece "@ variable @" türleriyle genişletilmemesini sağlar. Biraz kafa karıştırıcı (bana en azından), CMAKE_CURRENT_SOURCE_DIR, proje dizini ve yapı dizinine CMAKE_CURRENT_BINARY_DIR başvuruyor gibi görünüyor.

Son olarak, bu noktada PROJECT_NAME ve diğerlerinin geldiği yer, Doxyfile.in dosyasını düzenledim.

Bu

benim yeni Doxyfile.in başlangıcıdır:

DOXYFILE_ENCODING  = UTF-8 
PROJECT_NAME   = "@[email protected]" 
PROJECT_NUMBER   = @[email protected] 
PROJECT_BRIEF   = 
PROJECT_LOGO   = @[email protected]/res/doc_logo-200x55.png 
OUTPUT_DIRECTORY  = @[email protected]/doc 

Sen fikir, bence. Bu tamamen jenerikleştirildikten sonra (bu bir sözcük mü?) Diğer projelerime kopyalayabilirim ve kodumu etiketlediğim sürece her yerde güzel belgelerim olur.

Uyarı PROJECT_BRIEF belirtilmemiş. Bunu bitirmedim ve düşünmem gereken birkaç boşluk var. Örneğin, PROJECT_VERSION_TWEAK henüz bir şey içermiyor. Orada yapı numaramı almanın bir yolunu bulmalıyım.