CMAKE 中的 OS 特定指令:如何操作?

2024-10-18 09:00:00
admin
原创
71
摘要:问题描述:我是 CMAKE 的新手。下面是一个简单的 cmake 文件,它在 mingw 环境 windows 中运行良好。问题显然出在target_link_libraries()CMAKE 函数上,我正在链接 libwsock32.a。在 windows 中,这有效,我得到了结果。然而,正如预期的那样,在...

问题描述:

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

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

我的问题是:如何指示 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 )

解决方案 1:

使用

if (WIN32)
    # do something
endif (WIN32)

或者

if (UNIX)
    # do something
endif (UNIX)

或者

if (MSVC)
    # do something
endif (MSVC)

或类似

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

解决方案 2:

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

CMake 平台名称等

解决方案 3:

一般来说

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

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

解决方案 4:

您有一些来自 CMAKE 的特殊词语,请看一下:

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

解决方案 5:

现代 CMake 方式

避免使用WIN32、等。官方论坛APPLE上版主的回复摘录:

WIN32、、、APPLE等变量UNIX是“软”弃用的[...]CMAKE_SYSTEM_NAME是我在 CMake 代码中使用的,PLATFORM_ID在生成器表达式中是需要的。

CMAKE_SYSTEM_NAME可以或PLAFORM_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
  $<$<PLATFORM_ID:Linux,Windows>:OpenGL::GL>)

补充:生成器表达式只有在手册中提到时才可以使用。例如,target_link_libraries的文档提到了它,但set_target_properties没有。我必须阅读CMake:set_target_properties 因生成器表达式定义的目标而失败,才能明白原因。

解决方案 6:

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

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

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

CMake 生成器表达式

解决方案 7:

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

CMake 区分 TARGET 和 HOST 平台。

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

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

解决方案 8:

尝试一下:

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

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

您可以在这里找到其他有用的变量。

解决方案 9:

简单喜欢

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

解决方案 10:

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

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

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

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

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用