{"id":573,"date":"2006-12-14T00:39:55","date_gmt":"2006-12-14T05:39:55","guid":{"rendered":"http:\/\/blogs.law.harvard.edu\/hoanga\/2006\/12\/14\/getting-a-ruby-c-extension-to-compile-"},"modified":"2006-12-14T00:39:55","modified_gmt":"2006-12-14T05:39:55","slug":"getting-a-ruby-c-extension-to-compile-on-windows","status":"publish","type":"post","link":"https:\/\/archive.blogs.harvard.edu\/hoanga\/2006\/12\/14\/getting-a-ruby-c-extension-to-compile-on-windows\/","title":{"rendered":"Getting a Ruby C extension to compile on Windows"},"content":{"rendered":"<p>\nThe <a href=\"http:\/\/www.pragmaticprogrammer.com\/titles\/ruby\/index.html\">Programming Ruby<\/a> book is one of those must have references if you&#8217;re going to program Ruby.  I still use it all the time when I&#8217;m looking up information on Ruby.  One thing I&#8217;ve started playing with is getting a C extension to work with Ruby.  Chapter 21 of Volume 2 of <a href=\"http:\/\/www.pragmaticprogrammer.com\/titles\/ruby\/index.html\">Programming Ruby<\/a> gives you a great example for writing a C extension from scratch and getting it to compile and work in a UNIX-based environment however it falls short on handholding you through the Windows process.   Here&#8217;s my notes on what you need:\n<\/p>\n<h3>Executive Summary<\/h3>\n<ol>\n<li>Install <a href=\"http:\/\/msdn.microsoft.com\/vstudio\/express\/\">Visual Studio Express<\/a> or some other Visual C++ variant<\/li>\n<li>Install the <a href=\"http:\/\/www.microsoft.com\/msdownload\/platformsdk\/sdkupdate\/\">Platform SDK<\/a> (You need this if you want <em>windows.h<\/em> and you DO)<\/li>\n<li>Make minor changes in Ruby config.h (Not necessary for all versions of Visual Studio)<\/li>\n<li>Write the MyTest code and extconf.rb file from the book<\/li>\n<li>Run <em>ruby extconf.rb<\/em> to generate a nmake-based Makefile<\/li>\n<li>Startup a command prompt with the SDK environment variables set<\/li>\n<li>Run <em>nmake<\/em> to compile the library<\/li>\n<li>Done!<\/li>\n<\/ol>\n<h3>The detailed version<\/h3>\n<h4>Download Visual Studio<\/h4>\n<p>Unless you&#8217;re using cygwin or mingw as your compiler you&#8217;ll probably want to get Visual Studio.  The latest incarnation is <a href=\"http:\/\/msdn.microsoft.com\/vstudio\/express\/\">Visual Studio 2005<\/a> which is a free download.  I&#8217;ve found that it&#8217;s a pain to find the right URL to download it from on Microsoft but that&#8217;s Microsoft for you.<\/p>\n<h4>Download the Windows Platform SDK<\/h4>\n<p>Since the Windows version of Ruby ties in with many Win32 libraries it&#8217;s necessary to get the <a href=\"http:\/\/msdn.microsoft.com\/platformsdk\/\">Platform SDK<\/a>.  If you DON&#8217;T download it you will see strange error messages when trying to compile your Ruby extension such as this:<\/p>\n<blockquote>\n<pre>\r\nc:\\ruby\\lib\\ruby\\1.8\\i386-mswin32\\win32\/win32.h(32) : fatal error C1083: Cannot\r\nopen include file: 'windows.h': No such file or directory\r\nNMAKE : fatal error U1077: '\"C:\\Program Files\\Microsoft Visual Studio 8\\VC\\BIN\\cl.EXE\"' : return code '0x2'\r\nStop.\r\n<\/pre>\n<\/blockquote>\n<p><em>windows.h<\/em> is NOT included by default in Visual Studio 2005 (but I believe it is in older versions of Visual Studio) so you need the platform SDKs to get the right development libraries.  While it would be nice if the C-based version of Ruby could easily hook into the .Net platform, this would probably require significant hacking the <em>mkmf<\/em> library in Ruby to get it to work transparently.  I doubt that will happen soon.<\/p>\n<p>\nOnce again, I found Microsoft&#8217;s website really annoying to navigate in order to try to find the Platform SDK so you might want to click <a href=\"http:\/\/msdn.microsoft.com\/platformsdk\/\">here<\/a> then make sure you have the latest platform SDK (As of this writing the latest was R1)\n<\/p>\n<h4>Tweak $RUBY_HOME\/lib\/ruby\/1.8\/i386-mswin32\/config.h<\/h4>\n<p>For some versions Visual Studio (noteably Visual Studio 2005), the config file located in  $RUBY_HOME\/lib\/ruby\/1.8\/i386-mswin32\/config.h  (Usually $RUBY_HOME installs to C:\/Ruby) will  require a tweak to allow compilation.  Or you could rebuild Ruby from scratch yourself but I prefer to use the <a href=\"http:\/\/www.ruby-lang.org\/en\/downloads\/\">All-in-one installer<\/a>.  In the config.h file delete or comment out the following lines:<\/p>\n<blockquote>\n<pre>\r\n#if _MSC_VER != 1200\r\n#error MSC version unmatch\r\n#endif\r\n<\/pre>\n<\/blockquote>\n<h4>Finally!  Let&#8217;s compile it already<\/h4>\n<p>Okay now you&#8217;re ready to finally to actually compile your code.  In order to get all the environment variables set properly you might want to launch a command prompt from the shortcuts the Platform SDK makes in the Start Menu then make sure to run vsvars32.bat from Visual Studio&#8217;s directory (Usually in <em>C:\\Program Files\\Microsoft Visual Studio 8\\VC\\bin<\/em>).  Now with that all set you can finally compile something!  (whew!):<\/p>\n<blockquote>\n<pre>\r\nC:\\cygwin\\home\\foo\\exttest&gt;ruby extconf.rb\r\ncreating Makefile\r\n\r\nC:\\cygwin\\home\\foo\\exttest&gt;nmake\r\n\r\nMicrosoft (R) Program Maintenance Utility Version 8.00.50727.42\r\nCopyright (C) Microsoft Corporation.  All rights reserved.\r\n\r\n        cl -nologo -I. -Ic:\/ruby\/lib\/ruby\/1.8\/i386-mswin32 -Ic:\/ruby\/lib\/ruby\/1.\r\n8\/i386-mswin32 -I. -MD -Zi -O2b2xg- -G6  -c -Tcmy_test.c\r\ncl : Command line warning D9035 : option 'Og-' has been deprecated and will be r\r\nemoved in a future release\r\ncl : Command line warning D9002 : ignoring unknown option '-G6'\r\nmy_test.c\r\n        cl -nologo -LD -Femy_test.so my_test.obj msvcrt-ruby18.lib  oldnames.lib\r\n user32.lib advapi32.lib wsock32.lib  -link -incremental:no -debug -opt:ref -opt\r\n:icf -dll -libpath:\"c:\/ruby\/lib\" -def:my_test-i386-mswin32.def -implib:my_test-i\r\n386-mswin32.lib -pdb:my_test-i386-mswin32.pdb\r\n   Creating library my_test-i386-mswin32.lib and object my_test-i386-mswin32.exp\r\n\r\nC:\\cygwin\\foo\\exttest&gt;irb\r\nirb(main):001:0&gt; require 'my_test'\r\n=&gt; true\r\nirb(main):002:0&gt; test = MyTest.new\r\n=&gt; #\r\n<\/pre>\n<\/blockquote>\n<h3>References<\/h3>\n<ul>\n<li><a href=\"http:\/\/msdn.microsoft.com\/vstudio\/express\/\">Visual Studio Express<\/a><\/li>\n<li><a href=\"http:\/\/www.microsoft.com\/msdownload\/platformsdk\/sdkupdate\/\">Windows Platform SDK<\/a> (This will point you to SP1 but you want a more recent version)<\/li>\n<li><a href=\"http:\/\/www.turnofthecrank.com\/2006\/09\/11\/ruby-ldap-and-win32\/\">Ruby LDAP and Windows<\/a><\/li>\n<li><a href=\"http:\/\/www.joeygibson.com\/blog\/tech\/ruby\/RubyMySQL.html\">Ruby + Mysql on Windows<\/a><\/li>\n<li><a href=\"http:\/\/blade.nagaokaut.ac.jp\/cgi-bin\/scat.rb\/ruby\/ruby-talk\/80862\">A Ruby talk thread on build issues<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>The Programming Ruby book is one of those must have references if you&#8217;re going to program Ruby. I still use it all the time when I&#8217;m looking up information on Ruby. One thing I&#8217;ve started playing with is getting a C extension to work with Ruby. Chapter 21 of Volume 2 of Programming Ruby gives [&hellip;]<\/p>\n","protected":false},"author":703,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[364,615],"tags":[],"class_list":["post-573","post","type-post","status-publish","format-standard","hentry","category-japan","category-ruby"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/archive.blogs.harvard.edu\/hoanga\/wp-json\/wp\/v2\/posts\/573","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/archive.blogs.harvard.edu\/hoanga\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/archive.blogs.harvard.edu\/hoanga\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/hoanga\/wp-json\/wp\/v2\/users\/703"}],"replies":[{"embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/hoanga\/wp-json\/wp\/v2\/comments?post=573"}],"version-history":[{"count":0,"href":"https:\/\/archive.blogs.harvard.edu\/hoanga\/wp-json\/wp\/v2\/posts\/573\/revisions"}],"wp:attachment":[{"href":"https:\/\/archive.blogs.harvard.edu\/hoanga\/wp-json\/wp\/v2\/media?parent=573"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/hoanga\/wp-json\/wp\/v2\/categories?post=573"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/hoanga\/wp-json\/wp\/v2\/tags?post=573"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}