繁体   English   中英

如何使用自动工具设置项目,以便生成的可执行文件可以查看所需的二进制文件?

[英]How do I setup a project with autotools so resulting executables can see required binary files?

我正在使用c来针对allegro进行一些代码构建,并使用自动工具来处理构建系统。 问题是代码试图插入位图,我不确定使用自动工具时如何正确处理此位图。

我的项目的布局:

allegro-learning/
    Makefile.am
    README
    configure.ac
    src/
        stargate.c
        stargate.bmp

stargate.c中的代码通过以下方式插入位图:

stargate = load_bitmap("stargate.bmp", NULL);

allegro-learning / configure.ac的内容:

AC_PREREQ([2.69])
AC_INIT([allegro-learning], [1.0], [itsjustme@gmail.com])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_CONFIG_SRCDIR([config.h.in])
AC_CONFIG_HEADERS([config.h])
AC_PROG_CC
AM_PROG_CC_C_O
PKG_CHECK_MODULES([ALLEGRO], [allegro >= 4.2.3])
AC_CHECK_HEADERS([stdio.h])
AC_CONFIG_FILES([Makefile
                 src/Makefile])
AC_OUTPUT

allegro-learning / Makefile.am的内容:

SUBDIRS = src
dist_doc_DATA = README

allegro-learning / src / Makefile.am的内容:

bin_PROGRAMS = stargate

stargate_SOURCES = stargate.c
stargate_CFLAGS = $(ALLEGRO_CFLAGS) 
stargate_LDFLAGS = $(ALLEGRO_LIBS) 

当我使用自动工具来构建和安装时:

# autoreconf --install
# ./configure --prefix=$HOME/usr
# make
# make install

并运行生成的stargate可执行文件一切段错误。 使用GDB将其打开显示失败是在上面我突出显示的那一行(来自stargate.c)中,它拉入了stargate.bmp。

但是,当我进入allegro-learning / src并仅使用自动工具直接构建时:

# cd allegro-learning/src
# gcc `pkg-config allegro --cflags --libs` -o stargate stargate.c

runnig可执行文件正常工作。 这使我相信我没有使用自动工具正确设置项目来安装位图,因此可执行文件可以在安装后找到它们。

什么是正确的方法?

我已经咨询过Autotools ,当将autotools与java一起使用时,看起来好像安装jar也是一个类似的问题,其中您还具有必须安装的.jar文件,并且可供执行代码查看。 但是他的例子被嵌入到一个更大的项目中,这令我感到困惑。

我也查看了带有Automake的数据文件,但是仍然不确定如何修改项目,以便生成的可执行文件可以找到位图。 事实是,我不确定stargate.bmp是否在自动工具领域中符合“数据文件”的资格。 也许有一种完全不同的方式来处理这种情况?

对于如何处理这种情况的任何具体指导,将不胜感激。

在这里回答我自己的问题。 在自动制作邮件列表上进行了一些交互之后,我找到了问题的解决方案并进行了以下调整:

到allegro-learning / src / Makefile.am:

stargatedir = $(datadir)/stargate
stargate_DATA = stargate.bmp
stargate_SOURCES = stargate.c
stargate_CFLAGS = $(ALLEGRO_CFLAGS) -DPKGDATADIR=\"$(stargatedir)\"
stargate_LDFLAGS = $(ALLEGRO_LIBS) 

为了添加stargate.c,我添加了以下内容:

#include <stdio.h>

// for nice string concatenation:
#define Sasprintf(write_to,  ...) {           \
    char *tmp_string_for_extend = (write_to); \
    asprintf(&(write_to), __VA_ARGS__);       \
    free(tmp_string_for_extend);              \
}

char* addImageBaseDir(char* filename) {
  char *abspath = NULL;
  Sasprintf(abspath, PKGDATADIR);
  Sasprintf(abspath, "%s%s%s", abspath, "/", "stargate.bmp");
  return abspath;
}

现在我替换原来的

stargate = load_bitmap("stargate.bmp", NULL);

用,

stargate = load_bitmap(addImageBaseDir("stargate.bmp"), NULL)

现在使用自动工具构建就可以了。

这不是您问题的直接答案,但是作为设置数据已知位置的替代方法,您可能需要考虑将数据编译到可执行文件中,这样就无需查找任何外部文件。

您可以使用objcopy -I binary -O elf64-x86-64 -B i386 stargate.bmp stargate.o来执行此操作,以生成包含stargate.bmp数据的目标文件(如果需要,必须适当调整输出体系结构当然需要便携性)。 然后,如果将那些目标文件链接到可执行文件中,则符号_binary_stargate_bmp_start_binary_stargate_bmp_end将可用于指出数据的开始和结束,并可以将其传递给图像加载函数。 例如,您可以使用以下数据生成FILE *

extern char _binary_stargate_bmp_start, _binary_stargate_bmp_end;
FILE *imgstream = fmemopen(&_binary_stargate_bmp_start, &_binary_stargate_bmp_end - &_binary_stargate_bmp_start, "r");

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM