CMAKE 中操作系统的具体说明:如何?

发布于 2025-01-03 05:56:01 字数 1128 浏览 3 评论 0原文

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

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

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

任何帮助将不胜感激。

我的简单 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 )

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 )

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

小耗子 2025-01-10 05:56:01

使用

if (WIN32)
    # do something
endif (WIN32)

if (UNIX)
    # do something
endif (UNIX)

if (MSVC)
    # do something
endif (MSVC)

或类似的内容

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

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

瀟灑尐姊 2025-01-10 05:56:01

鉴于这是一个常见问题,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 布尔逻辑文档< /a>

CMake 平台名称等

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

CMake platform names, etc.

铁憨憨 2025-01-10 05:56:01

一般来说,

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

检测 Microsoft Windows

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

或:

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

检测 Apple MacOS

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

检测 Unix 和 Linux

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

您的特定链接器问题

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

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

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()
浮云落日 2025-01-10 05:56:01

现代 CMake 方式

避免使用 WIN32APPLE 等。摘自版主在 官方论坛

WIN32APPLEUNIX 等变量已“软”弃用 [...] CMAKE_SYSTEM_NAME 是我在 CMake 代码中使用的内容,生成器表达式中需要 PLATFORM_ID


CMAKE_SYSTEM_NAMEPLAFORM_ID 可以采用哪些可能的值? 参考源

如何检测平台

使用STREQUAL

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

如何检测多个平台

创建列表变量并使用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 ()

生成器表达式

使用PLATFORM_ID

target_link_libraries(TARGET_NAME PRIVATE
  
lt;
lt;PLATFORM_ID:Linux,Windows>:OpenGL::GL>)

旁白:生成器表达式只有在手册规定的情况下才能使用。例如,target_link_libraries 的文档会调用它,而 set_target_properties 则不会。我想阅读 CMake: set_target_properties 失败生成器表达式定义的目标来实现原因。

Modern CMake Way

Avoid using WIN32, APPLE, etc. Excerpt of a moderator's reply on official forum:

The WIN32, APPLE, UNIX, etc. variables are “soft” deprecated [...] CMAKE_SYSTEM_NAME is what I’d use in CMake code, PLATFORM_ID is needed in generator expressions.

What possible values can CMAKE_SYSTEM_NAME or PLAFORM_ID take? Refer the source.

How to detect a platform

Use STREQUAL:

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

How to detect multiple platforms

Create a list variable and use 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 ()

Generator Expression

Use PLATFORM_ID:

target_link_libraries(TARGET_NAME PRIVATE
  
lt;
lt;PLATFORM_ID:Linux,Windows>:OpenGL::GL>)

Aside: Generator expressions can only be used if the manual calls it out. For example target_link_libraries's documentation calls it out while set_target_properties doesn't. I'd to read CMake: set_target_properties fails with target defined by generator expression to realize why.

断肠人 2025-01-10 05:56:01

CMAKE里有一些特别的话,看一下:

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

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
初雪 2025-01-10 05:56:01

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

target_link_libraries(
    target_name
    PUBLIC
        libA
        
lt;
lt;PLATFORM_ID:Windows>:wsock32>
    PRIVATE
        
lt;
lt;PLATFORM_ID:Linux>:libB>
        libC
)

这将链接 libA、wsock32 和Windows 上的 libC 并链接 libA、libB 和 libC。 Linux 上的 libC

CMake 生成器表达式

Generator expressions are also possible:

target_link_libraries(
    target_name
    PUBLIC
        libA
        
lt;
lt;PLATFORM_ID:Windows>:wsock32>
    PRIVATE
        
lt;
lt;PLATFORM_ID:Linux>:libB>
        libC
)

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

CMake Generator Expressions

染火枫林 2025-01-10 05:56:01

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

CMake 区分目标平台和主机平台。

我的目标是 Android,因此 CMAKE_SYSTEM_NAME 等变量的值为“Android”,并且此处其他答案中的变量 WIN32 未定义。
但我想知道我的主机系统是否是 Windows,因为在 Windows、Linux 或 IO 上进行编译时,我需要做一些不同的事情。
为此,我使用了 CMAKE_HOST_SYSTEM_NAME ,我发现它在任何地方都几乎不为人知或提及,因为对于大多数人来说,TARGEt 和 HOST 是相同的,或者他们不关心。

希望这对某个地方的人有帮助......

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

CMake distinguishes between TARGET and HOST platform.

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.

Hope this helps someone somewhere...

梦巷 2025-01-10 05:56:01

尝试一下:

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

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

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

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.

月野兔 2025-01-10 05:56:01

简单的喜欢

target_link_libraries(${PROJECT_NAME}
  aaa
  bbb
  ccc
  
lt;
lt;BOOL:
lt;PLATFORM_ID:Linux>>:rt>
  
lt;
lt;BOOL:
lt;PLATFORM_ID:Linux>>:dl>
  )

simple like

target_link_libraries(${PROJECT_NAME}
  aaa
  bbb
  ccc
  
lt;
lt;BOOL:
lt;PLATFORM_ID:Linux>>:rt>
  
lt;
lt;BOOL:
lt;PLATFORM_ID:Linux>>:dl>
  )
无远思近则忧 2025-01-10 05:56:01

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

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

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文