Как встроить отдельный каталог с помощью автоинструмента - PullRequest
0 голосов
/ 12 октября 2019

У меня есть рабочий каталог, как показано ниже:

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

Я хотел бы использовать автоинструмент для созданияmakefile, а затем соберите проект в каталоге сборки.

. / 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 is

include HelloWorld/Makefile.am

Обратите внимание, что я использую include, чтобы убедиться, что исполняемый файл находится в каталоге, где выполняется команда make.

. / HelloWorld / Makefile. am is

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

#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. Может успешно создать make-файл при запуске
./ $autoreconf --install  
Может успешно построить проект в корневом каталоге с помощью следующих команд
./ $./configure   
./ $make  
Получить ошибку при сборке в директории ./build. Команды:
./build/ $../configure   
./build/ $make 

Получена ошибка, как показано на рисунке ниже:

Изображение ошибки сборки

Я думаю, что эта ошибка вызванаКомпилятор не может успешно найти заголовочные файлы. Мой первый вопрос Почему AM_CPPFLAGS=-I%D%/../Pet/ -I%D% -I%C% в makefile.am не может решить эту проблему?

Поскольку компилятор создает файлы .o в каталоге компоновки, при этом дерево компоновки имеетта же схема подкаталога, что и у исходного дерева. Так что я могу решить эту проблему, скопировав файл Pet.h в \ build \ Pet. Однако это означает, что мне всегда нужно копировать файлы заголовков в каталог сборки, что не удобно.

Я нахожу некоторую информацию о VPATH . Поэтому я прокомментировал #VPATH = ./HelloWorld ./Pet in ./HelloWorld/Makefile.am. Тем не менее, это вызовет у меня новую проблему:

ошибка с изображением automake

Я предполагаю, что настройка VPATH каким-то образом конфликтует с файлом make make.am. Мой второй вопрос Как правильно использовать VPATH с использованием include makefile?

Ответы [ 2 ]

0 голосов
/ 12 октября 2019

Почему AM_CPPFLAGS=-I%D%/../Pet/ -I%D% -I%C% в makefile.am не может решить эту проблему?

Поскольку %D% и %C% создают пути к included фрагмент makefile относительно make-файла, который включает его , а не относительно каталога build. Они не предназначены или не подходят для обработки сборки вне источника, хотя при правильном использовании они не мешают этому.

Как правильно использовать VPATH с использованием include makefile?

Вы задумывались над проблемой. Automake поддерживает автоматическое построение. Вам не нужно (и не следует) настраивать VPATH самостоятельно.

Вы также создаете проблемы для себя с директивой Makefile include. Эта директива, безусловно, имеет хорошее применение, но вы бы добились большего успеха, либо консолидировав все в верхний уровень Makefile.am, либо настроив рекурсивный make. Вам не нужны эти вещи %D% и %C%.

Automake настроит для вас VPATH, и он позаботится о поиске необходимых условий при выполнении сборки из источника. По большей части вы просто указываете пути к источникам и целям относительно местоположения вашего Makefile.am и / или configure.ac.

Иногда вам нужно обратиться к исходному каталогу, и в этом случаевы должны использовать соответствующий из $(srcdir), $(top_srcdir), $(abs_srcdir) или $(abs_top_srcdir), чтобы убедиться, что сборки из исходного кода работают правильно.

Макет вашего проекта немного странный, нолюбая из этих альтернатив должна сделать это:


Рекурсивный

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

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.

$ mkdir build
$ cd build
$ path/to/configure
$ make
0 голосов
/ 12 октября 2019

Я случайно решил проблему, изменив ./HelloWorld/Makefile.am на

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

bin_PROGRAMS=hello

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

Обратите внимание, что путь к hello_SOURCES изменен, а путь к заголовку отличается от пути к исходному. Но почему это решило бы проблему?

...