# Exporting a static data member of a class for dll using MSVC

**URL:** <https://discourse.cmake.org/t/exporting-a-static-data-member-of-a-class-for-dll-using-msvc/5892>\
**Category:** Code\
**Tags:** os:windows\
**Created:** [June 18, 2022, 3:10am UTC](https://discourse.cmake.org/t/exporting-a-static-data-member-of-a-class-for-dll-using-msvc/5892 "2022-06-18T03:10:56Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![ravimohan1991](https://discourse.cmake.org/user_avatar/discourse.cmake.org/ravimohan1991/32/2513_2.png) [@ravimohan1991](https://discourse.cmake.org/u/ravimohan1991)\
**Post date:** [June 18, 2022, 3:10am UTC](https://discourse.cmake.org/t/exporting-a-static-data-member-of-a-class-for-dll-using-msvc/5892/1 "2022-06-18T03:10:56Z")

</div>

Since past couple of days I have been searching and experimenting with the right way to export a static data member of a class for dynamic linkage in Windows using MSVC solution generated by CMake.

The CMake hierarchy is as follows:

```auto
DLLLinkingExperiment
-CMakeLists.txt    
-SubDirectory 
  -CMakeLists.txt    
  -LibraryDummy.cpp
  -LibraryDummy.h
-ExternalLibrary
  -CMakeLists.txt    
  -Executable.cpp

```

With bare minimum, the C++ code is as follows

LibraryDummy.h/.cpp

```nohighlight
// LibraryDummy.h
#pragma once
#include <iostream>

namespace Rachel
{
	class Retrospect
	{
	public:
		static void Status();
		static Retrospect* ReturnStaticPointer() { return s_Ret; }
	private:
		static Retrospect* s_Ret;
	};
}
----------------------------------------------------------------------------------------------
// LibraryDummy.cpp
#include "LibraryDummy.h"

namespace Rachel 
{
	Rachel::Retrospect* Retrospect::s_Ret = nullptr;
	void Retrospect::Status()
	{
		std::cout << "I am Xan!";
	}
}

```

and corresponding CMakeLists.txt is

```auto
project(LibraryDummy VERSION 1.0)

#add a library that runs
# Building the project (STATIC or DYNAMIC (SHARED))
if (BUILD_SHARED_LIBS)
    add_library(LibraryDummy SHARED LibraryDummy.cpp LibraryDummy.h)
else()
    add_library(LibraryDummy STATIC LibraryDummy.cpp LibraryDummy.h)
endif()

target_include_directories(LibraryDummy
    PRIVATE
        # where the library itself will look for its internal headers
        ${CMAKE_CURRENT_SOURCE_DIR}
    PUBLIC
        # where top-level project will look for the library's public headers
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
        # where external projects will look for the library's public headers
        $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

target_compile_definitions(LibraryDummy PUBLIC LibraryDummy)

```

Now Executable.cpp is

```nohighlight
#include "LibraryDummy.h"

int main()
{
	Rachel::Retrospect::Status();
	Rachel::Retrospect::ReturnStaticPointer();
	return 0;
}

```

with CMakeLists.txt as follows

```auto
add_executable(External Executable.cpp)

```

Finally the top level CMakeLists.txt is as follows

```auto
# Here top level

cmake_minimum_required(VERSION 3.23)

# First we specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# control where the static and shared libraries are built so that on windows
# we don't need to tinker with the path to run the executable
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")

# Setting some options
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)

project(DllExternal VERSION 1.0)

# Build the test library
add_subdirectory(SubDirectory)

add_subdirectory(ExternalLibrary)

target_link_libraries(External PUBLIC LibraryDummy)

```

Visual Studio linker is complaining as follows

 ![image](https://discourse.cmake.org/uploads/default/original/2X/9/93cecc33632fc5c0068a4f340cd9b7d1e7999bc7.png)

I have done some research, searched .def files and assembly files (given I am junior in reading assembly code), I can’t find any way for graceful linking in Windows.

Note: This issue never arises in Mac or Linux using gcc or clang!

---

<div class="post-metadata">

**Author:** ![benthevining](https://discourse.cmake.org/user_avatar/discourse.cmake.org/benthevining/32/1924_2.png) [@benthevining](https://discourse.cmake.org/u/benthevining)\
**Post date:** [June 18, 2022, 5:16am UTC](https://discourse.cmake.org/t/exporting-a-static-data-member-of-a-class-for-dll-using-msvc/5892/2 "2022-06-18T05:16:52Z")

</div>

Look into the GenerateExportHeader module.

---

<div class="post-metadata">

**Author:** ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)\
**Post date:** [June 18, 2022, 11:24pm UTC](https://discourse.cmake.org/t/exporting-a-static-data-member-of-a-class-for-dll-using-msvc/5892/3 "2022-06-18T23:24:40Z")

</div>

See also the following talk which covers symbol visibility in general, including the GenerateExportHeader module Ben mentioned:

> **[CppCon 2019: Deep CMake For Library Authors](https://crascit.com/2019/10/16/cppcon-2019-deep-cmake-for-library-authors/)**
>
> This talk highlights key CMake features relevant to C++ cross-platform library authors, digging deeper into platform-specific quirks and conventions.
