[MERFISH报错合集]Error3:fatal error: 'fftw3.h' file not found \#include <fftw3.h>

继续生成storm_analys所需要的各种动态库,这次出现了新的错误。

fatal error: 'fftw3.h' file not found 
------->#include <fftw3.h>

缺失一个头文件。所以自己装一下。FFTW 这个库是C语言的快速傅里叶变换库。

官方安装指南 在MacOS上安装FFTW

Step 1. 安装C语言的fftw库

后来百度了一下发现homebrew可以直接安装这个,于是键入命令brew install fftw,安装过程的部分输出如下

==> ./configure --prefix=/usr/local/Cellar/open-mpi/4.0.2 --enable-ipv6 --with-libevent=/usr/local/opt/libevent --with-sge
==> make all
==> make check
==> make install
🍺  /usr/local/Cellar/open-mpi/4.0.2: 752 files, 11.2MB, built in 12 minutes 57 seconds
==> Installing fftw
==> ./configure --enable-single --enable-shared --prefix=/usr/local/Cellar/fftw/3.3.8_1 --enable-threads --enable-mpi --enable-openmp -
==> make install
==> make clean
==> ./configure --enable-shared --prefix=/usr/local/Cellar/fftw/3.3.8_1 --enable-threads --enable-mpi --enable-openmp --enable-sse2 --e
==> make install
==> make clean
==> ./configure --enable-long-double --enable-shared --prefix=/usr/local/Cellar/fftw/3.3.8_1 --enable-threads --enable-mpi --enable-ope
==> make install
🍺  /usr/local/Cellar/fftw/3.3.8_1: 73 files, 14.8MB, built in 6 minutes 56 seconds
==> Caveats
==> hwloc
Bash completion has been installed to:
  /usr/local/etc/bash_completion.d

安装完后可以在gcc的默认路径/usr/local/include下找到一系列的头文件。可以看到时间,都是我刚刚装上的

ll /usr/local/include | grep fftw
lrwxr-xr-x    1 user  admin      44 Aug 12 09:53 fftw3-mpi.f03@ -> ../Cellar/fftw/3.3.8_1/include/fftw3-mpi.f03
lrwxr-xr-x    1 user   admin      42 Aug 12 09:53 fftw3-mpi.h@ -> ../Cellar/fftw/3.3.8_1/include/fftw3-mpi.h
lrwxr-xr-x    1 user   admin      38 Aug 12 09:53 fftw3.f@ -> ../Cellar/fftw/3.3.8_1/include/fftw3.f
lrwxr-xr-x    1 user   admin      40 Aug 12 09:53 fftw3.f03@ -> ../Cellar/fftw/3.3.8_1/include/fftw3.f03
lrwxr-xr-x    1 user   admin      38 Aug 12 09:53 fftw3.h@ -> ../Cellar/fftw/3.3.8_1/include/fftw3.h
lrwxr-xr-x    1 user   admin      45 Aug 12 09:53 fftw3l-mpi.f03@ -> ../Cellar/fftw/3.3.8_1/include/fftw3l-mpi.f03
lrwxr-xr-x    1 user  admin      41 Aug 12 09:53 fftw3l.f03@ -> ../Cellar/fftw/3.3.8_1/include/fftw3l.f03
lrwxr-xr-x    1 user  admin      41 Aug 12 09:53 fftw3q.f03@ -> ../Cellar/fftw/3.3.8_1/include/fftw3q.f03

至于这个/usr/local/include是怎么确定的,有关gcc默认的库文件搜索路径,可以用以下命令查看

 gcc -x c -v -E /dev/null
 
 ##部分输出展示 包含默认的include寻址路径
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /Library/Developer/CommandLineTools/usr/lib/clang/11.0.3/include
 /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include
 /Library/Developer/CommandLineTools/usr/include
 /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks (framework directory)
End of search list.
# 1 "/dev/null"

Step 2.解决头文件与源文件无法关联的问题

安装好并能够找到头文件后,重新生成动态链接库,这次不会再提示找不到头文件了,但是之前的那个错误又一次出现了。

gcc  -dynamiclib -o libmatched_filter.dylib matched_filter.c
Undefined symbols for architecture x86_64:
  "_fftw_destroy_plan", referenced from:
      _cleanup in matched_filter-d9e7cc.o
  "_fftw_execute", referenced from:
      _convolve in matched_filter-d9e7cc.o
      _initialize in matched_filter-d9e7cc.o
  "_fftw_free", referenced from:
      _cleanup in matched_filter-d9e7cc.o
  "_fftw_malloc", referenced from:
      _initialize in matched_filter-d9e7cc.o
  "_fftw_plan_dft_c2r_2d", referenced from:
      _initialize in matched_filter-d9e7cc.o
  "_fftw_plan_dft_r2c_2d", referenced from:
      _initialize in matched_filter-d9e7cc.o
  "_ftmComplexCopyNormalize", referenced from:
      _initialize in matched_filter-d9e7cc.o
  "_ftmComplexMultiply", referenced from:
      _convolve in matched_filter-d9e7cc.o
  "_ftmDoubleCopy", referenced from:
      _convolve in matched_filter-d9e7cc.o
      _convolveMemo in matched_filter-d9e7cc.o
      _initialize in matched_filter-d9e7cc.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

这次我明白了,肯定是找到了头文件,但是关联不上头文件对应的源文件。因为是用homebrew安装的,安装路径可能不在gcc的默认寻址路径中。那么昨天有关kdtree的报错无法解决肯定是同样的原因了。

在网络上查询了一下有关C语言头文件与库函数的关联方式,得到以下信息。

二、头文件如何来关联源文件

这个问题实际上是说,已知头文件“a.h”声明了一系列函数,“b.cpp”中实现了这些函数,那么如果我想在“c.cpp”中使用“a.h”中声明的这些在“b.cpp”中实现的函数,通常都是在“c.cpp”中使用#include “a.h”,那么c.cpp是怎样找到b.cpp中的实现呢?

其实.cpp和.h文件名称没有任何直接关系,很多编译器都可以接受其他扩展名。比如偶现在看到偶们公司的源代码,.cpp文件由.cc文件替代了。

在Turbo C中,采用命令行方式进行编译,命令行参数为文件的名称,默认的是.cpp和.h,但是也可以自定义为.xxx等等。

谭浩强老师的《C程序设计》一书中提到,编译器预处理时,要对#include命令进行“文件包含处理”:将file2.c的全部内容复制到#include “file2.c”处。这也正说明了,为什么很多编译器并不care到底这个文件的后缀名是什么----因为#include预处理就是完成了一个“复制并插入代码”的工作。

编译的时候,并不会去找b.cpp文件中的函数实现,只有在link的时候才进行这个工作。我们在b.cpp或c.cpp中用#include “a.h”实际上是引入相关声明,使得编译可以通过,程序并不关心实现是在哪里,是怎么实现的。源文件编译后成生了目标文件(.o或.obj文件),目标文件中,这些函数和变量就视作一个个符号。在link的时候,需要在makefile里面说明需要连接哪个.o或.obj文件(在这里是b.cpp生成的.o或.obj文件),此时,连接器会去这个.o或.obj文件中找在b.cpp中实现的函数,再把他们build到makefile中指定的那个可以执行文件中。

参考链接:C头文件和源文件的关联

所以我的link过程会出错,因为链接器根本找不到原始文件在哪里,自然不能用在头文件里被声明的的函数了。

使用-L-l对路径进行指定,还是有报错,但是至少找到了一些东,报错的未定义文件少了不少。

gcc -L /usr/local/lib -l fftw3  -dynamiclib -o libmatched_filter.dylib matched_filter.c
Undefined symbols for architecture x86_64:
  "_ftmComplexCopyNormalize", referenced from:
      _initialize in matched_filter-9f6f25.o
  "_ftmComplexMultiply", referenced from:
      _convolve in matched_filter-9f6f25.o
  "_ftmDoubleCopy", referenced from:
      _convolve in matched_filter-9f6f25.o
      _convolveMemo in matched_filter-9f6f25.o
      _initialize in matched_filter-9f6f25.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation

#说明一下参数问题
-L #接动态库所在的路径
-l #接动态库的名字 如果动态库文件是libxxxx.dylib, 那么参数设置的时候应该输入 -l xxxx

这次报错提示的未定义内容

有关gcc的链接参数的一些东西:gcc -l -L -i

posted @ 2021-10-21 09:50  Craven胆小鬼  阅读(355)  评论(0)    收藏  举报