c++ 程序 (.cpp) 如何与 header(.h) 和 libtool (.la) 一起工作?
Posted
技术标签:
【中文标题】c++ 程序 (.cpp) 如何与 header(.h) 和 libtool (.la) 一起工作?【英文标题】:How a c++ program (.cpp) work with header(.h) and libtool (.la)? 【发布时间】:2020-02-13 10:13:21 【问题描述】:我在 linux 中创建了一个名为 helloworld 的文件夹。 这个文件夹里面有子目录:
包括 库 源代码包括/ 在这个目录中,我创建了一个名为 helloworld.h 的头文件 内容是:
class helloworld
public:
void getvalue();
;
lib/ 在 lib 目录中,我创建了一个名为 helloworld.cpp 的 cpp 文件 内容主要是功能:
#include<iostream>
#include<helloworld.h>
using namespace std;
void helloworld::getvalue()
src/ 在 src 目录中,我创建了一个名为 main.cpp 的主 cpp 文件 内容是主要的:
#include<iostream>
#include<helloworld.h>
int main()
helloworld a;
a.getvalue();
但在我使用 autoconf、automake、./configure 和 make 之后 它有一个错误:
helloworld/src/main.cpp:8: undefined reference to `helloworld::getvalue()'
我只想在 main.cpp 中使用 helloworld.cpp 的函数。我花了很多时间搜索和尝试错误。请帮忙。
添加了 Makefiles.am
在父目录中, 我有两个文件 Makefile.am 和 configure.ac:
Makefile.am
AUTOMAKE_OPTIONS = foreign
SUBDIRS=src lib
配置.ac
AC_INIT([helloworld], [0.1], [helloworld@gmail.com])
AM_INIT_AUTOMAKE
AC_PROG_RANLIB
AC_LANG(C++)
AC_PROG_CC
AC_PROG_CXX
AC_CONFIG_MACRO_DIR([m4])
AC_PROG_LIBTOOL
AC_DISABLE_STATIC
AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile])
AC_SUBST([CC])
LT_INIT
AC_OUTPUT
在lib目录下有一个Makefile.am
INCDIR=../include
INCPATH=-I. -I$(INCDIR)
AM_CPPFLAGS=$(INCPATH)
lib_LTLIBRARIES=libhelloworld.la
libhelloworld_la_SOURCES=helloworld.cpp
在src目录下有一个Makefile.am
INCDIR=../include
INCPATH=-I. -I$(INCDIR)
AM_CPPFLAGS=$(INCPATH)
helloworld_LDADD=-L/lib/libhelloworld.la
bin_PROGRAMS=helloworld
helloworld_SOURCES=main.cpp
如果我拿出来编译成功
a.getvalue();
【问题讨论】:
是helloworld
一个库还是只是另一个 .cpp
你想用 main.cpp
编译?
如果你有库是动态的还是静态的?
因为这是一个关于 autoconf/automake 的问题(而不是 C++ 本身),也许你应该添加你的 autoconf/automake 脚本。
【参考方案1】:
helloworld_LDADD=-L/lib/libhelloworld.la
/lib/libhelloworld.la
这个从根目录搜索的 lib 不是你的项目 lib/ 目录
试试
./lib/libhelloworld.la
或
../lib/libhelloworld.la
或
lib/libhelloworld.la
【讨论】:
也不工作。我试图将所有文件一起移动到目录中。同样的问题。 @Jemttinhwa 没关系。你添加了你的makefile。我改变了答案。 ../lib/libhelloworld.la => 没有制定目标的规则 '../lib/libhelloworld.la' ...... lib/libhelloworld.la => 没有制定规则目标'lib/libhelloworld.la' ...... ./lib/libhelloworld.la => 没有规则来制作目标'lib/libhelloworld.la' ...... @Jemttinhwa 您的项目生成的 libhelloworld.la 的位置是什么? hmm.. 它现在在 /helloworld/lib/.libs/libhelloworld.la【参考方案2】:这是 not 使用递归 make 的一个很好的演示案例,因为这简化了依赖于库的可执行文件的声明。此外,使用单个 Makefile.am
有助于并行构建 (make -j3
)。
为了您的方便,我已经完成了示例并将其放在github.com/ndim/cxx-automake-lib-and-main。
configure.ac
现在直接使用 LT_INIT
而没有弃用的宏,只生成一个 Makefile
,并生成一个 helloworld-config.h
配置头,以保持编译器命令行与所有 -D
定义无关:
AC_INIT([helloworld], [0.1], [bug-me-not], [helloworld], [this-url])
AC_CONFIG_SRCDIR([lib/helloworld.cpp])
AC_CONFIG_HEADERS([helloworld-config.h])
AC_CONFIG_MACRO_DIR([auto-m4])
AC_CONFIG_AUX_DIR([auto-aux])
AM_INIT_AUTOMAKE([
-Wall
-Werror
foreign
subdir-objects
])
AC_PROG_CXX
AM_PROG_AR
LT_INIT([disable-static])
AC_LANG([C++])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
***Makefile.am
现在是唯一的Makefile.am
:
ACLOCAL_AMFLAGS = -I auto-m4
EXTRA_DIST =
bin_PROGRAMS =
lib_LTLIBRARIES =
include include/Makefile-files
include lib/Makefile-files
include src/Makefile-files
然后include/Makefile-files
处理我放入include/helloworld/helloworld
的头文件,以帮助保持包含文件命名空间干净,并防止make 对可执行文件helloworld
和头文件helloworld
产生混淆。
# -*- makefile-automake -*-
EXTRA_DIST += %reldir%/helloworld/helloworld
/* -*- c++ -*- */
#ifndef HELLOWORLD_HEADER
#define HELLOWORLD_HEADER
class helloworld
public:
void getvalue();
;
#endif /* !defined(HELLOWORLD_HEADER) */
现在,lib/Makefile-files
将从库源文件 lib/helloworld.cpp
构建 libhelloworld.la
,我必须针对更改后的标头名称进行一些调整:
# -*- makefile-automake -*-
lib_LTLIBRARIES += libhelloworld.la
libhelloworld_la_CPPFLAGS = -I$(top_srcdir)/include
libhelloworld_la_SOURCES = %reldir%/helloworld.cpp
#include "helloworld/helloworld"
void helloworld::getvalue()
helloworld
程序在src/Makefile-files
中定义,以便在必要时自动(重新)构建依赖关系libhelloworld.la
。源文件src/main.cpp
已适应新的标题名称/位置。
# -*- makefile-automake -*-
bin_PROGRAMS += helloworld
helloworld_CPPFLAGS = -I$(top_srcdir)/include
helloworld_SOURCES = %reldir%/main.cpp
helloworld_LDADD = libhelloworld.la
#include "helloworld/helloworld"
int main()
helloworld a;
a.getvalue();
【讨论】:
【参考方案3】:如果您坚持使用递归 make,则需要在 src/Makefile.am
中添加一个特殊规则,以确保应用 lib/Makefile.am
重建库的规则(此处未经测试,但在其他项目中使用)。
现在这意味着正常的递归构建将构建.
、include
、lib
、src
,然后再次构建lib
。我强烈建议放弃递归 make 并使用我在另一个答案中列出的 Makefile.am
解决方案。
bin_PROGRAMS = helloworld
helloworld_CPPFLAGS = $(top_srcdir)/include
helloworld_LDADD = $(top_builddir)/lib/libhelloworld.la
helloworld_SOURCES = main.cpp
$(top_builddir)/lib/libhelloworld.la:
cd $(top_builddir)/lib && $(MAKE) libhelloworld.la
【讨论】:
以上是关于c++ 程序 (.cpp) 如何与 header(.h) 和 libtool (.la) 一起工作?的主要内容,如果未能解决你的问题,请参考以下文章