Какая структура будет у проекта:

/ext/library.cpp /ext/extconf.rb /lib /test Rakefile

Почему обязательно выносится код на C в каталог ext? Да что бы можно было потом ставить через rubygems. Когда ставишь пакет через rubygems, в каталоге ext делается make && make install && make clean. make install делается в каталог lib. Если код на C находится там же, то потом будет сделан make clean, который все удалит. Поэтому надо, что бы результирующая библиотека перекладывалась в другой каталог, нежели тот, в котором исходный код. Это не специфика c++, так будет и в случае с C.

Теперь открываем extconf.rb:

require ‘mkmf’ CONFIG[“CPP”] = "g++ -E " CONFIG[“CC”] = "g++ " CONFIG[“LDSHARED”].gsub!(/^cc /,"g++ ")

@CPP@ — это препроцессор с помощью которого mkmf проверяет наличие заголовочных файлов. Он, конечно же, должен быть не gcc, а g++, иначе ничего не подключится. Тоже самое с @CC@ — это уже компилятор.
Для линковки объектных файлов в результирующую библиотеку тоже надо заменить gcc на g++, что и делается в третьей строке.

Заодно расскажу про использование OptParse. Предположим, ваш экстеншн должен иметь доступ до какой-то библиотеки, которая не всегда лежит в одном и том же месте. Вам надо, что бы пользователь при установке передал ключи --include-dir и --library-dir: gem install my_lib --include-dir=/opt/local/include. Делается это следующим образом:

require ‘optparse’ OptionParser.new do |opts| opts.on(“—I PATH”, “—include-dir=PATH”, “Prefix, where headers are installed: /usr/local or /opt/local”) do |path| @includes << path end opts.parse!(ARGV.include?(“——”) ? ARGV[ARGV.index(“—”)+1..-1] : ARGV.clone) end

Sidebar