使用make构建我的项目

时间:2009-12-28 23:52:15

标签: c++ linux build-process makefile

我正在努力改进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)

4 个答案:

答案 0 :(得分:4)

原始make并不真正支持任何这些用途。 make认为在命令行上传入的目标是要构建的不同程序,或者要采取不同的操作,并且它没有使用传入的两个目标来为单个构建切换独立选项的概念。 make也没有任何内置支持来检查已安装软件包的版本。

这是一个陡峭的学习曲线,但所有这些问题的最常见解决方案是使用GNU autotools工具链(AutoconfAutomake,具体而言)。编写这些工具是为了帮助编写可移植的可配置构建系统,可以在不同位置探测系统库,并根据配置选项和用户系统生成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系统非常完整,并且支持很多平台,但它有点巴洛克式。有一些替代构建系统支持一些类似的自动配置行为,如CMakeSCons,如果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