如何正确使用带有子目录的 automake/autoconf?

Posted

技术标签:

【中文标题】如何正确使用带有子目录的 automake/autoconf?【英文标题】:How to use automake/autoconf with subdirectories properly? 【发布时间】:2020-12-13 01:55:35 【问题描述】:

我希望将 automake 用于具有很多子目录的项目。我想要实现的是将所有子目录中的所有源代码编译成一个Linux上的可执行文件。

现在我正在使用子目录对象,我必须手动指定整个层次结构的每个源代码文件的路径。

我曾尝试对每个子目录使用 LTLIBRARIES 方法,使用 Makefile.am,但由于某种原因,程序无法编译并给我很多未定义的引用错误。

现在我的 Makefile.am 文件如下所示:

AUTOMAKE_OPTIONS = subdir-objects
bin_PROGRAMS = a.out
a_out_SOURCES = EntryPoint.cpp ./glad/src/glad.cpp ./ImageLoader/ImageLoader.cpp ./FileIO/FileIO.cpp ./Debug/DebugLog.cpp ./Object/Object.cpp \
./Texture/Texture.cpp ./Window/Window.cpp ./Shader/Shader.cpp
include_HEADERS = ./glad/include/glad/glad.h ./ImageLoader/stb_image.h ./FileIO/FileIO.h ./Debug/DebugLog.h ./Object/Object.h \
./Texture/Texture.h ./Window/Window.h ./Shader/Shader.h
a_out_LDADD = -lGLEW -lGL -lsfml-graphics -lsfml-window -lsfml-system -ldl -lglfw -lm

有没有更好的方法来做到这一点?

【问题讨论】:

【参考方案1】:

现在我正在使用必须手动指定的子目录对象 整个层次结构的每个源代码文件的路径。

在任何情况下,您都必须在某处单独指定每个源文件。

我曾尝试对每个使用 Makefile.am 的 LTLIBRARIES 方法 子目录,但由于某种原因程序无法编译 并给了我很多未定义的参考错误。

我认为您正在谈论为每个子目录构建一个实用程序库。您没有提供与此尝试相对应的 Makefile.am 文件,但您描述的未定义引用的最可能原因之一是您未能在链接中包含所有实用程序库(通过在适当的位置列出它们在a_out_LDADD)。

实用程序库方法最有意义

    您的构建系统是递归的,或者 您希望从同一来源构建多个目标。

对于问题中提出的Makefile.am,这些都不正确。它可以转换为递归,但每个子目录中的源代码很少,这对我来说似乎不值得。结果会更复杂,而不是更少,而且还会因为*** make 没有完整的依赖树可使用的问题而遭受严重痛苦。

有没有更好的方法来做到这一点?

提供的Makefile.am 类似于我将用于描述的源布局。我所做的改变主要是风格上的:

AUTOMAKE_OPTIONS = subdir-objects

bin_PROGRAMS = a.out

a_out_SOURCES = \
  EntryPoint.cpp \
  Debug/DebugLog.cpp \
  Debug/DebugLog.h \
  FileIO/FileIO.cpp \
  FileIO/FileIO.h \
  glad/src/glad.cpp \
  glad/include/glad/glad.h \
  ImageLoader/ImageLoader.cpp \
  ImageLoader/stb_image.h \
  Object/Object.cpp \
  Object/Object.h \
  Shader/Shader.cpp \
  Shader/Shader.h \
  Texture/Texture.cpp \
  Texture/Texture.h \
  Window/Window.cpp \
  Window/Window.h
a_out_LDADD = -lGLEW -lGL -lsfml-graphics -lsfml-window -lsfml-system -ldl -lglfw -lm

其中一个语义变化是将标头从include_HEADERS 移动到a_out_SOURCES。从技术上讲,它们并不需要专门列在程序源中,但这是可行的,而且它们确实需要列在某个地方,以免它们从发行版中被忽略。但是,它们不应该列在HEADERS 主目录中,因为这将导致它们被make install 安装到系统中,而且这只对库的公共头文件有意义。

不太重要的是,将每个文件单独列出一行并对这些行进行排序,包括将标题放在相应的源旁边,使源列表更易于检查和维护。从路径中省略不必要的前导 ./ 有助于使这些条目更易于阅读,至少对我而言,但当前目录源和子目录源之间的区别是通过首先列出所有当前目录源来保持的。

【讨论】:

以上是关于如何正确使用带有子目录的 automake/autoconf?的主要内容,如果未能解决你的问题,请参考以下文章

LUA:如何正确读取带有重音字母和变音符号的 UFT8 文件名和路径?

如何在Go中递归列出带有频道的文件?

如何正确使用 addResourcePath?

如何正确使用带有 typescript 的 createAsyncThunk 函数?

如何正确使用带有 Ajax Begin 表单的局部视图

如何正确使用带有本地标识符的获取资产?