Is it really not mandatory to use DBO_EXTERN_TEMPLATES and DBO_INSTANTIATE_TEMPLATES?
I have read
https://redmine.emweb.be/boards/2/topics/4238
and
https://www.mail-archive.com/witty-interest@lists.sourceforge.net/msg06963.html
and a few others and I understand that using DBO_EXTERN_TEMPLATES and DBO_INSTANTIATE_TEMPLATES is to optimize compilation speed and in normal case there is no need to use them while my code does not compile without them. The error is as follows:
g++ ./build/./src/navigationBar.cpp.o ./build/./src/howToSolveSecion.cpp.o ./build/./src/Session.cpp.o ./build/./src/questionsSection.cpp.o ./build/./src/servicesSection.cpp.o ./build/./src/heroSection.cpp.o ./build/./src/User.cpp.o ./build/./src/footerSection.cpp.o ./build/./src/database/DbUser.cpp.o ./build/./src/main.cpp.o ./build/./src/MyAuthWidget.cpp.o -o out.wt -std=c++14 -lwthttp -lwt -lwtdbosqlite3 -lwtdbo
/usr/bin/ld: ./build/./src/main.cpp.o: in functionvoid Wt::Dbo::persist<DbUser, void>::apply<Wt::Dbo::InitSchema>(DbUser&, Wt::Dbo::InitSchema&)':
void DbUser::persistWt::Dbo::InitSchema(Wt::Dbo::InitSchema&)'
main.cpp:(.text._ZN2Wt3Dbo7persistI6DbUservE5applyINS0_10InitSchemaEEEvRS2_RT_[_ZN2Wt3Dbo7persistI6DbUservE5applyINS0_10InitSchemaEEEvRS2_RT_]+0x23): undefined reference to
/usr/bin/ld: ./build/./src/main.cpp.o: in functionvoid Wt::Dbo::persist<DbUser, void>::apply<Wt::Dbo::DropSchema>(DbUser&, Wt::Dbo::DropSchema&)':
void DbUser::persistWt::Dbo::DropSchema(Wt::Dbo::DropSchema&)'
main.cpp:(.text._ZN2Wt3Dbo7persistI6DbUservE5applyINS0_10DropSchemaEEEvRS2_RT_[_ZN2Wt3Dbo7persistI6DbUservE5applyINS0_10DropSchemaEEEvRS2_RT_]+0x23): undefined reference to
/usr/bin/ld: ./build/./src/main.cpp.o: in functionvoid Wt::Dbo::persist<DbUser, void>::apply<Wt::Dbo::LoadDbAction<DbUser> >(DbUser&, Wt::Dbo::LoadDbAction<DbUser>&)':
void DbUser::persistWt::Dbo::LoadDbAction
main.cpp:(.text._ZN2Wt3Dbo7persistI6DbUservE5applyINS0_12LoadDbActionIS2_EEEEvRS2_RT_[_ZN2Wt3Dbo7persistI6DbUservE5applyINS0_12LoadDbActionIS2_EEEEvRS2_RT_]+0x23): undefined reference to>(Wt::Dbo::LoadDbAction&)'
/usr/bin/ld: ./build/./src/main.cpp.o: in functionvoid Wt::Dbo::persist<DbUser, void>::apply<Wt::Dbo::SaveBaseAction>(DbUser&, Wt::Dbo::SaveBaseAction&)':
void DbUser::persistWt::Dbo::SaveBaseAction(Wt::Dbo::SaveBaseAction&)'
main.cpp:(.text._ZN2Wt3Dbo7persistI6DbUservE5applyINS0_14SaveBaseActionEEEvRS2_RT_[_ZN2Wt3Dbo7persistI6DbUservE5applyINS0_14SaveBaseActionEEEvRS2_RT_]+0x23): undefined reference to
/usr/bin/ld: ./build/./src/main.cpp.o: in functionvoid Wt::Dbo::persist<DbUser, void>::apply<Wt::Dbo::SaveDbAction<DbUser> >(DbUser&, Wt::Dbo::SaveDbAction<DbUser>&)':
void DbUser::persistWt::Dbo::SaveDbAction
main.cpp:(.text._ZN2Wt3Dbo7persistI6DbUservE5applyINS0_12SaveDbActionIS2_EEEEvRS2_RT_[_ZN2Wt3Dbo7persistI6DbUservE5applyINS0_12SaveDbActionIS2_EEEEvRS2_RT_]+0x23): undefined reference to>(Wt::Dbo::SaveDbAction&)'
/usr/bin/ld: ./build/./src/main.cpp.o: in functionvoid Wt::Dbo::persist<DbUser, void>::apply<Wt::Dbo::TransactionDoneAction>(DbUser&, Wt::Dbo::TransactionDoneAction&)':
void DbUser::persistWt::Dbo::TransactionDoneAction(Wt::Dbo::TransactionDoneAction&)'
main.cpp:(.text._ZN2Wt3Dbo7persistI6DbUservE5applyINS0_21TransactionDoneActionEEEvRS2_RT_[_ZN2Wt3Dbo7persistI6DbUservE5applyINS0_21TransactionDoneActionEEEvRS2_RT_]+0x23): undefined reference to
My codes are as follows:
DbUser.h :
#include <string>
#include <Wt/Dbo/Dbo.h>
#include <Wt/Dbo/backend/Sqlite3.h>
#include <Wt/Dbo/Session.h>
#include <Wt/Dbo/Transaction.h>
#include <Wt/Dbo/DbAction.h>
#include <Wt/Dbo/ptr.h>
#include <Wt/Dbo/SqlConnection.h>
#include <Wt/Dbo/Field.h>
class DbUser
{
private:
/* data */
std::string userName_;
std::string passwordHash_;
public:
DbUser(/* args */);
~DbUser();
template <class Action>
void persist (Action& a);
};
DbUser.cpp :
#include "DbUser.hpp"
#include <Wt/Dbo/Dbo.h>
DbUser::DbUser(/* args */)
{
}
DbUser::~DbUser()
{
}
template <class Action>
void DbUser::persist (Action& a)
{
Wt::Dbo::field (a, userName_, "username");
Wt::Dbo::field (a, passwordHash_, "passwordHash");
}
main.c :
...
#include "database/DbUser.hpp"
#include <Wt/Dbo/Dbo.h>
#include <Wt/Dbo/backend/Sqlite3.h>
#include <Wt/Dbo/Session.h>
#include <Wt/Dbo/Transaction.h>
#include <Wt/Dbo/DbAction.h>
#include <Wt/Dbo/ptr.h>
class Test : public Wt::WApplication
{
private:
/* data */
void initDB (void);
public:
Test (const Wt::WEnvironment &env);
~Test();
};
Test::Test (const Wt::WEnvironment &env) : Wt::WApplication(env)
{
...
}
Raha::~Raha()
{
}
void Test::initDB (void)
{
auto sqlite3 = std::make_unique<Wt::Dbo::backend::Sqlite3>("myDB.db");
Wt::Dbo::Session session;
session.setConnection(std::move(sqlite3));
session.mapClass<DbUser>("user");
session.createTables();
}
int main (int argc, char **argv)
{
return Wt::WRun (argc, argv, [](const Wt::WEnvironment &env){
return (std::make_unique<Test>(env));
});
}
Why my compiler can not instantiate the template code automatically?
My compiler is:
gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
Replies (3)
RE: Is it really not mandatory to use DBO_EXTERN_TEMPLATES and DBO_INSTANTIATE_TEMPLATES? - Added by Matthias Van Ceulebroeck 9 days ago
It seems there is some cyclic including going on. It can be avoided, by not calling Wt/Dbo/Impl.h
too soon.
Weirdly, Wt::Dbo::Dbo
is part of Wt/Dbo/ptr.h
. Whereas I would expect this in Wt/Dbo/Dbo.h
.
This ought to be included in the header. If you want to specify class DbUser : public Wt::Dbo::Dbo<DbUser>
.
In case you do not, you can just drop all Wt/Dbo
inclusions in DbUser.h(pp)
.
That should resolve your compilation issue. I'll look a little further into this.
RE: Is it really not mandatory to use DBO_EXTERN_TEMPLATES and DBO_INSTANTIATE_TEMPLATES? - Added by Ali Ali 8 days ago
Actually, I added the all Wt/Dbo
inclusions in DbUser.h(pp)
before finding DBO_EXTERN_TEMPLATES
and DBO_INSTANTIATE_TEMPLATES
to fix the problem. Anyway, I did what you said, but the problem still remains.
RE: Is it really not mandatory to use DBO_EXTERN_TEMPLATES and DBO_INSTANTIATE_TEMPLATES? - Added by Matthias Van Ceulebroeck 7 days ago
I apologize, I had performed other changes as well, that caused this to compile.
You can move the implementation of DbUser::persist
to the header. Then it should all compile nicely.