[PATCH] Basic experimental support for Windows

Matthias Goldhoorn matthias.goldhoorn at dfki.de
Thu Oct 11 18:09:05 CEST 2012


---
 lib/autobuild/environment.rb    |   53 ++++++++++++++++++-------------
 lib/autobuild/import/archive.rb |   65 +++++++++++++++++++++++++++++++++++++--
 lib/autobuild/packages/cmake.rb |    5 +++
 lib/autobuild/subcommand.rb     |   27 ++++++++++++++--
 4 files changed, 123 insertions(+), 27 deletions(-)

diff --git a/lib/autobuild/environment.rb b/lib/autobuild/environment.rb
index 43001b1..6971e65 100644
--- a/lib/autobuild/environment.rb
+++ b/lib/autobuild/environment.rb
@@ -1,9 +1,12 @@
 require 'set'
+require 'rbconfig'
+
 module Autobuild
     @inherited_environment = Hash.new
     @environment = Hash.new
     @env_source_files = Set.new
-
+	@windows = RbConfig::CONFIG["host_os"] =~%r!(msdos|mswin|djgpp|mingw|[Ww]indows)!
+	
     class << self
         # List of the environment that should be set before calling a subcommand
         #
@@ -56,7 +59,8 @@ module Autobuild
 
         if !inherited_environment.has_key?(name)
             if parent_env = ENV[name]
-                inherited_environment[name] = parent_env.split(':')
+				
+                inherited_environment[name] = parent_env.split(@windows ? ";" : ":")
             else
                 inherited_environment[name] = Array.new
             end
@@ -72,7 +76,7 @@ module Autobuild
         @environment[name] = values
 
         inherited = inherited_environment[name] || Array.new
-        ENV[name] = (values + inherited).join(":")
+        ENV[name] = (values + inherited).join(@windows ? ";" : ":")
     end
 
     def self.env_add_path(name, path, *paths)
@@ -101,25 +105,30 @@ module Autobuild
     #
     # It also sources the files added by Autobuild.env_source_file
     def self.export_env_sh(io)
-        variables = []
-        Autobuild.environment.each do |name, value|
-            variables << name
-            shell_line = "#{name}=#{value.join(":")}"
-            if Autoproj.env_inherit?(name)
-                if value.empty?
-                    next
-                else
-                    shell_line << ":$#{name}"
-                end
-            end
-            io.puts shell_line
-        end
-        variables.each do |var|
-            io.puts "export #{var}"
-        end
-        env_source_files.each do |path|
-            io.puts ". \"#{path}\""
-        end
+		
+		variables = []
+		Autobuild.environment.each do |name, value|
+			variables << name
+			shell_line = "#{@windows ? 'set ' : ''}#{name}=#{value.join(@windows ? ";" : ":")}"
+			if Autoproj.env_inherit?(name)
+				if value.empty?
+					next
+				else
+					if @windows
+						shell_line << ";%#{name}%"
+					else
+						shell_line << ":$#{name}"
+					end	
+				end
+			end
+			io.puts shell_line
+		end
+		variables.each do |var|
+			io.puts "#{@windows ? 'set' : 'export'} #{var}"
+		end
+		env_source_files.each do |path|
+			io.puts "#{@windows? '': '. \"'}#{path}#{@windows? '': '\"'}"
+		end
     end
 
     # DEPRECATED: use env_add_path instead
diff --git a/lib/autobuild/import/archive.rb b/lib/autobuild/import/archive.rb
index e2c0116..9c1d31c 100644
--- a/lib/autobuild/import/archive.rb
+++ b/lib/autobuild/import/archive.rb
@@ -2,6 +2,15 @@ require 'autobuild/importer'
 require 'open-uri'
 require 'fileutils'
 
+WINDOWS = RbConfig::CONFIG["host_os"] =~%r!(msdos|mswin|djgpp|mingw|[Ww]indows)! 
+if WINDOWS 
+	require 'net/http' 
+	require 'net/https'
+	require 'rubygems/package'
+	require 'zlib'
+end
+
+
 module Autobuild
     class ArchiveImporter < Importer
 	# The tarball is not compressed
@@ -36,6 +45,47 @@ module Autobuild
 
         def update_cached_file?; @options[:update_cached_file] end
 
+		
+	def get_url_on_windows(url, filename)
+		uri = URI(url)		
+		STDOUT.puts("Host: #{uri.host} Port: #{uri.port} url: #{url}")
+		
+		http = Net::HTTP.new(uri.host,uri.port)
+		http.use_ssl = true if uri.port == 443
+		http.verify_mode = OpenSSL::SSL::VERIFY_NONE  #Unsure, critical?, Review this
+		resp = http.get(uri.request_uri)
+		
+		if resp.code == "301" or resp.code == "302"
+			get_url_on_windows(resp.header['location'],filename)
+		else
+			if(resp.message != 'OK')
+				raise "Could not get File from url \"#{url}\", got response #{resp.message} (#{resp.code})"
+			end
+			open(filename, "wb") do |file|
+				file.write(resp.body)
+			end
+		end
+	end
+	
+	def extract_tar_on_windows(filename,target)
+	
+		Gem::Package::TarReader.new(Zlib::GzipReader.open(filename)).each do |entry|
+			newname = File.join(target,entry.full_name.slice(entry.full_name.index('/'),entry.full_name.size))
+			if(entry.directory?)
+				FileUtils.mkdir_p(newname)
+			end
+			if(entry.file?)
+				dir = newname.slice(0,newname.rindex('/'))
+				if(!File.directory?(dir))
+					FileUtils.mkdir_p(dir)
+				end
+				open(newname, "wb") do |file|
+					file.write(entry.read)
+				end
+			end
+		end
+	end
+	
 	# Updates the downloaded file in cache only if it is needed
         def update_cache(package)
             do_update = false
@@ -73,7 +123,11 @@ module Autobuild
             if do_update
                 FileUtils.mkdir_p(cachedir)
                 begin
-                    Subprocess.run(package, :import, Autobuild.tool('wget'), '-q', '-P', cachedir, @url, '-O', "#{cachefile}.partial")
+					if(WINDOWS)
+						get_url_on_windows(@url, "#{cachefile}.partial")
+					else
+						Subprocess.run(package, :import, Autobuild.tool('wget'), '-q', '-P', cachedir, @url, '-O', "#{cachefile}.partial")
+					end
                 rescue Exception
                     FileUtils.rm_f "#{cachefile}.partial"
                     raise
@@ -171,13 +225,18 @@ module Autobuild
                 if !@options[:no_subdirectory]
                     cmd << '--strip-components=1'
                 end
-                Subprocess.run(package, :import, Autobuild.tool('tar'), *cmd)
+				
+				if(WINDOWS)
+					extract_tar_on_windows(cachefile,package.srcdir)
+				else
+					Subprocess.run(package, :import, Autobuild.tool('tar'), *cmd)
+				end
             end
 
         rescue OpenURI::HTTPError
             raise Autobuild::Exception.new(package.name, :import)
         rescue SubcommandFailed
-            FileUtils.rm_f cachefile
+			FileUtils.rm_f cachefile
             raise
         end
     end
diff --git a/lib/autobuild/packages/cmake.rb b/lib/autobuild/packages/cmake.rb
index 9d9e3af..fb9fa2f 100644
--- a/lib/autobuild/packages/cmake.rb
+++ b/lib/autobuild/packages/cmake.rb
@@ -304,6 +304,11 @@ module Autobuild
 
                     command = [ "cmake", "-DCMAKE_INSTALL_PREFIX=#{prefix}", "-DCMAKE_MODULE_PATH=#{CMake.module_path.join(";")}" ]
 
+					if(RbConfig::CONFIG["host_os"] =~%r!(msdos|mswin|djgpp|mingw|[Ww]indows)!)
+						command << '-G' 
+						command << "MSYS Makefiles"
+					end
+					
                     defines.each do |name, value|
                         command << "-D#{name}=#{value}"
                     end
diff --git a/lib/autobuild/subcommand.rb b/lib/autobuild/subcommand.rb
index 083af70..5739e2d 100644
--- a/lib/autobuild/subcommand.rb
+++ b/lib/autobuild/subcommand.rb
@@ -70,6 +70,11 @@ module Autobuild
         if @processor_count
             return @processor_count
         end
+		
+		#No parralel build on windows yet, since CPU detection is not easy do able
+		if(RbConfig::CONFIG["host_os"] =~%r!(msdos|mswin|djgpp|mingw|[Ww]indows)!)
+			return 1
+		end
 
         if File.file?('/proc/cpuinfo')
             cpuinfo = File.readlines('/proc/cpuinfo')
@@ -162,7 +167,7 @@ module Autobuild::Subprocess
             options[:working_directory] ||= target.working_directory
         end
 
-        logname = File.join(logdir, "#{target_name}-#{phase}.log")
+		logname = File.join(logdir, "#{target_name.gsub(/[:]/,'_')}-#{phase.to_s.gsub(/[:]/,'_')}.log")
         if !File.directory?(File.dirname(logname))
             FileUtils.mkdir_p File.dirname(logname)
         end
@@ -205,7 +210,23 @@ module Autobuild::Subprocess
             end
             cread, cwrite = IO.pipe # to control that exec goes well
 
-            cwrite.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
+			if Autoproj::OSDependencies.operating_system[0].include?("windows")
+				olddir = Dir.pwd
+				if options[:working_directory] && (options[:working_directory] != Dir.pwd)
+					Dir.chdir(options[:working_directory])
+				end
+				system(*command)
+				result=$?.success?
+				if(!result)
+					error = Autobuild::SubcommandFailed.new(target, command.join(" "), logname, "Systemcall")
+					error.phase = phase
+					raise error
+				end
+				Dir.chdir(olddir)
+				return
+			end
+			
+			cwrite.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
 
             pid = fork do
                 if options[:working_directory] && (options[:working_directory] != Dir.pwd)
@@ -317,3 +338,5 @@ module Autobuild::Subprocess
 
 end
 
+
+
-- 
1.7.10.4


--------------020000030508070909090903
Content-Type: text/x-patch;
 name="autoproj-0001-Basic-experimental-support-for-windows.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename*0="autoproj-0001-Basic-experimental-support-for-windows.patch"



More information about the Rock-dev mailing list