如何以跨平台方式使用CMake ExternalProject_Add或替代项? [英] How do I use CMake ExternalProject_Add or alternatives in a cross-platform way?

查看:141
本文介绍了如何以跨平台方式使用CMake ExternalProject_Add或替代项?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想构建一个第三方项目,该项目已经具有CMake作为我的项目CMake条的一部分. ExternalProject_Add是用于此目的的,但是我发现它只能与特定的生成器一起使用,并且我希望它可以轻松地在许多平台上工作.

I would like to build a third-party project that already has CMake as part of my project's CMake strips. ExternalProject_Add is for this purpose, but I have found it can only be made to work with a specific generator, and I wanted it to work on many platforms easily.

例如,这是我的外部项目,其中添加了zlib脚本,该脚本具有自己的CMakeLists.txt:

For example, here is my external project with an added script for zlib, which has its own CMakeLists.txt:

set(USE_PROJECT_CMAKE_MODULE_PATH "-DCMAKE_MODULE_PATH=${MAKE_MODULE_PATH}")
ExternalProject_Add(ZLIB
                    SOURCE_DIR ${CMAKE_SOURCE_DIR}/external/zlib
                    DOWNLOAD_COMMAND ""
                    UPDATE_COMMAND ""
                    CMAKE_ARGS
                       -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
                       -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
                       -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}
                       -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
                       ${USE_PROJECT_CMAKE_MODULE_PATH}
                    INSTALL_COMMAND "")

ExternalProject_Add_Step(ZLIB installInternally
                         COMMAND cd <BINARY_DIR> && make install
                         DEPENDEES install
                         ALWAYS 1)
ExternalProject_Get_Property(ZLIB install_dir)

if(UNIX)
    set(ZLIB_NAME libz)
else(UNIX)
    set(ZLIB_NAME zlib)
endif(UNIX)

add_library(zlib UNKNOWN IMPORTED)
set_property(TARGET zlib PROPERTY IMPORTED_LOCATION ${install_dir}/lib/${ZLIB_NAME}.a)
set(ZLIB_LIBRARIES zlib)
set(ZLIB_LIBRARIES_OPTIONAL ${ZLIB_LIBRARIES})
set(ZLIB_DIR ${install_dir} CACHE INTERNAL "zlib ROOT dir")
set(ZLIB_INCLUDE_DIRS ${install_dir}/include CACHE INTERNAL "zlib include dirs")
set(ZLIB_DEFINES "-msse2 -mfpmath=sse" CACHE INTERNAL "zlib defines")

此问题是它与make一起使用,但不适用于Xcode或Visual Studio.也许有某种方法可以将CMake构建命令传递给我的项目,并将其转发给ExternalProject_Add.

The problem with this is that it works with make, but not with Xcode or Visual Studio. Perhaps there is some way to take the CMake build commands passed to my project and forward them to ExternalProject_Add.

如何以最小的代码复杂度以跨平台方式编写ExternalProject_Add调用,或者有更好的选择吗?

How can I write ExternalProject_Add calls in a cross-platform way with minimal code complexity, or is there a better alternative?

推荐答案

问题

-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}

这对于单配置项目就足够了.但是对于Xcode和Visual Studio,您需要在构建阶段设置CMAKE_CONFIGURATION_TYPES并调用build . --config.参见我的答案... >

This is enough for single-configuration projects. But for Xcode and Visual Studio, you need to set CMAKE_CONFIGURATION_TYPES plus call build . --config at the build stage. See my answer.

COMMAND cd <BINARY_DIR> && make install

这当然仅适用于Makefile生成器.要跨平台,您可以使用:

This will work only for Makefile generators of course. To be cross-platform you can use:

--build . --target install --config.

看看此模板文件,尤其是以下几行:

ExternalProject_Add(
    "${current_project}"
    URL
    @HUNTER_PACKAGE_URL@
    URL_HASH
    SHA1=@HUNTER_PACKAGE_SHA1@
    DOWNLOAD_DIR
    "@HUNTER_PACKAGE_DOWNLOAD_DIR@"
    SOURCE_DIR
    "@HUNTER_PACKAGE_SOURCE_DIR@"
    INSTALL_DIR
    "@HUNTER_PACKAGE_INSTALL_PREFIX@"
        # Not used, just avoid creating Install/<name> empty directory
    BUILD_COMMAND ""
        # This command is empty because all necessary targets will
        # be built on install stage
    CMAKE_ARGS
    "-G@CMAKE_GENERATOR@"
    "-C@HUNTER_CACHE_FILE@"
    "-C@HUNTER_ARGS_FILE@"
    "-D${postfix_name}=${${postfix_name}}"
    "-DCMAKE_BUILD_TYPE=${configuration}"
    "-DCMAKE_CONFIGURATION_TYPES=${configuration}"
    "-DCMAKE_INSTALL_PREFIX=@HUNTER_PACKAGE_INSTALL_PREFIX@"
    "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}"
    INSTALL_COMMAND
        "@CMAKE_COMMAND@"
        --build .
        --target install
        --config ${configuration}
        --
        ${jobs_option}
)

替代

还是有更好的选择?

or is there a better alternative?

您看到猎人了吗?

您可以像一样添加zlib:

You can add zlib just like this:

hunter_add_package(ZLIB)
find_package(ZLIB CONFIG REQUIRED)
target_link_libraries(... ZLIB::zlib)

此代码可在任何地方使用.第三方依赖项将在配置步骤中自动下载.使用不同的生成器/工具链进行构建的示例( build.py 只是设置CMAKE_TOOLCHAIN_FILE的CMake包装器和-G/-B):

This code works everywhere. Third party dependencies will be downloaded automatically in the configuration step. Example of building with different generator/toolchains (build.py is just a CMake wrapper that sets CMAKE_TOOLCHAIN_FILE and -G/-B):

build.py --toolchain mingw --config Release # MinGW Makefiles
build.py --toolchain vs-12-2013 --config Debug # Visual Studio 12 2013
build.py --toolchain xcode --config Release # Xcode
build.py --toolchain libcxx --config Release # Makefile with -stdlib=libc++ toolchain
build.py --toolchain ios-8-2 --config Release # Xcode with iOS SDK 8.2 toolchain

您完全控制了选项构建类型工作数量.例如,这是您可以为zlib生成Debug,Release,MinSizeRel和RelWithDebInfo四种类型并将MinSizeRel链接到当前项目的方法:

You got full control what options, build types or number of jobs you want to have while building third-party packages. For instance, this is how you can build four types, Debug, Release, MinSizeRel, and RelWithDebInfo for zlib and link MinSizeRel to the current project:

> build.py --toolchain xcode --verbose --config MinSizeRel --fwd "HUNTER_CONFIGURATION_TYPES=Release;Debug;MinSizeRel;RelWithDebInfo"
/.../clang  /.../lib/libz-MinSizeRel.a ... -o /.../_builds/xcode/MinSizeRel/foo

> ls -la /.../.hunter/_Base/d1232c0/326318e/37e4682/Install/lib/libz*
   99056 /.../.hunter/_Base/d1232c0/326318e/37e4682/Install/lib/libz-MinSizeRel.a
  307872 /.../.hunter/_Base/d1232c0/326318e/37e4682/Install/lib/libz-RelWithDebInfo.a
  109536 /.../.hunter/_Base/d1232c0/326318e/37e4682/Install/lib/libz.a
  258904 /.../.hunter/_Base/d1232c0/326318e/37e4682/Install/lib/libzd.a

这篇关于如何以跨平台方式使用CMake ExternalProject_Add或替代项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆