【问题标题】:Building my project with make用 make 构建我的项目
【发布时间】:2010-12-30 15:22:36
【问题描述】:

我正在努力改进Bitfighter 的漫长的 Linux 构建过程,但我遇到了 make 问题。我的过程实际上很简单,而且由于 make 是(几乎)通用的,如果可以的话,我想坚持下去。

下面我附上了我当前的 Makefile,它可以工作,但很笨拙。我正在寻找改进方法,目前有三个具体问题。

首先,可以使用多种选项来构建项目。让我们以调试和专用于这个例子。专用选项将排除所有 UI 代码,并为托管(但不玩)游戏创建更有效的二进制文件。 debug 选项将一个标志添加到激活调试代码的编译器。有人可能希望使用这些选项中的一个、两个或一个都不来构建游戏。

所以问题是,我该如何进行这项工作?从下面 makefile 中的 cmets 可以看出,通过设置 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 生成文件 ####################################### # # 配置 # # # 一些安装的 lua 用不同的名字调用 lua 库,而你 # 可能需要覆盖默认的 lua 库路径。对于 ServerHitch # CENTOS 安装,例如,你需要指定 lua 库 # 在 make 命令行上: # LUALIB=/usr/lib/liblua.a # # # 要在启用调试的情况下编译 Bitfighter,请指定 # DFLAGS=-DTNL_DEBUG # 在 make 命令行上 # # # 在 Windows 上使用 make 构建仍然是高度实验性的。你会 # 可能需要添加 # WFLAGS="-DWIN32 -D_STDCALL_SUPPORTED" THREADLIB= 过剩=-lglut32 INPUT=winJoystick.o # 到 make 命令行有任何希望让它工作! :-) # # ####################################### CC=g++ -g -I../tnl -I../glut -I../openal -DTNL_ENABLE_LOGGING 线程库= -lpthread 过剩=-lGL -lGLU -lglut 输入=linuxInput.o 对象_ZAP=\ CTFGame.o\ ...还有很多... BotNavMeshZone.o\ ../master/masterInterface.o\ 标志= DFLAGS= EXEFILE=bitfighter 开放=../openal/linux/libopenal.a LUALIB=-llua5.1 WFLAGS= .co: $(CC) $(DFLAGS) $(WFLAGS) -c $(CFLAGS) $

【问题讨论】:

    标签: c++ linux build-process makefile


    【解决方案1】:

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

    这有点陡峭的学习曲线,但所有这些问题的最常见解决方案是使用GNU autotools 工具链(特别是AutoconfAutomake)。这些工具旨在帮助编写可移植的、可配置的构建系统,可以探测系统中不同位置的库,并根据配置选项和用户系统生成 Makefile。

    如果您曾经运行过./configure; make; make install,那么您可能使用过由 Autoconf 和 A​​utomake 生成的 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,所以它不是一个通用的解决方案,但它可以是一种快速简便的方法来构建一些东西,而不会过多地弄乱它确实有效的情况。

    【讨论】:

    • 我认为对于我的情况,与其深入了解自动工具的复杂性,我将创建一个简单的 bash 脚本来确定要传递的标志。如果我的构建比它更复杂,那么我会接受你的建议。在这一点上,我需要的东西似乎有点矫枉过正。
    【解决方案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 宏来提供友好的错误消息并为库获取正确的命令行参数很简单。

    由于您似乎想使用 Windows 进行构建,因此您可能需要考虑使用 CMake 来生成特定于所用系统和所需配置的 Makefile。输出看起来确实更好,它仍然可以与 pkg-config 一起使用。

    【讨论】:

    • 是的,这将有助于检测想法。但它没有提供构建适当的 makefile 的框架。
    • 很抱歉,如果不清楚,但 autoconf 将使用 PKG_CHECK_MODULES 和相关宏来执行此操作
    【解决方案3】:

    我会从推荐CMake 开始(像往常一样)。它将从更高的抽象级别为您生成生成文件。如果您想构建不同配置的二进制文件,您可以让 CMake 生成具有不同参数的不同构建树(一个用于“调试”,一个用于“专用”)。这将为您提供两组独立的 Makefile,一组用于构建调试二进制文件,另一组用于构建专用二进制文件,它们都来自同一组源。 (CMake 以二进制形式提供给当今最常用的平台。Linux、Solaris、Windows、OSX 等,也可以从许多其他平台上的源代码构建。)

    CMake 还支持检测外部库的存在,尽管我没有使用它的经验。

    如果您想继续使用 GMake,我会通过递归调用 make 来解决“调试与专用”问题,如下所示:

    default: debug
    
    debug:
            $(MAKE) all FLAGS=....
    
    dedicated:
            $(MAKE) all FLAGS=...
    

    【讨论】:

    • 感谢您的建议。这似乎不能很好地处理“专用调试”情况。但是,我会研究 CMake,看看它是否能满足我的需求。
    • CMake 相当灵活;通常有几种方法可以解决此类问题。
    【解决方案4】:

    第一点有个捷径,不完全满意。使用:

    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
    

    【讨论】:

      猜你喜欢
      • 2010-11-16
      • 2019-11-28
      • 1970-01-01
      • 2013-11-23
      • 2013-10-28
      • 1970-01-01
      • 1970-01-01
      • 2021-07-23
      • 2018-11-11
      相关资源
      最近更新 更多