autorake 2.0

Sign up to get free protection for your applications and to get access to all the features.
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
+