174 votes

Instructions spécifiques au système d'exploitation dans CMAKE : How to ?

Je suis un débutant en CMAKE. Voici un fichier cmake simple qui fonctionne bien dans l'environnement mingw de Windows. Le problème se situe clairement au niveau de target_link_libraries() de CMAKE où je lie libwsock32.a. Sous Windows, cela fonctionne et j'obtiens les résultats.

Toutefois, comme prévu, sous Linux, le /usr/bin/ld recherchera -lwsock32 qui n'existe pas dans le système d'exploitation Linux.

Mon problème est le suivant : comment puis-je demander à CMAKE d'éviter de lier la bibliothèque wsock32 dans le système d'exploitation Linux ???

Toute aide sera grandement appréciée.

Mon fichier CMake simple :

 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 )

223voto

relaxxx Points 1392

Utilisation

if (WIN32)
    # do something
endif (WIN32)

ou

if (UNIX)
    # do something
endif (UNIX)

ou

if (MSVC)
    # do something
endif (MSVC)

ou similaire

voir Variables utiles de CMake et Plate-forme de vérification CMake

120voto

mlvljr Points 1281

Étant donné qu'il s'agit d'un problème très courant, geronto-posting :

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()

Documentation sur la logique booléenne de CMake

les noms des plates-formes CMake, etc.

74voto

vertoe Points 688

En général

Vous pouvez détecter et spécifier des variables pour plusieurs systèmes d'exploitation de cette manière :

Détecter Microsoft Windows

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

Ou bien :

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

Détecter Apple MacOS

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

Détecter Unix et Linux

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

Votre problème spécifique de linker

Pour résoudre votre problème avec le logiciel wsock32 il suffit de le retirer des autres systèmes, comme cela :

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

31voto

Bruno Soares Points 122

Vous avez des mots spéciaux de la part de CMAKE, jetez-y un coup d'œil :

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

27voto

legends2k Points 6380

La voie moderne de CMake

Évitez d'utiliser WIN32 , APPLE , etc. Extrait de la réponse d'un modérateur sur forum officiel :

Les WIN32 , APPLE , UNIX etc. sont "doucement" dépréciées [...] CMAKE_SYSTEM_NAME est ce que j'utiliserais dans le code CMake, PLATFORM_ID est nécessaire dans les expressions des générateurs.

Quelles sont les valeurs possibles CMAKE_SYSTEM_NAME o PLAFORM_ID prendre ? Consulter la source .

Comment détecter une plate-forme

Utilice STREQUAL :

if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
  # Linux-specific stuff
endif ()

Comment détecter les plates-formes multiples

Créez une variable de type liste et utilisez IN_LIST :

set(OPENGL_PLATFORMS Linux Windows)
if (CMAKE_SYSTEM_NAME IN_LIST OPENGL_PLATFORMS)
  # platform-specific stuff e.g.
  find_package(OpenGL REQUIRED)
endif ()

Générateur Expression

Utilice PLATFORM_ID :

target_link_libraries(TARGET_NAME PRIVATE
  $<$<PLATFORM_ID:Linux,Windows>:OpenGL::GL>)

A l'écart : Les expressions génératrices ne peuvent être utilisées que si le manuel l'indique. Par exemple, les expressions du générateur ne peuvent être utilisées que si le manuel l'indique. target_link_libraries La documentation de la Commission européenne l'indique, tandis que la documentation de la Commission européenne sur les set_target_properties ne le fait pas. Je voudrais lire CMake : set_target_properties échoue avec une cible définie par une expression de générateur pour comprendre pourquoi.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X