[英]undefined reference when using local header file
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. 在使用automake时遇到了undefined reference
错误,只有在存储库中存在某个本地头文件( include/lmp2atomstyle.h
,这是同一存储库中的库所需)时才会发生。
I was working on combining multiple automake project source folders, lmpio
and lmp2atomstyle
, into a single one for convenience. 为方便起见,我正在努力将多个automake项目源文件夹lmpio
和lmp2atomstyle
合并为一个。 Both projects are libraries which also provide a small program each for testing. 这两个项目都是库,它们也提供了一个用于测试的小程序。
After manually merging Makefile.am
, lmp2atomstyle
compiles just fine, but lmpio
cannot find the symbols from liblmp2atomstyle.so
: 手动合并后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
Here's Makefile.am
: 这是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
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. 我也只使用LDADD
,但它没有帮助。
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. 跟踪更改后,我发现只要include/lmp2atomstyle.h
不存在, lmpio
编译就可以了,但是自动包含在/ usr / local / include中。 The libraries aren't installed at this point. 此时未安装库。 As soon as I copy lmp2atomstyle.h
to include/
, the error occurs. 只要将lmp2atomstyle.h
复制到include/
,就会发生错误。
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? 在使用automake时,头文件的路径如何导致链接错误?
Follow-up question: If it's caused by a missing extern guard, why does it work when compiling in different directories? 后续问题:如果它是由缺少外部防护引起的,为什么它在不同目录中编译时有效?
Here's the lmpiotest
output of a successful make check
run, ie without include/lmp2atomstyle.h
: 这是成功的make check
run的lmpiotest
输出,即没有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'
My configure.ac
: 我的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
Thanks :) 谢谢 :)
As Matt McNabb pointed out, it has to do with extern guards: 正如Matt McNabb指出的那样,它与外部守卫有关:
In include/lmp2atomstyle.h
, I forgot to add an extern guard for c++: 在include/lmp2atomstyle.h
,我忘了为c ++添加一个外部保护:
#ifdef __cplusplus
extern "C" {
#endif
[function headers]
#ifdef __cplusplus
}
#endif
That fixed it for me. 这为我解决了这个问题。
Follow-up question: Why did it work when compiling in different directories? 后续问题:为什么在不同目录中编译时它可以工作?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.