Monday, May 12, 2008

 

Fixing Perl installation under Cygwin

I discussed on multiple occasions before various issues arising from Cygwin upgrade, but there is one problem I fixed multiple times but never cared to document properly.

Perl built-in extension installation tools rely on existence and/or executability of certain files; this is tested with Perl test operators like 'if -r <filename>". As specified in the documentation, this operator tests that "File is readable by effective uid/gid.". No doubt that this test simply matches file permissions as reported by 'stat'' system call with file owner and current user id.

This seems sane enough, but the trouble is, Windows-centric notions of "Administrative rights" cannot be reliably mapped to Cygwin world. I always work in Windows as "myself," but with full Administrative rights, but Cygwin cannot possibly appreciate that I can access each file as if I were "Administrator" even though I am not one. As a result, multiple files which are created with permissions like that:

-rwxrwx---+ 1 Administrators SYSTEM 470528 May  1  2007 /usr/bin/bash.exe*

fail Perl's "-r" test, unless of course one wants to actually login as "Administrator", though I can still read and execute them.

While it is beyond me why Cygwin should create such peculiar permissions, here is a quick patch which should resolve most, if not all, problems related to installing Perl extensions.

chmod a+x /usr/bin/perl.exe
cd /usr/lib/perl5/5.8/ExtUtils
chmod a+x,a+r typemap xsubpp .
cd /usr/lib/perl5/vendor_perl/5.8/ExtUtils
chmod a+x,a+r xsubpp .

Labels: ,


Saturday, April 12, 2008

 

ImageMagick and RMagick

There is now a "standard" (free, BSD-style) image manipulation library ImageMagick. As it is pretty customary these days, it provides bindings for many popular higher-level languages, including Java, .NET, PHP, Perl, Python and Ruby. Ruby binding is known as RMagick.

One problem with ImageMagick is that it is notoriously difficult to install. The root of this problem may be that library insists on integration with X-server libraries (and indeed provides some X-client capabilities, though interestingly enough not supported on Windows).

(As a result, people are coming up with various ways to make a smaller library with restricted functionality, e.g. mini-magick. Unfortunately, there seems to be no documentation available, other than this tutorial, so I didn't want to spend time researching this)

Cygwin does include ImageMagic (you'll need at least 2 cygwin packages for ImageMagic: image-magick and libMagick-devel and various dependents for some reason not picked up by cygwin setup utility, e.g. libXft-devel and libbz2-devel), but all my attempts to first install ImageMagic and then RMagic failed (perhaps bundled version was too old, though judging from version numbers it was ok). ImageMagick web site includes pre-built version of all libraries for cygwin, but it appears to be very poorly built, includes many hardcoded paths from original build machine, etc.

So, the only option was to install ImageMagick from the sources, and it succeeded, after I explicitly excluded Perl bindings

./configure --without-perl

(be aware that built could take several hours to complete). After that, RMagick can be installed with command as simple as:

gem install rmagick

To try it out, you can use this program; try to uncomment line "canvas.display" near the end and look at the result. This didn't work well under Cygwin at all (though displaying same image just read from file worked fine).

Library itself is very powerful indeed. Documentation is good and detailed. One interesting thing that I discovered is that library has no less than 3 different methods to resize an image: "to sample", "to scale", and "to resize". You can compare all three by picking some random picture (sufficiently large) and running on it program like that:

#! /usr/local/bin/ruby -w

require 'rubygems'
require 'RMagick'
include Magick

imgfile = ARGV[0]
img = (Image.read imgfile)[0]

factor = 0.25
osize = File.size imgfile
puts "Original file #{imgfile} : #{osize} bytes, factor=#{factor}"

[:sample, :resize, :scale].each { |resize_alg|
  t = Time.now
  img_resized = img.method(resize_alg).call factor
  dt = Time.now - t
  fname = "test_#{resize_alg}.jpg"
  img_resized.write( fname );
  size = File.size fname
  puts "#{sprintf("%-6s",resize_alg)}: #{dt.to_f} secs, #{size} bytes =\
 #{sprintf("%.2f",100*size.to_f/osize)}%"
}

On my machine, it generated this output:

sample: 0.012 secs, 258985 bytes= 11.08%
resize: 1.287 secs, 227424 bytes= 9.73%
scale : 0.469 secs, 222147 bytes= 9.51%

Which is mathematically interesting: apparently, "resize" and "scale" provide some smoothing, therefore reducing size of the compressed image; "sample" is by far the fastest way to resize, but by just picking some more or less random pixels from the original image it generated result which is not only visually worse, but is harder to compress.

Labels: , ,


Friday, February 01, 2008

 

cal.exe under Cygwin

Upgrading Cygwin is never free of surprises, big or small. This time, following an upgrade, I noticed that decades-old utility "cal" (display a Gregorian calendar) suddenly disappeared.

Searching Cygwin-related sites took me a while, since quite obviously queries like "Cygwin cal" or "cygwin Gregorian calendar" bring up thousands of false positives.

Finally, I found a posting on Cygwin mailing list saying that for whatever reason cal.exe, along with some other utilities which used to be part of package "cygutils" (installed by default) now moved to (supposedly new) package "util-linux", so it has to be installed (I don't actually think it has any other useful utilities except "cal").

OK, one more problem solved... What is awaiting us at the next upgrade?

Labels:


Sunday, October 07, 2007

 

Kdiff3 for cygwin

Kdiff3 is an excellent utility for GUI-based comparison and merge. However, it is a bit cumbersome to build it properly. Default configuration assumes presence of KDE, so if you are not working from within KDE desktop, you are out of luck. However, there is also "QT only version" which only relies on QT libraries from Trolltech; it is primarily used to build Windows-version of the utility (also very good and highly recommended). If you want to build QT-only version of kdiff3 on a Unix-like system (including Cygwin), here is what to do (based on Kdiff3 version 0.9.92, released in April'07)
  1. Make sure you have X development libraries, headers, and fonts installed (included in Cygwin);
  2. Make sure you have QT3 installed (>= 3.3) (also included in Cygwin); set environment variable QTDIR, e.g. "setenv QTDIR /usr/lib/qt3"
  3. Download Kdiff 0.9.92 source distribution;
  4. Untar and go to sub-directory "src"
  5. Edit Makefile.qt, primarily compilation option and include directories (you might want to replace -I$(QTDIR)/include with -I/usr/include/qt3)
  6. make -f Makefile.qt
  7. make -f Makefile.qt install
Enjoy!
UPD (11-March-08)
. Under Debian (kernel 2.6.18-6-686):

Labels: ,


Saturday, December 09, 2006

 

Cygwin shell hangs upon upgrade

I just updated my cygwin installation and it stopped working: on startup any cygwin shell hangs.

Quick Internet search revealed nothing, so a little research of my own was in order...

It appears that cygwin shell startup files insist that file /bin/sh be a copy of /bin/bash. This logic is coded into file /etc/profile.d/00bash.sh :

# Get here if missing, broken, ash, or old bash, so an update is needed.
# Use copy, not hard or symlink, since symlinks won't work from Windows cmd
# and a hardlink to a running shell can't be broken. Try in-place copy
# first, but fall back to --remove-destination in case /bin/sh has different
# ACLs than /bin/bash. Record the attempt in /var/log/setup.log.full.
echo "`date '+%Y/%m/%d %T'` /etc/profile.d/00bash.sh:" "Attempting to update /bin/sh.exe" >> /var/log/setup.log.full 2>&1
{ /bin/cp -fpuv /bin/bash.exe /bin/sh.exe ||
/bin/cp -puv --remove-destination /bin/bash.exe /bin/sh.exe
} >> /var/log/setup.log.full 2>&1

On the other hand, cygwin upgrade only changes /bin/bash and not /bin/sh, thus triggering the above code (and more) to execute, and this was apparently causing hang (I didn't look into where exactly).

Therefore, it this happens to you, reboot your machine, and immediately afterwards, before any cygwin applications can initiate, do this (or similar depending on where your cygwin installation is)

copy /B c:\cygwin\bin\bash.exe c:\cygwin\bin\sh.exe

Labels:


This page is powered by Blogger. Isn't yours?