我正在努力改进Bitfighter长期萎缩的Linux构建过程,并且遇到make问题 . 我的过程实际上非常简单,因为make(几乎)是通用的,所以如果可以的话,我想坚持下去 .
下面我附上了我当前的Makefile,它有效,但很笨拙 . 我正在寻找改进它的方法,并且此时有三个具体问题 .
First ,该项目可以构建多个选项 . 我们来看看这个例子的调试和专用 . 专用选项将排除所有UI代码,并为托管(但不播放)游戏创建更高效的二进制文件 . debug选项向编译器添加一个标志,用于激活调试代码 . 有人可能想要使用这两种选项中的任何一种,两者或两者来构建游戏 .
所以问题是,我该如何做到这一点?正如您在下面的makefile中的注释中所看到的,通过设置DFLAGS = -DTNL_DEBUG来启用调试 . 我想要用户类型
make dedicated debug
而不是
make dedicated DFLAGS=-DTNL_DEBUG
如何重写我的makefile以使其有效?
Secondly ,当我在不同版本的Linux上安装lualibs软件包时,我得到了不同的库 . 例如,在Ubuntu上,当我用apt-get安装lualib包时,我在/ usr / lib文件夹中得到了lua5.1.a . 在Centos上,当我用yum安装相同的东西时,我最终在我的/ usr / lib文件夹中使用liblua.a . 我怎样才能弄清楚哪个库我喜欢用户不必担心Lua安装时的结果,以及makefile的工作原理 .
Finally ,有没有办法让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)
4 回答
Raw
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将在生成_1190349时填写这些变量 .虽然GNU Autotools系统非常完整,并且支持很多平台,但它有点巴洛克式 . 有一些替代构建系统支持一些类似的自动配置行为,如CMake和SCons,如果Autotools感觉太多,可能值得研究 .
对于检测某些库的特定任务,并找到需要链接到它们的选项,可以使用pkg-config;然而,并非所有库都安装了
pkg-config
定义,并且并非所有系统都安装了pkg-config
,因此它不是一个通用的解决方案,但它可以是一种快速简便的方法来构建一些东西而不会过多地混淆选项 . 确实有效 .pkgconfig将回答你的很多问题 .
要检测是否安装了lua,请检查返回值
(如果安装了lua,则应返回0)使用
看看应该在命令行中传递什么来在系统上用lua编译 . (您可能希望将此添加到CFLAGS) .
对于第一个,Make不会帮助你 . 您给它的命令指定目标,而不是选项 . 你会想要使用类似的东西autoconf生成./configure脚本 . 由此,您的用户可以键入./configure --enable-debug --enable-dedicated(或使用--disable- 显式关闭它们) . 只要您的依赖项使用pkg-config(大多数 nix程序执行,不确定freeglut),那么在autoconf中使用PKG_CHECK_MODULES宏来提供友好的错误消息并获取库的正确命令行参数很简单 .
由于您希望使用Windows构建,因此您可能希望使用CMake来生成特定于所用系统和所需配置的Makefile . 输出确实看起来更好,它应该仍然适用于pkg-config .
我将通过推荐CMake开始(我一如既往) . 它将从更高级别的抽象中为您生成makefile . 如果您想构建不同配置的二进制文件,您可以让CMake生成具有不同参数的不同构建树(一个用于"debug",一个用于"dedicated") . 这将为您提供两组独立的Makefile,一组用于构建调试二进制文件,另一组用于构建专用二进制文件,所有这些都来自同一组源 . (CMake现在以二进制形式提供,适用于当今最常用的平台.Linux,Solaris,Windows,OSX等,也可以在许多其他平台上的源代码中构建 . )
CMake也支持检测外部库的存在,尽管我很少使用它 .
如果你想继续使用GMake,我会通过递归调用make来解决“调试与专用”问题,如下所示:
第一点有一条捷径,并不完全令人满意 . 使用:
并在您的makefile中:
它还允许打开其他选项,例如: