OS specific instructions in CMAKE: How to?

2019-01-30 08:00发布

I am a beginner to CMAKE. Below is a simple cmake file which works well in mingw environment windows. The problem is clearly with target_link_libraries() function of CMAKE where I am linking libwsock32.a. In windows this works and I get the results.

However, as expected, in Linux, the /usr/bin/ld will look for -lwsock32 which is NOT there on the Linux OS.

My Problem is: How do I instruct CMAKE to avoid linking wsock32 library in Linux OS???

Any help will be greatly appreciated.

My Simple CMake file:

 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 )

6条回答
一纸荒年 Trace。
2楼-- · 2019-01-30 08:04

You have some special words from CMAKE, take a look:

if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
    // do something for Linux
else
    // do something for other OS
查看更多
爷、活的狠高调
3楼-- · 2019-01-30 08:08

Use some preprocessor macro to check if it's in windows or linux. For example

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

include -l$(LIB) in you build command.

You can also specify some command line argument to differentiate both.

查看更多
▲ chillily
4楼-- · 2019-01-30 08:10

In General

You can detect and specify variables for several operating systems like that:

Detect Microsoft Windows

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

Or:

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

Detect Apple MacOS

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

Detect Unix and Linux

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

Your specific linker issue

To solve your issue with the Windows-specific wsock32 library, just remove it from other systems, like that:

if(WIN32)
    target_link_libraries(${PROJECT_NAME} bioutils wsock32)
else
    target_link_libraries(${PROJECT_NAME} bioutils)
endif()
查看更多
贪生不怕死
5楼-- · 2019-01-30 08:10

Try that:

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

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

You can find other useful variables here.

查看更多
戒情不戒烟
6楼-- · 2019-01-30 08:22

Use

if (WIN32)
    #do something
endif (WIN32)

or

if (UNIX)
    #do something
endif (UNIX)

or

if (MSVC)
    #do something
endif (MSVC)

or similar

see CMake Useful Variables and CMake Checking Platform

查看更多
可以哭但决不认输i
7楼-- · 2019-01-30 08:26

Given this is such a common issue, 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()

CMake boolean logic docs

查看更多
登录 后发表回答