我正在使用c来处理一些针对allegro和使用的代码 autotools来处理构建系统。麻烦是代码正在尝试 拉入位图,我不知道如何正确处理这个问题 使用autotools。
我的项目布局:
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)
当我使用autotools构建和安装时:
# autoreconf --install
# ./configure --prefix=$HOME/usr
# make
# make install
并运行生成的stargate可执行文件所有段错误。破解它 用GDB打开显示失败就在我上面强调的那一行(来自stargate.c),它引入了stargate.bmp。
然而,当我只是去allegro-learning / src并且只是构建 直接没有使用autotools:
# cd allegro-learning/src
# gcc `pkg-config allegro --cflags --libs` -o stargate stargate.c
runnig可执行文件正常。这让我相信我没有使用autotools正确设置项目来安装位图,因此可执行文件可以在安装后找到它们。
这样做的正确方法是什么?
我咨询了Autotools,看起来在使用autotools和java时安装jar是一个类似的问题,你必须安装.jar文件,并且可以让执行代码看到。但是他的例子嵌入了一个让我感到困惑的更大的项目中。
我也看过Data Files With Automake,但我仍然不确定如何修改我的项目,以便生成的可执行文件可以找到位图。事实是,我不确定stargate.bmp是否有资格作为autotools Universe中的“数据文件”。或许有一种不同的方式来处理这种情况?
关于如何处理这种情况的任何具体指导都是 非常感谢。
答案 0 :(得分:2)
在这里回答我自己的问题。在automake mailing lists上进行了一些互动后,我找到了问题的解决方案并进行了以下调整:
到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)
使用autotools构建现在可以正常工作。
答案 1 :(得分:0)
这不是您问题的直接答案,但作为设置数据的已知位置的替代方法,您可能需要考虑将数据简单地编译到可执行文件中,以便不需要查找外部文件
您可以使用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");