如何使用CMake按需构建wxwidget并与之链接 [英] How can I use CMake to both build wxwidgets on-demand and link with it

查看:688
本文介绍了如何使用CMake按需构建wxwidget并与之链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下情况:


  • 我正在开发依赖于多个第三方库的应用程序,其中wxwidgets

  • 我使用Linux作为构建主机系统来构建用于多个目标配置(x86,arm,Linux,Windows)的应用程序

  • 上面提到的多个目标配置,我选择使用CMake的ExternalProject_Add函数从源代码构建那些第三方库。

  • 第三方库是在某个位置按需构建的与应用程序的CMAKE_BINARY_DIR分开,这样我就可以为应用程序擦除构建树,而不必重新构建第三方库(花费很长时间)。

  • 第三方的位置libs取决于我为其构建目标的配置(显然)是不同的。

  • I'm working on an application that depends on a number of third party libs, among them wxwidgets
  • I build the application for multiple target configurations (x86, arm, Linux, Windows) using Linux as my build host system
  • Due to the above mentioned multiple target configurations, I have chosen to build those third-party libs from source, using CMake's ExternalProject_Add function.
  • The third-party libs are built 'on-demand' at a location separate from my application's CMAKE_BINARY_DIR so that I can wipe the build tree for my application without having to rebuild the third-party libs (takes a looooong time).
  • The location of the third-party libs is different depending on what target configuration I build them for (obviously).

我对CMake还是很陌生当前面临的问题是:
我的应用程序中的源文件找不到wx包含文件,我需要设置正确的链接器标志才能将应用程序链接到wxwidgets。

I'm quite new to CMake and the problem I currently face is this: The source files in my application can't find the wx include files and I need to set the correct linker flags to be able to link my application against wxwidgets.

这似乎是由实用程序 wx-config处理的当与--cppflags或--libs标志一起运行时,提供的信息正是输出信息。但是,我无法弄清楚如何捕获该输出并将其附加到我从CMakeLists.txt文件设置的include dirs和链接库中。

This seems to be handled by a utility 'wx-config' that provides exactly that info as output when run with either the --cppflags or --libs flag. I can not however, figure out how to catch that output and append it to the include dirs and linked libraries I setup from my CMakeLists.txt files.

所以基本上


  1. 为当前目标配置构建wxwidgets(如果不存在)

  2. 运行wx-config --cppflags和--libs找出当前目标配置的正确包含目录和链接器标志

  3. 在构建目标时使用步骤2中的信息自己的应用程序

到目前为止,我已经尝试过以下操作:

So far I've tried something like this:

# Set a target-configuration-specific location 
set(wxwidgetsTop ${MYPROJECT_EXTERNAL_DIR}/wxwidgets/wxwidgets_${MYPROJECT_CURRENT_TARGET_CFG})

# Build the project
ExternalProject_Add( wxWidgetsExternal
  PREFIX ${wxwidgetsTop}
  URL ${MYPROJECT_EXTERNAL_DIR}/tarballs/wxWidgets-3.0.2.tar.bz2
  SOURCE_DIR ${wxwidgetsTop}/src/wxwidgets
  CONFIGURE_COMMAND ${configure_cmdline}
  BUILD_COMMAND make -j${MYPROJECT_NCPU}
  INSTALL_COMMAND make install
  )

# Create a wxwidgets target to be used as a dependency from other code
add_library(wxWidgets IMPORTED STATIC GLOBAL)
add_dependencies(wxWidgets wxWidgetsExternal)

# (non-working) attempt to get the correct include dirs and linker
# flags for wxwidgets 
add_custom_command(TARGET wxWidgetsExternal
  POST_BUILD
  COMMAND ${INSTALL_DIR}/bin/wx-config ARGS --cppflags
  COMMENT "Running wx-config"
)

,但是上述方法并未提供一种使用自定义命令的结果来附加实际值的方法在构建构成我的应用程序的目标时使用cppflags和链接器选项。

but the above does not provide a way to actually use the result from the custom command to append the cppflags and linker options when building the targets that make up my application.

实现我想要的目标的好方法是什么?

What is a good way to achieve what I want?

推荐答案

我看到了三种不同的方法:

I see three different ways of doing this:

将wxWidgets用作项目的独立要求,并希望开发人员在构建项目之前先安装它。在您的CMakeLists.txt中,您需要调用 find_package(wxWidgets) ,像这样:

Use wxWidgets as a standalone requirement for your project, and expect the devs to install it before building your project. In your CMakeLists.txt you will need to call find_package(wxWidgets), like this:

    find_package(wxWidgets COMPONENTS net gl core base)
    if(wxWidgets_FOUND)
        include(${wxWidgets_USE_FILE})
        # and for each of your dependent executable/library targets:
        target_link_libraries(<YourTarget> ${wxWidgets_LIBRARIES})
    endif()

这样做的好处是:您重建了项目,但是它需要您的用户(他们需要手工处理wxWidgets的安装)和您(您需要设置包含路径/编译定义/ ...)的一些工作。

This has the advantage of not rebuilding the lib if you rebuild your project, however it requires some work for your user (they need to handle the installation of wxWidgets by hand) and for you (you need to setup include paths / compile definitions / ... by hand).

第二个选择是将wxWidgets捆绑在仓库中(svn external或git子模块),通常(重新)写CMa该库的keLists.txt是面向目标的。然后,在最顶部的CMakeLists.txt中,可以执行以下操作:

The second option is to bundle wxWidgets in your repo (svn external or git submodule) and usually (re)write the CMakeLists.txt of this lib to be target-oriented. Then, in your top-most CMakeLists.txt, you can do the following:

    # for example, if you just need core and net:
    target_link_librairies(my_app PUBLIC wxWidgetsCore wxWidgetsNet)
    # No need to manually setup include dirs, etc...

要使CMakeLists.txt面向目标,请为目标而不是目录定义include目录和其他编译属性。示例:

To make a CMakeLists.txt target-oriented, you define include directories and other compilation properties for a target, not a directory. Example:

    # When defining wxWidgetsCore, for example
    add_library(wxWidgetsCore ...)
    target_include_directories(wxWidgetsCore PUBLIC someDir)
    target_compile_definitions(wxWidgetsCore PUBLIC -pedantic)
    target_link_libraries(wxWidgetsCore PUBLIC someLib)

此方法的缺点是重建项目将触发wxWidgets的重建。但是,可以通过不使用 rebuild而是仅清理我的应用程序,然后构建来欺骗它。 这里有一些关于如何实现这一目标的见识

The drawback of this approach is that rebuilding your project will trigger a rebuild of wxWidgets. However, it is possible to trick this by not using "rebuild" but "clean just my app, then build". Here is some insight on how to achieve this.

方法2的重大缺陷导致了第三种方法:不要将wxWidgets放入您的项目,但创建一个CMakeLists.txt即可导入该库。想法:您向用户询问安装wxWidgets的目录,然后此脚本将为您的项目设置所有内容。首先,将CMakeLists.txt放在此处:

The big drawback of method 2 leads to the third approach: don't put wxWidgets in your project, but create a CMakeLists.txt that will "import" the lib. The idea: you ask your user for the directory where wxWidgets is installed, then this script will setup everything for your project. First, put the CMakeLists.txt here:

    /your-project-root
        /thirdparty
            /wxWidgets
                CMakeLists.txt
    /dir-where-wxwidgets-is-installed
        ...

现在,您定义导入的目标:

Now, you define an imported target:

    # When defining wxWidgetsCore, for example
    set(WX_INCLUDE_DIR ${USER_SPECIFIED_WX_ROOT}/include)
    add_library(wxWidgetsCore IMPORTED GLOBAL)
    set_property(TARGET wxWidgetsCore APPEND PROPERTY
        INTERFACE_INCLUDE_DIRECTORIES ${WX_INCLUDE_DIR})

请参见 INTERFACE_INCLUDE_DIRECTORIES INTERFACE_LINK_LIBRARIES 。您需要用户在系统中的某个位置构建wxWidgets,但是从您的角度来看,您只需执行 target_link_libraries(your_app PUBLIC wxWidgets ...),如方法2所示。优点是该方法可以与方法2透明地互换,并且您不必将整个依赖项放在项目中。

See INTERFACE_INCLUDE_DIRECTORIES and INTERFACE_LINK_LIBRARIES. You need your user to have build wxWidgets somewhere in his system, but from your point of view you just do target_link_libraries(your_app PUBLIC wxWidgets...), as in method 2. The advantage is that this approach is interchangeable with method 2 transparently, and you don't put the whole dependency in your project.

这篇关于如何使用CMake按需构建wxwidget并与之链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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