c++ - 使用本地头文件时 undefined reference

标签 c++ gcc shared-libraries automake

我在使用 automake 时遇到了 undefined reference 错误,只有当某个本地头文件(include/lmp2atomstyle.h,这是一个库所需要的)时才会发生在同一个存储库中)存在于存储库中。

为了方便起见,我正在努力将多个 automake 项目源文件夹 lmpiolmp2atomstyle 组合成一个。这两个项目都是库,每个库还提供一个小程序用于测试。

手动合并Makefile.am后,lmp2atomstyle编译正常,但是lmpio无法从liblmp2atomstyle.so<中找到符号:

$ make check
make  lmpiotest
make[1]: Entering directory `/home/e.lorenz/code/lmputils'
/bin/sh ./libtool --tag=CXX   --mode=link g++  -g -O2 -lfftw3 -llmpio -llmp2atomstyle  -o lmpiotest src/lmpiotest.o -llammps_custom -lmpi_stubs
libtool: link: g++ -g -O2 -o .libs/lmpiotest src/lmpiotest.o  -lfftw3 /home/e.lorenz/code/lmputils/.libs/liblmpio.so /cluster/gcc/gcc-4.8.2/lib/../lib64/libstdc++.so -lm /home/e.lorenz/code/lmputils/.libs/liblmp2atomstyle.so -llammps_custom -lmpi_stubs -Wl,-rpath -Wl,/usr/local/lib -Wl,-rpath -Wl,/cluster/gcc/gcc-4.8.2/lib/../lib64
/home/e.lorenz/code/lmputils/.libs/liblmpio.so: undefined reference to `lmp2atomstyle_parse_file(void*, char const*)'
/home/e.lorenz/code/lmputils/.libs/liblmpio.so: undefined reference to `lmp2atomstyle_get_style(void*, char*, unsigned long)'
/home/e.lorenz/code/lmputils/.libs/liblmpio.so: undefined reference to `lmp2atomstyle_create()'
collect2: error: ld returned 1 exit status
make[1]: *** [lmpiotest] Error 1
make[1]: Leaving directory `/home/e.lorenz/code/lmputils'
make: *** [check-am] Error 2

这是 Makefile.am:

AUTOMAKE_OPTIONS = subdir-objects
ACLOCAL_AMFLAGS = -I m4

AM_CPPFLAGS = -Iinclude

lib_LTLIBRARIES = liblmp2atomstyle.la liblmpio.la
include_HEADERS = include/lmpio.h include/lmp2atomstyle.h
liblmp2atomstyle_la_SOURCES = src/lmp2atomstyle.c
liblmp2atomstyle_la_LDFLAGS = -version-info 1:0:0
liblmpio_la_SOURCES = src/lmpio.cpp
liblmpio_la_LDFLAGS = -version-info 1:0:0 -llmp2atomstyle

bin_PROGRAMS = lmp2atomstyle
lmp2atomstyle_SOURCES = src/lmp2atomstyle_main.c
lmp2atomstyle_LDFLAGS = -llmp2atomstyle

check_PROGRAMS = lmpiotest
lmpiotest_SOURCES = src/lmpiotest.cpp
lmpiotest_LDADD = -llammps_custom -lmpi_stubs
lmpiotest_LDFLAGS = -lfftw3 -llmpio -llmp2atomstyle

首先,我假设了一个错误的链接顺序,但在仔细评估所有库的依赖关系后,链接顺序似乎没问题。无论如何,它在存储库合并之前就起作用了。我也只使用了 LDADD,但没有帮助。

跟踪更改后,我发现只要 include/lmp2atomstyle.h 不存在,lmpio 就可以正常编译,但是会自动从/usr/local 包含/包括。此时尚未安装这些库。一旦我将 lmp2atomstyle.h 复制到 include/,就会发生错误。

我错过了什么?是否对本地 header 和库有一些要求?使用 automake 时,头文件的路径如何导致链接错误?

跟进问题:如果是缺少extern guard导致的,为什么在不同目录下编译会起作用?

这是成功运行 make checklmpiotest 输出,即没有 include/lmp2atomstyle.h:

make  lmpiotest
make[1]: Entering directory `/home/e.lorenz/code/lmputils'
depbase=`echo src/lmpiotest.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\
  g++ -DHAVE_CONFIG_H -I.  -Iinclude   -g -O2 -MT src/lmpiotest.o -MD -MP -MF $depbase.Tpo -c -o src/lmpiotest.o src/lmpiotest.cpp &&\
  mv -f $depbase.Tpo $depbase.Po
/bin/sh ./libtool --tag=CXX   --mode=link g++  -g -O2 -lfftw3 -llmpio -llmp2atomstyle  -o lmpiotest src/lmpiotest.o -llammps_custom -lmpi_stubs
libtool: link: g++ -g -O2 -o .libs/lmpiotest src/lmpiotest.o  -lfftw3 /home/e.lorenz/code/lmputils/.libs/liblmpio.so /cluster/gcc/gcc-4.8.2/lib/../lib64/libstdc++.so -lm /home/e.lorenz/code/lmputils/.libs/liblmp2atomstyle.so -llammps_custom -lmpi_stubs -Wl,-rpath -Wl,/usr/local/lib -Wl,-rpath -Wl,/cluster/gcc/gcc-4.8.2/lib/../lib64
make[1]: Leaving directory `/home/e.lorenz/code/lmputils'

我的configure.ac:

AC_INIT([lmputils], [1.0], [(email...)])
LT_INIT
AM_INIT_AUTOMAKE()
AC_CONFIG_HEADERS([config.h])
AC_PROG_CXX
AM_PROG_CC_C_O
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

最后,这是导致错误的最小目录树:

./include
./include/lmpio.h
./include/lmp2atomstyle.h
./src
./src/lmp2atomstyle.c
./src/lmp2atomstyle_main.c
./src/lmpio.cpp
./src/lmpiotest.cpp
./Makefile.am
./configure.ac
./autogen.sh

谢谢:)

最佳答案

正如 Matt McNabb 所指出的,这与外部 guard 有关:

include/lmp2atomstyle.h 中,我忘记为 C++ 添加外部保护:

#ifdef __cplusplus
extern "C" {
#endif

  [function headers]

#ifdef __cplusplus
}
#endif

这对我来说已经解决了。

后续问题: 为什么在不同的目录下编译都可以?

关于c++ - 使用本地头文件时 undefined reference ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23341068/

相关文章:

c++ - 在 g++ 中编译 .c 假定 c++ 任何命令行选项都将其视为 .c

c - gcc 的 -fstack-protector 选项如何防止堆栈崩溃?

MacOS 上的 Python "dyld: Library not loaded"- 错误

c++ - 如何选择从QCPCurve的哪一侧填充渐变?

c++ - 奇怪的链接器错误

c++ - 当 C++ lambda 表达式有很多引用捕获时,未命名函数对象的大小变大

c++ - 级联 NavigationPane : connect to an object signal into another qml file

c++ - 如何使用 mbed-os 中的可用库?

c++ - 是否导出共享库中类的构造函数?

gcc - 加载共享库时出错 : libsandbox. 所以