Reputation: 157
I have a problem with linking my project. I'm trying to create shared library which could be used between three different projects. This library will be used for parsing XML files and general handling with objects from these XML files.
Here is minimal example which is affected. Library project consist of these files
============= Library.cpp =============
#include "library.h"
Library::Library(QString name){
this->name = name;
}
============= Library.h =============
#ifndef LIBRARY_H
#define LIBRARY_H
#include <QString>
class Library
{
public:
Library(QString name);
private:
static QString name;
};
#endif // LIBRARY_H
============= Library.pro =============
QT -= gui
TARGET = Library
TEMPLATE = lib
CONFIG += staticlib
SOURCES += library.cpp
HEADERS += library.h
unix {
target.path = /usr/lib
INSTALLS += target
}
Main application is made by these files.
============= main.c =============
#include <QCoreApplication>
#include "library.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Library lib("MyLib");
return a.exec();
}
============= Application.pro =============
QT += core
QT -= gui
TARGET = Application
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
SRCDIR = $$IN_PWD/../Library
INCLUDEPATH += $$SRCDIR
SRCDIR = $$IN_PWD/../Library
INCLUDEPATH += $$SRCDIR
LIBDIR = $$IN_PWD/../build-Library-Desktop_Qt_5_5_1_GCC_64bit-Ladění/libLibrary.a
LIBS += $$LIBDIR
Here is the output of linker
g++ -c -pipe -g -Wall -W -D_REENTRANT -fPIC -DQT_CORE_LIB -I../Application -I. -I../Library -I../Library -I../../../Qt/5.5/gcc_64/include -I../../../Qt/5.5/gcc_64/include/QtCore -I. -I../../../Qt/5.5/gcc_64/mkspecs/linux-g++ -o main.o ../Application/main.cpp
g++ -Wl,-rpath,/home/mint/Qt/5.5/gcc_64 -Wl,-rpath,/home/mint/Qt/5.5/gcc_64/lib -o Application main.o /home/mint/Development/test/Application/../build-Library-Desktop_Qt_5_5_1_GCC_64bit-Ladění/libLibrary.a -L/home/mint/Qt/5.5/gcc_64/lib -lQt5Core -lpthread
/home/mint/Development/test/Application/../build-Library-Desktop_Qt_5_5_1_GCC_64bit-Ladění/libLibrary.a(library.o): In function `Library::Library(QString)':
Makefile:214: recipe for target 'Application' failed
/home/mint/Development/test/build-Library-Desktop_Qt_5_5_1_GCC_64bit-Ladění/../Library/library.cpp:6: undefined reference to `Library::name'
collect2: error: ld returned 1 exit status
When I change static QString name in Library.h to non static variable, then everything is ok. It could be linked then. I think, that project files are setup correctly, but what am I missing ?
Upvotes: 0
Views: 1639
Reputation: 583
in C++, static member should be defined and initialized outside the class declaration.
============= Library.h =============
#ifndef LIBRARY_H
#define LIBRARY_H
#include <QString>
class Library
{
public:
Library(QString name);
private:
static QString name;// declare
};
#endif // LIBRARY_H
============= Library.cpp =============
#include "library.h"
//add this line if name is static member of Library
QString Library::name;// define and initialize
//you can also initialize it to other value like:
//QString Library::name = "banana!";
Library::Library(QString name){
this->name = name;
}
Upvotes: 0
Reputation: 62898
In C++, static
member variables are essentially global exported "class variables" (so very different from other static
variables, in a sense even opposite, you make file scope variables static to avoid them being exported globals).
And in that .h file, you only have variable declaration: you declare that this kind of variable exists, somewhere.
However, to actually make it exist for real, you have to define it. Therefore you need to add this to one .cpp
file:
QString Library::name = QStringLiteral("initial value");
Additionally, it is class variable, so you (probably) shouldn't change it every time an instance is created, so your consturctor would be just:
Library::Library() {
}
If you want to initialize it from somewhere else (quite probably main()
, to replace the code in your constructor, simply assign to it:
Library::name = whatever;
However, if you actually want to have it as instance variable (each instance/object of the class has its own copy), then just remove static
from the definition in the .h file.
Also, with global variables (including static
class variables), you have to be careful about initialization order. They're also global variables, with all the trouble that can bring. So, if you don't really need them, don't use them.
Upvotes: 1