CMAKE 中的操作系统特定说明:操作方法
OS specific instructions in CMAKE: How to?
我是CMAKE的初学者。下面是一个简单的 cmake 文件,在 mingw 环境窗口中运行良好。问题显然出在我链接libwsock32.a target_link_libraries()
CMAKE的功能上。在窗口中,这有效,我得到了结果。
但是,正如预期的那样,在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 )
使用
if (WIN32)
# do something
endif (WIN32)
或
if (UNIX)
# do something
endif (UNIX)
或
if (MSVC)
# do something
endif (MSVC)
或类似
请参阅 CMake 有用变量和CMake检查平台
鉴于这是一个如此普遍的问题,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 平台名称等
一般
您可以检测并指定多个操作系统的变量,如下所示:
检测Microsoft窗口
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()
您有一些来自CMAKE的特殊词,请看:
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
// do something for Linux
else
// do something for other OS
生成器表达式也是可能的:
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 生成器表达式
Modern CMake Way
避免使用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 在生成器表达式定义的目标下失败以了解原因。
我想把这个留在这里,因为我在使用Android SDK在Windows中为Android编译时遇到了困难。
CMake 区分了 TARGET 和 HOST 平台。
我的目标是Android,所以像CMAKE_SYSTEM_NAME这样的变量的值为"Android",而这里另一个答案中的变量WIN32没有定义。但我想知道我的主机系统是否是Windows,因为我在Windows,Linux或IO上编译时需要做一些不同的事情。为此,我使用了CMAKE_HOST_SYSTEM_NAME我发现在任何地方都鲜为人知或提及,因为对于大多数人来说,TARGEt 和 HOST 是相同的,或者他们不在乎。
希望这对某个地方的某人有所帮助...
试试:
if(WIN32)
set(ADDITIONAL_LIBRARIES wsock32)
else()
set(ADDITIONAL_LIBRARIES "")
endif()
target_link_libraries(${PROJECT_NAME} bioutils ${ADDITIONAL_LIBRARIES})
您可以在此处找到其他有用的变量。
简单
target_link_libraries(${PROJECT_NAME}
aaa
bbb
ccc
$<$<BOOL:$<PLATFORM_ID:Linux>>:rt>
$<$<BOOL:$<PLATFORM_ID:Linux>>:dl>
)
使用一些预处理器宏来检查它是在Windows还是Linux中。例如
#ifdef WIN32
LIB=
#elif __GNUC__
LIB=wsock32
#endif
在构建命令中包含 -l$(LIB(。
您还可以指定一些命令行参数来区分两者。
- 轮班操作在条件下使用的说明
- 设计模式中对象中的过程(方法和操作)的状态
- 从C++与 C 灵活阵列成员互操作的正确方法是什么?
- 在C 中操作数据的更好方法是什么
- Swift Call C 方法带有char **参数,并且需要操作char **参数
- 使用Modulo操作的正确方法
- 是否有另一种方法可以在不使用宏定义的情况下进行此操作
- 重载二进制操作的正确方法
- 有没有一种便携式方法可以在 C/C++ 中生成 nop 操作码?
- 有关读取 UTF-8 编码文本时 Ifstream get() 方法行为的说明 (C++)
- DirectWrite GDI 互操作:使用"IDWriteFontFace"绘制文本的简单方法
- 在std ::线程中升级ASIO阻止操作,而不是使用异步方法
- 在 c++ 中实现内联汇编器以对变量进行异或操作的正确方法
- 操作方法:将 boost::endian 缓冲区类型转换回本机格式
- 如何使用 Ruby 的 Enumerable .map 方法在 C++ 中执行类似于 map 的操作
- 位操作的标准(跨平台)方法
- 停止提升的规范方法::asio 操作
- 是否有不涉及 I/O 流的 mingw 库原生的就地字符串操作方法
- CMAKE 中的操作系统特定说明:操作方法
- C++ 操作方法:从.txt或.csv文件导入数值变量