CMAKEのOS固有の手順:方法


108

私はCMAKEの初心者です。以下は、mingw環境ウィンドウでうまく機能する単純なcmakeファイルです。問題は明らかにtarget_link_libraries()、libwsock32.aをリンクしているCMAKEの機能にあります。Windowsではこれが機能し、結果が得られます。

ただし、予想通り、Linuxでは、Linux OSにはないもの/usr/bin/ldを探します-lwsock32

私の問題は、Linux OSでwsock32ライブラリをリンクしないようにCMAKEにどのように指示するのですか?

どんな助けでも大歓迎です。

私のシンプルな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 )

回答:


144

使用する

if (WIN32)
    #do something
endif (WIN32)

または

if (UNIX)
    #do something
endif (UNIX)

または

if (MSVC)
    #do something
endif (MSVC)

または類似

CMakeの有用な変数CMakeチェックプラットフォームを参照してください


Solarisでは何を使用しますか?
jww 2017

リンク先のページは役に立ちますが、WIN32とUNIXのどちらについても言及していません。可能性のある他の/類似のリソースはありますか?
rchilton1980 2017年

1
ああ、これを見つけた。UNIX、WIN32、およびおそらくすべての「ピア」について言及しています:cmake.org/Wiki/CMake_Checking_Platform
rchilton1980 '29

2
@ rchilton1980:ページは、新しいリンクを移動:gitlab.kitware.com/cmake/community/wikis/doc/cmake/...
schnaader

疑問に思っている人のために:Per legacy, the else() and endif() commands admit an optional <condition> argument. If used, it must be a verbatim repeat of the argument of the opening if command.ソース:cmake.org/cmake/help/latest/command/if.html
Zyl

73

これがそのような一般的な問題であることを考えると、ジェロント投稿:

    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プラットフォーム名など


9
言及していただきありがとうございAPPLEます。
Victor Sergienko、2016年

@VictorSergienkoВсегдарадпомочь:)
mlvljr 2016年

3
unixがlinuxであると仮定しないでください。cmake_system_nameのcmake有用な変数のWebサイトへのリンク。Linuxの大文字と小文字が混在するOS検出器を使用する
明るく

tiburの答えはより良いです
明るいドン

1
ええ、FreeBSDも通過し(UNIX AND NOT APPLE)ます...そして@mlvljrのリンクはgitlab.kitware.com/cmake/community/-/wikis/doc/tutorials/…に変更されました。
SlySven

45

一般に

そのようないくつかのオペレーティングシステムの変数を検出して指定できます。

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

2
Solarisでは何を使用しますか?
jww 2017

1
タイプミス:MSVSはMSVCである必要があります。私はあなたのためにそれを編集しようとしましたが、stackoverflowは何らかの理由で6文字未満の編集を許可しません...
mchiasson

1
ドキュメントによると、「APPLE」は、私たちがappleターゲット用に構築していることを意味するだけです。つまり、OSXだけでなく、iOS、watchOSなど。OSXを信頼できる方法で検出する方法はありますか?

@Julien iOS、tvOS、またはwatchOS用にビルドしている場合は、cmakeツールチェーンファイルを使用する可能性があります。cmakeツールチェーンファイルには、探しているものを達成するために使用できる変数のセットが含まれているはずです。
mchiasson

@Julien FWIWは:cmakeのドキュメントは唯一、それはまた以来のiOS、watchOS、tvOSを含んでいることを確認する3.10.3
itMaxence

19

CMAKEからの特別な言葉があります。見てみましょう。

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

3
標準的なCMakeの方法:internal-inconsistent :) [これは1つの正しい/
的確な

これらの検索のために、ここで名前のリストであるgithub.com/Kitware/CMake/blob/master/Modules/...
AT

STREQUAL最初のオペランドとして(文字列に加えて)変数を受け入れるため、より簡潔になる可能性がありますif(CMAKE_SYSTEM_NAME STREQUAL "Linux")...
Ad N

10

ジェネレータ式も可能です。

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ジェネレーター式


これに感謝するのは、「>」を追加するだけです。「$ <$ <PLATFORM_ID:Windows>:wsock32>」
wow2006

6

それを試してください:

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

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

他の便利な変数はここにあります


これはうまくいき、私は個人的にこれが非常に直感的であるので好きです。どうもありがとうございました。
Prasad、

2

Android SDK for WindowsでAndroid向けにコンパイルするときに苦労したので、ここに残しておきます。

CMakeはTARGETとHOSTプラットフォームを区別します。

私のターゲットはAndroidだったので、CMAKE_SYSTEM_NAMEのような変数の値は「Android」であり、ここで他の回答からの変数WIN32は定義されていませんでした。しかし、Windows、Linux、IOのいずれかでコンパイルする場合、いくつかのことを異なる方法で行う必要があるため、HOSTシステムがWindowsであるかどうかを知りたいと思いました。そのために、ほとんどの人にとってTARGEtとHOSTが同じであるか気にしないため、ほとんど知られていないか、どこにも言及されていないことがわかったCMAKE_HOST_SYSTEM_NAMEを使用しました。

これが誰かを助けることを願っています...


-5

いくつかのプリプロセッサマクロを使用して、それがWindowsまたはLinuxにあるかどうかを確認します。例えば

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

ビルドコマンドに-l $(LIB)を含めます。

コマンドライン引数を指定して、両方を区別することもできます。


6
ユーザーはCMakeメイクファイルを要求しています。
tibur
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.