【问题标题】:C++ | Compiling LOG4CXX AND APRC++ |编译 LOG4CXX 和 APR
【发布时间】:2021-02-01 23:17:53
【问题描述】:

我想在我的项目中使用外部库。 例如 apache log4cxx。 我正在为 windows 编译。

我知道我必须先编译:

  1. Apache APR
  2. Apache APR 实用程序
  3. Apache 图标v.

我在主页上只看到了这三个依赖项。

我使用 MinGW-64 作为编译器,使用 CodeBlocks 作为 IDE。 简单地在我的项目中导入每个依赖项的所有文件是行不通的。

例如:如果我添加 Apache APR 的所有文件,我会得到“找不到文件错误”:

如果我尝试对其他库执行相同操作,则会出现其他错误。

我确定我不了解如何使用它们的源代码构建外部库。

更新 我安装了 Visual Studio,现在我正在尝试编译库,但是(显然......)编译器返回错误(错误代码 C2513):

文件夹结构如下:

【问题讨论】:

  • 这意味着您的包含路径设置不正确。
  • 你能帮我理解一下吗?我应该为链接器设置某种文件夹吗?
  • 不,它是关于告诉您的编译器您将第三方库的标头放在哪里。它与链接器无关。
  • 在对此进行了一些研究之后,似乎 MSYS2 的人们不得不稍微修补这些库以使它们在 MinGW 上工作。一些更流行的库开箱即用地支持 MinGW,但这些似乎不支持。 “便携”就这么多。您可能想开始学习如何在其他一些库上构建库,但如果您真的想自己构建这些库,我会使用补丁并从 MSYS2 构建脚本(例如here are the ones for APR)。

标签: c++ libraries apr log4cxx


【解决方案1】:

前言

  • 我先解释一下我的思考过程,而不是马上给你答案。

  • 我只会浏览其中一个库,但对其他库重复相同的操作应该很容易。

  • 由于我不在 Windows 上,我不能使用 MSYS2 本身,而必须使用 its bastard child(我是它的作者)。因此,说明中可能存在细微的错误。

安装 MSYS2

MSYS2 是一种在 Windows 上获取 GCC 的方法。除了编译器之外,它在其包管理器中还提供了一些预构建的库,以及命令行实用程序的端口,例如 bashmake(在 Linux 上开箱即用,但通常不适用于窗户)。

首先,卸载您当前可能拥有的 MinGW/GCC 上的任何版本。从 MSYS2 安装 GCC 后,您可以告诉 CodeBlocks 使用它而不是现在使用的任何东西。

here 下载并安装 MSYS2。您不希望安装路径包含空格或任何奇怪的符号。

启动它,你应该会看到一个终端。

-- 更新 MSYS2 --

MSYS2 应在安装后更新。要更新,请运行 pacman -Syuu

它可能会警告您它将自行关闭以完成更新。 如果发生这种情况,请重新启动它并再次运行相同的命令以完成更新。

您可能希望不时运行此命令以使您的安装保持最新。

现在您可以运行pacman -Ss SomeText 来搜索包,运行pacman -S PackageNames 来安装包。

-- MSYS2的三个方面--

MSYS2 可以在三种不同的模式下启动,当前模式以洋红色字母显示在终端中。

选择模式的一种方法是使用安装目录中的不同 exe 文件(mingw64.exe 等)。

在包管理器中,有三组对应于这些模式的包。安装包时激活哪种模式无关紧要,但对于实际编译很重要。

  • MINGW32 - 用于编译 32 位应用程序。包名以mingw-w64-i686-为前缀。
  • MINGW64 - 用于编译 64 位应用程序。包名以mingw-w64-x86_64-为前缀
  • MSYS - 用于使用 POSIX 仿真编译应用程序。包没有前缀。

通常您不想使用最后一个。它用于编译最初为类 Linux 系统编写的非便携式应用程序,否则这些应用程序在 Windows 上不起作用。 MSYS2自带的bashmake等程序都是用它编译的。

您通常会看到一个包的三种变体,每种模式一个。例如,如果您执行pacmake -Ss gcc(搜索“gcc”包),您将看到mingw-w64-i686-gccmingw-w64-x86_64-gccgcc

你如何从三个包中选择一个包?这是经验法则:

  • 首先,寻找一个带前缀的包。 (mingw-w64-x86_64-... 编译 64 位,mingw-w64-i686-... 编译 32 位)。

  • 如果没有前缀包,而您正在寻找编译器,那么您很不走运,没有这样的包。

  • 如果您不是在寻找编译器或库,您可以选择不带前缀的包。

-- 安装工具--

有了这些知识,您就可以从 MSYS2 包管理器安装工具了。

  • pacman -S mingw-w64-x86_64-gcc 代表 GCC。

  • pacman -S mingw-w64-x86_64-gdb 用于 GDB,调试器。可能有用。

  • pacman -S mingw-w64-x86_64-cmake make patch 用于其他一些工具。希望我没有忘记任何事情。

    请注意,make 是经验法则的例外。还有另一个包名为 mingw-w64-x86_64-make,但长话短说它是 jank,你想改用不带前缀的 make

    我曾经在使用 CMake 包时遇到过一些问题。如果它开始起作用,请将其卸载并下载官方 CMake 安装程序。如果你使用它,别忘了将它添加到PATH

编译库

我要编译APR,其他的库​​应该差不多。

首先,我在包中搜索它:pacman -Ss apr - 包在那里。我尝试安装它并编译了一个测试程序(它工作),所以我们确定它可以在 Windows 上使用。

但既然你想自己编译它,我们会继续。如果您决定安装 APR 包进行试用,现在是卸载它的好时机,以避免任何干扰。

确保 MSYS2 在MINGW64 模式下运行(查看终端中的洋红色文本)。如果不是,请使用mingw64.exe 重新启动它。当您安装软件包时,处于活动状态的模式并不重要,但现在当您编译时,它变得很重要。

我将首先展示我失败的尝试,以解释思考过程。

-- 尝试 1 失败--

我从here 下载了 APR 源。 Windows 和 Linux 有单独的下载,我决定去apr-1.7.0-win32-src.zip

提取档案。在终端中打开生成的目录(使用cd,希望你知道这是什么)。

你接下来要做什么取决于你看到的文件。

由于有CMakeLists.txt,我尝试使用 CMake 构建:

# Create an arbitrary directory
mkdir _build
cd _build
# Configure
cmake .. -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -G "MSYS Makefiles"
# Build (-j12 is optional, 12 is the number of CPU cores you want to use)
make -j12

在最后一个命令中,我得到了一些神秘的错误。让我们试试别的。我删除了_build 并开始寻找不同的方法。

-- 尝试 2 失败--

我下载了apr-1.7.0.tar.gz(源代码的非 Windows 变体)。有CMakeLists.txt,所以我再次尝试了 CMake - 不,没有运气。

我还看到了一个configure 文件,因此也可以使用 Autotools 进行构建。 (通常是CMakeLists.txtconfigure。如果你都没有看到,那么构建过程就更奇特了,应该在自述文件中解释。)

让我们试试 Autotools:

# Configure
./configure
# Build
make -j12

第一步出现错误,所以我们需要一种不同的方法。

-- 成功尝试--

通常此时您已经成功,但 APR 拒绝开箱即用。然而 MSYS2 的人设法构建了它,如何?

让我们弄清楚。转到MSYS2 package sourceslook for APR

这里我们看到了几个.patch 文件。他们解释了 MSYS2 开发人员对 APR 源代码进行了哪些修改才能构建它。它们采用计算机可读格式,并且有一个程序可以自动将它们应用于代码。

下载.patch文件,以后会有用。

现在查看PKGBUILD 文件。它包含有关构建 APR 的计算机可读说明。有一种方法可以自动执行它们,但出于教育目的,我宁愿手动执行。

我不了解PKGBUILD 的所有内容,但这不是必需的。您会在其中看到以下内容:

  • pkgver=1.6.5 他们使用稍微过时的 1.6.5 而不是 1.7.0。

    我尝试构建 1.7.0 但失败了,所以摆脱 1.7.0 并从 here 下载 1.6.5。


  • makedepends=("${MINGW_PACKAGE_PREFIX}-gcc"
                 "${MINGW_PACKAGE_PREFIX}-libtool"
                 "${MINGW_PACKAGE_PREFIX}-python")
    
    为了能够构建这个包,他们安装了gcclibtoolpython。我们已经有了 GCC,现在我们只需要剩下的。跑:
    pacman -S mingw-w64-x86_64-libtool mingw-w64-x86_64-python
    

  • prepare() {
      cd "${srcdir}/${_realname}-${pkgver}"
    
      patch -p0 -i ${srcdir}/apr_ssize_t.patch
      patch -p0 -i ${srcdir}/apr_wtypes.patch
    
      ./buildconf
      # autoreconf -fi
    }
    
    这就是他们为构建“准备”的方式。让我们做一些类似的事情。将补丁文件复制到apr-1.6.5目录并运行:
    patch -p0 -i apr_wtypes.patch
    patch -p0 -i apr_ssize_t.patch
    ./buildconf
    

  • build() {
      [[ -d build-${MINGW_CHOST} ]] && rm -rf build-${MINGW_CHOST}
      mkdir -p build-${MINGW_CHOST}
      cd build-${MINGW_CHOST}
    
      # Disable IPv6.
      ../${_realname}-${pkgver}/configure \
        --prefix="${MINGW_PREFIX}" \
        --build=${MINGW_CHOST} \
        --host=${MINGW_CHOST} \
        --target=${MINGW_CHOST} \
        --enable-static \
        --enable-shared \
        --includedir="${MINGW_PREFIX}/include/apr-1" \
        --with-installbuilddir="${MINGW_PREFIX}/share/apr-1/build" \
        --enable-nonportable-atomics \
        --with-devrandom=/dev/urandom \
        --disable-ipv6
    
      make
    }
    
    所以他们使用configuremake 就像我们试图做的那样,但有一些额外的标志。让我们不用担心标志,只需执行以下操作:
    ./configure
    make -j12
    

而且...它构建成功!

使用编译库

您编译了库,它创建了一些文件供您使用。它们是什么?

您需要.a(静态库)和.dll(动态库)。快速搜索显示它们位于.libs 目录中。

您还需要标题,它们似乎位于include 目录中。其他一切都不再需要了。

现在您需要知道要使用哪些编译器和链接器标志。这些可以在.pc 文件(在这种情况下为apr.pc)中找到,对我来说看起来像这样:

prefix=/usr/local/apr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
APR_MAJOR_VERSION=1
includedir=${prefix}/include/apr-${APR_MAJOR_VERSION}

Name: APR
Description: The Apache Portable Runtime library
Version: 1.6.5
Libs: -L${libdir} -lapr-${APR_MAJOR_VERSION} -lshell32 -ladvapi32 -lws2_32 -lrpcrt4 -lmswsock
Cflags: -DWIN32 -D__MSVCRT__ -D_LARGEFILE64_SOURCE -g -O2 -I${includedir}

查看最后两行并忽略一些可选标志,我们得到:

  • 编译器标志:-DWIN32 -D__MSVCRT__ -D_LARGEFILE64_SOURCE -Ipath/to/apr-1.6.5/include
  • 链接器标志:-lapr-1 -lshell32 -ladvapi32 -lws2_32 -lrpcrt4 -lmswsock -Lpath/to-apr-1.6.5/.libs

现在我们可以尝试从终端编译一个简单的程序。创建一个名为1.cpp 的文件,其内容如下:

#include <iostream>
#include <apr_strings.h>

int main()
{
    char a[] = " Hello , world ! ";
    char b[sizeof a];
    apr_collapse_spaces(b, a);
    std::cout << b << '\n';
}

使用以下方法构建它:

g++ 1.cpp -DWIN32 -D__MSVCRT__ -D_LARGEFILE64_SOURCE -Iapr-1.6.5/include -lapr-1 -lshell32 -ladvapi32 -lws2_32 -lrpcrt4 -lmswsock -Lapr-1.6.5/.libs

由于我们是从终端构建的,所以我们的编译器和链接器标志在同一个地方。但是当您使用 CodeBlocks 时,您必须将它们放在项目设置中的两个不同位置。

在此命令中,您必须将 -I-L 之后的路径替换为 APR 源的实际路径。

如果命令运行成功,您将获得a.exe

要运行它,首先需要将apr-1.6.5/.libs中的所有.dlls复制到.exe所在的目录下。现在您应该可以输入./a.exe 并看到它打印Hello,world!

代码块

如果你想从 CodeBlocks 做同样的事情,你需要创建一个项目,并在项目设置中指定你在此处使用的相同编译器和链接器标志。

此外,在 CodeBlocks 设置中,您必须指定从 MSYS2 安装的 GCC 编译器的路径(它应该在 C:/msys64/mingw64/bin/ 中)。

【讨论】:

  • 非常感谢您的回答,我正在尝试重现您的步骤。我假设这种事情只适用于 MinGW 项目而不适用于 Visual Studio 项目,对吧?
  • @FrancescoRizzi 是的,Visual Studio 完全不同。
【解决方案2】:

如何构建 log4cxx 有多种选择,具体取决于您的设置。当前的方法是使用提供的 cmake 文件来构建它。

唯一需要的依赖项是 APR 和 APR-util(取决于 expat 或 libxml)。

选项 1:vcpkg

如果您在 Windows 上并使用 CMake 构建项目,最简单的方法是安装 vcpkg 并使用已包含在 vcpkg 中的配方。这可以简单地完成如下:

git clone https://github.com/microsoft/vcpkg
.\bootstrap-vcpkg.bat
.\vcpkg install log4cxx

这将下载 log4cxx 和所需的所有依赖项(APR、APR-util、expat 等)。然后,您可以从那里使用 vcpkg 创建的生成的 CMake 工具链文件(有关更多信息,请参阅vcpkg documentation

选项 2:单独构建所有依赖项

所有必需的依赖项都可以使用 CMake 构建。安装和配置依赖项时,最好的方法是确保它们都安装在系统上的同一根文件夹中(例如,所有依赖项的安装目录设置为相同)。这样可以更轻松地配置构建系统。

请参阅this JIRA issue 了解更多信息以及有关如何单独构建的一些线索。

【讨论】:

    猜你喜欢
    • 2013-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-09
    • 2013-08-08
    • 2014-05-23
    • 2012-07-30
    • 1970-01-01
    相关资源
    最近更新 更多