关于库如何在 C 中工作的问题

Posted

技术标签:

【中文标题】关于库如何在 C 中工作的问题【英文标题】:Questions about how libraries work in C 【发布时间】:2015-06-27 01:41:04 【问题描述】:

我是一名学习 C 的新手学生,希望将 gLib 库函数用于项目:http://www.linuxfromscratch.org/blfs/view/svn/general/glib2.html (我使用的是 Ubuntu)

我有几个关于库在 C 中的工作方式以及安装或想要使用库时会发生什么的问题:

    当我安装它时(在文件夹中运行 ./configure && make && make install),它到底在做什么?据我所知,C 中有共享库,C 中有静态库。它是否正在安装库并将文件包含到 /usr/lib/ 或某处?

    将 gcc 与外部库一起使用时,您必须指定 -L 和 -I 标志来指定查找库和头文件的位置。当我安装 glib 时,我需要指定这些标志吗?

    如果我想为另一台机器打包我的可执行文件,如果另一台机器没有 glib 会发生什么?我想如果我有静态库,我可以将它包含在二进制文件中,但它如何用于 glib?

【问题讨论】:

【参考方案1】:

我熟悉使用 GTK+ 和 GLIB 进行开发。据我所知,库文件位于 /usr/lib 中,包含文件位于 /usr/include 中。某些库可能位于 /usr/local/lib 等位置。我会尽量回答你的问题。

    通过源包安装库时,是的,它会将文件安装到各种文件夹 /usr/share /usr/lib /usr/include 等。强烈建议您使用发行版的包管理器来安装库包和开发头文件.从源代码安装总是会失败,因为可能需要必要的依赖项。

    这是 autogen 和 makefile 等工具派上用场的地方。您不一定需要自己指定所有这些。诸如pkg-config 之类的工具可以处理所有这些工作。大多数库会将包配置文件安装到 /usr/lib/pkgconfig 和 /usr/share/pkgconfig 目录中。这有助于任何开发应用程序的人轻松地将他们的代码链接到库。

使用包配置获取配置:

 $ pkg-config --cflags --libs glib-2.0
-I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include  -lglib-2.0

使用 GCC 和包配置链接:

$gcc example.c `pkg-config --cflags --libs gtk+2.0 glib-2.0` -o example

上面的命令会将我的程序与 gtk & glib 链接起来。

使用 Makefile 不必再次输入那些长行:

生成文件:

OBJS = main.o callbacks.o
CFLAGS = `pkg-config --cflags --libs  gtk+-2.0`
program:  $(OBJS)
    gcc -o program $(OBJS)
main.o: main.c
    gcc -c main.c $(FLAGS)
callbacks.o: callbacks.c callbacks.h
    gcc -c callbacks.c $(FLAGS)

.PHONY : clean
clean:
    rm *.o
    rm program
.PHONY : install
install:
    cp program /usr/bin
.PHONY : uninstall
uninstall:
    rm /usr/bin/program

上面的 makefile 是一个简单的 GTK+2.0 应用程序,您可以通过 CFLAGS 中包含的包配置来判断,以使程序可执行,您必须在源目录中输入 make。 pkg-config 仅在您已为您尝试使用的库安装了开发包时才有效。要让 ubuntu 安装 GTK+-3.0 和 GLIB 开发文件,您需要输入:

$ apt-get install libgtk-3-dev
    我认为这是一个很好的可移植性问题。没有一个静态库会是跨平台的。它必须为这些平台手动编译。我认为可以摆脱使用 GNOME 软件基金会开发的 Anjuta IDE 的所有麻烦。它使开发支持 C 和 C++ 的 GLIB 和 GTK+ 应用程序变得轻而易举。它将创建Makefileconfigure 和其他文件,使跨平台的代码开发和部署变得容易。我可以给你链接一些资源,但是我在堆栈溢出方面的声誉不到 10。所以我将在下面提到一些资源的名称。

进一步阅读

Makefile 教程

Anjuta IDE (C/C++)):://anjuta.org/

使用 pkg-config 编译和链接的 GTK+-3.0 Hello World:

【讨论】:

【参考方案2】:

当我安装这个(运行 ./configure && make && make install inside 文件夹),它到底在做什么?从我了解到的有 C中的共享库和C中的静态库。是真的吗 将库和包含文件安装到 /usr/lib/ 或其他地方?

它首先运行./configure,然后如果成功则运行make,如果成功则运行make installconfigure 是一个脚本,负责处理系统之间的许多兼容性问题。它们通常是 shell 脚本,因为这是跨系统的共同点,因此配置脚本可以跨各种系统工作。 configure 所做的一件事就是创建一个Makefile。第二个命令make 将使用新创建的 Makefile 来构建库或可执行文件。由于您没有指定目标(就像您将在 make install 中那样),make 将构建默认目标,通常是 all 目标。这只是惯例。 Makefile 基本上是要构建的东西(目标)的列表,以及它们依赖的内容(依赖项)以及如何构建目标(规则)。最后,make install 将实际安装必要的组件。对于库,这是可执行文件的库和必要的头文件,它只是程序。 man pages 也可能被安装。安装库的位置取决于您指定的安装位置。通常configure 将采用--prefix 参数,让您控制它们的安装位置。如果您不使用--prefix,您很可能会安装在系统的默认位置。

当使用 gcc 和外部库时,你必须指定 -L 和 -I 标志指定在哪里查找库和头文件。当我 安装 glib,我需要指定这些标志吗?

你的问题有点不清楚,所以让我先确保我理解。您是否在问安装 glib 后是否需要使用 -L 和 -I 来告诉 gcc 在哪里寻找它们?如果是这样,这取决于您安装它们的位置。通常,当您制作和安装库时,您会将库和头文件安装在默认位置或不安装。如果你这样做了,那么假设你的 gcc 配置正确,那么你不会。如果你没有,那么你很可能不得不使用-L-I

如果我想将我的可执行文件打包到另一台机器上,应该怎么做? 如果另一台机器没有 glib,会发生什么?我想如果我有静电 库我可以将它包含在二进制文件中,但是如何 它适用于 glib 吗?

如果它没有 glib 并且您使用了共享库,您的应用程序将无法运行。您将需要在另一台机器上拥有相同版本的 glib 库或静态构建库。如何在统计上构建它们取决于库。 This SO question 可能会有所帮助。

【讨论】:

嘿,所以我最终运行 sudo apt-get install libglib2.0-dev 来安装 glib。但是我需要在我的 gcc 命令中添加一些标志,例如 pkg-config --cflags glib-2.0,它告诉 gcc 在哪里可以找到包含文件。 (我猜它没有安装到 gcc 查找库的地方?)无论如何,管理这些标志似乎很乏味,所以我使用的是 Makefile。但是,我的目标只是编写一个简单的程序;是我过于复杂还是 C 语言往往如此复杂?【参考方案3】:

    关于configuremakemake installconfigure 是一个 shell 脚本,用于发现(和配置)您的开发环境。 makemake install 是构建软件的便捷方式。 make 通常会涉及编译和链接,而 make install 通常会涉及将可执行文件和库复制到标准路径并进行设置(如果有的话,还包括通常在/usr/include 中的文件),这样您就不必在运行可执行文件之前明确给出路径。 make 做的事情可以手工完成,但是很麻烦。

    对于 glibc - 是的,您必须指定这些标志。通常,所有库在大多数平台上都会有两种风格。实际加载程序时,二进制形式用于动态链接。此外 - 大多数发行版将具有这些库的 -dev-devel 版本。这些是构建使用这些库的软件所必需的(上面的configure 可以帮助确定是否安装了开发库)。通常,当您看到已安装库但未开发时 - 您可能会看到 configure 错误。简而言之,如果您想与这些库链接,则需要 devel 版本。如果您还使用make and make install 从源代码构建库,则不需要此步骤。

    1234563 ,您应该在构建(编译/链接)库时进行静态链接。 this gcc man page 有几个关于链接选项的详细信息。我相信应该有一种方法可以静态链接 glib(或 glib2)。虽然通常如果您有足够的应用程序正在使用它,则可能不需要。

【讨论】:

如果自定义 glib 安装在默认位置,则不需要指定标志,例如编译器和链接器已经在查看的位置。

以上是关于关于库如何在 C 中工作的问题的主要内容,如果未能解决你的问题,请参考以下文章

关于管道如何在 Bash 中工作的简单解释是啥?

关于 connection.end() 如何在 node.js mySQL 模块中工作的困惑

$ 究竟是如何在 NASM 中工作的?

如何在 iPhone 模拟器中工作的 UIAutomation 中获取 captureScreenWithName?

如何定义在 Laravel 数据库迁移中工作的非 id 主键?

如何创建在 Visual Studio Code 中工作的 Java / Maven 项目?