CMAKE'de işletim sistemine özel talimatlar: Nasıl yapılır?


115

CMAKE için yeni başlayan biriyim. Aşağıda, mingw ortam pencerelerinde iyi çalışan basit bir cmake dosyası bulunmaktadır. Sorun, target_link_libraries()libwsock32.a'yı bağladığım CMAKE işlevinde açıkça görülüyor. Pencerelerde bu çalışır ve sonuçları alıyorum.

Bununla birlikte, beklendiği gibi, Linux'ta, Linux işletim sisteminde bulunmayan arayış /usr/bin/ldolacaktır -lwsock32.

Benim Sorunum: CMAKE'ye Linux OS'de wsock32 kitaplığını bağlamayı önlemek için nasıl talimat verebilirim?

Herhangi bir yardım çok takdir edilecektir.

Basit CMake dosyam:

 PROJECT(biourl)
 set (${PROJECT_NAME}_headers ./BioSocketAddress.h  ./BioSocketBase.h ./BioSocketBuffer.h ./BioSocketCommon.h  ./BioSocketListener.h  ./BioSocketPrivate.h  ./BioSocketStream.h ./BioUrl.h BioDatabase.h )

set (${PROJECT_NAME}_sources BioSocketAddress.C  BioSocketBase.C  BioSocketCommon.C BioSocketStream.C  BioUrl.C BioDatabase.C )

add_library(${PROJECT_NAME} STATIC ${${PROJECT_NAME}_headers} ${${PROJECT_NAME}_sources} )

# linkers
#find_library(ws NAMES wsock32 PATHS ${PROJECT_SOURCE_DIR} NO_SYSTEM_ENVIRONMENT_PATH NO_DEFAULT_PATH)

target_link_libraries(${PROJECT_NAME} bioutils wsock32)

install (TARGETS ${PROJECT_NAME}
       RUNTIME DESTINATION bin
       LIBRARY DESTINATION lib
       ARCHIVE DESTINATION lib/archive )

Yanıtlar:


154

Kullanım

if (WIN32)
    #do something
endif (WIN32)

veya

if (UNIX)
    #do something
endif (UNIX)

veya

if (MSVC)
    #do something
endif (MSVC)

veya benzeri

bkz CKağıt Faydalı Değişkenler ve CKağıt Denetleme Platformu


Solaris için ne kullanılır?
jww

Hmm, bağlantılı sayfa yararlıdır, ancak WIN32 veya UNIX'den bahsetmez. Olabilecek başka / benzer kaynaklar var mı?
rchilton1980

1
Ah, bunu buldum. UNIX, WIN32 ve muhtemelen tüm "akranlarından" bahsediyor
rchilton1980

2
@ rchilton1980: Sayfa taşındı, yeni bağlantı: gitlab.kitware.com/cmake/community/wikis/doc/cmake/…
schnaader

Merak eden başka biri için: Per legacy, the else() and endif() commands admit an optional <condition> argument. If used, it must be a verbatim repeat of the argument of the opening if command.Kaynak: cmake.org/cmake/help/latest/command/if.html
Zyl

76

Bunun çok yaygın bir sorun olduğu göz önüne alındığında, geronto-post:

    if(UNIX AND NOT APPLE)
        set(LINUX TRUE)
    endif()

    # if(NOT LINUX) should work, too, if you need that
    if(LINUX) 
        message(STATUS ">>> Linux")
        # linux stuff here
    else()
        message(STATUS ">>> Not Linux")
        # stuff that should happen not on Linux 
    endif()

CMoole mantığı belgeleri oluşturun

CPlatform adları vb. Alın


9
Bahsettiğin için teşekkürler APPLE.
Victor Sergienko

@VictorSergienko Всегда рад помочь :)
mlvljr

3
unix'in linux olduğunu varsaymayın. cmake_system_name için cmake yararlı değişkenler web sitesine bağlantı. Kullanım Linux karışık durumda işletim sistemi dedektörü
don parlak

tibur'un cevabı daha iyi
parlak

1
Evet, FreeBSD de geçecek (UNIX AND NOT APPLE)... ve @mlvljr'ın bağlantısı şu şekilde değişti: gitlab.kitware.com/cmake/community/-/wikis/doc/tutorials/… .
SlySven

48

Genel olarak

Bunun gibi birkaç işletim sistemi için değişkenleri algılayabilir ve belirtebilirsiniz:

Microsoft Windows'u algıla

if(WIN32)
    # for Windows operating system in general
endif()

Veya:

if(MSVC OR MSYS OR MINGW)
    # for detecting Windows compilers
endif()

Apple MacOS'u algıla

if(APPLE)
    # for MacOS X or iOS, watchOS, tvOS (since 3.10.3)
endif()

Unix ve Linux'u tespit edin

if(UNIX AND NOT APPLE)
    # for Linux, BSD, Solaris, Minix
endif()

Özel bağlayıcı sorununuz

Windows'a özgü wsock32kitaplıkla ilgili sorununuzu çözmek için , onu aşağıdaki gibi diğer sistemlerden kaldırmanız yeterlidir:

if(WIN32)
    target_link_libraries(${PROJECT_NAME} bioutils wsock32)
else
    target_link_libraries(${PROJECT_NAME} bioutils)
endif()

2
Solaris için ne kullanılır?
jww

1
Yazım hatası: MSVS, MSVC olmalıdır. Sizin için düzenlemeyi denedim, ancak stackoverflow herhangi bir nedenle 6 karakterden daha az düzenlemelere izin vermiyor ...
mchiasson

1
Belgelere göre, "APPLE" yalnızca bir elma hedefi için inşa ettiğimizi ima ediyor; OSX, aynı zamanda iOS, watchOS vb. OS X'i güvenilir bir şekilde algılamanın herhangi bir yolu var mı?

@Julien, iOS, tvOS veya watchOS için geliştirme yapıyorsanız, büyük olasılıkla, aradığınız şeyi elde etmek için kullanılabilecek bir tür değişken kümesinin olması gereken bir cmake araç zinciri dosyası kullanacaksınız.
mchiasson

@Julien FWIW: cmake belgeleri sadece o da beri iOS, watchos, tvOS içerdiğini teyit 3.10.3
itMaxence

19

CMAKE'den bazı özel sözleriniz var, bir göz atın:

if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
    // do something for Linux
else
    // do something for other OS

3
Standart CMake yöntemi: dahili olarak tutarsız :) [yine de bu doğru / noktadan noktaya bir cevaptır]
mlvljr

Bu arama için, burada isimleri listesi github.com/Kitware/CMake/blob/master/Modules/...
AT

STREQUALdeğişkenleri (dizeye ek olarak) ilk işlenen olarak kabul eder, bu nedenle daha kısa olabilirif(CMAKE_SYSTEM_NAME STREQUAL "Linux")...
Ad N

13

Jeneratör ifadeleri de mümkündür:

target_link_libraries(
    target_name
    PUBLIC
        libA
        $<$<PLATFORM_ID:Windows>:wsock32>
    PRIVATE
        $<$<PLATFORM_ID:Linux>:libB>
        libC
)

Bu, Windows'ta libA, wsock32 ve libC'yi ve Linux'ta libA, libB ve libC'yi bağlayacaktır.

CMake Jeneratör İfadeleri


Bunun için teşekkürler, sadece fazladan ">" ekleyin. "$ <$ <PLATFORM_ID: Windows>: wsock32>"
wow2006

6

Bunu dene:

if(WIN32)
    set(ADDITIONAL_LIBRARIES wsock32)
else()
    set(ADDITIONAL_LIBRARIES "")
endif()

target_link_libraries(${PROJECT_NAME} bioutils ${ADDITIONAL_LIBRARIES})

Diğer yararlı değişkenleri burada bulabilirsiniz .


Bu işe yaradı ve ben şahsen bunu sezgisel olduğu için seviyorum. Çok teşekkür ederim.
Prasad

2

Bunu burada bırakmak istiyorum çünkü Windows'ta Android için Android SDK ile derlerken bununla uğraştım.

CMake, TARGET ve HOST platformunu birbirinden ayırır.

HEDEFİM Android'di, bu nedenle CMAKE_SYSTEM_NAME gibi değişkenler "Android" değerine sahipti ve buradaki diğer cevaptan WIN32 değişkeni tanımlanmadı. Ancak HOST sistemimin Windows olup olmadığını bilmek istedim çünkü Windows veya Linux veya IO'larda derlerken birkaç şeyi farklı yapmam gerekiyordu. Bunu yapmak için, bulduğum CMAKE_HOST_SYSTEM_NAME'i kullandım, ancak hiçbir yerde çok az biliniyor veya bahsediliyor çünkü çoğu insan için TARGEt ve HOST aynı ya da umursamıyor.

Umarım bu bir yerlerde birine yardımcı olur ...


-5

Windows veya linux'ta olup olmadığını kontrol etmek için bir önişlemci makrosu kullanın. Örneğin

#ifdef WIN32
LIB= 
#elif __GNUC__
LIB=wsock32
#endif

inşa komutuna -l $ (LIB) ekleyin.

Her ikisini de ayırt etmek için bazı komut satırı bağımsız değişkenleri de belirtebilirsiniz.


6
Kullanıcı CMake makefiles istiyor.
tibur
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.