Есть некий код, какой-то динамической библиотеки, который успешно собирается в msvc под винду.
Моя задача собрать его в линуксе (дебиан, g++4.9.2), итак сделал симейк, проект собирается из кучи отдельных модулей
модули собираются с ключами
set(CMAKE_CXX_FLAGS "-Wall -std=c++14 -fpermissive -fPIC")
в объектники
add_library(NAME OBJECT ${NAME_SOURCES})
с этим все ок.
Результирующая либа собирается такой строкой
add_library(ИМЯ SHARED ${Сырцы_Главного_Модуля_Либы} $<TARGET_OBJECTS:имя_объектника1>...$<TARGET_OBJECTS:имя_объектникаN> >)
тут вроде тоже все норм (вообще первый раз в жизни сам руками собирал симейк, обычнно это IDE делали за меня).
Но а теперь то что я не могу понять до сих пор.
Есть класс, код не мой, поэтому приводить не детали реализации не могу, но тут суть именно в переменных:
class TopologicalSorter {
public:
int method_1(ссылка на неконстантный контейнер);
static const int sm_success = 0;
static const int sm_circle = -1;
static const int sm_badGraph = -2;
private:
int method_1_private() //юзается в method_1
std::vector<int> m_state;
static const int sm_notVisited = 0;
static const int sm_pcocessing = 1;
static const int sm_finished = 2;
};
итак, мы видим статик члены. Напомню в винде компиляется работает, в линуксе компиляется но не линкуется:
перемещение R_X86_64_PC32 для неопределённого символ «_ZN12_GLOBAL__N_117TopologicalSorter13sm_notVisitedE» не может использоваться при создании общего объекта(ов)
я конечно гуглил, даже на лоре чето нашел (ошибка при создании shared объекта в x86_64. (комментарий) но это не мой случай). Далее я обнаружил, что класс объявлен и реализован в .cpp файле и в пустом неймспейсе
namespace {
class TopologicalSorter {код который я урезанно привел};
}
вопрос1 - пустой неймспейс - какая-то смыслу у этого есть, или это просто автор забыл имя дать или т.п.?
далее я убрал неймспейс и получил более читаемую ошибку
undefined reference to `TopologicalSorter::sm_finished'
С которой естественно уже, помня азы плюсов - справился таким образом
class TopologicalSorter {
public:
int method_1(ссылка на неконстантный контейнер);
static const int sm_success = 0;
static const int sm_circle = -1;
static const int sm_badGraph = -2;
private:
int method_1_private() //юзается из "некийМетод" в случае успеха возвра sm_success
std::vector<int> m_state;
static const int sm_notVisited;
static const int sm_pcocessing;
static const int sm_finished;
};
const int TopologicalSorter::sm_notVisited = 0;
const int TopologicalSorter::sm_pcocessing = 1;
const int TopologicalSorter::sm_finished = 2;
т.е. вынес объявление статик членов за определение класса, т.ю. привел к классическому, так сказать, каноническому виду таких определений.
Вопрос2 - почему такие члены как sm_success или sm_badGraph успешно линкуются, а sm_notVisited, sm_pcocessing, sm_finished - нет?
Дело вероятно не в public/private (пробовал переносить в зону паблик эти три переменные, которые не линкуются). Доподленно известно что sm_notVisited, sm_pcocessing, sm_finished не используются нигде кроме класса в котором определены.
Но тем не менее: sm_badGraph и sm_circle так же используются только внутри класса, а вот sm_success имеет return наружу, но к слову и sm_badGraph, sm_circle косвенно тоже передаются наружу, через int error_code =
При этом нигде в коде-пользователе классом TopologicalSorter нет пользования этими переменными, что возвращает метод method_1, т.е. он вызывается как «процедура» в каком-то из классов-клиентов: TopologicalSorter sorter; sorter.method_1(input_output_container);