Visual Studio 2017 和 CMake 的致命错误 LNK1104

Fatal error LNK1104 with Visual Studio 2017 and CMake

我在文件 matrix_utils.hpp 中有以下 header :

#include "someIncludes"

void ReadMtxMatrixHeader(){}

int ScanCurrentLine() {}

void ReadMtxMatrixHeader( {}

template<typename T> void RTS_EXPORTS ReadMtxMatrixToCSR() {}

template<typename T> void RTS_EXPORTS ReadMtxMatrixToColMajorArray() {}

这里的实现并不重要,所以我留下了空括号。

RTS_EXPORTS 是一个宏:

#  define RTS_EXPORTS __declspec(dllexport) // if WIN32
#  define RTS_EXPORTS __attribute__ ((visibility ("default"))) // if GNUC >=4

此 header 是名为 "utils" 的模块的一部分,由目标 "rts_test_utils" 使用。使用 Cygwin 和 CLion,此代码在 Linux 和 Windows 上运行良好。但是一旦我尝试使用 Visual Studio 2017(我的项目是一个 CMake 项目),我在构建 "rts_test_utils" 时收到此错误:

$buildPath\build\x86-Debug\modules\utils\LINK : fatal error LNK1104: 
cannot open file '..\..\lib\Debug\rts_utilsd.lib'

Visual Studio 为 rts_utils 生成 DLL,但不生成库。 如果我将如下所示的虚拟 class 添加到 "matrix_utils.hpp",那么它会起作用并创建一个 rts_utilsd.lib。为什么?

class RTS_EXPORTS Foo{}; 

根据 oLen 的评论,我在 matrix_utils.cpp 中添加了以下代码(也可能在 header 中)以强制编译器看到模板函数已导出:

template void RTS_EXPORTS
ReadMtxMatrixToColMajorArray(std::vector<float> &col_major_host_ptr,
                           const std::string filename, bool is_one_based);

我知道我会使用这个 float 专业化的函数,所以它甚至没有浪费。