我正在努力改进Bitfighter长期萎缩的Linux构建过程,并且遇到make问题。我的过程实际上非常简单,因为make(几乎)是通用的,所以如果可以的话,我想坚持下去。
下面我附上了我当前的Makefile,它有效,但很笨拙。我正在寻找改进方法,目前有三个具体问题。
首先,可以使用多个选项构建项目。我们来看看这个例子的调试和专用。专用选项将排除所有UI代码,并为托管(但不播放)游戏创建更高效的二进制文件。 debug选项向编译器添加一个标志,用于激活调试代码。人们可能想要用这两种选择中的任何一种,两者或两种都不构建游戏。
所以问题是,我该如何做到这一点?正如您在下面的makefile中的注释中所看到的,通过设置DFLAGS = -DTNL_DEBUG来启用调试。我想要用户输入
make dedicated debug
而不是
make dedicated DFLAGS=-DTNL_DEBUG
如何重写我的makefile以使其有效?
其次,当我在不同版本的Linux上安装lualibs软件包时,我得到了不同的库。例如,在Ubuntu上,当我使用apt-get安装lualib包时,我在/ usr / lib文件夹中得到 lua5.1.a 。在Centos上,当我用yum安装相同的东西时,我最终在/ usr / lib文件夹中使用 liblua.a 。我怎样才能弄清楚我得到了哪个库,并将其链接到?显然,-l指令对此不够智能。我希望用户不必担心Lua在安装时会在哪里结束,并且makefile只能正常工作。
最后,有没有办法让make检测是否还没有安装某些必需的软件包(例如freeglut),并自动安装它们或者至少提醒用户注意这个事实他们需要安装它们(而不是简单地用一个神秘的错误信息终止)?
谢谢!
这是我的Makefile。
# Bitfighter Makefile ####################################### # # Configuration # # # Some installs of lua call the lua library by different names, and you # may need to override the default lua library path. For the ServerHitch # CENTOS installs, for example, you will need to specify the lua library # on the make command line: # LUALIB=/usr/lib/liblua.a # # # To compile Bitfighter with debugging enabled, specify # DFLAGS=-DTNL_DEBUG # on the make command line # # # Building with make on Windows is still highly experimental. You will # probably need to add # WFLAGS="-DWIN32 -D_STDCALL_SUPPORTED" THREADLIB= GLUT=-lglut32 INPUT=winJoystick.o # to the make command line to have any hope of getting it to work! :-) # # ####################################### CC=g++ -g -I../tnl -I../glut -I../openal -DTNL_ENABLE_LOGGING THREADLIB= -lpthread GLUT=-lGL -lGLU -lglut INPUT=linuxInput.o OBJECTS_ZAP=\ CTFGame.o\ ...many more... BotNavMeshZone.o\ ../master/masterInterface.o\ CFLAGS= DFLAGS= EXEFILE=bitfighter OPENAL=../openal/linux/libopenal.a LUALIB=-llua5.1 WFLAGS= .c.o: $(CC) $(DFLAGS) $(WFLAGS) -c $(CFLAGS) $< .cpp.o : $(CC) $(DFLAGS) $(WFLAGS) -c $(CFLAGS) $< default: ../exe/bitfighter bitfighter: ../exe/bitfighter dedicated: CFLAGS=-DZAP_DEDICATED dedicated: GLUT= dedicated: OPENAL= dedicated: EXEFILE=bitfighterd dedicated: ../exe/bitfighter ../exe/bitfighter: $(OBJECTS_ZAP) $(CC) -o ../exe/$(EXEFILE) $(OBJECTS_ZAP) ../tnl/libtnl.a \ ../libtomcrypt/libtomcrypt.a \ $(OPENAL) $(GLUT) $(THREADLIB) $(LUALIB) -lstdc++ -lm ../master/masterInterface.o: make -C ../master clean: rm -f $(OBJECTS_ZAP) ../exe/bitfighter ../exe/bitfightered cleano: rm -f $(OBJECTS_ZAP)
答案 0 :(得分:4)
原始make
并不真正支持任何这些用途。 make
认为在命令行上传入的目标是要构建的不同程序,或者要采取不同的操作,并且它没有使用传入的两个目标来为单个构建切换独立选项的概念。 make
也没有任何内置支持来检查已安装软件包的版本。
这是一个陡峭的学习曲线,但所有这些问题的最常见解决方案是使用GNU autotools工具链(Autoconf和Automake,具体而言)。编写这些工具是为了帮助编写可移植的可配置构建系统,可以在不同位置探测系统库,并根据配置选项和用户系统生成Makefile。
如果您曾经运行./configure; make; make install
,则可能使用了使用Autoconf和Automake生成的configure
脚本。
Wikipedia article提供了一些概述,Automake manual提供了介绍工具链的教程。
对于您的使用,您可能想要做的是使用Autoconf创建configure
,其中包含--enable-debug
和--enable-dedicated
等选项,以设置生成Makefile的选项。然后,您可以将Makefile移植到Automake,或者只需将Makefile转换为Makefile.in
,其中包含一些变量,Autoconf会在生成Makefile
时填写这些变量。
虽然GNU Autotools系统非常完整,并且支持很多平台,但它有点巴洛克式。有一些替代构建系统支持一些类似的自动配置行为,如CMake和SCons,如果Autotools感觉太多,可能值得研究。
对于检测某些库的特定任务,并找到需要链接到它们的选项,可以使用pkg-config
;但是,并非所有库都安装了pkg-config
定义,并且并非所有系统都安装了pkg-config
,因此它不是一个通用的解决方案,但它可以是一种快速简便的方法,可以在没有太多混乱的情况下进行构建在其可行的情况下使用选项。
答案 1 :(得分:2)
pkgconfig会回答你的很多问题。
要检测是否安装了lua,请检查
的返回值pkg-config --exists lua
(如果安装了lua,则应返回0)使用
pkg-config --cflags --libs lua
查看在命令行中应该传递什么以在系统上使用lua进行编译。 (你可能想把它添加到CFLAGS)。
首先,Make不会帮助你。您给它的命令指定目标,而不是选项。您将希望使用类似autoconf的内容来生成./configure脚本。由此,您的用户可以键入./configure --enable-debug --enable-dedicated(或使用--disable- *显式关闭它们)。只要您的依赖项使用pkg-config(大多数* nix程序执行,不确定freeglut),那么在autoconf中使用PKG_CHECK_MODULES宏来提供友好的错误消息并获取库的正确命令行参数很简单。 / p>
由于您希望使用Windows构建,因此您可能希望使用CMake来生成特定于所用系统和所需配置的Makefile。输出确实看起来更好,它应该仍然适用于pkg-config。
答案 2 :(得分:0)
我将通过推荐CMake开始(我一如既往)。它将从更高级别的抽象中为您生成makefile。如果你想构建不同配置的二进制文件,你可以让CMake生成具有不同参数的不同构建树(一个用于“debug”,一个用于“dedicated”)。这将为您提供两组独立的Makefile,一组用于构建调试二进制文件,另一组用于构建专用二进制文件,所有这些都来自同一组源。 (CMake现在以二进制形式提供,适用于当今最常用的平台.Linux,Solaris,Windows,OSX等,也可以在许多其他平台上的源代码构建。)
CMake也支持检测外部库的存在,尽管我很少使用它。
如果你想继续使用GMake,我会通过递归调用make来解决“调试与专用”问题,如下所示:
default: debug
debug:
$(MAKE) all FLAGS=....
dedicated:
$(MAKE) all FLAGS=...
答案 3 :(得分:0)
第一点有一条捷径,并不完全令人满意。使用:
make dedicated DEBUG=1
并在您的makefile中:
ifdef DEBUG
DFLAGS += -DTNL_DEBUG
endif
它还允许打开其他选项,例如:
ifdef DEBUG
# Turn on gdb symbols
CFLAGS += -ggdb3
# Pass a specific DEBUG level to your code
CFLAGS += -DDEBUG=$(DEBUG)
# And so on
endif