Commit 1e8887192987e857b6ea66b240ce7e667611fdfa

Thomas de Grivel 2023-02-21T00:34:55

configure

diff --git a/.gitignore b/.gitignore
index 2c0cdd0..f330201 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
 /bin/
 /lib/
 /src/
+/target/
 /var/lock/
 /var/log/
 
diff --git a/bin/rbpkg b/bin/rbpkg
index 588fe41..c73ca73 100755
--- a/bin/rbpkg
+++ b/bin/rbpkg
@@ -15,13 +15,13 @@ def usage()
 Source directory commands :
  clone            shortcut for git clone
  clean-sources    remove source directory
- fetch           -shortcut for git fetch
- pull            -shortcut for git pull
- checkout TREE   -shortcut for git checkout
+ fetch            shortcut for git fetch
+ pull             shortcut for git pull
+ checkout TREE    shortcut for git checkout
 
 Build commands :
  autogen         -post checkout command usually named autogen
- configure       -configure build for this system
+ configure       .configure build for this system
  clean-configure -remove configure-done tag file
  build           -run parallel build
  clean-build     -remove object files
@@ -66,6 +66,8 @@ def rbpkg
   when "checkout"
     branch = shift()
     Rbpkg.checkout(branch, $ARGS)
+  when "configure"
+    Rbpkg.configure($ARGS)
   when "info"
     Rbpkg.info($ARGS)
   else
diff --git a/lib/rbpkg.rb b/lib/rbpkg.rb
index ec7eec8..a2c1062 100644
--- a/lib/rbpkg.rb
+++ b/lib/rbpkg.rb
@@ -3,30 +3,59 @@ require __FILE__ + '/../rbpkg/repos'
 
 module Rbpkg
 
+  def self.cc
+    if `which cc`
+      "cc"
+    elsif `which gcc`
+      "gcc"
+    elsif `which egcc`
+      "egcc"
+    end
+  end
+
+  def self.cc!
+    r = cc()
+    raise "C compiler not found" unless r
+    r
+  end
+
   def self.checkout(branch, repos)
     repos.each do |name|
       Repos.repo(name).checkout(branch)
     end
   end
 
+  def self.clean_configure(repos)
+    repos.each do |name|
+      Repos.repo(name).clean_configure()
+    end
+  end
+
   def self.clean_sources(repos)
     repos.each do |name|
       Repos.repo(name).clean_sources()
     end
   end
 
+  def self.configure(repos)
+    repos.each do |name|
+      Repos.repo(name).configure()
+    end
+  end
+
   @@date = nil
   def self.date
     @@date || @@date = Time.now.utc.iso8601
   end
 
+  @@dir = nil
   def self.dir
-    ENV["RBPKG_DIR"] || "#{ENV["HOME"]}/rbpkg"
+    @@dir || @@dir = (ENV["RBPKG_DIR"] || "#{ENV["HOME"]}/rbpkg")
   end
 
   def self.ensure_dir(path)
     if ! File.directory?(path)
-      cmd "mkdir -p #{sh_quote(path)}"
+      cmd! "mkdir -p #{sh_quote(path)}"
     end
   end
 
@@ -43,6 +72,9 @@ module Rbpkg
   end
 
   def self.info(repos)
+    global_info = inspect()
+    $log.puts global_info
+    puts global_info
     repos.each do |name|
       repo_info = Repos.repo(name).inspect()
       $log.puts repo_info
@@ -59,6 +91,14 @@ module Rbpkg
     end
   end
 
+  def self.inspect
+    """%Rbpkg{
+ dir: #{dir.inspect},
+ CC: #{cc.inspect},
+ target: #{target.inspect}
+}"""
+  end
+
   def self.lock(name)
     path = lock_path(name)
     #verbose(2, "Locking #{path}")
@@ -94,6 +134,19 @@ module Rbpkg
   def self.src_dir
     "#{dir}/src"
   end
+
+  def self.tag_dir
+    "#{target_dir}/tag"
+  end
+
+  @@target = nil
+  def self.target
+    @@target || @@target = `LC_ALL=C.UTF-8 #{sh_quote(cc!)} -v 2>&1 | grep '^Target: ' | head -n 1 | cut -c 9-`.strip
+  end
+
+  def self.target_dir
+    "#{dir}/target/#{target}"
+  end
 end
 
 def cmd(string)
@@ -103,9 +156,17 @@ def cmd(string)
       $log.puts line
       puts line
     end
+    pipe.close
+    $?.success?
   end
 end
 
+def cmd!(string)
+  r = cmd(string)
+  raise "command failed: #{string}" unless r
+  true
+end
+
 def sh_quote (str)
   if str.scan("\n") == []
     if str.match?(/^[-+\/=.,:^_0-9A-Za-z]*$/)
diff --git a/lib/rbpkg/repo.rb b/lib/rbpkg/repo.rb
index 53ca094..1057e11 100644
--- a/lib/rbpkg/repo.rb
+++ b/lib/rbpkg/repo.rb
@@ -5,17 +5,44 @@ class Rbpkg::Repo
   @@git_remote_default = "origin"
   @@git_branch_default = "master"
 
+  def autogen()
+    r = if File.executable?("#{src_dir}/autogen")
+          cmd! "cd #{sh_quote(src_dir)} && ./autogen"
+        elsif File.exists?("#{src_dir}/autogen.sh")
+          cmd! "cd #{sh_quote(src_dir)} && ./autogen"
+        else
+          true
+        end
+    raise "autogen failed" unless r
+    true
+  end
   def checkout(branch)
     sh_branch=sh_quote(branch)
-    cmd "cd #{sh_quote(src_dir!)} && git fetch #{sh_quote(git_remote)} #{sh_branch} && git checkout #{sh_branch} && git submodule update"
+    cmd! "cd #{sh_quote(src_dir!)} && git fetch #{sh_quote(git_remote)} #{sh_branch} && git checkout #{sh_branch} && git submodule update"
   end
 
   def clean_sources
     if File.directory?(src_dir)
-      cmd "rm -rf #{sh_quote(src_dir)}"
+      cmd! "rm -rf #{sh_quote(src_dir)}"
     end
     if File.directory?(src_parent_dir) && Dir.new(src_parent_dir).children == []
-      cmd "rmdir #{sh_quote(src_parent_dir)}"
+      cmd! "rmdir #{sh_quote(src_parent_dir)}"
+    end
+  end
+
+  def configure
+    if ! File.directory?(src_dir)
+      git_clone()
+    end
+    if ! tag_present?("configure-done")
+      autogen()
+      r = if File.executable?("#{src_dir}/configure")
+            cmd! "cd #{sh_quote(src_dir)} && ./configure"
+          elsif File.exists?("#{src_dir}/configure.sh")
+            cmd! "cd #{sh_quote(src_dir)} && sh configure.sh"
+          end      
+      tag_set("configure-done") if r
+      r
     end
   end
 
@@ -24,7 +51,7 @@ class Rbpkg::Repo
   end
 
   def fetch
-    cmd "cd #{sh_quote(src_dir!)} && git fetch"
+    cmd! "cd #{sh_quote(src_dir!)} && git fetch"
   end
 
   def git_branch
@@ -36,10 +63,10 @@ class Rbpkg::Repo
       false
     else
       if ! File.directory?(src_parent_dir)
-        cmd "mkdir -p #{sh_quote(src_parent_dir)}"
+        cmd! "mkdir -p #{sh_quote(src_parent_dir)}"
       end
-      cmd "cd #{sh_quote(src_parent_dir)} && git clone #{sh_quote(git_url)} -b #{sh_quote(git_branch)} #{sh_quote(name)}"
-      cmd "cd #{sh_quote(src_dir)} && git submodule init && git submodule update"
+      cmd! "cd #{sh_quote(src_parent_dir)} && git clone #{sh_quote(git_url)} -b #{sh_quote(git_branch)} #{sh_quote(name)}"
+      cmd! "cd #{sh_quote(src_dir)} && git submodule init && git submodule update"
     end
   end
 
@@ -51,6 +78,22 @@ class Rbpkg::Repo
     raise "no git url for #{self}"
   end
 
+  def hash
+    if File.directory?(src_dir)
+      r = `git -C #{sh_quote(src_dir)} show-ref --head HEAD | cut -d ' ' -f 1 | head -n 1`.strip
+      raise "git error" unless r
+      r
+    end
+  end
+
+  def head
+    if File.directory?(src_dir)
+      r = `git -C #{sh_quote(src_dir)} show-ref | grep #{sh_quote(hash)} | grep ' refs/heads/' | sed -e 's,^.* refs/heads/,,'`.strip
+      raise "git error" unless r
+      r
+    end
+  end
+
   def inspect
     """%Repo{
  name: #{name.inspect}
@@ -58,6 +101,8 @@ class Rbpkg::Repo
  git_url: #{git_url.inspect}
  src_dir: #{src_dir.inspect}
  src_parent_dir: #{src_parent_dir.inspect}
+ head: #{head.inspect}
+ hash: #{hash.inspect}
 }"""
   end
 
@@ -66,7 +111,7 @@ class Rbpkg::Repo
   end
 
   def pull
-    cmd "cd #{sh_quote(src_dir!)} && git pull && git submodule update"
+    cmd! "cd #{sh_quote(src_dir!)} && git pull && git submodule update"
   end
 
   def src_dir
@@ -82,4 +127,33 @@ class Rbpkg::Repo
   def src_parent_dir
     File.dirname(src_dir)
   end
+
+  def tag_dir
+    "#{Rbpkg.tag_dir}/#{dir}/#{version}"
+  end
+
+  def tag_path(tag)
+    "#{tag_dir}/#{tag}"
+  end
+
+  def tag_present?(tag)
+    File.file?(tag_path(tag))
+  end
+
+  def tag_remove(tag)
+    raise "tag not set" unless tag_present?(tag)
+    File.delete(tag_path(tag))
+  end
+
+  def tag_set(tag)
+    raise "tag already set" if tag_present?(tag)
+    FileUtils.mkdir_p tag_dir unless File.directory?(tag_dir)
+    File.write(tag_path(tag), "#{Rbpkg.date}\n")
+  end
+
+  def version
+    if File.directory?(src_dir)
+      "#{head}-#{hash}"
+    end
+  end
 end