使用本地头文件时未定义的引用 [英] undefined reference when using local header file

查看:196
本文介绍了使用本地头文件时未定义的引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用自动制作功能时,我遇到了undefined reference错误,该错误仅在存储库中存在某个本地头文件(同一存储库中的库所要求的include/lmp2atomstyle.h)时发生.

I encountered an undefined reference error when working with automake, which only occurs when a certain local header file (include/lmp2atomstyle.h, which is required by a library within the same repository) exists in the repository.

为方便起见,我正在将多个自动制作项目源文件夹lmpiolmp2atomstyle组合到一个文件夹中.这两个项目都是库,每个库还提供一个小程序进行测试.

I was working on combining multiple automake project source folders, lmpio and lmp2atomstyle, into a single one for convenience. Both projects are libraries which also provide a small program each for testing.

手动合并Makefile.am后,lmp2atomstyle可以很好地进行编译,但是lmpio不能从liblmp2atomstyle.so中找到符号:

After manually merging Makefile.am, lmp2atomstyle compiles just fine, but lmpio cannot find the symbols from 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,但没有帮助.

First, I assumed a wrong linking order, but after carefully evaluating the dependencies of all libraries, the linking order seemed to be fine. It worked before the repository merge, anyhow. I also used LDADD only, but it didn't help.

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

After tracking the changes, I found that lmpio compiles fine as long as include/lmp2atomstyle.h doesn't exist, but is included automatically from /usr/local/include. The libraries aren't installed at this point. As soon as I copy lmp2atomstyle.h to include/, the error occurs.

我想念什么?关于本地头文件和库是否有一些要求?使用自动制作功能时,头文件的路径如何导致链接错误?

What am I missing? Is there some requirement regarding local headers and libraries? How can the path of a header file cause linking errors when working with automake?

后续问题:如果是由于缺少外部卫队引起的,为什么在不同目录中编译时仍起作用?

Follow-up question: If it's caused by a missing extern guard, why does it work when compiling in different directories?

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

Here's the lmpiotest output of a successful make check run, i.e. without 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

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

Finally, here's the minimal directory tree that causes the error:

./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)所指出的,这与外部警卫有关:

As Matt McNabb pointed out, it has to do with extern guards:

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

In include/lmp2atomstyle.h, I forgot to add an extern guard for c++:

#ifdef __cplusplus
extern "C" {
#endif

  [function headers]

#ifdef __cplusplus
}
#endif

那为我解决了.

后续问题: 为什么在不同目录中编译时仍能正常工作?

Follow-up question: Why did it work when compiling in different directories?

这篇关于使用本地头文件时未定义的引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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