Autotools 将链接库的 -l 标志放在编译命令的错误位置

Autotools puts -l flags for linked libraries at the wrong place in the compile command

我尝试使用 autotools 编译 Fortran 90 程序。我的 makefile.am 在这里 :

AUTOMAKE_OPTIONS = foreign subdir-objects
bin_PROGRAMS = medys
medys_SOURCES =   src/all_v001/basics.f90 src/all_v001/variables.f90 src/all_v001/read_input.f90 src/all_v001/math.f90 src/all_v001/champ1.f90 src/all_v001/grille.f90 src/all_v001/NewSubroutines.f90 src/all_v001/Tests.f90 src/all_v001/string.f90 src/all_v001/io_module.f90 src/all_v001/precision.f90 src/core/error.f90 src/all_v001/matrix_modifications.f90 src/all_v001/matrix_temp_lowlvl.f90 src/all_v001/matrix_temp_highlvl.f90 src/all_v001/read_columbus.f90 src/all_v001/ortho.f90 src/all_v001/qp_integrals.f90 src/all_v001/observable.f90 src/all_v001/nouveaudrt.f90 src/all_v001/read_gamess.f90 src/all_v001/dynamique.f90  src/main/main.f90

AM_FCFLAGS =  -L/opt/intel/composer_xe_2013_sp1.3.174/mkl/lib/intel64 -I/opt/intel/composer_xe_2013_sp1.3.174/mkl/include/intel64/lp64/ -lmkl_intel_lp64 -lmkl_core -lmkl_intel_thread -lpthread -liomp5 -lmkl_blas95_lp64 -lmkl_lapack95_lp64 -nogen-interface -fpe0  -traceback -debug extended -heap-arrays -fp-stack-check -debug all -openmp

我的 configure.ac 在这里:

AC_INIT([medys], [0.1], [meitnerium109@gmail.com])
m4_define([_AC_F95_FC], [ifort])
AC_CONFIG_SRCDIR([src/main/main.f90])
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE
AC_PROG_FC
AC_PROG_CC
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

每个 .o 文件都能正确编译,但 bin 文件编译失败。如果我手动编译,但是在编译的最后加上FLAG,编译就成功了。使用make命令,编译失败:

ifort -L/opt/intel/composer_xe_2013_sp1.3.174/mkl/lib/intel64 -I/opt/intel/composer_xe_2013_sp1.3.174/mkl/include/intel64/lp64/ -lmkl_intel_lp64 -lmkl_core -lmkl_intel_thread -lpthread -liomp5 -lmkl_blas95_lp64 -lmkl_lapack95_lp64 -nogen-interface -fpe0  -traceback -debug extended -heap-arrays -fp-stack-check -debug all -openmp  -g -L/opt/intel/composer_xe_2013_sp1.3.174/mkl/lib/intel64 -I/opt/intel/composer_xe_2013_sp1.3.174/mkl/include/intel64/lp64/  -lmkl_intel_lp64 -lmkl_core -lmkl_intel_thread -lpthread -liomp5 -lmkl_blas95_lp64 -lmkl_lapack95_lp64  -o medys src/all_v001/basics.o src/all_v001/variables.o src/all_v001/read_input.o src/all_v001/math.o src/all_v001/champ1.o src/all_v001/grille.o src/all_v001/NewSubroutines.o src/all_v001/Tests.o src/all_v001/string.o src/all_v001/io_module.o src/all_v001/precision.o src/core/error.o src/all_v001/matrix_modifications.o src/all_v001/matrix_temp_lowlvl.o src/all_v001/matrix_temp_highlvl.o src/all_v001/read_columbus.o src/all_v001/ortho.o src/all_v001/qp_integrals.o src/all_v001/observable.o src/all_v001/nouveaudrt.o src/all_v001/read_gamess.o src/all_v001/dynamique.o src/main/main.o

有很多这样的消息错误

src/main/main.f90:471: undefined reference to `zgemm_mkl95_'

但是如果我把编译标志放在最后,编译工作:

 ifort -o medys src/all_v001/basics.o src/all_v001/variables.o src/all_v001/read_input.o src/all_v001/math.o src/all_v001/champ1.o src/all_v001/grille.o src/all_v001/NewSubroutines.o src/all_v001/Tests.o src/all_v001/string.o src/all_v001/io_module.o src/all_v001/precision.o src/core/error.o src/all_v001/matrix_modifications.o src/all_v001/matrix_temp_lowlvl.o src/all_v001/matrix_temp_highlvl.o src/all_v001/read_columbus.o src/all_v001/ortho.o src/all_v001/qp_integrals.o src/all_v001/observable.o src/all_v001/nouveaudrt.o src/all_v001/read_gamess.o src/all_v001/dynamique.o src/main/main.o -L/opt/intel/composer_xe_2013_sp1.3.174/mkl/lib/intel64 -I/opt/intel/composer_xe_2013_sp1.3.174/mkl/include/intel64/lp64/ -lmkl_intel_lp64 -lmkl_core -lmkl_intel_thread -lpthread -liomp5 -lmkl_blas95_lp64 -lmkl_lapack95_lp64 -nogen-interface -fpe0  -traceback -debug extended -heap-arrays -fp-stack-check -debug all -openmp  -g -L/opt/intel/composer_xe_2013_sp1.3.174/mkl/lib/intel64 -I/opt/intel/composer_xe_2013_sp1.3.174/mkl/include/intel64/lp64/  -lmkl_intel_lp64 -lmkl_core -lmkl_intel_thread -lpthread -liomp5 -lmkl_blas95_lp64 -lmkl_lapack95_lp64

autotools 使用以下命令进行编译:

$(FC) $(AM_FCFLAGS) $(FCFLAGS) -c $(FCFLAGS_f90) $<

我可以更改吗?您还有其他建议吗?

你的 AM_FCFLAGS 实际上应该只包含 -I 标志,即使这样也只包含那些对你构建本地系统结构必不可少的标志(也就是,所有这些标志最有可能使用 $(top_srcdir)

当你想link使用第三方库时,你应该通过 FCFLAGS 的编译器标志(包括 -I 标志)和 LDADD 的 linker 标志,例如

medys_FCFLAGS = -I/opt/intel/composer_xe_2013_sp1.3.174/mkl/include/intel64/lp64/ -nogen-interface -fpe0  -traceback -debug extended -heap-arrays -fp-stack-check -debug all -openmp
medys_LDADD = -L/opt/intel/composer_xe_2013_sp1.3.174/mkl/lib/intel64 -lmkl_intel_lp64 -lmkl_core -lmkl_intel_thread -lpthread -liomp5 -lmkl_blas95_lp64 -lmkl_lapack95_lp64

或类似的东西。

我是一名 C++ 编码员,但两者并没有太大区别(我只需要在您使用 FC 的地方使用 CXX)。这是一个很好的 Makefile.am 的例子:https://github.com/CarloWood/ai-xml/blob/master/Makefile.am

如您所见,我所有的第三方库标志、编译器和 linker 都一样,都是来自 configure.ac 的 AC_SUBST。例如,其中的 BOOST*、LIBXML_CFLAGS 和 LIBXML_LIBS 是通过在我的 configure.ac 中包含(使用 m4_include())设置的:https://github.com/CarloWood/ai-xml/blob/master/configure.m4