C++ CMAKE中特定于操作系统的说明:如何?
我是CMAKE的初学者。下面是一个简单的cmake文件,它在mingw环境windows中运行良好。问题显然出在CMAKE的C++ CMAKE中特定于操作系统的说明:如何?,c++,linux,cmake,mingw,portability,C++,Linux,Cmake,Mingw,Portability,我是CMAKE的初学者。下面是一个简单的cmake文件,它在mingw环境windows中运行良好。问题显然出在CMAKE的target\u link\u libraries()函数上,我在这里链接libwsock32.a。在windows中,这可以工作,我可以得到结果 但是,正如预期的那样,在Linux中,/usr/bin/ld将查找Linux操作系统上没有的-lwsock32 我的问题是:如何指导CMAKE避免在Linux操作系统中链接wsock32库 任何帮助都将不胜感激 我的简单CMak
target\u link\u libraries()
函数上,我在这里链接libwsock32.a。在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 )
试试看:
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)
或
或
或类似
看
还有你有一些来自CMAKE的特殊词语,看看:
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
// do something for Linux
else
// do something for other OS
鉴于这是一个常见问题,Geronito发布:
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()
总的来说
您可以为以下几种操作系统检测和指定变量:
if(WIN32)
target_link_libraries(${PROJECT_NAME} bioutils wsock32)
else
target_link_libraries(${PROJECT_NAME} bioutils)
endif()
检测Microsoft Windows
或:
检测苹果MacOS
检测Unix和Linux
您的特定链接器问题
要解决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
)
目标链接库(
目标名称
公开的
利巴
$
私有的
$
libC
)
这将在Windows上链接libA、wsock32和libC,在Linux上链接libA、libB和libC
我想把这个放在这里,因为我在使用Android SDK在Windows中为Android编译时遇到了这个问题 CMake区分目标平台和主机平台。 我的目标是Android,所以像CMAKE_SYSTEM_NAME这样的变量的值为“Android”,而另一个答案中的变量WIN32没有定义。 但我想知道我的主机系统是否是Windows,因为在Windows、Linux或IOs上编译时,我需要做一些不同的事情。 为了做到这一点,我使用了CMAKE_HOST_SYSTEM_名称,我发现这个名称几乎不为人所知或在任何地方被提及,因为对于大多数人来说,目标和主机是相同的,或者他们不在乎
希望这对其他人有所帮助…用户要求使用CMake makefiles。这很有效,我个人很喜欢,因为它非常直观。非常感谢。标准的CMake方法:内部不一致:)[这是一个正确/切中要害的答案]对于那些搜索,这里是名称列表
STREQUAL
接受变量(除了字符串)作为第一个操作数,因此它可能是更简洁的if(CMake\u SYSTEM\u NAME STREQUAL“Linux”)…
感谢您提及苹果公司(APPLE)@VictorSergienkoаСааааПааача:)不要假设unix就是linux。链接到cmake有用变量网站,获取cmake_系统_名称。使用Linux混合操作系统Detectoribur的答案是betterYeah,FreeBSD也将通过(UNIX而非APPLE)
。。。@mlvljr的链接改为:现在。Solaris用什么?啊,找到了这个。它提到了UNIX、WIN32,可能还提到了它们的所有“对等体”:@rchilton1980:Page moved,new link:对于任何想知道:Per legacy的人,else()和endif()命令允许一个可选参数。如果使用,则必须逐字重复打开If命令的参数。
Source:Wait,这是检查主机平台还是构建目标平台?似乎是后者(我需要前者)。Solaris使用什么?输入错误:MSV应该是MSVC。我试着为您编辑它,但stackoverflow不允许出于某种原因编辑少于6个字符……根据文档,“APPLE”只意味着,我们正在为APPLE目标构建;i、 e.OSX,还有iOS、watchOS等。有没有可靠的方法来检测os X?@Julien如果你是为iOS、tvOS或watchOS构建,你很可能会使用cmake工具链文件,其中应该设置了某种变量,可以用来实现您想要的功能。@Julien FWIW:唯一确认的是它还包括iOS、watchOS、tvOS,因为感谢您添加了额外的“>”。哪一个是“$”
if(MSVC OR MSYS OR MINGW)
# for detecting Windows compilers
endif()
if(APPLE)
# for MacOS X or iOS, watchOS, tvOS (since 3.10.3)
endif()
if(UNIX AND NOT APPLE)
# for Linux, BSD, Solaris, Minix
endif()
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
)