关于库如何在 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+ 应用程序变得轻而易举。它将创建
Makefile
、configure
和其他文件,使跨平台的代码开发和部署变得容易。我可以给你链接一些资源,但是我在堆栈溢出方面的声誉不到 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 install
。 configure
是一个脚本,负责处理系统之间的许多兼容性问题。它们通常是 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】:
关于configure
、make
和make install
。 configure
是一个 shell 脚本,用于发现(和配置)您的开发环境。 make
和 make install
是构建软件的便捷方式。 make
通常会涉及编译和链接,而 make install 通常会涉及将可执行文件和库复制到标准路径并进行设置(如果有的话,还包括通常在/usr/include
中的文件),这样您就不必在运行可执行文件之前明确给出路径。 make
做的事情可以手工完成,但是很麻烦。
对于 glibc - 是的,您必须指定这些标志。通常,所有库在大多数平台上都会有两种风格。实际加载程序时,二进制形式用于动态链接。此外 - 大多数发行版将具有这些库的 -dev
或 -devel
版本。这些是构建使用这些库的软件所必需的(上面的configure
可以帮助确定是否安装了开发库)。通常,当您看到已安装库但未开发时 - 您可能会看到 configure
错误。简而言之,如果您想与这些库链接,则需要 devel
版本。如果您还使用make and make install
从源代码构建库,则不需要此步骤。
【讨论】:
如果自定义 glib 安装在默认位置,则不需要指定标志,例如编译器和链接器已经在查看的位置。以上是关于关于库如何在 C 中工作的问题的主要内容,如果未能解决你的问题,请参考以下文章
关于 connection.end() 如何在 node.js mySQL 模块中工作的困惑
如何在 iPhone 模拟器中工作的 UIAutomation 中获取 captureScreenWithName?