gpt4 book ai didi

c++ - 我如何使用 CMake 按需构建 wxwidgets 并与之链接

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:52:31 24 4
gpt4 key购买 nike

我有以下情况:

  • 我正在开发一个依赖于许多第三方库的应用程序,其中包括 wxwidgets
  • 我使用 Linux 作为我的构建主机系统为多个目标配置(x86、arm、Linux、Windows)构建应用程序
  • 由于上面提到的多个目标配置,我选择使用 CMake 的 ExternalProject_Add 函数从源代码构建这些第三方库。
  • 第三方库是在与我的应用程序的 CMAKE_BINARY_DIR 分开的位置“按需”构建的,这样我就可以删除我的应用程序的构建树,而不必重建第三方库(需要很长时间)。
  • 第三方库的位置因我构建它们的目标配置而异(很明显)。

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

这似乎是由一个实用程序 'wx-config' 处理的,它在使用 --cppflags 或 --libs 标志运行时提供准确的信息作为输出。但是,我无法弄清楚如何捕获该输出并将其附加到我从 CMakeLists.txt 文件设置的包含目录和链接库。

所以基本上我想要的是。

  1. 为当前目标配置构建 wxwidgets(如果它不存在)
  2. 运行 wx-config --cppflags 和 --libs 找出当前目标配置的正确包含目录和链接器标志
  3. 在构建属于我自己的应用程序的目标时使用第 2 步中的信息

到目前为止,我已经尝试过这样的事情:

# 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 和链接器选项的方法。

实现我想要的东西的好方法是什么?

最佳答案

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

方法一:使用find_package

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

    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 的安装)和你(你需要设置包含路径/编译)做一些工作定义/... 手动)。

方法二:嵌入wxWidgets

第二个选项是将 wxWidgets 捆绑在你的 repo(svn 外部或 git 子模块)中,并且通常(重新)编写这个库的 CMakeLists.txt 是面向目标的。然后,在最顶层的 CMakeLists.txt 中,您可以执行以下操作:

    # 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 面向目标,您需要为目标而不是目录定义包含目录和其他编译属性。示例:

    # 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 的重新构建。但是,可以通过不使用“重建”而是“只清理我的应用程序,然后构建”来欺骗它。 Here is some insight on how to achieve this .

方法3:某种混合

方法 2 的一大缺点导致了第三种方法:不要将 wxWidgets 放入您的项目中,而是创建一个将“导入”库的 CMakeLists.txt。这个想法:你向你的用户询问安装 wxWidgets 的目录,然后这个脚本将为你的项目设置一切。首先,将 CMakeLists.txt 放在这里:

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

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

    # 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_DIRECTORIESINTERFACE_LINK_LIBRARIES .您需要您的用户在他的系统中的某处构建 wxWidgets,但从您的角度来看,您只需执行 target_link_libraries(your_app PUBLIC wxWidgets...),就像方法 2 中那样。优点是这种方法可以透明地与方法 2 互换,并且您不会将整个依赖项放入您的项目中。

关于c++ - 我如何使用 CMake 按需构建 wxwidgets 并与之链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31092593/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com