如何在版本控制中存储C库依赖项?
来自 Rails 背景的我习惯于能够在 Gemfile 中指定应用程序的依赖项,该文件已签入我的 git 存储库。当我的应用程序被拉取时,用户只需运行 bundle install
并且他们拥有所有必要的依赖项。
在 这个答案中,社区似乎同意不应该检查 C 库进入源代码控制。这是有道理的(毕竟 Gems 本身没有在 Rails 下签入),但它仍然会产生问题。如果我编写一些代码并包含对用户创建的库的新依赖项,我如何在源代码管理中表达这种依赖项?
Coming from a Rails background, I am used to being able to specify the dependencies of my application in a Gemfile which is checked into my git repo. When my app gets pulled, the user just needs to run bundle install
and they have all of the necessary dependencies.
In this answer, the community seems to agree that C libraries should not get checked into source control. This makes sense (after all the Gems themselves aren't checked in under Rails) but it still creates a problem. If I write some code and include a new dependency on a user created library, how can I express this dependency in the source control?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
显然,C 世界中的情况有些不同,因为您在运行时不需要源代码。在 GNU/Linux(以及许多其他 *ix)系统上完成操作的一般方式是使用配置脚本或程序执行某些配置步骤。其中最常见的是著名的
configure
脚本,由 GNUautoconf
生成。自动工具会生成大量缓存文件并将大量辅助脚本复制到源代码树中,因此请记住设置.gitignore
,否则您会发疯的。许多库在
$prefix/lib/pkgconfig
或$prefix/share/pkgconfig
中安装pkg-config
的控制文件。这些由 pkg-config 工具读取,以检查库是否存在并获取该库的正确编译器和链接器标志。它们是纯文本,因此请查看/usr/lib/pkgconfig
以了解它们的外观。在autoconf中,通过调用宏处理器m4(通过包装器)将文件configure.ac编译为configure称为autoconf)。要检查是否有与
pkg-config
一起使用的库,事情非常简单。您将类似以下内容添加到configure.ac
这将检查
pkg-config
是否已安装,然后使用它来检查软件包glib-2.0,一路打印消息
,来自Checking for GLib...
。它还会设置 shell 变量GLib_CFLAGS
和GLib_LIBS
,并安排它们替换到AC_CONFIG_FILES
创建的任何文件中(例如您的 <代码>MakefileMakefile.in
)。如果找不到 glib,configure
将失败并出现错误。查看/usr/share/aclocal/pkg.m4
找到PKG_CHECK_MODULES
的定义,它支持一些其他选项。文档位于pkg-config(1)
手册页。如果您的依赖库没有
pkg-config
支持,有时库供应商会提供autoconf
宏。例如,旧版本的 SDL 提供了AM_PATH_SDL
,但新版本仅使用pkg-config
。如果没有供应商的支持,有时 autoconf 存档 中会有第三方支持。 autoconf 存档在 Debian GNU/Linux 和 MacPorts(可能还有许多其他系统)中作为软件包提供,这意味着可以使用任何所需的定义,而无需手动复制
.m4
文件。如果以上都不成立,则使用类似
AC_CHECK_HEADER
并使用类似AC_CHECK_LIB
。Obviously, things in the C world are a little different because you don't need the source at runtime. The general way things are done on GNU/Linux (and many other *ix) systems is that some configuration step is performed using a configuration script or program. The most common of these is the famous
configure
script, generated by GNUautoconf
. The autotools generate a lot of cache files and copy a lot of auxiliary scripts into your source tree, so remember to set up.gitignore
or you'll go crazy.A great many libraries install control files for
pkg-config
in$prefix/lib/pkgconfig
or$prefix/share/pkgconfig
. These are read by thepkg-config
tool to check for the existence of libraries and get the correct compiler and linker flags for that library. They're plain text, so have a look in/usr/lib/pkgconfig
to get an idea of what these look like.In
autoconf
, a fileconfigure.ac
is compiled intoconfigure
by invoking the macro processorm4
(through a wrapper calledautoconf
). To check for a library which works withpkg-config
, things are really easy. You add something like the following toconfigure.ac
This will check that
pkg-config
is installed and then use it to check for the packageglib-2.0
, printing the messageChecking for GLib...
along the way. It will also set the shell variablesGLib_CFLAGS
andGLib_LIBS
, and arrange for them to be substituted into any files created byAC_CONFIG_FILES
(such as yourMakefile
, fromMakefile.in
). If it doesn't find glib,configure
will fail with an error. Have a look at/usr/share/aclocal/pkg.m4
to find the definition ofPKG_CHECK_MODULES
, which supports a few other options. Documentation is in thepkg-config(1)
man page.If your dependant library doesn't have
pkg-config
support, sometimes the library vendor provides anautoconf
macro. Old versions of SDL, for example, providedAM_PATH_SDL
, but new versions just usepkg-config
.If there's no support from the vendor, sometimes there's third-party support at the autoconf archive. The autoconf archive is available as a package in Debian GNU/Linux and MacPorts (and probably many other systems), which means that any needed definitions can be used without copying
.m4
files around by hand.If none of the above are true, then check for a header using something like
AC_CHECK_HEADER
and check for the library using something likeAC_CHECK_LIB
.取决于您使用的库。例如,当我使用 Sqlite 时,我会在版本控制上签入 sqlite 文件并使用源文件构建它。这很容易,因为 sqlite 附带一个源文件和一个标头。如果库有更多文件,这将不切实际。
在 Linux 上,这是使用自动工具处理的。使用它,您可以指定要使用的包,并且配置将在构建时尝试找到它。如果您正在寻找跨平台解决方案,CMake 是最好的工具。这些工具可以找到安装在标准位置(
/usr/lib
和/usr/include
)上的软件包,并且还提供了一种调整搜索补丁的方法。Depends on the library you use. For example, when I use Sqlite, I check in the sqlite files on my version control and build it with my source files. This is easy as sqlite comes with one source file and a header. This won't be practical if the library has more files.
On Linux, this is handled using autotools. Using that, you can specify the packages to use with and the configure will try to find it when building. If you are looking for a cross platform solution, CMake is the best tool. These tools can find the packages installed on standard locations (
/usr/lib
&/usr/include
) and also provides a way to adjust the search patch.