Recently, I've started a project under Qt5.1.0.
After some development, I choose to make a scripting system under Javascript with Google V8.
Under Windows 7 x64, the only way to compile V8 is under msvc2012, and I got 3 .lib files to use.
In a single project using ONLY V8, everything works well. But integrating V8 with an existent project using Qt5 it's a bit more complicated.
Here is an example of a minimal code I'm using : (Of course, there is more file in this project...)
#include <QApplication>
#include <v8.h>
using namespace v8;
int v8_test() {
Isolate* isolate = Isolate::GetCurrent();
HandleScope handle_scope(isolate);
Handle<Context> context = Context::New(isolate);
Persistent<Context> persistent_context(isolate, context);
Context::Scope context_scope(context);
Handle<String> source = String::New("'Hello' + ', World!'");
Handle<Script> script = Script::Compile(source);
Handle<Value> result = script->Run();
persistent_context.Dispose();
String::AsciiValue ascii(result);
printf("%s\n", *ascii);
return 0;
}
int main(int ac, char **av)
{
std::cout<<"Starting application"<<std::endl;
QApplication app(ac, av);
v8_test();
//Do something else
return app.exec();
}
At this point, I got a lot of linking errors of this type :
1>v8_base.x64.lib(api.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in moc_aCertainFile.obj
1>v8_base.x64.lib(v8threads.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in moc_aCertainFile.obj
1>v8_base.x64.lib(checks.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in moc_aCertainFile.obj
It seems that Qt was compiled with /MDd
flag, and V8 can only be compiled /MTd
flag.
After lot of research and testing, I was unable to find anything...
Anyone got a clue to resolve this problem?
Thanks in advance.
Google V8 is built by default with MT
flag and consequently incompatible with Qt which is build with MD
flag.
The trick to get it to build V8 with Qt is to make the V8 compilation in visual studio with MD
flag. You can do this with the following:
- Generate the Visual Studio projects by executing build\gyp_v8.py.
- Open all.sln with Visual Studio.
- In all projects from the solution set the MD flag: properties > C/C++ > Code Generation > Runtime Library > Multi-threaded DLL (/MD)
- After that rebuild the solution
- You will get the correct lib files to use with QtCreator.
In QtCreator proceed with the linkage of V8 libraries:
LIBS += -L/PATH_TO_LIBRARIES/ -lv8_base.ia32 -licui18n -licuuc -lv8_nosnapshot.ia32 -lv8_snapshot
You need also to link with WinMM.lib
, WS2_32.lib
and advapi32.lib
, they are normally found in: C:\Program Files (x86)\Windows Kits\
This made it on my system. I hope it helps other people with the same problem.
Well, I was unable to use V8 and Qt5 in this way, even after many tries to build Qt in static.
So, I wrote a .dll wrapper for V8, which can be integrated into my project on QtCreator.
Here is my wrapper :
WrapTest.hh:
#ifndef WRAPTEST_HH_
#define WRAPTEST_HH_
#include <iostream>
namespace v8w {
class WrapTest {
public:
static __declspec(dllexport) void hello();
};
}
#endif /* WRAPTEST_HH_ */
WrapTest.cpp:
#include <v8.h>
#include "WrapTest.hh"
void v8w::WrapTest::hello() {
std::cout<<"Hello, i'm V8 wrapper! :D"<<std::endl;
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HandleScope handle_scope(isolate);
v8::Handle<v8::Context> context = v8::Context::New(isolate);
v8::Persistent<v8::Context> persistent_context(isolate, context);
v8::Context::Scope context_scope(context);
v8::Handle<v8::String> source = v8::String::New("'Hello' + ', World!'");
v8::Handle<v8::Script> script = v8::Script::Compile(source);
v8::Handle<v8::Value> result = script->Run();
persistent_context.Dispose();
v8::String::AsciiValue ascii(result);
printf("%s\n", *ascii);
std::cout<<"End v8w::WrapTest::hello()"<<std::endl;
}
I've got WrapTest.hh, V8_Wrapper.lib and V8_Wrapper.dll, and a add the .lib to my .pro file into my Qt5 project :
LIBS += -L"$$_PRO_FILE_PWD_/lib"\
-lV8_Wrapper
In my Qt project, the main.cpp file :
#include <iostream>
#include <QApplication>
#include "WrapTest.hh"
void testV8() {
std::cout<<"test"<<std::endl;
v8w::WrapTest::hello();
}
int main(int ac, char **av) {
std::cout<<"Starting application"<<std::endl;
QApplication app(ac, av);
testV8();
return app.exec();
}
Which gave me in the standard output :
Starting application
test
Hello, i'm V8 wrapper! :D
Hello, World!
End v8w::WrapTest::hello()
I hope this solution can help you if you're in the need ^_^