Search code examples
cmakevisual-studio-2017dllexport

Fatal error LNK1104 with Visual Studio 2017 and CMake


I have the following header in a file matrix_utils.hpp :

#include "someIncludes"

void ReadMtxMatrixHeader(){}

int ScanCurrentLine() {}

void ReadMtxMatrixHeader( {}

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

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

The implementation here is not important so I left empty brackets.

The RTS_EXPORTS is a macro for :

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

This header is part of a module called "utils" and is used by a target "rts_test_utils". This code works perfectly fine on Linux and on Windows using Cygwin and CLion. But as soon as I try to use Visual Studio 2017 (my project is a CMake project), I get this error when building "rts_test_utils" :

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

Visual Studio generates the DLL for rts_utils, but not the lib. If I add a dummy class like the one below to "matrix_utils.hpp", then it works and it creates a rts_utilsd.lib. Why ?

class RTS_EXPORTS Foo{}; 

Solution

  • Following comment from oLen, I added the following code in my matrix_utils.cpp (could have been in the header too) to force compiler to see that a template function is exported:

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

    I know I will use this function with float specialization, so it's not even wasted.