我正在开发一个C / C ++项目,我使用GNU Autotools进行构建。我的目录结构如下:
..
adapter/
libraryA/
include/
src/
..
libraryB/
include/
src/
..
..
src/
Log.cpp
..
除了libraryA
和libraryB
之外,我还在顶层有一个库,称之为libraryMain
,它们都使用来自Log.cpp
的{{1}} src
。如果我使用传递给--disable-dependency-tracking
的{{1}}选项构建了非源代码(另请参阅我的帖子here),configure
会抱怨
libtool:link:`Log.lo'不是有效的libtool对象
关联libtool
时,因为libraryMain
在构建Log.lo
和src
时生成了libraryA
,然后由libraryB
引用。如果我从libraryMain
手动删除Log.lo
并重建src
,则一切正常,因为libraryMain
在libraryMain
中生成了自己的Log.lo
。
为了使事情更加清晰,我build/src
Makefile.am
(位于libraryMain
)的内容如下所示:
src
..
libcomana_@COMANA_API_VERSION@_la_SOURCES = \
.. \
Log.cpp
..
的{{1}}(位于Makefile.am
)
libraryA
我已经明白问题是由于adapter/libraryA/src
中的库没有将生成的..
libraryA_la_SOURCES = \
.. \
$(top_srcdir)/src/Log.cpp
..
文件放在他们自己的目录中,而是直接放在项目根目录下的adapter
目录下。我实际上假设没有libtool对象放在源代码树中,而是放在构建树中,就像.lo
一样。作为第一个解决方法,我在src
和libraryMain
中为src/Log.cpp
创建了一个符号链接,但我认为这可能不是很优雅。我真的希望自己足够清楚。我非常感谢对此问题的任何评论。
答案 0 :(得分:1)
好的,我认为我的问题可能有点不清楚。总结一下,我通过省略--disable-dependency-tracking
选项并将我的Makefile.am
更改为不包含前缀为$(srcdir)
或$(top_srcdir)
的任何来源来规避问题,因为这似乎让人感到困惑automake
,至少在构建非源代码时(另请参阅我的帖子here或this错误报告)。虽然我不知道这是否适合这个,我决定设置一个小例子,它可以正常工作并避免我在我的问题中描述的问题。
我的目录结构如下:
autogen.sh
configure.ac
Makefile.am
adapter
Makefile.am
adapterA
Makefile.am
include
foo.h
src
foo.cpp
Makefile.am
adapterB
Makefile.am
include
foo.h
src
foo.cpp
Makefile.am
debug
include
hello.h
m4
src
hello.cpp
helloconf.sh.in
Makefile.am
这些文件包含以下代码:
autogen.sh
:
#!/bin/sh
# GNU autotools toolchain
libtoolize --automake
aclocal
autoheader
automake --add-missing --force-missing --gnu
autoconf
configure.ac
:
dnl Process this file with autoconf to produce a configure script.
dnl Project name and version
AC_INIT([hello], [0.1])
dnl Library version information
AC_SUBST([HELLO_API_VERSION], [0.1])
AC_SUBST([HELLO_SO_VERSION], [0:0:0])
dnl Create a separate header with C preprocessor `#define` statements
AC_CONFIG_HEADERS([config.h])
dnl Look for auxiliary scripts in the current directory
AC_CONFIG_AUX_DIR([.])
dnl Automake initialization
dnl -Wall Show warnings
dnl -Wall Treat warnings as errors
dnl subdir-objects Place generated object files (.o) into the same as
dnl directory their source files, in order to avoid
dnl collisions when non-recursive make is used
AM_INIT_AUTOMAKE([-Wall subdir-objects])
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
dnl Libtool settings
LT_INIT([disable-static])
AC_CONFIG_MACRO_DIR([m4])
dnl Doxygen
dnl DX_HTML_FEATURE(ON)
dnl DX_PDF_FEATURE(OFF)
dnl DX_INIT_DOXYGEN([$PACKAGE_NAME], [Doxyfile], [doc])
dnl Checks for programs
AC_PROG_CXX([g++])
AC_PROG_INSTALL
AC_PROG_LN_S
AM_PROG_LIBTOOL
dnl Use the C++ compiler for the following checks
AC_LANG([C++])
dnl Checks for libraries
dnl Checks for header files
AC_HEADER_STDC
AC_CHECK_HEADER(iostream)
dnl Checks for typedefs, structures, and compiler characteristics
AC_TYPE_SIZE_T
dnl Checks for library functions
dnl Compiler and linker flags
AC_SUBST([AM_CXXFLAGS], [-Wall]) # C++
AC_SUBST([AM_LDFLAGS], [-Wall]) # ld (Linker)
dnl Libraries
AC_SUBST([LIBS])
AC_CONFIG_FILES(
Makefile
adapter/Makefile
adapter/adapterA/Makefile
adapter/adapterA/src/Makefile
adapter/adapterB/Makefile
adapter/adapterB/src/Makefile
src/Makefile
src/helloconf.sh
)
AC_OUTPUT
Makefile.am
:
# Process this file with automake to produce Makefile.in
# Independent executable script for inclusion in the distribution archive
dist_noinst_SCRIPTS = autogen.sh
# Look for additional autoconf macros in the m4 subdirectory
ACLOCAL_AMFLAGS = \
-I m4 \
@ACLOCAL_FLAGS@
# Subdirectories
SUBDIRS = \
adapter \
src
# Entire directories copied recursively into the distribution
EXTRA_DIST =
# Delete anything except for files required to run `./configure && make`
MAINTAINERCLEANFILES =
# Delete anything which should not be part of the distribution
DISTCLEANFILES =
adapter/Makefile.am
:
# Process this file with automake to produce Makefile.in
SUBDIRS = \
adapterA \
adapterB
adapter/adapterA/Makefile.am
:
# Process this file with automake to produce Makefile.in
SUBDIRS = src
adapter/adapterA/include/foo.h
:
#ifndef FOO_H_
#define FOO_H_
void foo();
#endif
adapter/adapterA/src/foo.cpp
:
#include <iostream>
#include "foo.h"
void foo()
{
std::cout << "Hello, foo from adapterA" << std::endl;
}
adapter/adapterA/src/Makefile.am
:
# Process this file with automake to produce Makefile.in
# Adapter .so version
ADAPTER_SO_VERSION = 0:0:0
AM_CXXFLAGS = \
-I$(top_srcdir)/include \
-I$(srcdir)/../include \
@AM_CXXFLAGS@
# Library name
lib_LTLIBRARIES = libadapter-@HELLO_API_VERSION@.la
# Sources
libadapter_@HELLO_API_VERSION@_la_SOURCES = \
../../../src/hello.cpp \
foo.cpp
# Linker flags
libadapter_@HELLO_API_VERSION@_la_LDFLAGS = \
-version-info $(ADAPTER_SO_VERSION)
# Include directory and headers
libadapter_@HELLO_API_VERSION@_la_includedir = \
$(exec_prefix)/include/adapter/adapterA
libadapter_@HELLO_API_VERSION@_la_include_HEADERS = \
../include/foo.h
# Library install directory
libdir = $(exec_prefix)/lib/adapter/adapterA
adapter/adapterB/Makefile.am
和adapter/adapterB/include/foo.h
与他们的A
等价物相同。
adapter/adapterB/src/foo.cpp
:
#include <iostream>
#include "foo.h"
void foo()
{
std::cout << "Hello, foo from adapterB" << std::endl;
}
adapter/adapterB/src/Makefile.am
:
# Process this file with automake to produce Makefile.in
# Adapter .so version
ADAPTER_SO_VERSION = 0:0:0
AM_CXXFLAGS = \
-I$(top_srcdir)/include \
-I$(srcdir)/../include \
@AM_CXXFLAGS@
# Library name
lib_LTLIBRARIES = libadapter-@HELLO_API_VERSION@.la
# Sources
libadapter_@HELLO_API_VERSION@_la_SOURCES = \
../../../src/hello.cpp \
foo.cpp
# Linker flags
libadapter_@HELLO_API_VERSION@_la_LDFLAGS = \
-version-info $(ADAPTER_SO_VERSION)
# Include directory and headers
libadapter_@HELLO_API_VERSION@_la_includedir = \
$(exec_prefix)/include/adapter/adapterB
libadapter_@HELLO_API_VERSION@_la_include_HEADERS = \
../include/foo.h
# Library install directory
libdir = $(exec_prefix)/lib/adapter/adapterB
include/hello.h
:
#ifndef HELLO_H_
#define HELLO_H_
void hello();
#endif
src/hello.cpp
:
#include <iostream>
#include "hello.h"
void hello()
{
std::cout << "Hello, world!" << std::endl;
}
src/helloconf.sh.in
:
#!/bin/bash
echo @prefix@
src/Makefile.am
:
# Process this file with automake to produce Makefile.in
# Look for additional autoconf macros in the m4 subdirectory
ACLOCAL_AMFLAGS = \
-I m4 \
@ACLOCAL_FLAGS@
# Compiler flags
AM_CXXFLAGS = \
-I$(top_srcdir)/include \
@AM_CXXFLAGS@
# Library name
lib_LTLIBRARIES = libhello-@HELLO_API_VERSION@.la
# Sources
libhello_@HELLO_API_VERSION@_la_SOURCES = \
hello.cpp
# Libraries
libhello_@HELLO_API_VERSION@_la_LDFLAGS = \
-version-info $(HELLO_SO_VERSION)
libhello_@HELLO_API_VERSION@_la_LIBADD = @LTLIBOBJS@
# Include directory and headers
libhello_@HELLO_API_VERSION@_la_includedir = $(includedir)
libhello_@HELLO_API_VERSION@_la_include_HEADERS = \
$(top_srcdir)/include/hello.h
# Data
helloconf_DATA = helloconf.sh
helloconfdir = $(exec_prefix)/bin
EXTRA_DIST = $(helloconf_DATA)
P.S。:我知道上传档案可能更好,但我想将所有内容保存在一个地方。