by Nicolas Luck

Thursday, August 20, 2009

Compiling qtruby under MacOSX

Well.. It took me a while and cost some neural cells to get qtruby installed on my new MacBook.

After doing the tutorial for Basic principles of high frequency technics during the last semester I now have  time to resume work at my software that will be published along with PHOTOSS as soon as it’s done. PQueue is the name and after I had began this project in C++ I started over in Ruby just before the semester. Back then I used my Windows machine the chair gave me. But now I use my very cool MacBook Pro for everything. I really did look forward to writing Ruby code with Textmate on MacOSX…!

But! ..there are a lot of pitfalls one can fall into when trying to compile qtruby on MacOSX. To save you the hassle I had to go through I’m writing this post.

I’m using the latest  - at the time of writing – MacOSX 10.5.8. I already had Qt-4.5.2 installed. I’ve downloaded qt4-qtruby-2.0.3, decompressed it and tried

cmake .
make

but got

Can’t open perl script “2/kalyptus”: No such file or directory
make[2]: *** [smoke/qt/smokedata.cpp] Error 2
make[1]: *** [smoke/qt/CMakeFiles/smokeqt.dir/all] Error 2
make: *** [all] Error 2
lucksus:qt4-qtruby-2.0.3 2 nico$

I remembered there was a problem with this. My friend Wojtek already wrote a post concerning compiling qtruby under MacOSX. After reading this again I downloaded Qt-4.4.3 and qt4-qtruby-1.4.10. I don’t like packages that use a installer to spread their parts across my hard disk leaving me confused where everything went. So after seeing my first attempts failing I wanted a Qt source package. But for MacOSX you have to be sure to take the “mac” version. So download qt-mac-opensource-src-4.4.3.tar.bz2 from Trolltech’s (err.. Nokia’s) FTP server (not qt-all-opensource-src-4.4.3! Otherwise you will get something like “XEvent not declared…“). Then add QtWebKit to link.txt as Wojtek mentioned. Also notice my comment there stating to do the same with a second link.txt in another directory.

Now everything could be ok for you if you don’t have different Qt versions installed. What I got was

Undefined symbols:
make: *** [all] Err
Undefined symbols:
“QString::compare_helper(QChar const*, int, QChar const*, int, Qt::CaseSensitivity)”,
referenced from: QStringRef::compare(QString const&, Qt::CaseSensitivity) constin
libQtUiTools.a(abstractformbuilder.o)
“QBoxLayout::stretch(int) const”,
referenced from: __ZNK10QBoxLayout7stretchEi$non_lazy_ptr in libQtUiTools.a(formbuilderextra.o) “QBoxLayout::setStretch(int, int)”,
referenced from: __ZN10QBoxLayout10setStretchEii$non_lazy_ptr in libQtUiTools.a(formbuilderextra.o)
ld: symbol(s) not found
collect2: ld returned 1 exit status
make[2]: *** [smoke/qt/libsmokeqt.2.0.0.dylib] Error 1
make[1]: *** [smoke/qt/CMakeFiles/smokeqt.dir/all] Error 2
make: *** [all] Error 2

So some symbols referenced from libQtUiTools.a could not be found when linking. To see the compiler command line I entered

make VERBOSE=1

and got

Linking CXX shared library libsmokeqt.dylib cd /Users/nico/Desktop/qt4-qtruby-1.4.10/smoke/qt && /opt/local/bin/cmake -E cmake_link_script CMakeFiles/smokeqt.dir/link.txt –verbose=1 /usr/bin/c++ -dynamiclib -headerpad_max_install_names -compatibility_version 2.0.0 -current_version 2.0.0 -o libsmokeqt.2.0.0.dylib -install_name /Users/nico/Desktop/qt4-qtruby-1.4.10/smoke/qt/libsmokeqt.2.dylib CMakeFiles/smokeqt.dir/smokedata.o CMakeFiles/smokeqt.dir/x_1.o CMakeFiles/smokeqt.dir/x_2.o CMakeFiles/smokeqt.dir/x_3.o CMakeFiles/smokeqt.dir/x_4.o CMakeFiles/smokeqt.dir/x_5.o CMakeFiles/smokeqt.dir/x_6.o CMakeFiles/smokeqt.dir/x_7.o CMakeFiles/smokeqt.dir/x_8.o CMakeFiles/smokeqt.dir/x_9.o CMakeFiles/smokeqt.dir/x_10.o CMakeFiles/smokeqt.dir/x_11.o CMakeFiles/smokeqt.dir/x_12.o CMakeFiles/smokeqt.dir/x_13.o CMakeFiles/smokeqt.dir/x_14.o CMakeFiles/smokeqt.dir/x_15.o CMakeFiles/smokeqt.dir/x_16.o CMakeFiles/smokeqt.dir/x_17.o CMakeFiles/smokeqt.dir/x_18.o CMakeFiles/smokeqt.dir/x_19.o CMakeFiles/smokeqt.dir/x_20.o -F/usr/local/Trolltech/Qt-4.4.3/lib -framework QtNetwork -F/usr/local/Trolltech/Qt-4.4.3/lib -framework QtOpenGL -F/usr/local/Trolltech/Qt-4.4.3/lib -framework QtDBus -F/usr/local/Trolltech/Qt-4.4.3/lib -framework QtSql -F/usr/local/Trolltech/Qt-4.4.3/lib -framework QtSvg /usr/lib/libQtUiTools.a -F/usr/local/Trolltech/Qt-4.4.3/lib -framework QtXml -F/usr/local/Trolltech/Qt-4.4.3/lib -framework QtWebKit -F/usr/local/Trolltech/Qt-4.4.3/lib -framework Qt3Support -F/usr/local/Trolltech/Qt-4.4.3/lib -framework QtCore -lpthread -F/usr/local/Trolltech/Qt-4.4.3/lib -framework QtGui
Undefined symbols:
“QString::compare_helper(QChar const*, int, QChar const*, int, Qt::CaseSensitivity)”,
referenced from: QStringRef::compare(QString const&, Qt::CaseSensitivity) constin
libQtUiTools.a(abstractformbuilder.o)
“QBoxLayout::stretch(int) const”,
referenced from: __ZNK10QBoxLayout7stretchEi$non_lazy_ptr in libQtUiTools.a(formbuilderextra.o)

Whoops! libQtUiTools.a is taken from /usr/lib while my self-compiled Qt install resides in /usr/local/Trolltech/Qt-4.4.3. So libQtUiTools.a must be from another Qt install. To fix this you have to alter link.txt again and replace /usr/lib/libQtUiTools.a with /usr/local/Trolltech/Qt-4.4.3/lib/libQtUiTools.a or whatever is right for you.

Boy, anybody has to improve qtruby’s installation process for macs, perhaps by creating a binary gem as it already exists for Windows…?

posted by lucksus at 5:34 pm  

Thursday, February 12, 2009

cygwin and undefined reference to `__getreent’

I’m trying to switch from Visual Studio to Qt Creator. Since I used qmake for the project I want to develop right from the start this should not be too dificult. But Qt Creator uses GCC (on Windows MinGW). So I’m also switching from Microsofts Compiler to MinGW.

This should not be a problem neither.. But I’m using LAPACK! More precisely CLAPACK. Somwhere on the net I found a clapack.lib when I started that project. But now I had to compile CLAPACK myself.

So I downloaded the CLAPACK sources and compiled them in cygwin (perhaps that was the problem. should have used the MinGW I use in Qt Creator..? Well, compiling CLAPACK under Windows with MinGW and without Cygwin isn’t that easy). Then I copied liblapack.a, libblas.a and libf2c.a into the lib directory of my Qt Creator-MinGW installation. And then I got:
C:/Qt/QtCreator/mingw/bin/../lib/gcc/mingw32/3.4.5/../../../libf2c.a(f77_aloc.o):(.text+0×2a): undefined reference to `__getreent’
After some googling I found out that what’s missing is libcygwin.a, which comes with cygwin (/lib in the cygwin directory). I copied this file to the MinGW installation’s lib directory and added a -lcygwin and the undefined reference was gone.

Edit:
That was not all. Now I get:
C:/MinGW/bin/../lib/gcc/mingw32/3.4.2/../../../libcygwin.a(d000681.o)(.text+0×0): multiple definition of `atexit’
C:/MinGW/bin/../lib/gcc/mingw32/3.4.2/../../../crt2.o(.text+0×260):crt1.c: first defined here

I solved this by overwriting MinGW’s crt2.o with cygwin’s crt0.o. Now I have a cygwinized MinGW installation with a working lapack compilation and I can use Qt Creator to compile my project! Only drawback is that I now have to deploy the cygwin.dll together with the executable.

posted by lucksus at 2:24 pm  

Wednesday, January 14, 2009

Qt under LGPL

From version 4.5 (coming March 2009) Qt will be available under the LGPL additionaly to the GPL and the commercial license. This is very good news because everyone will be able to use this cute C++ library (which in my opinion makes C++ A LOT more usable) even in commercial projects without having to pay for a commercial license.

Question is, why is Nokia so kind to donate Qt to.. well to every C++ programmer? [From their FAQ:]

What does Nokia hope to accomplish with this new strategy?
Our aim is to:

* To establish Qt as the de facto standard for rich UI
and application development, ensuring that there is a
vibrant ecosystem of application developers for Nokia
devices and other platforms
* Ensure that Qt is of the highest quality possible with
good supporting tools and services such that Nokia is
able to get devices to market faster, and with better
software. The widespread use of Qt translates into greater
richness and stability across and between platforms.
* By spreading Qt usage as widely as possible and
establishing a robust ecosystem, Nokia will gain access
to true cross-platform APIs for developing applications
and services once, and deploying them across desktops,
devices and the web without rewriting the source code.

So they want everybody to use (and improve) Qt so that there are many applications which can easily be ported to their mobile phones..;)

Also from the FAQ:

What platforms (operating systems) does the licensing
change apply to?

We will license Qt under the LGPL for all platforms we
currently support. This includes Windows, Linux/X11,
Mac OS X, Windows CE, embedded Linux, and the
upcoming S60 port.
posted by lucksus at 5:05 pm  

Wednesday, January 14, 2009

libxml-ruby on windows

At HFT we are working on a (RESTful) webservice extension to our CBRSuite. To test this webservice I chose to use RSpec and Cucumber, which allows to write runnable specifications like

Feature: getting a list of provided graphs
 I want to get a list of provided graphs
 So that I am able to create a simulation
 by referencing a graph to use

Scenario: standard
 When getting '/graphs'
 Then the response is a valid XML document
 And the response has a root element called 'graphs'
 And the response has a root element with at least one child
 And the response's nodes 'graph/graphs/*' all have text

given these steps are implemented in Ruby like

When /^getting '(.*)'$/ do |resource|
 @response = Net::HTTP.get host, resource, 80
end

Then /^the response has a root element called '(.*)'$/ do |rootname|
 doc = REXML::Document.new(@response)
 doc.root.name.should == rootname
end
...

See RSpec and Cucumber for more information on this cool way of writing specifications.

Our webservice responds by sending XML back to the client. These XML fragments are specified by XML Schema Definitions. To check if the genereted XML is valid according to the XSDs I don’t want to check every tag manualy (as in the example above). I want to write something like

Scenario: standard
 When getting '/graphs'
 Then the response is a valid XML document
 And the response is a valid 'http://cbrsuite/graph.xsd' XSD

So I need to check a XML document against a given XSD in Ruby. REXML does not (yet?) support XML validation but libxml-ruby does. But if you are bound to Windows for some reason you may encouter problems when trying to use libxml-ruby (as I did). I had Ruby and Ruby Gems installed via the one-click-installer. All further Ruby packages I had installed via gems. When using libxml-ruby I got

c:/ruby/lib/ruby/gems/1.8/gems/libxml-ruby-0.9.7-x86-mswin32-60/lib/libxml_ruby.so:
127: Die angegebene Prozedur wurde nicht gefunden.
- c:/ruby/lib/ruby/gems/1.8/gems/libxml-ruby-0.9.7-x86-mswin32-60/lib/libxml_ruby.so (LoadError)
Failed to load steps.rb from c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in
`require'
        from c:/ruby/lib/ruby/gems/1.8/gems/libxml-ruby-0.9.7-x86-mswin32-60/lib/libxml.rb:12
        from c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
        from c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
        from c:/ruby/lib/ruby/gems/1.8/gems/libxml-ruby-0.9.7-x86-mswin32-60/lib/xml.rb:11
        from c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:36:in `gem_original_require'
        from c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:36:in `require'
        from ./steps.rb:4
         ... 6 levels...
        from c:/ruby/lib/ruby/gems/1.8/gems/cucumber-0.1.15/bin/../lib/cucumber/cli.rb:14:in `execute'
        from c:/ruby/lib/ruby/gems/1.8/gems/cucumber-0.1.15/bin/cucumber:6
        from c:/ruby/bin/cucumber:16:in `load'
        from c:/ruby/bin/cucumber:16

In order to fix this I tried installing libiconv manually and reinstalling libxml-ruby afterwards (manually and via gems), but to no avail..

To be able to use libxml-ruby under Windows I had to use cygwin. I installed Ruby, libiconv, libxml and the gcc via the cygwin setup. Then I downloaded Ruby Gems and installed it manually in cygwin. Installing libxml-ruby via the cygwin-gems would not work:

$ gem install libxml-ruby
Building native extensions.  This could take a while...
ERROR:  Error installing libxml-ruby:
 ERROR: Failed to build gem native extension./usr/bin/ruby.exe extconf.rb install libxml-ruby
checking for socket() in -lsocket... no
checking for gethostbyname() in -lnsl... no
checking for atan() in -lm... no
checking for atan() in -lm... yes
checking for inflate() in -lz... yes
checking for iconv_open() in -liconv... no
checking for libiconv_open() in -liconv... yes
checking for xmlParseDoc() in -lxml2... no
checking for xmlParseDoc() in -llibxml2... no
checking for xmlParseDoc() in -lxml2... no
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.
...

So I downloaded libxml2 and compiled and installed it under cygwin myself. After this gems was able to install libxml-ruby

$ gem install libxml-ruby
Building native extensions.  This could take a while...
Successfully installed libxml-ruby-0.9.7
1 gem installed
Installing ri documentation for libxml-ruby-0.9.7...

Enclosing class/module 'cXMLParser' for class Context not known

Enclosing class/module 'mXPath' for class Context not known

Enclosing class/module 'mXPath' for class Expression not known

Enclosing class/module 'mXPath' for class Object not known
Installing RDoc documentation for libxml-ruby-0.9.7...

Enclosing class/module 'cXMLParser' for class Context not known

Enclosing class/module 'mXPath' for class Context not known

Enclosing class/module 'mXPath' for class Expression not known

Enclosing class/module 'mXPath' for class Object not known

and everything worked fine!

posted by lucksus at 3:44 pm  

Wednesday, November 19, 2008

Qt TextMate Bundle

Now that’s cool.. I just stumbled across a TextMate bundle for Trolltech’s Qt. Here’s the blog post from its creator. You can get a checkout from the official TextMate bundle server with:svn co http://svn.textmate.org/trunk/Bundles/C++%20Qt.tmbundle/Too bad it seems the Documentation for Word command won’t work with the newest Qt version (4.4.3)…

posted by lucksus at 9:23 pm  

Wednesday, October 15, 2008

Non equidistant slider

Ever needed a widget which allows to select a double value out of a set of given values? You could use a combo box. Not very nice… Sliders are much more convenient to use but QSlider (which comes with Qt) can only be used to let the user select a value out of some equidistant spaced values. E.g. 1, 2, 3 … 10. What if you want the user to choose from say 5, 10, 12.34, 23.1, 30, 38? You have to write your own widget… Here’s what i came up with.

It looks like this:

nonEquidistantSlider

I subclassed QWidget and implemented paint-, mouseMove- and mousePressEvent() and added some signals and slots. You just have to set the values and connect to the valueChanged(double) signal.

Use it like this:

QList<double> values;
values << 5 << 10 << 12.24 << 23.1 << 30 << 38;

NonEquidistantSlider* slider = new NonEquidistantSlider(this);
slider->setValues(values);
connect(slider,SIGNAL(valueChanged(double)),
this,SLOT(setValue(double));

You can download und use my code as you like: NonEquidistantSlider.h NonEquidistantSlider.cpp

posted by lucksus at 12:59 pm  

Wednesday, March 12, 2008

Blogging from TextMate

This video just tought me how to post to a blog by using the best editor ever: TextMate. I needed to try it myself. So this is my first post I wrote with TextMate.. ;)

posted by lucksus at 12:11 am  

Friday, March 7, 2008

Nice Refactoring C++ plugin for Visual Studio

Say you want to change some method’s name. But the method is very often referenced. So unless you have a nice refactoring tool you have to find all that references and change them manually. You’ll soon think that’s the sort of task computers were made for..Eclipse for example can do this for you. You only have to right click the method’s name and choose “change name”. I’ve searched for something similar for Microsoft’s Visual Studio C++ some time ago. I only found expensive commercial plugins which I didn’t like much. But today I stumbled across Refactor! for C++ which is free and looks very nice..

Edit:

Well, I’m sorry. I’m quite disappointed by this tool. “Extract Method” works very well. But that’s it. “Rename” only works within a method. You cannot rename a class and if you try to rename a class’ member no reference to that member is updated. So it’s useless.. The reason might be that the references are in the .cpp file but I’m starting the refactoring while editing the .h file. Perhaps the real features are limited to the commercial pro version..

posted by lucksus at 10:41 am  

Monday, February 4, 2008

Condor C++ Adapter

For my diploma thesis I’m using the grid computing software Condor to distribute complex computations among multiple workstations. After installing Condor on all machines all you have to do is writing a Condor job file and submit this job with Condor’s command line tool “condor_submit”. Condor will copy over the executable (which was specified in that job file) to any idle machine, execute it and copy back any created output files. You don’t have to bother which machines are occupied and you even don’t need an user account on that machine. Condor creates an user account for every job and removes that account when the job is finished. So it’s a quite convenient way to distribute computations.

But you have to write that job file, wait for the job to return and then collect the output files. To automate this wouldn’t it be nice to use a Condor pool out of your code? There is a Java lib which does this. But since I’m writing a C++ app for my diploma thesis I wonder why I could not find something similar written in C++. So I did it myself..

I present the missing Condor C++ Adapter! It’s a C++ library depending on Qt. It incorporates Condor and Condor jobs and is used like this:


Job j1("~/my_working_dir","/usr/local/bin/calculation");
j1.addFileToBeTransfered("~/my_working_dir/data_file");
j1.addArgument("--data data_file");
Condor::getInstance().submit(j1);

while(j1.getState() != _finished){
Sleep(2000);
}

Qt is needed for threading and for its signals and slots. A Job object has signals like started() and finished() which can be connected to your slot instead of using the while(j1.geState() != _finished) loop. So if you have a Qt event loop and a class with some slot you could also write something like this:

connect(&j1, SIGNAL(finished()), this, SLOT(jobFinished());

The code is documented with Qt-style comments which could be read by doxygen.

You can download a tarball here and use this code for your noncommercial as well as commercial projects with out asking or something else (but you need an apropriate Qt licence of course). I will provide an update shortly as soon as I need more features myself.. ;)

 

CondorC++Adapter Homepage and Documentation

posted by lucksus at 3:17 pm  

Sunday, February 3, 2008

Finally

I planed on creating a website for my own for a long time now. Finally I managed to do so. Actually i wanted to build it from scratch but since I don’t have much time while working on my diploma thesis I just wanted to give a blogging software like WordPress a go. After trying out and customizing numerous themes I’m quit happy with the result… Although it’s not finished yet please let me know if you like it!

posted by lucksus at 10:35 pm  

Powered by WordPress