2

我对 C/C++ 的基本问题在于库编译领域。例如,软件 A 使用库 Z,因此您必须先编译库 Z,然后才能编译并随后使用和/或开发软件 A。

在许多情况下,存在配置项目然后调用 make + make install 的概念。例如,您打开命令行并输入:

./configure
make
make install

./configure是放置在项目顶层目录中的shell脚本。我想它会检查系统上是否存在所有依赖项并保存这些依赖项的路径。稍后,make 可以利用这些收集到的信息为编译器提供相应的包含路径和库位置(例如 .so/.a 文件的位置)。

make负责以正确的顺序编译和链接源文件(由 makefile 指定,由 I-dont-know 生成并具有 XYZ 格式)。当然,它本身并不编译/链接任何东西,而是调用实际的编译器和链接器来完成它的工作。

make install获取生成的二进制文件并将它们放在系统中的某个位置(例如 /usr/lib 如果项目是库或 /usr/bin 用于可执行文件)。如果手头的项目是一个库,它应该也会获取库的头文件并将它们安装在系统的某个位置。

这是一个相对复杂的过程;让我们用 CMI 来表示这种类型的编译过程(CMI = configure-make-install)。此外,据我所知,CMI 概念是特定于 Linux 世界的。它在 Windows 上不像那样工作,例如因为没有可用于执行 ./configure 的 shell。make 甚至可能仅限于 gcc/g++,但我不知道是不是这样。

最重要的是,我什至不知道在哪里查找。我也想看看CMI概念是否支持同时安装不同版本的库。假设您是软件 B 和软件 C 的开发人员。软件 B 和 C 都依赖于库 Y,但无论出于何种原因,B 需要 Y 1.0.x 而 C 需要 1.1.x。如果 make install 将库的头文件放在系统的某个地方,会不会发生冲突?再次,我问我自己,我在哪里可以找到它?


让我们讨论一个示例库:libzip。主页没有说明支持或推荐哪些编译器或平台。你现在将如何进行?

有趣的是,该页面声称 MySQL Workbench 正在使用 libzip。MySQL Workbench 也为 Windows 提供,所以我想 libzip 可以在 Windows 上编译。

我还观察到 libzip 附带了一个CMakeLists.txt 一个配置脚本。甚至还有一个libzip.pc.in CMake 模板,据说是用于pkg-config工具的。还有 Makefile.am - 不管是什么 - 和 Makefile.in,据说是另一个 CMake 模板。最后但并非最不重要的一点是,我注意到文件夹 m4 和 .m4 文件(都在 m4 文件夹和项目的根文件夹中)。但我们不要忘记 cmake-config.h.in、cmake-zipconf.h.in。

因此,如果要编译 libzip,则必须考虑以下替代方案:

  • 使用 CMI 概念
    • 不适用于 Windows(对吗?)
  • 使用 CMake,这是一个元构建系统
    • 那么您必须决定应该为哪些编译器/IDE CMake 生成:gcc?微软?Mingw 还是 QTSDK/MingW?(无论有什么区别)
  • 也许使用 M4,不管那是什么

M4 似乎与 GNU autoconf 有关。我想我也可以将其添加到上面的列表中。

(旁注:到目前为止,我已经尝试使用 CMake + Visual Studio 2010 的组合来编译 libzip。目前我正在修复各种编译错误。)


这是我的中心观察:

libzip 是一个简单的库;只是一些拉链的东西。然而,编译涉及的工具太多,即使对于高级程序员来说,这也是一项不可能完成的任务。

此外,大多数这些工具的文档都缺乏(否则为什么我有所有这些问题,不知道在哪里可以找到答案?)。更不用说大多数工具甚至在不投入大量时间进行逆向工程来修复(例如,有缺陷的 CMake FindPackage-scripts sigh )的情况下都无法工作


我可以这样持续数周。我迷失在众多的编译概念中,所有这些概念如何相互关联,它们可以很好地使用哪些平台和编译器等等。

另一个例子:RetroShare。尽管 Windows 的编译过程有文档记录,但要完成编译是极其困难的。只需考虑在 Windows 上编译 RetroShare 涉及 QtSDK/MingW、Cygwin 和 MingW/MSYS,它们都用于不同的部分/依赖项。这些工具如何协同工作?

我完全迷失了,我想让你告诉我你是如何处理这类问题的,以及考虑到所有这些工具/工具链/编译器/平台,你如何保护你的思想免受严重损害。

你们是非常聪明还是我非常愚蠢?为什么这如此复杂(或者不是)?

4

2 回答 2

2

“我可以这样持续数周。”

你确实听起来有点困惑。我会讲几个具体的点。

“configure-make-install”过程特别使用了make,这是一个更通用的工具。即,make 和makefile 可以以其他方式使用。记在脑子里。

“make 负责以正确的顺序编译和链接源文件(由 makefile 指定,由 I-dont-know 生成并具有 XYZ 格式)。”

迟早,您几乎肯定会不得不自己学习编写 makefile。Make 是一个构建系统,对于 C/C++ 程序员来说,它是一个非常有用的、近乎强制性的工具。如果您使用 IDE,它可能已经在为您创建 makefile。这是一个为一个小项目手工编写的 makefile 示例:

wx = `wx-config --cxxflags --libs`

test1: main.cpp main.h window.o
        g++ -Wall -g main.cpp window.o -o test1 $(wx)

window.o: window.cpp window.h
        g++ -Wall -g -c window.cpp -o window.o $(wx)

第一行定义了一个变量,链接器的一些标志,之后使用了两次。如果您在命令行上使用 gcc,接下来的两位应该很熟悉。要在没有 的情况下构建此项目make,您将首先编译 window.o g++ ...,然后再编译test1。有了makefile,你所要做的就是运行make。向项目中添加更多对象 (.o) 文件,它开始看起来非常方便。此外,您可以将不同的“目标”写入一个 makefile。周围有各种制作教程,以及 GNU 版本的官方文档:

http://www.gnu.org/software/make/manual/make.html

不难弄清楚。

“make install 获取生成的二进制文件并将它们放在系统中的某个位置”

make install是在 configure-make-install 上下文中使用的 makefile 中通常定义为执行此操作的目标。你可以在上面的 makefile 中添加这样的东西:

install: test1
    cp test1 /usr/local/bin/

冒号后与目标位于同一行的任何内容都是先决条件——它指的是必须存在于构建树中的文件(或必须运行的另一个目标指令)。如果文件不存在(或者如果它的一些先决条件在构建后发生了变化)并且有一个同名的目标(在这种情况下,test1-- 也请查看之前的 prereqs)然后运行该目标指令第一的。

“此外,据我所知,CMI 概念是特定于 Linux 世界的。”

不,但它对 windows 世界有点陌生。这有时与autotools相关,可用于生成配置脚本和相应的 makefile。请注意,如果您安装了mingw ,则可以在 Windows 上使用 CMI 包。

“使用 CMake,这是一种元构建系统”

CMake 本质上与 make 相同,只是不同。 make仅当在 makefile 中显式调用 gcc 时才使用它;可以编写 makefile 来执行 shell 脚本可以执行的任何操作,包括运行编译器等。CMake 渴望更加便携/平台无关,并且可能对用户友好。有些人更喜欢它。

“如果 make install 将库的头文件放在系统的某个位置,会不会发生冲突?”

理想情况下,没有。自动工具(“CMI”)设置的部分要点是允许打包程序实施机制来处理此类问题(如果存在)。您可以安装同一个库的多个版本。WRT 标头,如果这些更改,它们(希望)保持向后兼容,库本身也是如此。如果没有,应该有一些明确的指示(“版本 2 与版本 1 不兼容!”),当这种情况发生时,任何有头脑的人都会从一开始就有版本 2 的不同标头,并在 API 中引用该标头.

于 2012-05-06T15:23:03.017 回答
0

了解使用什么也可能会有所帮助:http ://www.elpauer.org/stuff/learning_cmake.pdf

于 2013-11-12T13:33:52.347 回答