Opened 8 years ago

Closed 8 years ago

Last modified 8 years ago

#246 closed defect (fixed)

QML plugins cannot be loaded

Reported by: dmik Owned by:
Priority: major Milestone: Qt 4.7
Component: General Version: 4.6.3
Severity: low Keywords:
Cc:

Description

While playing with the QtDemo? application and QML demos/examples, I found that QtDeclarative cannot load its plugins (located in the imports subdirectory). Of course, due to the fact we use short DLL names.

A solution needs to be found.

Attachments (1)

qmlpluginfix.diff (3.0 KB) - added by rudi 8 years ago.
Name translation for qml plugins

Download all attachments as: .zip

Change History (8)

comment:1 Changed 8 years ago by rudi

Arrgh ! Reducing the module name length was really a stupid decision by IBM ! ISTR, that this was done for performance reason when they switech from 2.x to 3.0. Anyway, here is an attempt for a workaround. The idea ia to create a kind of symlink (i.e. a text file that contains the name of the real plugin dll). Seems to work here...

Changed 8 years ago by rudi

Name translation for qml plugins

comment:2 Changed 8 years ago by rudi

Just to add: First I thought about putting this info into the "qmldir" file. But I decided not to do so because I don't know what Nokia is going to do with that file and because it uses a so much less flexible structure than the *.pluginspec files in Creator.

Last edited 8 years ago by rudi (previous) (diff)

comment:3 Changed 8 years ago by dmik

Yes, short DLL names is really a big and fat PITA.

However, no "symlink"-like files are necessary. You can use qmldir itself for that. It contains lines "plugin <filename>" for each plugin DLL. You may simply put a short name there. This is what I will do.

I will also fix the version suffix (it should not be appended to QML plugin DLLs, it's just an accident resulting from my other change).

comment:4 Changed 8 years ago by rudi

As I said: I was not entirely sure if changing qmldir will have any side effects. Probably it has not... Just out of curiosity: how to change qmldir ? It looks like QMAKE_SUBSTITUTES (is that documented somewhere ???) is a possibility, but this stuff really looks like a hackish solution. So I guess we will end up using sed and add another tool to the requirements :-(. BTW, my fix did not include the solution for QtWebKit?...

comment:5 Changed 8 years ago by dmik

  • Resolution set to fixed
  • Status changed from new to closed

I checked the code parsing 'qmldir' and found that the plugin line does just that: defines what DLL to load. I also got understanding that this DLL name is not used anywhere else. There may be several plugin lines in the qmldir file and each just defines the DLL file name (and the third argument may also define the search path); all QML types defined by the plugins are defined by the special callback in the DLL, the DLL name doesn't seem to be involved in this process (and in fact, Symbian will also give different DLL names if I read the .pro file correctly).

The fix is in r1052 and r1053. The Same Game demo works now (I really suggest everybody to look at it if you haven't already done so -), as all other QML examples I could find.

comment:6 Changed 8 years ago by rudi

O.K. I see that you added a special *.cmd for that. Yesterday evening I played a bit with QMAKE_SUBSTITUTES and it turned out that this could be used as well given the following "qimportbase.pri":

QMLDIRFILE = $${_PRO_FILE_PWD_}/qmldir
QMAKE_SUBSTITUTES += $${QMLDIRFILE}.in
os2:!isEmpty(TARGET_SHORT):PLUGINFILENAME = $$TARGET_SHORT
else:PLUGINFILENAME = $$TARGET
copy2build.input = QMLDIRFILE
copy2build.output = $$QT_BUILD_TREE/imports/$$TARGETPATH/qmldir
!contains(TEMPLATE_PREFIX, vc):copy2build.variable_out = PRE_TARGETDEPS
copy2build.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
copy2build.name = COPY ${QMAKE_FILE_IN}
copy2build.CONFIG += no_link
# `clean' should leave the build in a runnable state, which means it shouldn't delete qmldir
copy2build.CONFIG += no_clean
QMAKE_EXTRA_COMPILERS += copy2build

and a file named "qmldir.in" with the following content:

plugin $$PLUGINFILENAME

in each of the plugin subdirs. QMake will create "qmldir" from "qmldir.in" by replacing $$PLUGINFILENAME. "qmldir" is then copied around as it used to be. This is the approach used by Creator to build the *.pluginspec files.

Alsp note that there is another Q_OS_WIN dependency in qdeclarativeimport.cpp. See http://svn.netlabs.org/qt4/browser/trunk/src/declarative/qml/qdeclarativeimport.cpp#L753.

comment:7 Changed 8 years ago by dmik

Yes, what you suggest will also work and this is much smarter than the dumb "fixed file" approach originally used by Nokia here. First, I didn't want to change the source structure so much (i.e. add/rename files) because it creates too much hassle when merging, but more thinking tells me that this is the right way to do upstream as well. Also, I didn't like this dumb cp-qmldir.cmd I had to create anyway...

I further optimized the QMAKE_SUBSTITUTES approach. It actually understands .input and .output suffixes which makes the whole copy2build thing unnecessary (and also doesn't require to generate files in the source directory which is definitely unwanted in shadow builds). I really wonder why the Qt guys didn't do that on their own. Now it looks much cleaner than the original Nokia solution (and than mine from r1053 too). See r1057.

The other Q_OS_OS2 dependency was overlooked by me. I fixed it in r1056. Thanks.

Note: See TracTickets for help on using tickets.