autorake 2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/LICENSE ADDED
@@ -0,0 +1,34 @@
1
+ _ _ _
2
+ / \ _ _| |_ ___ _ __ __ _| | _____
3
+ / _ \| | | | __/ _ \| '__/ _` | |/ / _ \
4
+ / ___ \ |_| | || (_) | | | (_| | < __/
5
+ /_/ \_\__,_|\__\___/|_| \__,_|_|\_\___|
6
+
7
+
8
+ Copyright (c) 2009-2013, Bertram Scharpf <software@bertram-scharpf.de>.
9
+ All rights reserved.
10
+
11
+ Redistribution and use in source and binary forms, with or without
12
+ modification, are permitted provided that the following conditions are
13
+ met:
14
+
15
+ * Redistributions of source code must retain the above copyright
16
+ notice, this list of conditions and the following disclaimer.
17
+
18
+ * Redistributions in binary form must reproduce the above copyright
19
+ notice, this list of conditions and the following disclaimer in
20
+ the documentation and/or other materials provided with the
21
+ distribution.
22
+
23
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
26
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
27
+ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
+
data/README ADDED
@@ -0,0 +1,15 @@
1
+ Autorake
2
+ ========
3
+
4
+ Author: Bertram Scharpf <software@bertram-scharpf.de>
5
+ License: BSD
6
+
7
+ This project wants to be to Rake what Autocmd is to Make.
8
+
9
+ Have a look at the self-explaining samples directory.
10
+
11
+ The script mkrf_conf will build a file .configure that contains
12
+ the whole configuration information. The Rakefile will read it in
13
+ by extending itself. Various #defines will be given in autoconf
14
+ style.
15
+
@@ -0,0 +1,129 @@
1
+ #
2
+ # autorake.rb -- Autorake module
3
+ #
4
+
5
+ require "autorake/configure"
6
+ require "autorake/compile"
7
+
8
+ module Autorake
9
+
10
+ module Rakefile
11
+
12
+ class <<self
13
+ def extended obj
14
+ obj.load_autorake
15
+ Compiler.verbose = true
16
+ end
17
+ end
18
+
19
+ def has? name
20
+ @autorake.features[ name]
21
+ end
22
+
23
+ def parm
24
+ @autorake.parameters
25
+ end
26
+
27
+ def compiler *args
28
+ CompilerC.new @autorake.incdirs, @autorake.macros, *args
29
+ end
30
+
31
+ def linker *args
32
+ Linker.new @autorake.libdirs, @autorake.libs, *args
33
+ end
34
+
35
+
36
+ def installer under, files, destdir = nil, params = nil
37
+ not params and case destdir
38
+ when nil, Hash then
39
+ under, files, destdir, params = nil, under, files, destdir
40
+ end
41
+ destdir = @autorake.directories.expand destdir
42
+ d = ENV[ "DESTDIR"]
43
+ if d then
44
+ d = File.expand_path d
45
+ destdir = File.join d, destdir
46
+ end
47
+ files = case files
48
+ when Array then files
49
+ else [ files]
50
+ end
51
+ unless @autorake_install then
52
+ task :install do install_targets end
53
+ task :uninstall do uninstall_targets end
54
+ @autorake_install = []
55
+ end
56
+ @autorake_install.push [ under, files, destdir, params]
57
+ end
58
+
59
+ def load_autorake filename = nil
60
+ @autorake = YAML.load_file filename||Configuration::CONFIG_FILE
61
+ @autorake.do_env
62
+ end
63
+
64
+ private
65
+
66
+ def install_targets
67
+ @autorake_install.each { |under,files,destdir,params|
68
+ File.directory? destdir or mkdir_p destdir
69
+ files.each { |f| install under, f, destdir, params }
70
+ }
71
+ end
72
+
73
+ def uninstall_targets
74
+ @autorake_install.reverse.each { |under,files,destdir,|
75
+ files.each { |f| uninstall under, f, destdir }
76
+ }
77
+ end
78
+
79
+ def paths_for_install under, src, dir
80
+ dst = File.join dir, src
81
+ here = under ? (File.join under, src) : src
82
+ there, = File.split src
83
+ there = nil if there == "."
84
+ yield dst, here, there
85
+ end
86
+
87
+ def install under, src, dir, ugm
88
+ paths_for_install under, src, dir do |dst,here,there|
89
+ install under, there, dir, ugm if there
90
+ if File.directory? here or not File.exists? here then
91
+ return if File.directory? dst
92
+ mkdir dst
93
+ elsif File.symlink? here then
94
+ rm dst if File.exists? dst
95
+ rdl = File.readlink here
96
+ ln_s rdl, dst
97
+ else
98
+ cp here, dst
99
+ end
100
+ if ugm then
101
+ u, g = [ :user, :group].map { |x| y = ugm[ x] ; y unless y.empty? }
102
+ chown u, g, dst if u or g
103
+ m = ugm[ :mode]
104
+ if m and not m.empty? then
105
+ m = Integer m
106
+ chmod m, dst
107
+ end
108
+ end
109
+ end
110
+ end
111
+
112
+ def uninstall under, src, dir
113
+ paths_for_install under, src, dir do |dst,here,there|
114
+ if File.directory? here or not File.exists? here then
115
+ rmdir dst rescue return
116
+ else
117
+ rm dst if File.exists? dst or File.symlink? dst
118
+ end
119
+ uninstall under, there, dir if there
120
+ end
121
+ end
122
+
123
+ end
124
+
125
+ end
126
+
127
+ # When we're loaded from a Rakefile, include the extensions to it.
128
+ module Rake ; @application ; end and extend Autorake::Rakefile
129
+
@@ -0,0 +1,138 @@
1
+ #
2
+ # autorake/application.rb -- Parse commandline arguments
3
+ #
4
+
5
+ module Autorake
6
+
7
+ class Application
8
+
9
+ class Option
10
+ class <<self ; def [] *args ; new *args ; end ; end
11
+ attr_reader :desc, :arg
12
+ def initialize *args
13
+ @desc, @arg, *@call = *args
14
+ end
15
+ def call
16
+ @call.dup
17
+ end
18
+ end
19
+
20
+ class Done < Exception ; end
21
+
22
+ class <<self
23
+
24
+ def attr_bang *syms
25
+ syms.each { |sym|
26
+ define_method :"#{sym}!" do
27
+ instance_variable_set :"@#{sym}", true
28
+ end
29
+ }
30
+ nil
31
+ end
32
+
33
+ end
34
+
35
+ def run
36
+ process_options do
37
+ while (arg = $*.shift) do
38
+ case arg
39
+ when /\A--/ then
40
+ a, val = $'.split "=", 2
41
+ do_option a do val end
42
+ when /\A-/ then
43
+ arg = $'
44
+ until (a = arg.slice! 0, 1).empty? do
45
+ do_option a do
46
+ arg.slice! 0, arg.length unless arg.empty?
47
+ end
48
+ end
49
+ else
50
+ n, v = arg.split "="
51
+ environ n, v
52
+ end
53
+ end
54
+ end
55
+ execute
56
+ rescue Done
57
+ rescue
58
+ raise if @verbose
59
+ $stderr.puts "#$! (#{$!.class})"
60
+ exit 1
61
+ end
62
+
63
+ private
64
+
65
+ def define_options
66
+ add_option %w(h help), "display this help", nil, :help
67
+ add_option %w(V version), "display version information", nil, :version
68
+ end
69
+
70
+ def add_option names, *desc_arg_call
71
+ o = Option[ *desc_arg_call]
72
+ names.each { |n| @options[ n] = o }
73
+ end
74
+
75
+ def process_options
76
+ @options = {}
77
+ define_options
78
+ @rest = @options.values.uniq
79
+ yield
80
+ @rest.each { |o|
81
+ if o.arg then
82
+ c = o.call
83
+ c.push o.arg
84
+ send *c
85
+ end
86
+ }
87
+ ensure
88
+ @options = @rest = nil
89
+ end
90
+
91
+ def do_option a
92
+ o = @options[ a]
93
+ o or raise "Unknown option: #{a}"
94
+ c = o.call
95
+ if o.arg then
96
+ g = yield || $*.shift
97
+ c.push g
98
+ end
99
+ send *c
100
+ @rest.delete o
101
+ end
102
+
103
+ def environ nam, val
104
+ raise "Define your own environment setter."
105
+ end
106
+
107
+ def help
108
+ puts " %-16s %-16s %-40s" % %w(Option Argument Description)
109
+ prev = nil
110
+ @options.each { |k,v|
111
+ k = (k.length>1 ? "--" : "-") + k
112
+ l = " %-16s" % k
113
+ unless v == prev then
114
+ l << " %-16s %-40s" % [ v.arg, v.desc]
115
+ end
116
+ puts l
117
+ prev = v
118
+ }
119
+ raise Done
120
+ end
121
+
122
+ def version
123
+ require "autorake/version"
124
+ puts <<-EOT
125
+ #{NAME} #{VERSION} -- #{SUMMARY}
126
+
127
+ Copyright: #{COPYRIGHT}
128
+ License: #{LICENSE}
129
+
130
+ #{HOMEPAGE}
131
+ EOT
132
+ raise Done
133
+ end
134
+
135
+ end
136
+
137
+ end
138
+
@@ -0,0 +1,134 @@
1
+ #
2
+ # autorake/compile.rb -- C compiler
3
+ #
4
+
5
+ module Autorake
6
+
7
+ class Compiler
8
+
9
+ class Error < StandardError ; end
10
+
11
+ class <<self
12
+ attr_accessor :verbose, :quiet
13
+ end
14
+
15
+ def cc *a
16
+ a.flatten!
17
+ a.compact!
18
+ a.unshift ENV[ "CC"] || "cc"
19
+ message a
20
+ f = fork do
21
+ $stderr.reopen "/dev/null" if Compiler.quiet
22
+ exec *a
23
+ end
24
+ Process.waitpid f
25
+ $?.success? or raise Error, "#{self.class} failed."
26
+ end
27
+
28
+ private
29
+
30
+ def message a
31
+ if Compiler.verbose then
32
+ m = a.join " "
33
+ puts m
34
+ end
35
+ end
36
+
37
+ end
38
+
39
+ class CompilerPP < Compiler
40
+
41
+ def initialize incdirs, macros, *args
42
+ @incdirs = incdirs.map { |d| "-I#{d}" }
43
+ @macros = macros.map { |k,v|
44
+ next unless v
45
+ m = "-D#{k}"
46
+ m << "=#{v}" if String === v
47
+ m
48
+ }
49
+ @args = args
50
+ e = ENV[ "CFLAGS"]
51
+ @cflags = e.split if e
52
+ end
53
+
54
+ def cc obj, src
55
+ io = [ "-o", obj.to_s, "-c", src.to_s]
56
+ super @cflags, @macros, @incdirs, @args, opt_E, io
57
+ end
58
+
59
+ private
60
+
61
+ def opt_E
62
+ "-E"
63
+ end
64
+
65
+ end
66
+
67
+ class CompilerC < CompilerPP
68
+
69
+ private
70
+
71
+ def opt_E ; end
72
+
73
+ end
74
+
75
+ class Linker < Compiler
76
+
77
+ def initialize libdirs, libs, *args
78
+ @libdirs = libdirs.map { |d| "-Wl,-L#{d}" }
79
+ @libs = libs.map { |d| "-Wl,-l#{d}" }
80
+ @args = args
81
+ e = ENV[ "LDFLAGS"]
82
+ @ldflags = e.split if e
83
+ end
84
+
85
+ def cc bin, *objs
86
+ io = [ "-o", bin.to_s, objs]
87
+ super @ldflags, @libdirs, @libs, @args, io
88
+ end
89
+
90
+ end
91
+
92
+
93
+ class TmpFiles
94
+
95
+ class <<self
96
+ def open source
97
+ i = new source
98
+ yield i
99
+ ensure
100
+ i.cleanup
101
+ end
102
+ private :new
103
+ end
104
+
105
+ attr_reader :src
106
+
107
+ def initialize source
108
+ @plain = "tmp-0001"
109
+ begin
110
+ @src = "#@plain.c"
111
+ File.open @src, File::WRONLY|File::CREAT|File::EXCL do |c|
112
+ c.puts source
113
+ end
114
+ rescue Errno::EEXIST
115
+ @plain.succ!
116
+ retry
117
+ end
118
+ end
119
+
120
+ def cpp ; @cpp = "#@plain.cpp" ; end
121
+ def obj ; @obj = "#@plain.o" ; end
122
+ def bin ; @bin = "#@plain" ; end
123
+
124
+ def cleanup
125
+ File.delete @bin if @bin and File.exists? @bin
126
+ File.delete @obj if @obj and File.exists? @obj
127
+ File.delete @cpp if @cpp and File.exists? @cpp
128
+ File.delete @src
129
+ end
130
+
131
+ end
132
+
133
+ end
134
+