【问题标题】:Use autotools installation prefix使用 autotools 安装前缀
【发布时间】:2018-12-23 11:00:06
【问题描述】:

我正在编写一个 C++ 程序,使用 gtkmm 作为窗口库并使用 autotools 作为我的构建系统。在我的 Makefile.am 中,我按如下方式安装图标:

icondir = $(datadir)/icons/hicolor/scalable/apps
icon_DATA = $(top_srcdir)/appname.svg

编辑:从prefix更改为datadir

这会导致在安装程序时将appname.svg 复制到$(datadir)/icons/hicolor/scalable/apps。在我的 C++ 代码中,我想在运行时访问该图标以进行窗口装饰:

string iconPath = DATADIR + "/icons/hicolor/scalable/apps/appname.svg";
// do stuff with the icon

我不确定如何为此目的获得DATADIR。我可以使用相对路径,但是移动二进制文件会破坏图标,这似乎很明显。我认为应该有一种特殊的方式来处理与一般数据分开的图标,因为人们可以安装第 3 方图标包。所以,我有两个问题:

  1. 在 autotools/C++/gtkmm 中安装 和使用图标的标准方法是什么?

编辑:gtkmm 有一个IconTheme 类,这是在gtkmm 中使用图标的标准方式。看来我add_resource_path()(还是需要安装前缀的),然后就可以使用库按名称获取图标了。

  1. 用autotools/C++访问autotools安装前缀的一般方法是什么?

【问题讨论】:

  • 抱歉,因为string iconPath = PREFIX + "/icons/hicolor/scalable/apps/appname.svg"; 不是C,并且没有“C/C++”语言,所以删除了C 引用。
  • 按照你的设想做事我相信你需要从环境中读取PREFIX和[可能]DESTDIRPREFIX 通常是相对的,例如 ../../share/...。我不确定您可以对 staging 和 DESTDIR 做些什么。也许布林格会有一个答案。他通常会回答我的重要问题。
  • 我可以依靠环境变量来保持一致吗?主要问题是,如果我在 IDE 中手动编译或将其转换为 flatpak,则会有不同的前缀。现在我可以做的是编写一个构建钩子来修改我的代码并在其中编辑它,但这基本上是一个宏(或编译指示?指令?),我很难相信这样的事情还没有标准化。
  • 你应该在 Makefile 中定义一个预处理器符号(例如 -DPREFIX=...),或者在 config.h 中写一些东西
  • 安装图标的通常位置是$(datadir)/icons/hicolor/scalable/apps。那将类似于/usr/local/share/icons/...。你确定这不是你真正想要的地方吗?

标签: c++ linux autotools autoconf gtkmm


【解决方案1】:

要将configure 确定的数据传送到源文件,可用的主要方法是将它们写入源#include 的标头中,或者在编译器命令行上将它们定义为宏。通过AC_DEFINE Autoconf 宏可以最方便地处理这些问题。在某些情况下,您可能还考虑将源文件转换为模板以供 configure 处理,但除非 Autoconf 本身使用该技术的内部版本来构建 config.h(如果需要),我通常不会推荐它。

但是,安装前缀和其他安装目录是特殊情况。在您实际运行make 之前,它们不会最终设置。即使您通过configure 的命令行选项设置它们,您仍然可以通过在make 命令行上指定不同的值来覆盖它。因此,将AC_DEFINE 用于此特定目的是不安全的,事实上,这样做可能根本不起作用(不会prefix 本身起作用)。

相反,您应该在make 时间评估的命令行选项中指定适当的宏定义。您可以通过在Makefile.am 文件中设置AM_CPPFLAGS 变量来对正在构建的所有目标执行此操作,如another answer 中所示。该特定示例将指定符号设置为扩展为包含前缀的 C 字符串文字的宏。或者,您可以考虑将整个图标目录定义为符号。如果您只需要它用于多个目标中的一个,那么您可能更喜欢设置适当的onetarget_CPPFLAGS 变量。

顺便说一句,请注意$(prefix)/icons/hicolor/scalable/apps 是您图标安装目录的非标准选择。这通常会解析为/usr/local/icons/hicolor/scalable/apps 之类的东西。传统的选择是$(datadir)/icons/hicolor/scalable/apps,它将解析为/usr/local/share/icons/hicolor/scalable/apps

【讨论】:

  • 将此标记为正确的完整性。感谢您指出prefixdatadir 之间的区别;我最终将CPPFLAGS = -DDATADIR='"$(datadir)"' @CPPFLAGS@ 添加到我的Makefile.am 并在我的代码中将其引用为DATADIR
  • 最好使用AM_CPPFLAGSyourprogram_CPPFLAGS 而不是CPPFLAGS。构建您的程序的人运行make CPPFLAGS=-Dfoo=bar 进行构建是预期用途并且完全正常,这将覆盖您的CPPFLAGS 定义,因此在没有定义DATADIR 的情况下构建。
【解决方案2】:

在您的 Makefile.am 中,使用以下内容

AM_CPPFLAGS = -DPREFIX='"$(prefix)"'

请参阅 autoconf 手册中的Defining Directories

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-25
    • 2013-11-04
    • 2019-05-16
    相关资源
    最近更新 更多