Linux CMAKE 中的操作系统特定说明:如何?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9160335/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:25:06  来源:igfitidea点击:

OS specific instructions in CMAKE: How to?

c++linuxcmakemingwportability

提问by Prasad

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.

我是 CMAKE 的初学者。下面是一个简单的 cmake 文件,它在 mingw 环境窗口中运行良好。问题显然target_link_libraries()出在我链接 libwsock32.a 的 CMAKE 功能上。在 Windows 中,这有效,我得到了结果。

However, as expected, in Linux, the /usr/bin/ldwill look for -lwsock32which is NOT there on the Linux OS.

然而,正如预期的那样,在 Linux 中,/usr/bin/ld将查找-lwsock32Linux 操作系统上不存在的内容。

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

我的问题是:如何指示 CMAKE 避免在 Linux 操作系统中链接 wsock32 库???

Any help will be greatly appreciated.

任何帮助将不胜感激。

My Simple CMake file:

我的简单 CMake 文件:

 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 )

采纳答案by relaxxx

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 Variablesand CMake Checking Platform

请参阅CMake 有用的变量CMake 检查平台

回答by tibur

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.

您可以在此处找到其他有用的变量。

回答by Barun Parichha

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

使用一些预处理器宏来检查它是在 windows 还是 linux 中。例如

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

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

在构建命令中包含 -l$(LIB)。

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

您还可以指定一些命令行参数来区分两者。

回答by Bruno Soares

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

你有一些来自 CMAKE 的特殊词,看看:

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

回答by mlvljr

Given this is such a common issue, geronto-posting:

鉴于这是一个如此普遍的问题,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

CMake 布尔逻辑文档

CMake platform names, etc.

CMake 平台名称等。

回答by Afr

In General

一般来说

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

您可以为多个操作系统检测和指定变量,如下所示:

Detect Microsoft Windows

检测 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

检测苹果 MacOS

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

Detect Unix and Linux

检测 Unix 和 Linux

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

Your specific linker issue

您的特定链接器问题

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

要解决 Windows 特定wsock32库的问题,只需将其从其他系统中删除,如下所示:

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

回答by Cascades

Generator expressions are also possible:

生成器表达式也是可能的:

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

This will link libA, wsock32 & libC on Windows and link libA, libB & libC on Linux

这将在 Windows 上链接 libA、wsock32 和 libC,在 Linux 上链接 libA、libB 和 libC

CMake Generator Expressions

CMake 生成器表达式

回答by Nico Heidtke

I want to leave this here because I struggled with this when compiling for Android in Windows with the Android SDK.

我想把它留在这里,因为我在使用 Android SDK 在 Windows 中编译 Android 时遇到了这个问题。

CMake distinguishes between TARGET and HOST platform.

CMake 区分了 TARGET 和 HOST 平台。

My TARGET was Android so the variables like CMAKE_SYSTEM_NAME had the value "Android" and the variable WIN32 from the other answer here was not defined. But I wanted to know if my HOST system was Windows because I needed to do a few things differently when compiling on either Windows or Linux or IOs. To do that I used CMAKE_HOST_SYSTEM_NAME which I found is barely known or mentioned anywhere because for most people TARGEt and HOST are the same or they don't care.

我的目标是 Android,所以像 CMAKE_SYSTEM_NAME 这样的变量的值是“Android”,而另一个答案中的变量 WIN32 没有定义。但是我想知道我的 HOST 系统是否是 Windows,因为在 Windows、Linux 或 IO 上编译时我需要做一些不同的事情。为此,我使用了 CMAKE_HOST_SYSTEM_NAME,我发现它在任何地方都鲜为人知或被提及,因为对于大多数人来说,TARGEt 和 HOST 是相同的,或者他们不在乎。

Hope this helps someone somewhere...

希望这可以帮助某人某处...