title: CMake on Windows generates both a static and dynamic version of a library set to be built as SHARED
body: <p>I am very inexperienced when it comes to C++ on Windows. For some odd reason <code>add_library(&lt;some-target-name&gt; SHARED)</code> generates both a static library (<code>.lib</code>) and a dynamic one (<code>.dll</code>). This wouldn't be an issue per say if it didn't break the following project during the linking stage.</p>
  <p><strong>CMakeLists.txt (library)</strong>:</p>
  <pre><code>cmake_minimum_required (VERSION 3.8)
  
  project(test
      LANGUAGES CXX
  )
  
  #set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
  
  set(SRC
      ${CMAKE_CURRENT_SOURCE_DIR}/src/test.cpp
  )
  set(INCLUDE_DIR
      include
      #${PROJECT_BINARY_DIR}
  )
  include_directories(test ${INCLUDE_DIR})
  
  
  add_library(test SHARED)
  target_sources(test PUBLIC ${SRC})
  include(GenerateExportHeader)
  generate_export_header(test
      BASE_NAME test
      EXPORT_MACRO_NAME test_EXPORT
      STATIC_DEFINE test_BUILT_AS_STATIC
      #EXPORT_FILE_NAME ${CMAKE_BINARY_DIR}/deploy/test_export.h  
      EXPORT_FILE_NAME ${CMAKE_CURRENT_SOURCE_DIR}/include/test_export.h
  )
  </code></pre>
  <p><strong>CMakeLists.txt (executable that uses library):</strong></p>
  <pre><code>cmake_minimum_required (VERSION 3.8)
  project(playground
      LANGUAGES CXX CUDA
  )
  
  set(SRC
      ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
  )
  set(INCLUDE_DIR
      ${CMAKE_SOURCE_DIR}/test/include
  )
  
  link_directories(${CMAKE_BINARY_DIR}/deploy)
  add_executable(playground ${SRC})
  target_include_directories(playground PUBLIC ${INCLUDE_DIR})
  target_link_libraries(playground PRIVATE test)
  </code></pre>
  <p><strong>CMakeLists.txt (top-level project):</strong></p>
  <pre><code>cmake_minimum_required (VERSION 3.8)
  
  project (&quot;mainproject&quot;)
  
  set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/deploy)
  set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/deploy)
  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/deploy)
  
  add_subdirectory (&quot;test&quot;)
  add_subdirectory (&quot;playground&quot;)
  </code></pre>
  <p>You can probably put anything in the source files above to reproduce the error. In my case I have the following simple content:</p>
  <p><strong>test.h (library)</strong></p>
  <pre><code>#include &quot;test_export.h&quot;
  #include &lt;string&gt;
  
  namespace mainproject
  {
      namespace library
      {
          class Test {
          private:
              std::string txt;
          public:
              test_EXPORT Test(std::string);
              virtual test_EXPORT void msg();
          };
      } // library
  } // mainproject
  </code></pre>
  <p><strong>test.cpp (library)</strong></p>
  <pre><code>#include &quot;test.h&quot;
  #include &lt;iostream&gt;
  
  mainproject::library::Test::Test(std::string txt)
      : txt(txt)
  {
  }
  
  void mainproject::library::Test::msg() {
      std::cout &lt;&lt; &quot;Message is &quot; &lt;&lt; this-&gt;txt &lt;&lt; std::endl;
  }
  </code></pre>
  <p><strong>main.cpp (executable)</strong></p>
  <pre><code>#include &quot;test.h&quot;
  #include &lt;iostream&gt;
  
  
  int main(int argc, char* argv[])
  {
      std::cout &lt;&lt; &quot;PLAYGROUND&quot; &lt;&lt; std::endl;
  
      mainproject::library::Test t(&quot;hello&quot;);
      t.msg();
  
      return 0;
  }
  </code></pre>
  <p>I use <strong>Visual Studio 2017</strong> and <strong>CMake 3.21</strong> on <strong>Windows 10</strong>.</p>
  <p>The first thing I did after creating my top-level project was to create a sub-project for the library. Everything built without any issues. I didn't even look at the output directory of my build (normally I do that only when something breaks - more on that below :D).</p>
  <p>But after linking against it all of a sudden I got:</p>
  <pre><code>fatal error LNK1169: one or more multiply defined symbols found
  </code></pre>
  <p>I spent a lot of time until I discovered the issue: my library was being built in two versions - static and dynamic. So simply using</p>
  <pre><code>target_link_libraries(playground PUBLIC test)
  </code></pre>
  <p>basically was throwing <code>test.lib</code> and <code>test.dll</code> at the linker hence the error. I fixed the issue by specifying that I want the DLL:</p>
  <pre><code>target_link_libraries(playground PUBLIC test.dll)
  </code></pre>
  <p>I would like to know why this is happening. On Linux I have never experienced such a behaviour. When I set it to <code>SHARED</code> I get a shared object file (<code>.so</code>; equivalent to the dynamic library on Windows). When I set it to <code>STATIC</code> I get an archive file (<code>.a</code>; equivalent to the static library on Windows). If the property is not set explicitly, the default is taken. The behaviour exhibited in the example above points at implicit overriding explicit.</p>
  <p>It goes either weirder - even my executable has its own LIB file. If I remove all the LIB files, I can still run the executable without any issues.</p>