A case study: how to compile a Fcitx platforminputcontext plugin for a proprietary software that uses Qt 5

Due to the fact, that Qt 5 does not support XIM, the only way to type with fcitx under Qt is to use platforminputcontext plugin. The problem is that for some proprietary software like mathematica, it is impossible to use the system Qt plugin because the Qt version does not match (also the library path may not be correct).

If the proprietary software uses shared library version of Qt, it is still possible to get a special version of platforminputcontext plugin compiled. Though, they may have private modification on the Qt library, but it is highly likely the plugin interface is not changed so we can compile it with official Qt 5 source code but link to the private shared Qt library in the proprietary software. So here’s how I did it for mathematica.

First, you need to figure out which version of Qt that the software is using, this can be done easily by using some very hacky tool like strings / objdump since Qt encode it’s compilation info in Qt5Core library in string literals.

$ strings /opt/Mathematica/SystemFiles/Libraries/Linux-x86-64/libQt5CoreWRI.so.5 | grep "Qt 5"
Qt 5.6.2 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 4.8.2 20140120 (Red Hat 4.8.2-15))
This is the QtCore library version Qt 5.6.2 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 4.8.2 20140120 (Red Hat 4.8.2-15))
If that is not possible, in Qt 5 you must at least reimplement

Now we know it’s Qt 5.6.2. Then we can go to Qt’s offical site to download a official version of Qt 5.6.2. http://download.qt.io/official_releases/qt/5.6/5.6.2/ You can just use the QtCreator bundled with in it so it’ll be much easier to get compilation argument right.

Then, use QtCreator and choose import project from Git, https://github.com/fcitx/fcitx-qt5/ , and select the Qt that comes with your installation, instead of your system Qt 5. I managed to make fcitx-qt5 plugin standalone recently, so it will be really easy to get it compiled.

But remember, we need to link it against the mathematica’s Qt, instead of the Qt binary that we just installed.  The problem is, Qt relies on qmake to find the library path, and it is hard to make it find the mathematica’s Qt. In order to solve this problem, we can directly hack the final link command line generated by cmake.

First, cd to the right path. fcitx-qt5’s plugin does not rely on fcitx-qt5’s library any more, so it is possible to only compile and copy the plugin library. If you already compiled it with QtCreator, you need to run make clean first. So here’s what it looks like:

# Locate the build-fcitx-qt5-Desktop_Qt_5_6_2_GCC_64bit-Default directory.
cd platforminputcontext/
make clean
make VERBOSE=1

Pay attention to the last command, it may looks like this:

/usr/bin/c++ -fPIC -std=c++11 -Wall -Wl,--no-undefined -shared -o libfcitxplatforminputcontextplugin.so CMakeFiles/fcitxplatforminputcontextplugin.dir/fcitxinputcontextproxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/fcitxqtdbustypes.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/fcitxwatcher.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/qfcitxplatforminputcontext.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/main.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/qtkey.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/inputcontextproxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/inputcontext1proxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/inputmethodproxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/inputmethod1proxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/fcitxplatforminputcontextplugin_autogen/moc_compilation.cpp.o -Wl,-rpath,/home/saber/Develop/build/Qt560/5.6/gcc_64/lib: /home/saber/Develop/build/Qt560/5.6/gcc_64/lib/libQt5Gui.so.5.6.2 /home/saber/Develop/build/Qt560/5.6/gcc_64/lib/libQt5DBus.so.5.6.2 /usr/lib/libxkbcommon.so /home/saber/Develop/build/Qt560/5.6/gcc_64/lib/libQt5Core.so.5.6.2

You’ll need to replace the Qt library with the one comes with mathematica.

/usr/bin/c++ -fPIC -std=c++11 -Wall -Wl,--no-undefined -shared -o libfcitxplatforminputcontextplugin.so CMakeFiles/fcitxplatforminputcontextplugin.dir/fcitxinputcontextproxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/fcitxqtdbustypes.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/fcitxwatcher.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/qfcitxplatforminputcontext.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/main.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/qtkey.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/inputcontextproxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/inputcontext1proxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/inputmethodproxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/inputmethod1proxy.cpp.o CMakeFiles/fcitxplatforminputcontextplugin.dir/fcitxplatforminputcontextplugin_autogen/moc_compilation.cpp.o /opt/Mathematica/SystemFiles/Libraries/Linux-x86-64/libQt5CoreWRI.so.5 /opt/Mathematica/SystemFiles/Libraries/Linux-x86-64/libQt5DBusWRI.so.5 /opt/Mathematica/SystemFiles/Libraries/Linux-x86-64/libQt5GuiWRI.so.5 /usr/lib/libxkbcommon.so

Also remember to remove the rpath option from it. If the command finishes successfully, now you’ll get an usable fcitx plugin for mathematica. Then just copy it to the right directory:

sudo cp libfcitxplatforminputcontextplugin.so /opt/Mathematica/SystemFiles/Libraries/Linux-x86-64/Qt-Plugins/platforminputcontexts/

Then you can enjoy typing with fcitx in mathematica.

The directory path above need to be adjusted based on your own system.

This entry was posted in fcitx development and tagged , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

Note: Commenter is allowed to use '@User+blank' to automatically notify your reply to other commenter. e.g, if ABC is one of commenter of this post, then write '@ABC '(exclude ') will automatically send your comment to ABC. Using '@all ' to notify all previous commenters. Be sure that the value of User should exactly match with commenter's name (case sensitive).