2

I'm trying to use Visual Studio 2015 to compile a project that uses FFTW. Unfortunately, the precompiled binaries from the FFTW website aren't compatible with VS 2015, due to this problem: unresolved external symbol __imp__fprintf and __imp____iob_func, SDL2. You get a link error when you try to compile.

I'm looking for any advice on how I can compile a compatible version. The obvious answer would be to recompile FFTW with VS 2015, but I can't find any instructions on how to compile it with Visual Studio at all, and lots of suggestions that it would be hard to do that. The standard version was compiled with MinGW, and they do provide instructions on how to do that. But can MinGW produce a library compatible with VS 2015? I haven't found any information about that either.

4

2 回答 2

5

如果有人需要使用Visual Studio 2019为 Windows 程序构建静态或动态 FFTW 库:

您实际上不需要在接受的答案中执行任何手动和复杂的步骤 - 它们容易出错并且比以下步骤长一百倍。

首先,我有一个好消息要告诉你——Visual Studio 2019(免费社区版和专业版)支持 CMake!因此,您只需要执行以下步骤:

  1. 如果您尚未安装Visual Studio 2019 提供的所有组件,请启动它,按 Ctrl-Q,然后键入“ cmake tools for linux ”。它应该找到安装选项,您单击并安装组件。如果您不在线,请启动 VS 的安装程序并选择此可选组件(“ CMake tools for Linux ”)进行安装。

  2. 在 Visual Studio 2019 中创建一个空解决方案,选择适用于库、C++ 和 Windows 桌面开发的模板。

  3. 创建解决方案后,像往常一样选择所需的目标平台(例如 x64 Release)和构建类型(Release/Debug)。退出VS。

  4. 从http://www.fftw.org下载最新的源代码存档并将文件解压缩到您创建 VS 解决方案和项目的文件夹中。不要在 MinGW 下运行任何提供的配置脚本,也不要执行官方或第三方文档中指示您执行的任何其他步骤。

  5. 运行 Visual Studio,打开您创建的解决方案,在解决方案资源管理器子窗口中,单击带有“切换视图”工具提示的图标,并使用它切换到“文件夹视图”模式。一旦发生这种情况,VS 开始使用所有文件填充解决方案资源管理器,最重要的是,它会自动发现配置脚本和 CMake 生成文件并开始配置解决方案,包括至关重要的 config.h。

  6. 等到该过程完成(VS 应该说类似“ CMake generation finished. ”)。然后,在解决方案资源管理器子窗口中,再次单击带有“切换视图”图标工具提示的图标,并使用它切换到“ CMake 目标视图”。

  7. 右键单击解决方案资源管理器子窗口中的项目名称,然后选择“ CMake Settings ”。

  8. 在 CMake 设置子窗口中,将“配置类型”设置为“调试”或“发布”,并在“工具集”字段中选择 x64 或 x86 等。

  9. 在 CMake 设置子窗口中单击链接“保存并生成 CMake 缓存以加载变量”。该过程完成后,再次单击该链接(有时需要这样做,尤其是在更改构建目标/类型时)。

  10. 如果要构建静态 .lib 文件,请在 CMake 设置子窗口中禁用选项BUILD_SHARED_LIBS。否则,您将构建一个共享的 .dll。(不确定这是否仍然需要,但对于 .dll 构建,FFTW 文档告诉我们“在编译前向 fftw3.h 和 ifftw.h 添加一行 #define FFTW_DLL”)。

  11. 在 VS 中,选择 Build > Rebuild All并且您的 .lib 和 .dll 文件应该在子文件夹 \out\build\x64-Debug\ 中(当然对于 x64 Debug 构建 - 其他目标将在其他地方)。如果失败,有时只是基准测试应用程序的构建失败。幸运的是,您可以在 CMake Settings 子窗口中轻松禁用它的构建——只需禁用BUILD_TESTS选项。

  12. 将生成的 .lib 或 .dll 文件添加到您的主应用程序项目中(在 VS 项目设置中:Linker > General > ' Additional Library Directories ' > .lib 文件的路径;以及Linker > Input > ' Additional Dependencies ' .lib 文件名)。

  13. 当然,还要将所有 FFTW API 头文件添加到您的主应用程序项目中——即“ api ”子文件夹中的所有头文件(例如“ api.h ”和任何其他带有.h后缀的文件)。

重要提示:当您关闭 VS 解决方案然后再次打开它时,您必须重复步骤 5 和 6。否则,如果您使用“ Rebuild All ” ,则不会构建任何内容。

最后的技术说明:如果您的主应用程序静态链接到 C 运行时库 (CRT),而不是作为 DLL 动态链接,您还需要在您找到的所有名为“CMakeCache.txt”的文件中进行以下替换在“ out ”子文件夹中:将所有/MDd替换为/MTd并将所有/MD替换为/MT。但是只有在创建了所有构建配置(调试/发布、x86/x64)之后才应该这样做。进行替换后,再次在 VS 中打开 CMake 设置,然后再次单击链接“保存并生成 CMake 缓存以加载变量”。

希望这有帮助。享受!

于 2019-07-14T19:42:16.100 回答
1

我最终设法自己解决了这个问题。我不保证我会以最好的方式做到这一点,因为我不是 Visual Studio 专家,但它确实有效。因此,为了后代的利益,这就是我所做的。

首先,复制 config.h.in。调用新副本config.h。现在手动编辑它,为你要生成的库设置选项:它应该使用什么精度模式,要编译的向量指令集(如果有的话),各种类型的大小(这取决于你是否计划以 32 位或 64 位模式编译),是否包括线程支持等。

现在创建一个空的 VS 项目。我建议将它放在源文件夹的顶层。然后在解决方案资源管理器中,单击顶部的“显示所有文件”图标。这将使以下步骤更容易,因为您可以直接从解决方案资源管理器添加或排除文件。

打开项目属性窗口。您需要设置很多选项:

一般来说,将“配置类型”设置为静态库。(或者如果你想要一个 DLL,你可以将它设置为动态库,但是你需要弄清楚如何让它导出必要的符号。我没有这样做,因为我想要一个静态库。)

在 VC++ 目录中,编辑“包含目录”。添加以下目录(将“(源目录)”替换为包含源的实际目录):

(source dir)
(source dir)\api
(source dir)\dft
(source dir)\rdft
(source dir)\reodft
(source dir)\kernel
(source dir)\simd-support
(source dir)\dft\simd
(source dir)\dft\scalar
(source dir)\rdft\simd
(source dir)\rdft\scalar

如果您包含线程支持,则在 C/C++ > 语言中,将“Open MP Support”设置为是。

如果您包含 AVX 支持,则在 C/C++ > 代码生成中,将“启用增强指令集”设置为 AVX。这意味着您生成的库将无法在任何不支持 AVX 的计算机上运行。您可以通过仅在使用 AVX 的单个源文件上设置此选项来绕过该限制。对此我不确定。

在 C/C++ > 输出文件中,将“对象文件名”设置为$(IntDir)/%(RelativeDir)/. (FFTW有很多同名但在不同目录下的文件,VS默认将所有对象文件放在同一个目录下,这样是行不通的。)

现在您已准备好将源文件添加到项目中,您可以通过右键单击解决方案资源管理器并选择“包含在项目中”来完成。您应该在以下文件夹中添加所有 .c 文件:

api
dft
dft/scalar
kernel
rdft
rdft/scalar
reodft

如果你想要线程支持,你应该在“线程”中添加所有源文件,除了threads.c。(那个包含 pthreads 版本。)

如果你想支持任何向量指令集,你应该只包含与你想要从以下文件夹中的特定指令集相关的文件:

dft/simd
rdft/simd
simd-support

大概如果您想要 mpi 支持,您可以将文件包含在“mpi”中。我没有这样做,所以我不知道您是否还需要其他任何东西来完成这项工作。

请务必将配置设置为“Release”和“x86”或“x64”,具体取决于您想要的二进制文件类型。

现在,如果我没有忘记任何关键的东西,你应该能够编译一个库。

于 2016-03-04T18:59:22.063 回答