如何将自动制作文件写入递归构建子目录?

问题描述 投票:-1回答:1

我的工作目录如以下树所示:

./  
|--HelloWorld/  
|--|--main.cpp  
|--|--Dog/   
|--|--|--Dog.h  
|--|--|--Dog.cpp    
|--Pet/  
|--|--Pet.h  
|--|--Pet.cpp  
|--build/  

main.cpp包括dog.hpet.h。 Dog是Pet的继承类,因此Dog.h也包括Pet.h。我知道这是一种组织代码的有线方式,但是我很好奇如何为每个子目录创建makefile.am文件,以便自动工具可以在构建目录中构建项目。

请注意,我想拥有一些其他功能:

  1. 是否可以在build目录而不是build/HelloWorld/目录中构建hello.exe?为此,我是否必须将bin_PROGRAMS放在./Makefile.am
  2. 我不想将Pet构建为库,我想知道是否有一种方法可以告诉automake在不同位置查找源代码。
  3. 我知道使用非递归的makefile会更容易。但是我只想学习如何为多个目录创建递归Makefile。

我尝试过的是:

configure.ac

AC_PREREQ([2.69])
AC_INIT([Hello], [1.0], [[email protected]])
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
AC_CONFIG_SRCDIR([HelloWorld/main.cpp])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CXX
AC_PROG_CC
#AC_PROG_CPP

AC_CONFIG_FILES([Makefile
                 HelloWorld/Makefile
                 Pet/Makefile
                 HelloWorld/Dog/Makefile])
AC_OUTPUT

Makefile.am

SUBDIRS = HelloWorld Pet

HelloWorld / Makefile.am

AM_CPPFLAGS=-I$(srcdir)/../Pet -I$(srcdir)/Dog 
SUBDIRS = Dog
bin_PROGRAMS=hello 
hello_SOURCES = main.cpp

Pet / Makefile.am

hello_SOURCES = Pet.h Pet.cpp

HelloWorld / Dog / Makefile.am

AM_CPPFLAGS=-I$(srcdir)/../../Pet

hello_SOURCES = Dog.h Dog.cpp 

我刚刚开始学习自动制作东西,并且我知道这些代码根本不起作用。

有人可以帮我修复它们吗?谢谢。

linux autotools autoconf automake
1个回答
0
投票

您说您有兴趣

如何为每个子目录创建makefile.am文件,以便自动工具可以在构建目录中构建项目

,但这不是一个适当的目标,如本示例本身所示。没有定义任何要构建的目标的Makefile.am很少有用或不合适。您已规定您不想将Pet建为库,那么Makefile.am在其目录中将定义什么目标?如果要避免将其构建为库,则类似的内容适用于Dog。在这种情况下,使用递归make几乎没有意义。

但是,我注意到Automake的概念是“便利库”,它是一个中间目标,它从未安装过,但包含可以链接到可执行文件或更大库中的目标代码。我将在稍后进行演示,因为在这种特殊情况下,这是设置所需的每个目录的makefile的最明智的方法。

此外,关于将输出定向到源树中的特定目录:可以这样做,但是可能很浪费精力。 Autotools已经为源外构建提供了一种方便的方法,如果构建项目的人员希望这样做,则可以更轻松地实现将构建结果与源分离的目标。

NEVERTHELESSthe basics of recursive builds with the Autotools非常简单。有两件事要做:

  • 每个Makefile.am要表示一个或多个子目录的递归,是通过在变量SUBDIRS中列出每个子目录的相对路径来实现的。

  • 项目configure.ac必须通过其Makefile宏指定要构建的AC_CONFIG_FILES

这是一般设置递归所需要做的,并且有关如何设置特定目标和选项的详细信息是特定于项目的。

  1. 是否可以在build目录而不是build/HelloWorld/目录中构建hello.exe?为此,我必须放bin_PROGRAMS处的./Makefile.am

是,您可以将建筑物指定为build/hello,而不是build/HelloWorld/hello。您可能没有严格地have将相应的bin_PROGRAMS放入顶层Makefile.am,但您肯定应该将其放置在build/Makefile.am文件中。我敦促您避免尝试使任何makefile构建目标都植根于该特定makefile所在目录的树之外。

  1. 我不想将Pet构建为库,我想知道是否有一种方法可以告诉automake在其中查找源代码。不同的位置。

您可以绝对地在Makefile.am之外的其他目录中指定源文件。只需提供相对于makefile目录的适当路径即可。对于与makefile相同的树中的源,这更有意义,但是使用其他位置的源并不像尝试在其他位置构建目标那样重要。

  1. 我知道使用非递归的makefile会更容易。但是我只想学习如何为多个创建递归makefile目录。

非递归的makefile不一定比递归的makefile容易,但是它们通常更好,因为它们将整个目标/先决条件树表示为一个单元,而不是将其切成碎片。 make一次拥有所有信息时,可以做出更好的构建决策。

我刚刚开始学习自动制作东西,而且我知道这些代码并不完全可以。

我对your related question的回答为相关问题提供了递归解决方案。它展示了您似乎缺少的关键原则之一:指定目标源和其他构建属性的变量需要出现在定义目标本身的同一Makefile.am文件中。每个Makefile.am对应一个单独的makefile。初步估计,makefile之间不会共享数据,因此构建给定目标所需的所有信息都必须显示在同一文件中。

似乎使这个问题与您的另一个问题区分开的另一件事是,您想要(但是错误地)指定了特定的输出目录在您的makefile中。请记住,无论最初生成的文件在哪里,它都是一个暂存区域–没什么大不了的,因为它们在make install之前被放置到最终目标位置。即使这样,您也可以通过提供正确的相对路径来指定驻留在其他目录中的目标。当然,对目标名称的这种更改需要反映在the names of the variables derived from the target name中。

那么,这是一个递归Automake设置,应该在每个源目录中使用一个makefile来构建示例项目:


Makefile.am

SUBDIRS = Pet HelloWorld

# Note: specifying output into a different directory
bin_PROGRAMS = build/hello

# Note the form of the following names:
build_hello_SOURCES = HelloWorld/main.cpp
build_hello_CPPFLAGS = -I$(srcdir)/Pet -I$(srcdir)/HelloWorld/Dog
# Note that library order matters
build_hello_LDADD = HelloWorld/Dog/libDog.a Pet/libPet.a

Pet / Makefile.am

noinst_LIBRARIES = libPet.a

libPet_a_SOURCES = \
    Pet.cpp        \
    Pet.h

HelloWorld / Makefile.am

SUBDIRS = Dog

# No own targets defined here, just the recursion into Dog.  This could have been
# skipped altogether, but I'm sticking to the letter of one Makefile.am per source
# directory.

HelloWorld / Dog / Makefile.am

noinst_LIBRARIES = libDog.a

libDog_a_SOURCES = \
  Dog.cpp          \
  Dog.h
libDog_a_CPPFLAGS = -I$(top_srcdir)/Pet

您的configure.ac应该按原样使用。

注意,这不依赖于VPATH;它将specifically构建到构建树的build/子目录中,包括直接在源代码树中构建时的情况。

© www.soinside.com 2019 - 2024. All rights reserved.