Issue
I've been migrating my project to use CMake but I've stumbled upon an issue with static member variables. Even when there is a definition for it in the .cpp file.
I've created a minimal reproducable example.
Directory structure:
- dll
- dll.cpp
- dll.h
- main.cpp
- CMakeLists.txt
CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
add_compile_definitions(BUILD)
add_library(sharedLib SHARED dll/dll.cpp dll/dll.h)
link_libraries(sharedLib)
add_executable(exec main.cpp)
main.cpp
#include "dll/dll.h"
#include <iostream>
int main( )
{
std::cout << A::member << std::endl;
return 0;
}
dll.cpp
#include "dll.h"
int A::member = 10;
dll.h
#pragma once
#if !defined(BUILD)
#define API __declspec(dllimport)
#else
#define API __declspec(dllexport)
#endif
class API A
{
public:
static int member;
};
Solution
The add_compile_definitions
command add macros globally. For all targets. In your example it will be set for both the DLL and the application.
Use target_compile_definitions
instead, to set macros for a single target:
# add_compile_definitions(BUILD)
add_library(sharedLib SHARED dll/dll.cpp dll/dll.h)
target_compile_definitions(sharedLib PRIVATE BUILD)
It's similar with link_libraries
, it's a global command. Use target_link_libraries
instead, to set only for a specific target.
Answered By - Some programmer dude Answer Checked By - Gilberto Lyons (WPSolving Admin)