我有以下情况:
我对CMake很新,我目前面临的问题是: 我的应用程序中的源文件无法找到wx包含文件,我需要设置正确的链接器标志才能将我的应用程序与wxwidgets链接。
这似乎是由一个实用工具' wx-config'当使用--cppflags或--libs标志运行时,它提供与输出完全相同的信息。但是,我无法弄清楚如何捕获该输出并将其附加到我从CMakeLists.txt文件设置的包括dirs和链接库。
基本上我想要的是。
到目前为止,我尝试过这样的事情:
# 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和链接器选项。
实现我想要的好方法是什么?
答案 0 :(得分:3)
我看到了三种不同的方法:
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()
这样做的好处是,如果重建项目不会重建lib,但是它需要为您的用户做一些工作(他们需要手动处理wxWidgets的安装)和你(需要设置include paths / compile)定义/ ...手工制作。
第二个选项是在你的repo(svn external或git子模块)中捆绑wxWidgets,并且通常(重新)写这个lib的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
方法2的一大缺点导致了第三种方法:不要在项目中放置wxWidgets,而是创建一个“导入”lib的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_DIRECTORIES和INTERFACE_LINK_LIBRARIES。您需要您的用户在他的系统中的某个位置构建wxWidgets,但是从您的角度来看,您只需执行target_link_libraries(your_app PUBLIC wxWidgets...)
,就像方法2一样。优点是这种方法可以透明地与方法2互换,并且您不会t将整个依赖项放在项目中。
答案 1 :(得分:1)
设置cppflags和链接器标志必须在CMake时完成,但是你试图在构建时运行wx-config并且你还没有捕获它的输出,所以你的add_custom_command()
没有做任何有用的事情除了将内容打印到构建工具的输出外。
理想情况下,您可以使用CMake已提供的FindwxWidgets
模块。它需要已经构建了wxWidgets(但是请参见下文)。看看CMake documentation for it,看看它是否至少听起来像你想要通过使用wx-config手动实现的那样。如果你能让FindwxWidgets
为你完成这项工作,那将是一种更加清洁的方法。
在配置时获取内容以便稍后在CMakeLists.txt文件中使用它会有点棘手。 ExternalProject_Add()
在 build 时下载和构建内容,但您需要在 configure 时间之前构建wxWidgets。我最近写了一篇文章,关于如何在配置时至少完成下载部分,你应该能够在配置时调整它来完成整个构建。本文使用Google Test作为示例,可以在此处找到:
https://crascit.com/2015/07/25/cmake-gtest/
将wxWidgets构建在任何你喜欢的地方,而不只是在CMAKE_BINARY_DIR
区域,这将是微不足道的。这将允许您为每个构建配置创建不同的wxWidgets构建,并且能够独立于wxWidgets构建消除应用程序的构建树。
希望指出你正确的方向。
答案 2 :(得分:0)
我使用的解决方案使用find_package
检查系统中的wxWidgets安装,如果找不到,则脚本从github下载wxWidgets并将程序与下载的库链接。该库安装在build
目录中,因此只有第一个构建缓慢-后续构建甚至不检查wxWidgets源时间戳,因此该过程与使用预安装的wxWidgets库构建一样快。
这是我的脚本的工作方式:
find_package(wxWidgets QUIET)
悄悄地检查wxWidgets的安装,ExternalProject
的wxWidgets_external,它会在build
目录中下载,构建和安装该库,并将wxWidgets_ROOT_DIR
设置为指向wxWidgets安装目录,< / li>
ExternalProject
指向包含主程序源文件和CMakeLists.txt
构建脚本的文件夹。此外部项目取决于wxWidgets_external
,如果在系统中预先安装了wxWidgets,则它是一个虚拟库,或者是一个设置为从github下载该库的外部项目,CMakeLists.txt
中,我们再次使用find_package
参数调用REQUIRED
,并以标准方式(https://docs.wxwidgets.org/trunk/overview_cmake.html)使用该库。因为我们正确设置了依赖项和变量,所以此调用将使用预安装的wxWidgets(如果有)或从github下载的wxWidgets。还有更多奇怪之处,但这就是要点。完整的示例代码(在Linux,Windows和Mac上进行了测试)可在github(https://github.com/lszl84/wx_cmake_template)上找到。
另请参阅完整的博客文章,其中对此进行了更详细的解释:https://justdevtutorials.medium.com/wxwidgets-cmake-multiplatform-superbuild-4ea86c4e6eda