Mind Ramblings My Blog

Reconfiguring building and Travis Setup

This week was one of the most engaging one for me up until now. Not in a way that I could write thousands of lines of code, but more like I intensively collaborated with people online, to debug code. Many errors popped up, I discussed them with team-mates and we arrived at a solution(it was more like them telling me the solution :P). This whole week was spend trying to debug errors and get the wrappers to work and get integrated with Travis-CI. I will explain how we tackled them, one by one. I got done with so many things this week, that I am confused where to begin.

Problems in project setup and building

After solving the LoadError for the extensions. One of the other errors that we faced was something like this, a symbol lookup error

2.2.0 :001 > require 'symengine'
 => true
2.2.0 :002 > a = SymEngine::Basic.new
irb: symbol lookup error: /home/abinashmeher999/.rvm/gems/ruby-2.2.0/gems/symengine-0.0.0.pre/lib/symengine/symengine.so: undefined symbol: basic_init

The library for the extensions symengine.so wasn’t able to find the library at runtime. It was very much dependent if the library for symengine libsymengine was compiled as a static or dynamic library. And in my case, I had the static version(libsymengine.a) and I had to make and install the dynamic version(libsymengine.so). This solved the issue, but again there was another error

2.2.0 :001 > require 'symengine'
LoadError: /home/abinashmeher999/.rvm/gems/ruby-2.2.0/gems/symengine-0.0.0.pre/lib/symengine/symengine.so: undefined symbol: __cxa_pure_virtual - /home/abinashmeher999/.rvm/gems/ruby-2.2.0/gems/symengine-0.0.0.pre/lib/symengine/symengine.so
    from /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
    from /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
    from /home/abinashmeher999/.rvm/gems/ruby-2.2.0/gems/symengine-0.0.0.pre/lib/symengine.rb:1:in `<top (required)>'
    from /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:128:in `require'
    from /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:128:in `rescue in require'
    from /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:39:in `require'
    from (irb):1
    from /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/bin/irb:11:in `<main>'

Now this symbol is defined in the C++ standard library. I had to compile the C wrappers using a C++ compiler to link against it. I configured the extconf.rb to use a C++ compiler.

One of our aims during developing this was to get rid of unessential dependencies. The ones we already had the tools for. Like later the file extconf.rb, that is used to generate Makefile for the extension was removed, because that could also be done by cmake. Flags were added to cmake for building the Ruby extensions, like the flag -DWITH_RUBY=yes. The Makefile then generates the library symengine.so in the directory lib/symengine. The one that we were not able to load the previous week. Along with extconf.rb, the file extconf.h was also gone. Along these lines, the dependency on rake was also removed, and with that the Rakefile. Any task automation will most probably be done in python. So, the Rake::ExtensionTask was done by cmake and the Rake::GemPackageTask was replaced by the manual method of gem build symengine.gemspec and gem install symengine-0.0.0.gem. mkmf.log

Travis Setup

Not many projects have travis-ci setup for multiple languages. Not even the tutorials had clearly mentioned about setting up for multiple languages. But I did know about one of them, which is Shogun, the machine-learning toolbox. I referred to their .travis.yml and setup something like this,

    - compiler: clang
      compiler: clang
    - language: ruby
      env: WITH_RUBY="yes"
      rvm: 1.9.3
    - language: ruby
      env: WITH_RUBY="yes"
      rvm: 2.0
    - language: ruby
      env: WITH_RUBY="yes"
      rvm: 2.1
    - language: ruby
      env: WITH_RUBY="yes"
      rvm: 2.2

We were doubtful if something like this would work. The earlier plan was to manually install the required version of ruby and then execute the shell commands to build the respective libraries. But this worked, build jobs with Ruby as the language were indeed created and I felt like I was beginning to understand how travis takes in the parameters and soon I will be doing some experiments with .travis.yml :), out of this project.


  • Added TEST_IN_TREE=yes in env for builds with Ruby
  • Printing if symengine.so was made
  • Printing files in lib/symengine/ in travis log
  • Replaced ../lib with ../../lib in expand_path
  • Added lib to $LOAD_PATH & removed require_relative
  • Added the LOAD_PATH code in gemspec
  • Added lib/symengine to $LOAD_PATH
  • Added lib to $LOAD_PATH in spec_helper and removed gem install symengine
  • Added rest of the tests with pending statuses
  • [ci skip] untabified gemspec (converted tabs to spaces)
  • Installing the gem while testing Ideally this should not be done. This is just t
  • Changed the version from 0.0.0.pre to 0.0.0
  • Test push to debug travis failures
  • Added sudo: true to .travis.yml to support new container-based infrastructure in
  • Fixed errors in ruby_basic.c
  • Experimental fix with FindRuby.cmake
  • Kept duplicate LICENSE as temporary fix for installation errors
  • Added functions for binary, unary op
  • Changed symengine_BINARY_DIR to symengine_SOURCE_DIR
  • Added FindPackageHandleStandardArgs.cmake
  • Removed installation of new Bundler
  • Added new FindRuby.cmake
  • Moved dependencies from Gemfile to gemspec And rectified error in CMakelists.txt
  • Experimental fix for build errors removed the empty if[[ "${WITH_RUBY}" != "" ]`
  • Attempt at travis integration for building and testing the extensions
  • Updated configuration for rspec
  • Rectified error in CMakeLists and updated README
  • Added test file that makes an object of Basic test passes
  • Used symengine license in gem and updated Manifest
  • Removed rake and rake-compiler from dependencies
  • Removed unnecessary files as discussed LICENSE, Rakefile and extconf.rb
  • Added display messages in CMakeLists.txt for Ruby
  • Updated the docs
  • Added src/ruby/pkg to gitignore
  • Removed bin folder
  • Fix typo
  • Build ruby wrappers with CMake
  • Tried to use g++ compiler
  • Updated compile instructions in README
  • Added the option to config dirs

comments powered by Disqus