操作系统的具体指令在 CMAKE: 如何?

我是 CMAKE 的初学者。下面是一个简单的 cmake 文件,它可以在 mingw 环境窗口中很好地工作。很明显,CMAKE 的 target_link_libraries()函数出现了问题,我正在链接 libwsock32.a。在窗口中这个工作,我得到的结果。

然而,正如预期的那样,在 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 )
166636 次浏览

试试这个:

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


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

您可以找到其他有用的变量 给你

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

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

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

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

使用

if (WIN32)
# do something
endif (WIN32)

或者

if (UNIX)
# do something
endif (UNIX)

或者

if (MSVC)
# do something
endif (MSVC)

或类似的

请参见: > CMake Useful Variables 和一个 href = “ https://gitlab.kitware.com/CMake/community/wikis/doc/Tutorials/How-To-Write-Platform-Checks”rel = “ norefrer”> CMake Checking Platform

你有一些来自 CMAKE 的特别词汇,看看吧:

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

鉴于这是一个如此普遍的问题,Geronto 发帖:

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

制作布尔逻辑文档

制作平台名称等等。

一般而言

您可以像下面这样为几个操作系统检测和指定变量:

检测 MicrosoftWindows

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

或者:

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

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

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

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

制作生成器表达式

我想把这篇文章留在这里,因为我在用 Android SDK 在 Windows 系统中编译 Android 时曾经为此而苦苦挣扎。

CMake 区分 TARGET 和 HOST 平台

我的目标是 Android,所以像 CMAKE _ System _ NAME 这样的变量的值是“ Android”,另一个答案的变量 WIN32没有定义。 但是我想知道我的 HOST 系统是否是 Windows,因为在 Windows、 Linux 或 IOS 上编译时,我需要做一些不同的事情。 为了做到这一点,我使用了 CMAKE _ HOST _ System _ NAME,我发现几乎没有人知道或在任何地方提到它,因为对大多数人来说,目标和主机是相同的,或者他们不关心。

希望这能帮到什么人。

现代 CMake Way

避免使用 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
$<$<PLATFORM_ID:Linux,Windows>:OpenGL::GL>)

除了 : 只有在手册调用它时才能使用生成器表达式。例如,target_link_libraries的文档调用了它,而 set_target_properties没有。我读了 Set _ target _ properties 失败,目标由生成器表达式定义才明白为什么。

就像

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