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

2024-10-18 09:00:00
admin
原创
229
摘要:问题描述:我是 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)。

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

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用