You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@subversion.apache.org by Joe Swatosh <jo...@gmail.com> on 2006/12/27 07:46:01 UTC

[Patch] Compiling Ruby bindings on Windows

Okay, here is a cut a patch that will let the Ruby bindings compile using VC6
and SWIG 1.3.24.  I'm dissatisfied because I can't get the tests to run.  The
core tests usually pass except for some line ending comparison problems.  The
other tests generally cause a segmentation fault:

<Quote>
D:\SVN\src-trunk\subversion\bindings\swig\ruby>ruby -I.ext -Itest
-rtest\my-assertions.rb test\test_client.rb -v
Loaded suite test/test_client
Started
test_add_force(SvnClientTest): E
test_add_no_ignore(SvnClientTest): .
test_add_not_recurse(SvnClientTest): ./.ext/svn/util.rb:68: [BUG]
Segmentation fault
ruby 1.8.4 (2006-04-14) [i386-mswin32]


This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
</Quote>

Most failures occur at svn/util.rb:68 where a Proc for a forwarding function is
created.  I tried "puts" of the target_method before the "call," but that moved
the SegFault around too.  It often claimed to be svn_utf_cstring_to_utf8, but I
couldn't figure out how we were getting there from any of the test code.

So this patch is in no way ready for primetime, but I'm hoping someone will be
interested enough to help me figure something out.  In spite of that I tried to
get the format right.  If I fouled that up, please let me know about that too.

The test code modifications create a dependency on win32-service which is part
of Win32Utils on RubyForge (http://rubyforge.org/projects/win32utils/) or as a
gem.

Attached find the log of my build attempt complete with 28 warnings.  Here are
the versions I'm using:

db4-win32-4.4.20
gettext-0.14.4
httpd-2.0.59
neon-0.26.1
openssl-0.9.7d
svn-win32-libintl
SWIG-1.3.24
zlib123
ruby 1.8.4 (2006-04-14) [i386-mswin32]
VC6 SP6


[[[

Compile the Ruby bindings on Windows with VC6.  Get a start on getting the
testing working on Windows.

* subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.c
  define a EMPTY_WORKAROUND_FOR_VC6_PREPROCESSOR macro and replace the empty
  space in the argument of every "function-like" macro. Don't define the
  MESSAGES constant when _WIN32 is defined. Use SIZEOF_LONG_LONG instead of
  sizeof(long long).

* subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.h
  When building with VC compiler use the #pragma comment directive to link with
  the ruby library.

* subversion/bindings/swig/ruby/test/run-test.rb
  Copy files around to create the directory structure for testing, not using
  links.  Create a Service entry for svnserve.

* subversion/bindings/swig/ruby/test/util.rb
  Start and stop the Service, without using fork.  Fix typo in URI?


]]]


Index: subversion/bindings/swig/ruby/test/util.rb
===================================================================
--- subversion/bindings/swig/ruby/test/util.rb	(revision 22814)
+++ subversion/bindings/swig/ruby/test/util.rb	(working copy)
@@ -17,7 +17,7 @@
     @realm = "sample realm"
     @repos_path = File.join("test", "repos")
     @full_repos_path = File.expand_path(@repos_path)
-    @repos_uri = "file://#{@full_repos_path}"
+    @repos_uri = "file:///#{@full_repos_path}"
     @svnserve_host = "127.0.0.1"
     @svnserve_ports = (64152..64282).collect{|x| x.to_s}
     @wc_base_dir = File.join("test", "wc-tmp")
@@ -142,6 +142,19 @@
     end
   end

+  if RUBY_PLATFORM =~ /mswin/
+    require 'win32/service'
+
+    def setup_svnserve
+      Win32::Service.start('testsvn')
+      @repos_svnserve_uri = "svn://#{@svnserve_host}"
+    end
+
+    def teardown_svnserve
+      Win32::Service.stop('testsvn')
+    end
+  end
+
   def setup_wc
     teardown_wc
     make_context("").checkout(@repos_uri, @wc_path)
Index: subversion/bindings/swig/ruby/test/run-test.rb
===================================================================
--- subversion/bindings/swig/ruby/test/run-test.rb	(revision 22814)
+++ subversion/bindings/swig/ruby/test/run-test.rb	(working copy)
@@ -3,6 +3,7 @@
 require "test/unit"
 require "fileutils"

+if RUBY_PLATFORM !~ /mswin/
 ENV["PATH"] = File.join(Dir.pwd, "..", "..", "..", "svnserve") + ":"
+ ENV["PATH"]
 ext_dir = File.join(Dir.pwd, ".ext")
 ext_svn_dir = File.join(ext_dir, "svn")
@@ -12,7 +13,36 @@

 $LOAD_PATH.unshift(ext_dir)
 $LOAD_PATH.unshift(Dir.pwd)
+else
+  require 'win32/file'
+  require 'win32/service'

+  ext_dir = File.join(Dir.pwd, ".ext")
+  ext_svn_dir = File.join(ext_dir, "svn")
+  ext_svn_ext_dir = File.join(ext_svn_dir, "ext")
+  FileUtils.mkdir_p(ext_svn_ext_dir)
+  Dir.glob(File.join(Dir.pwd, "svn", '*.rb')).each do |f|
+    FileUtils.cp(f, File.join(ext_svn_dir, File.basename(f) ) )
+  end
+  Dir.glob(File.join(Dir.pwd,
'..','..','..','..',ENV['build_type'],'subversion','bindings','swig','ruby',
'*.dll')).each do |f|
+    FileUtils.cp(f, File.join(ext_svn_ext_dir, File.basename(f) ) )
+  end
+  repo_dir = File.join(Dir.pwd, "test", "repos")
+  FileUtils.mkdir_p(repo_dir)
+  svnserve_full_path =
File.expand_path(File.join(Dir.pwd,'..','..','..','..','..','svn-win32-1.4.2','bin','svnserve.exe'))
+  Win32::Service.delete('testsvn') rescue Win32::ServiceError
+  s = Win32::Service.new
+  s.create_service{ |s|
+    s.service_name        = "testsvn"
+    s.binary_path_name    = "\"#{svnserve_full_path}\"".tr('/','\\')
+    s.binary_path_name    << " --service"
+    s.binary_path_name    << " --root \"#{repo_dir}\"".tr('/','\\')
+  }
+  #at_exit {Win32::Service.delete('testsvn')}
+  #at_exit {FileUtils.rm_rf(ext_dir)}
+  $LOAD_PATH.unshift(ext_dir)
+end
+
 require 'svn/core'
 Svn::Locale.set

Index: subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.h
===================================================================
--- subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.h	(revision
22814)
+++ subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.h	(working copy)
@@ -16,6 +16,10 @@
 #include "svn_client.h"
 #include "svn_repos.h"

+#ifdef _MSC_VER
+  #pragma comment(lib,"msvcrt-ruby18.lib")
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
Index: subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.c
===================================================================
--- subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.c	(revision
22814)
+++ subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.c	(working copy)
@@ -20,6 +20,7 @@
 #define POOL_P(obj) (RTEST(rb_obj_is_kind_of(obj, rb_svn_core_pool())))
 #define CONTEXT_P(obj) (RTEST(rb_obj_is_kind_of(obj, rb_svn_client_context())))
 #define SVN_ERR_P(obj) (RTEST(rb_obj_is_kind_of(obj, rb_svn_error())))
+#define EMPTY_WORKAROUND_FOR_VC6_PREPROCESSOR

 static VALUE mSvn = Qnil;
 static VALUE mSvnClient = Qnil;
@@ -295,7 +296,9 @@
   rb_define_const(mSvnLocale, "ALL", INT2NUM(LC_ALL));
   rb_define_const(mSvnLocale, "COLLATE", INT2NUM(LC_COLLATE));
   rb_define_const(mSvnLocale, "CTYPE", INT2NUM(LC_CTYPE));
+#ifndef _WIN32
   rb_define_const(mSvnLocale, "MESSAGES", INT2NUM(LC_MESSAGES));
+#endif
   rb_define_const(mSvnLocale, "MONETARY", INT2NUM(LC_MONETARY));
   rb_define_const(mSvnLocale, "NUMERIC", INT2NUM(LC_NUMERIC));
   rb_define_const(mSvnLocale, "TIME", INT2NUM(LC_TIME));
@@ -779,21 +782,21 @@
 }

 DEFINE_APR_ARRAY_TO_ARRAY(VALUE, svn_swig_rb_apr_array_to_array_string,
-                          c2r_string, , const char *, NULL)
+                          c2r_string,
EMPTY_WORKAROUND_FOR_VC6_PREPROCESSOR, const char *, NULL)
 DEFINE_APR_ARRAY_TO_ARRAY(VALUE, svn_swig_rb_apr_array_to_array_svn_string,
                           c2r_svn_string, &, svn_string_t, NULL)
 DEFINE_APR_ARRAY_TO_ARRAY(static VALUE, c2r_commit_item3_array,
-                          c2r_client_commit_item3_dup, ,
+                          c2r_client_commit_item3_dup,
EMPTY_WORKAROUND_FOR_VC6_PREPROCESSOR,
                           svn_client_commit_item3_t *, NULL)
 DEFINE_APR_ARRAY_TO_ARRAY(VALUE, svn_swig_rb_apr_array_to_array_prop,
                           c2r_prop_dup, &, svn_prop_t, NULL)
 DEFINE_APR_ARRAY_TO_ARRAY(VALUE, svn_swig_rb_apr_array_to_array_svn_rev,
                           c2r_long, &, svn_revnum_t, NULL)
 DEFINE_APR_ARRAY_TO_ARRAY(VALUE, svn_swig_rb_apr_array_to_array_proplist_item,
-                          c2r_client_proplist_item_dup, ,
+                          c2r_client_proplist_item_dup,
EMPTY_WORKAROUND_FOR_VC6_PREPROCESSOR,
                           svn_client_proplist_item_t *, NULL)
 DEFINE_APR_ARRAY_TO_ARRAY(VALUE, svn_swig_rb_apr_array_to_array_external_item,
-                          c2r_wc_external_item_dup, ,
+                          c2r_wc_external_item_dup,
EMPTY_WORKAROUND_FOR_VC6_PREPROCESSOR,
                           svn_wc_external_item_t *, NULL)

 
@@ -2056,10 +2059,10 @@
     cbb.receiver = callbacks;
     cbb.message = rb_id_progress_func();
     cbb.args = rb_ary_new3(2,
-                           sizeof(apr_off_t) == sizeof(long long) ?
+                           sizeof(apr_off_t) == SIZEOF_LONG_LONG ?
                              LL2NUM(progress):
                              LONG2NUM(progress),
-                           sizeof(apr_off_t) == sizeof(long long) ?
+                           sizeof(apr_off_t) == SIZEOF_LONG_LONG ?
                              LL2NUM(total):
                              LONG2NUM(total));
     invoke_callback((VALUE)(&cbb), Qnil);
@@ -2665,7 +2668,7 @@
     cbb.receiver = proc;
     cbb.message = rb_id_call();
     cbb.args = rb_ary_new3(5,
-                           sizeof(apr_int64_t) == sizeof(long long) ?
+                           sizeof(apr_int64_t) == SIZEOF_LONG_LONG ?
                              LL2NUM(line_no):
                              LONG2NUM(line_no),
                            INT2NUM(revision),

Re: [Patch] Compiling Ruby bindings on Windows

Posted by Joe Swatosh <jo...@gmail.com>.
Hi,

On 12/29/06, Kouhei Sutou <ko...@cozmixng.org> wrote:
> Hi,
>
> In <ae...@mail.gmail.com>
>  "Re: [Patch] Compiling Ruby bindings on Windows" on Fri, 29 Dec 2006 11:55:14 -0800,
>  "Joe Swatosh" <jo...@gmail.com> wrote:
>
> > single file appealling, I'm not sure I like the idea of creating and
> > destroying the Windows Service for every test.  Perhaps we could move
> > the creation of the Service to when util.rb is loaded, then remove the
> > service at_exit?  That way we'd only have to start and stop the
> > service for each test?
>
> Yes. We can use the way. But I want to keep that we can run
> tests except for Svn::Client without svnserve. So I don't
> want to initialize Win32 Service when util.rb is loaded.
>
>
> I have a question. Can we use svnserve without Windows
> Service on Windows? Is the problem only fork?
>

I'll look into it.  I was having trouble and went to a way I was sure
would work.

--
Joe Swatosh

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: [Patch] Compiling Ruby bindings on Windows

Posted by Kouhei Sutou <ko...@cozmixng.org>.
Hi,

In <ae...@mail.gmail.com>
  "Re: [Patch] Compiling Ruby bindings on Windows" on Fri, 29 Dec 2006 11:55:14 -0800,
  "Joe Swatosh" <jo...@gmail.com> wrote:

> single file appealling, I'm not sure I like the idea of creating and
> destroying the Windows Service for every test.  Perhaps we could move
> the creation of the Service to when util.rb is loaded, then remove the
> service at_exit?  That way we'd only have to start and stop the
> service for each test?

Yes. We can use the way. But I want to keep that we can run
tests except for Svn::Client without svnserve. So I don't
want to initialize Win32 Service when util.rb is loaded.


I have a question. Can we use svnserve without Windows
Service on Windows? Is the problem only fork?


> > 'file' schema URI isn't a typo.
> >
> 
> Looking at http://svnbook.red-bean.com/nightly/en/svn.advanced.reposurls.html
> make me think that it should either include a node name or a third
> slash, but truely I am no expert.

OK. I didn't understand 'file' schema URI with drive
letter. I've merged your change.


Thanks,
--
kou

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: [Patch] Compiling Ruby bindings on Windows

Posted by Justin Erenkrantz <ju...@erenkrantz.com>.
On 12/29/06, Joe Swatosh <jo...@gmail.com> wrote:
> This is the thing that is bugging me most.  I hate that the tests
> aren't running.  I hope someone else who is interested in getting
> these bindings built for Windows jumps in and helps us out.

Ruby distributions don't allow compiling with VC 2005 - I've managed
to get it to compile with a snapshot, but because of those
incompatibilities, I didn't bother to check in my changes (which
you're independently rediscovering, sorry).  -- justin

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: [Patch] Compiling Ruby bindings on Windows

Posted by Joe Swatosh <jo...@gmail.com>.
On 12/28/06, Kouhei Sutou <ko...@cozmixng.org> wrote:
>  "Joe Swatosh" <jo...@gmail.com> wrote:
>

> > Most failures occur at svn/util.rb:68 where a Proc for a forwarding function is
> > created.  I tried "puts" of the target_method before the "call," but that moved
> > the SegFault around too.  It often claimed to be svn_utf_cstring_to_utf8, but I
> > couldn't figure out how we were getting there from any of the test code.
>
> Ah, OK. I'll think about another more debug friendly
> mechanism.
>

Great.

This is the thing that is bugging me most.  I hate that the tests
aren't running.  I hope someone else who is interested in getting
these bindings built for Windows jumps in and helps us out.

> > The test code modifications create a dependency on win32-service which is part
> > of Win32Utils on RubyForge (http://rubyforge.org/projects/win32utils/) or as a
> > gem.
>
> I agree with the idea but I think Win32 service setup should
> be done in SvnTestUtil#setup_svnserve not run-test.rb. So I
> will change run-test.rb like the following. What about this?
>

The patch looks good (eyeballs only, I haven't tried it yet).  While I
find the notion of keeping all the Windows service related stuff in a
single file appealling, I'm not sure I like the idea of creating and
destroying the Windows Service for every test.  Perhaps we could move
the creation of the Service to when util.rb is loaded, then remove the
service at_exit?  That way we'd only have to start and stop the
service for each test?

I happened to have the win32-service gem installed on my system, so I
used it.  However, I think we should consider carefully whether or not
we want to create a dependency on it.  The code would be a good deal
uglier, but what we are using it for could be accomplished by shelling
out to the "sc" and "net start|stop" commands.

>
> > * subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.c

> I've merged.

Yay.

>
> > * subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.h
> >   When building with VC compiler use the #pragma comment directive to link with
> >   the ruby library.
>
> I'll talk about this in the next mail.
>

I think we're getting close on that one.

> > * subversion/bindings/swig/ruby/test/util.rb
> >   Start and stop the Service, without using fork.  Fix typo in URI?
>
> We need to talk about them.
>
> 'file' schema URI isn't a typo.
>

Looking at http://svnbook.red-bean.com/nightly/en/svn.advanced.reposurls.html
make me think that it should either include a node name or a third
slash, but truely I am no expert.

Thanks for letting me help out a little.

-Joe

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: [Patch] Compiling Ruby bindings on Windows

Posted by Kouhei Sutou <ko...@cozmixng.org>.
Hi,

# I'm sorry for my late response.

In <ae...@mail.gmail.com>
  "[Patch] Compiling Ruby bindings on Windows" on Tue, 26 Dec 2006 23:46:01 -0800,
  "Joe Swatosh" <jo...@gmail.com> wrote:

> Okay, here is a cut a patch that will let the Ruby bindings compile using VC6
> and SWIG 1.3.24.

Great! I merged some your changes into the repository. (Yes,
you've already noticed.)

> Most failures occur at svn/util.rb:68 where a Proc for a forwarding function is
> created.  I tried "puts" of the target_method before the "call," but that moved
> the SegFault around too.  It often claimed to be svn_utf_cstring_to_utf8, but I
> couldn't figure out how we were getting there from any of the test code.

Ah, OK. I'll think about another more debug friendly
mechanism.


> The test code modifications create a dependency on win32-service which is part
> of Win32Utils on RubyForge (http://rubyforge.org/projects/win32utils/) or as a
> gem.

I agree with the idea but I think Win32 service setup should
be done in SvnTestUtil#setup_svnserve not run-test.rb. So I
will change run-test.rb like the following. What about this?

---
Index: subversion/bindings/swig/ruby/test/run-test.rb
===================================================================
--- subversion/bindings/swig/ruby/test/run-test.rb	(revision 22823)
+++ subversion/bindings/swig/ruby/test/run-test.rb	(working copy)
@@ -3,15 +3,27 @@
 require "test/unit"
 require "fileutils"
 
-ENV["PATH"] = File.join(Dir.pwd, "..", "..", "..", "svnserve") + ":" + ENV["PATH"]
-ext_dir = File.join(Dir.pwd, ".ext")
+test_dir = File.expand_path(File.join(File.dirname(__FILE__)))
+base_dir = File.expand_path(File.join(File.dirname(__FILE__), ".."))
+top_dir = File.expand_path(File.join(base_dir, "..", "..", ".."))
+
+ext_dir = File.join(base_dir, ".ext")
 ext_svn_dir = File.join(ext_dir, "svn")
 FileUtils.mkdir_p(ext_svn_dir)
-FileUtils.ln_sf(File.join(Dir.pwd, ".libs"), File.join(ext_svn_dir, "ext"))
 at_exit {FileUtils.rm_rf(ext_dir)}
 
+if /cygwin|mingw|mswin32|bccwin32/.match(RUBY_PLATFORM)
+  ext_svn_ext_dir = File.join(ext_svn_dir, "ext")
+  FileUtils.mkdir_p(ext_svn_ext_dir)
+  FileUtils.cp(Dir.glob(File.join(base_dir, "*.dll"), ext_svn_ext_dir))
+else
+  ENV["PATH"] = "#{File.join(top_dir, 'subversion', 'svnserve')}:#{ENV['PATH']}"
+  FileUtils.ln_sf(File.join(base_dir, ".libs"), File.join(ext_svn_dir, "ext"))
+end
+
 $LOAD_PATH.unshift(ext_dir)
-$LOAD_PATH.unshift(Dir.pwd)
+$LOAD_PATH.unshift(base_dir)
+$LOAD_PATH.unshift(test_dir)
 
 require 'svn/core'
 Svn::Locale.set
---

> * subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.c
>   define a EMPTY_WORKAROUND_FOR_VC6_PREPROCESSOR macro and replace the empty
>   space in the argument of every "function-like" macro. Don't define the
>   MESSAGES constant when _WIN32 is defined. Use SIZEOF_LONG_LONG instead of
>   sizeof(long long).

I've merged.

> * subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.h
>   When building with VC compiler use the #pragma comment directive to link with
>   the ruby library.

I'll talk about this in the next mail.

> * subversion/bindings/swig/ruby/test/run-test.rb
>   Copy files around to create the directory structure for testing, not using
>   links.  Create a Service entry for svnserve.
>
> * subversion/bindings/swig/ruby/test/util.rb
>   Start and stop the Service, without using fork.  Fix typo in URI?

We need to talk about them.

'file' schema URI isn't a typo.


Joe, thanks for your work!

Regards,
--
kou

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org