Como cross-compilar o ruby e suas extensões para o windows a partir de um unix

Enquanto eu desenvolvia a extensão Orca-Ruby para controlar a API Orca do PowerBuilder a partir do Ruby e montar um build system customizado para as necessidades da Myfreecomm, me deparei com a capciosa tarefa de cross-compilar o Ruby para o Windows.

Cross-compilar o Ruby sem as extensões, até que não é tão complicado, pois seu script de compilação possui algumas facilidades para realizar esta tarefa. Mas para as nossas ambições, as extensões eram importantes.

O problema acontece porque os scripts de compilação do ruby, contam com o próprio ruby recém compilado para compilar as extensões. E isto não pode acontecer normalmente quando se trata de cross-compilação, pois o ruby recém compilado não funciona no sistema que o compilou.

Para contornar este problema, é preciso fazer com que o script que compila as extensões funcione normalmente utilizando o ruby instalado no host, que no meu caso é um OS X.

A idéia é simples, mas alguns detalhes no script de compilação do ruby impedem que isso ocorra da maneira fácil. Por isso alguns ajustes são necessários, e para automatizar o processo e impactar o mínimo possível no código fonte do ruby, resolvi criar um Makefile para realizar a tarefa.

Para ser mais objetivo e evitar detalhar o Makefile no post, criei um projeto no github para simplificar. Clone o repositório:

>git clone git://github.com/henriquebastos/crosscompileruby.git

Pode ser necessário editar o Makefile e definir os valores das variáveis HOST e BUILD para refletir o seu ambiente.

Para saber exatamente quais comandos serão executados e entender os ajustes feitos, você pode rodar o comando make -n (dry-run). Para cross-compilar o ruby execute o comando make. Para “instalar” o ruby, ou seja, criar um diretório que poderá ser copiado para uma máquina windows, execute make install.

Lembrando que para cross-compilar o ruby, você precisará do compilador Mingw32. Quem usa Mac pode instalar o pacote do Macports:

>sudo port install i386-mingw32-gcc

Caso alguém tenha qualquer dúvida ou encontre algum bug, é só deixar um recado ou acertar o código.

Abraços.

Script Ruby para fazer FTP no Windows

Refatorando algumas tasks dos Rakefiles, precisei executar algumas tarefas de transferência de arquivos via FTP. Tentei usar os módulos socket e net, mas por qualquer motivo eles não estão funcionando no Windows.

Para contornar temporariamente o problema, resolvi usar o cliente FTP limitado que vem com o Windows, e acabei gostando da gambiarra final:

def ftp host, user, pwd
   raise "Block expected." unless block_given?
 
   File.open 'ftp.tmp', 'w' do |f|
      f.puts "open #{host}", user, pwd
      yield(f)
      f.puts 'quit'
   end
   system "ftp -s:ftp.tmp && del ftp.tmp"
end

Este método foca a simplicidade do código que o chamará, e para isso, espera que seja fornecido um bloco que definirá os comandos FTP:

task :exemplo do
   ftp "meuservidor.com.br", "login", "senha" do |cmd|
      cmd.puts "mkdir /home/henrique/tmp"
      cmd.puts "cd /home/henrique/tmp"
      cmd.puts "put arquivo.txt"
   end
end

Por limitações do cliente FTP, não é possível fazer um código interativo a partir de uma única conexão, como por exemplo, executar tarefas distintas dependendo do conteúdo verificado em um diretório remoto.

É um snippet bem simples, mas tem se mostrado muito útil por aqui! Quando descobrir porque o socket não funciona eu publico a solução.

O dia-à-dia de um Desenvolvedor Ninja

A publicação da vaga para Desenvolvedor Ninja tem dado o que falar por aqui. Temos recebido algumas respostas bem relevantes. Parece que começamos nossa busca com o pé direito. No entanto, alguns candidatos ao clã estão perguntado mais detalhes sobre nossas Missões Ninja.

É difícil definir um padrão para esse tipo de trabalho. Mas recentemente, um de nossos Ninjas, especializado em Linux concluiu uma missão bem interessante.

Com pouca experiência com a Plataforma Win32, ele criou um componente COM, estendendo um componente oferecido pelo Windows para melhorar e simplificar a interação com o Powerbuilder. Suas armas foram:

  1. Milhares de tabs do Firefox com a documentação do MSDN.
  2. VIM como editor de texto para atender seu requinte masoquista.
  3. GCC para compilar o código escrito no Linux para Windows.
  4. O código fonte do Wine 1.0 para compreender melhor a relação entre alguns elementos da arquitetura COM.
  5. Templates em C++ para simplificar o código e evitar repetições.

Mesmo com armas um tanto inusitadas, a chave do sucesso foi a técnica. Sua consciência de que ele não dominava a plataforma o levou a adotar abordagens mais conservadoras e seguras na hora de criar o código. Resultado: Missão cumprida!