如何使用自动工具在单独的目录中构建 [英] How to build in a separate directory with autotool

查看:100
本文介绍了如何使用自动工具在单独的目录中构建的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的工作目录如下:

./
| ---- HelloWorld/
| ---- | ---- main.cpp
| ---- | ---- Makefile.am
| ----宠物/
| ---- | ---- Pet.h
| ---- | ---- Pet.cpp
| ---- build/
| ---- configure.ac
| ---- Makefile.am

./
|----HelloWorld/
|----|----main.cpp
|----|----Makefile.am
|----Pet/
|----|----Pet.h
|----|----Pet.cpp
|----build/
|----configure.ac
|----Makefile.am

我想使用自动工具来构建makefile,然后在构建目录中构建项目.

I would like to use the autotool to construct makefile and then build the project in the build directory.

./configure.ac

#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.69])
AC_INIT([Hello], [1.0], [qub@oregonstate.edu])
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_CONFIG_FILES([Makefile])
AC_OUTPUT

./Makefile.am

include HelloWorld/Makefile.am

请注意,我正在使用include来确保exe位于make命令运行的目录中.

Note that I'm using the include to make sure the exe locates at the directory where the make command runs.

.//HelloWorld/Makefile.am

AM_CPPFLAGS=-I%D%/../Pet/ -I%D% -I%C%
#VPATH = ./HelloWorld ./Pet

bin_PROGRAMS=hello

hello_SOURCES=%D%/../Pet/Pet.h 
hello_SOURCES+=%D%/../Pet/Pet.cpp 
hello_SOURCES+=%D%/main.cpp

万一有些人想在自己的计算机上尝试,我在这里附加其他源代码: main.cpp

In case some people would like to try on their own computer, I attach other source codes here: main.cpp

#include <stdio.h>
#include <vector>
#include "Pet.h"

int main() {

    printf("Hello World\n");

    std::vector<Pet*> all_pets;

    Pet *dog = new Pet(string("Apple"));
    all_pets.push_back(dog);

    Pet *cat = new Pet(string("Pear"));
    all_pets.push_back(cat);

    for (int i = 0; i < all_pets.size(); i++) {
        all_pets[i]->showName();
    }

    return 0;
}

**Pet.h**

#pragma once
#include <string>
using namespace std;
class Pet
{
    public:
    Pet(string name);
    ~Pet();

    void showName();
    void showIndex();

    string _name;
    int _index;
};

Pet.cpp

#include "Pet.h"

Pet::Pet(string name)
{
    _name = name;
    srand(2345);
    _index = (rand() % 100);
}


Pet::~Pet()
{
}

void Pet::showIndex()
{
    printf("Index is %d\n", _index);
}

void Pet::showName()
{
    printf("Name is %s\n", _name.c_str());
}

问题陈述

  1. 可以通过运行成功创建makefile

./ $autoreconf --install  

  1. 可以使用以下命令在根目录下成功构建项目

./ $./configure   
./ $make  

  1. 在目录./build中构建时出错.命令为:

./build/ $../configure   
./build/ $make 

出现错误,如下图所示:

Got an error as below image shows:

构建错误图片

我认为此错误是由编译器无法成功找到头文件引起的.我的第一个问题是为什么makefile.am中的AM_CPPFLAGS=-I%D%/../Pet/ -I%D% -I%C%无法解决此问题?

I think this error is caused by the compiler cannot successfully find the header files. My first question is Why the AM_CPPFLAGS=-I%D%/../Pet/ -I%D% -I%C% in makefile.am cannot solve this problem?

由于编译器将在构建目录中创建.o文件,从而使构建树具有与源树相同的子目录布局.因此,我可以通过将Pet.h文件复制到\ build \ Pet来解决此问题.但是,这意味着我总是需要将头文件复制到构建目录,这不方便.

Since the compiler will create the .o files in the build directory with making the build tree has the same subdirectory layout as the source tree. So I can fix this problem by copy the Pet.h file to \build\Pet. However, this means I always need to copy the header files to the build directory, which is not convenient.

我找到一些有关 VPATH 的信息.因此,我在./HelloWorld/Makefile.am中注释了#VPATH = ./HelloWorld ./Pet.但是,这会给我带来一个新问题:

I find some info about VPATH. So I commented out #VPATH = ./HelloWorld ./Pet in ./HelloWorld/Makefile.am. However, it will give me a new problem:

自动制作错误图片

我的假设是VPATH设置与include makefile.am有所冲突.我的第二个问题是如何与包含makefile一起正确使用VPATH?

My assumption is the VPATH setting somehow conflicts with the include makefile.am. My second question is How can I use the VPATH correctly with using include makefile?

推荐答案

为什么makefile.am中的AM_CPPFLAGS=-I%D%/../Pet/ -I%D% -I%C%无法解决此问题?

Why the AM_CPPFLAGS=-I%D%/../Pet/ -I%D% -I%C% in makefile.am cannot solve this problem?

因为%D%%C%会生成include d生成文件片段的路径,该片段相对于包含它的生成文件,而不是相对于构建目录.尽管正确使用它们,但它们并不妨碍或不适合处理资源外建筑物.

Because %D% and %C% produce paths to the included makefile fragment relative to the makefile that includes it, not relative to the build directory. They are not intended or suited for handling out-of-source building, though when used correctly, they do not interfere with that.

如何与包含makefile一起正确使用VPATH?

您正在考虑问题. Automake自动支持源外构建.您不需要(也不应该)自己设置VPATH.

You are overthinking the problem. Automake supports out-of-source building automatically. You don't need to (and shouldn't) set up VPATH yourself.

使用Makefile include指令也会给自己带来麻烦.该指令肯定有很好的用途,但是您可以通过将所有内容合并到顶级Makefile.am或通过设置递归make来做得更好.您不需要这些%D%%C%东西.

You are also making trouble for yourself with the Makefile include directive. That directive definitely has good uses, but you would do better here by either consolidating everything into the top-level Makefile.am or by setting up for recursive make. You shouldn't need that %D% and %C% stuff.

Automake将为您设置VPATH,这将在您执行源代码外构建时解决查找先决条件的问题.在大多数情况下,您只需指定相对于Makefile.am和/或configure.ac位置的来源和目标的路径即可.

Automake will set up VPATH for you, and that takes care of locating prerequisites when you perform an out-of-source build. For the most part, you just specify paths to sources and targets relative to the location of your Makefile.am and / or configure.ac.

有时,您确实需要引用源目录,在这种情况下,您应该使用$(srcdir)$(top_srcdir)$(abs_srcdir)$(abs_top_srcdir)中的适当一种,以确保源代码外构建正常工作.

Occasionally you do need to refer to the source directory, and in that case you should use the appropriate one of $(srcdir), $(top_srcdir), $(abs_srcdir), or $(abs_top_srcdir) to ensure that out-of-source builds work correctly.

您的项目布局有点奇怪,但是下列任何一种方法都可以做到:

Your project layout is a bit odd, but either one of these alternatives ought to do it:

Makefile.am

SUBDIRS = HelloWorld

HelloWorld/Makefile.am

# VPATH helps *make* identify prerequisites, but the compiler doesn't know about it.
# We therefore need to give compiler options with real paths.  But we shouldn't need 
# any extra options to support sources that #include headers via (correct) paths expressed
# relative to the sources' own location.
AM_CPPFLAGS = -I$(srcdir)/../Pet

# Note: builds 'hello' in subdirectory HelloWorld/ of the build directory
bin_PROGRAMS = hello

hello_SOURCES =    \
    ../Pet/Pet.h   \
    ../Pet/Pet.cpp \
    main.cpp


非递归

Makefile.am


Non-recursive

Makefile.am

AM_CPPFLAGS = -I$(srcdir)/Pet

# Builds 'hello' directly in the build directory
bin_PROGRAMS = hello

hello_SOURCES = \
    Pet/Pet.h   \
    Pet/Pet.cpp \
    HelloWorld/main.cpp

HelloWorld/Makefile.am

(无)

无论哪种方式,您都可以像尝试执行的那样执行源代码外构建:切换到所需的构建目录,如有必要,请首先创建该目录,然后通过适当的路径从该目录运行configure脚本,然后然后继续make.

Either way, you perform an out-of-source build just as you were trying to do: change to the wanted build directory, creating it first if necessary, run the configure script from there via an appropriate path, and then proceed with make.

$ mkdir build
$ cd build
$ path/to/configure
$ make

这篇关于如何使用自动工具在单独的目录中构建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆