rscons 1.8.1 → 1.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +13 -5
- data/bin/rscons +3 -0
- data/lib/rscons.rb +102 -83
- data/lib/rscons/builder.rb +4 -2
- data/lib/rscons/builders/command.rb +2 -1
- data/lib/rscons/builders/directory.rb +31 -0
- data/lib/rscons/builders/install.rb +64 -0
- data/lib/rscons/builders/preprocess.rb +28 -8
- data/lib/rscons/cache.rb +39 -12
- data/lib/rscons/cli.rb +78 -0
- data/lib/rscons/environment.rb +31 -25
- data/lib/rscons/varset.rb +2 -0
- data/lib/rscons/version.rb +1 -1
- metadata +23 -18
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MWI2OTdhMDUzYjBhZGY4NWRhNDZkOWYwNjBkYzA5OGZhNTJiOGI1Mw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
M2QwZmE3NjFmNTc5NmU1M2NlYWE1NGIyZGJjNWZiOWI0NGI5ZmExNQ==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YTQ3ODI3N2ZlNjQ4OWVmOWQ3NWRmMTQ2M2Y1NTBkOWExMTg3ZDRiODBiMmU2
|
10
|
+
NTdlNDliNmUyNWY5OTEyMmM4MzE5OWNkYjJmNjNiMDQxYTQ0N2UzMzhlNTkz
|
11
|
+
ZDg5YmNjM2ZjZTE0N2NiNjBiYWUxYjY4NzJmOWJkY2M3MmJkZDk=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZTYxNmZjNjQzMjFlOWZjZDZiMzE2MGFmYzAyMzk0MWE2NjRjNWQ3NWMwNDVl
|
14
|
+
MDAzODUxOWZjYzNmZDQxZjVjMjA4ODQ3YzkwYjE3Mjc5MGU5MTllZjJlOTU5
|
15
|
+
NGVkYTc2OTVmZTY1ZWNkNDVjY2M4ZWMzZWNkMTZjODUwYzRlMWM=
|
data/bin/rscons
ADDED
data/lib/rscons.rb
CHANGED
@@ -6,9 +6,11 @@ require_relative "rscons/varset"
|
|
6
6
|
require_relative "rscons/version"
|
7
7
|
|
8
8
|
# default builders
|
9
|
-
require_relative "rscons/builders/command"
|
10
9
|
require_relative "rscons/builders/cfile"
|
10
|
+
require_relative "rscons/builders/command"
|
11
|
+
require_relative "rscons/builders/directory"
|
11
12
|
require_relative "rscons/builders/disassemble"
|
13
|
+
require_relative "rscons/builders/install"
|
12
14
|
require_relative "rscons/builders/library"
|
13
15
|
require_relative "rscons/builders/object"
|
14
16
|
require_relative "rscons/builders/preprocess"
|
@@ -17,12 +19,16 @@ require_relative "rscons/builders/simple_builder"
|
|
17
19
|
|
18
20
|
# Namespace module for rscons classes
|
19
21
|
module Rscons
|
22
|
+
|
20
23
|
# Names of the default builders which will be added to all newly created
|
21
24
|
# {Environment} objects.
|
22
25
|
DEFAULT_BUILDERS = [
|
23
|
-
:Command,
|
24
26
|
:CFile,
|
27
|
+
:Command,
|
28
|
+
:Copy,
|
29
|
+
:Directory,
|
25
30
|
:Disassemble,
|
31
|
+
:Install,
|
26
32
|
:Library,
|
27
33
|
:Object,
|
28
34
|
:Preprocess,
|
@@ -32,101 +38,114 @@ module Rscons
|
|
32
38
|
# Class to represent a fatal error while building a target.
|
33
39
|
class BuildError < RuntimeError; end
|
34
40
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
cache.directories.sort {|a, b| b.size <=> a.size}.each do |directory|
|
46
|
-
next unless File.directory?(directory)
|
47
|
-
if (Dir.entries(directory) - ['.', '..']).empty?
|
48
|
-
Dir.rmdir(directory) rescue nil
|
41
|
+
class << self
|
42
|
+
|
43
|
+
# Remove all generated files.
|
44
|
+
#
|
45
|
+
# @return [void]
|
46
|
+
def clean
|
47
|
+
cache = Cache.instance
|
48
|
+
# remove all built files
|
49
|
+
cache.targets.each do |target|
|
50
|
+
FileUtils.rm_f(target)
|
49
51
|
end
|
52
|
+
# remove all created directories if they are empty
|
53
|
+
cache.directories.sort {|a, b| b.size <=> a.size}.each do |directory|
|
54
|
+
next unless File.directory?(directory)
|
55
|
+
if (Dir.entries(directory) - ['.', '..']).empty?
|
56
|
+
Dir.rmdir(directory) rescue nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
cache.clear
|
50
60
|
end
|
51
|
-
cache.clear
|
52
|
-
end
|
53
61
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
+
# Return whether the given path is an absolute filesystem path.
|
63
|
+
#
|
64
|
+
# @param path [String] the path to examine.
|
65
|
+
#
|
66
|
+
# @return [Boolean] Whether the given path is an absolute filesystem path.
|
67
|
+
def absolute_path?(path)
|
68
|
+
path =~ %r{^(/|\w:[\\/])}
|
69
|
+
end
|
62
70
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
end
|
71
|
+
# Return whether the given target is a phony target.
|
72
|
+
#
|
73
|
+
# @param target [Symbol, String] Target name.
|
74
|
+
#
|
75
|
+
# @return [Boolean] Whether the given target is a phony target.
|
76
|
+
def phony_target?(target)
|
77
|
+
target.is_a?(Symbol)
|
78
|
+
end
|
72
79
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
80
|
+
# Return a new path by changing the suffix in path to suffix.
|
81
|
+
#
|
82
|
+
# @param path [String] The path to alter.
|
83
|
+
# @param suffix [String] The new filename suffix, e.g. ".exe".
|
84
|
+
#
|
85
|
+
# @return [String] New path.
|
86
|
+
def set_suffix(path, suffix)
|
87
|
+
path.sub(/\.[^.]*$/, "") + suffix
|
88
|
+
end
|
89
|
+
|
90
|
+
# Return the system shell and arguments for executing a shell command.
|
91
|
+
#
|
92
|
+
# @return [Array<String>] The shell and flag.
|
93
|
+
def get_system_shell
|
94
|
+
@shell ||=
|
95
|
+
begin
|
96
|
+
test_shell = lambda do |*args|
|
97
|
+
begin
|
98
|
+
"success" == IO.popen([*args, "echo success"]) do |io|
|
99
|
+
io.read.strip
|
100
|
+
end
|
101
|
+
rescue
|
102
|
+
false
|
83
103
|
end
|
84
|
-
rescue
|
85
|
-
false
|
86
104
|
end
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
105
|
+
if ENV["SHELL"] and ENV["SHELL"] != "" and test_shell[ENV["SHELL"], "-c"]
|
106
|
+
[ENV["SHELL"], "-c"]
|
107
|
+
elsif Object.const_get("RUBY_PLATFORM") =~ /mingw/
|
108
|
+
if test_shell["sh", "-c"]
|
109
|
+
# Using Rscons from MSYS should use MSYS's shell.
|
110
|
+
["sh", "-c"]
|
111
|
+
else
|
112
|
+
["cmd", "/c"]
|
113
|
+
end
|
94
114
|
else
|
95
|
-
["
|
115
|
+
["sh", "-c"]
|
96
116
|
end
|
97
|
-
else
|
98
|
-
["sh", "-c"]
|
99
117
|
end
|
100
|
-
|
101
|
-
end
|
118
|
+
end
|
102
119
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
120
|
+
# Return an Array containing a command used to execute commands.
|
121
|
+
#
|
122
|
+
# This will normally be an empty Array, but on Windows if Rscons detects
|
123
|
+
# that it is running in MSYS then ["env"] will be returned.
|
124
|
+
#
|
125
|
+
# @return [Array<String>] Command used to execute commands.
|
126
|
+
def command_executer
|
127
|
+
@command_executer ||=
|
128
|
+
if Object.const_get("RUBY_PLATFORM") =~ /mingw/
|
129
|
+
if ENV.keys.find {|key| key =~ /MSYS/}
|
130
|
+
begin
|
131
|
+
if IO.popen(["env", "echo", "success"]) {|io| io.read.strip} == "success"
|
132
|
+
["env"]
|
133
|
+
end
|
134
|
+
rescue
|
116
135
|
end
|
117
|
-
rescue
|
118
136
|
end
|
119
|
-
end
|
120
|
-
|
121
|
-
|
137
|
+
end || []
|
138
|
+
end
|
139
|
+
|
140
|
+
# Set the command executer array.
|
141
|
+
#
|
142
|
+
# @param val [Array<String>] Command used to execute commands.
|
143
|
+
#
|
144
|
+
# @return [Array<String>] Command used to execute commands.
|
145
|
+
def command_executer=(val)
|
146
|
+
@command_executer = val
|
147
|
+
end
|
122
148
|
|
123
|
-
# Set the command executer array.
|
124
|
-
#
|
125
|
-
# @param val [Array<String>] Command used to execute commands.
|
126
|
-
#
|
127
|
-
# @return [Array<String>] Command used to execute commands.
|
128
|
-
def self.command_executer=(val)
|
129
|
-
@@command_executer = val
|
130
149
|
end
|
131
150
|
end
|
132
151
|
|
data/lib/rscons/builder.rb
CHANGED
@@ -87,8 +87,10 @@ module Rscons
|
|
87
87
|
# The name of the target on success or false on failure.
|
88
88
|
def standard_build(short_cmd_string, target, command, sources, env, cache)
|
89
89
|
unless cache.up_to_date?(target, command, sources, env)
|
90
|
-
|
91
|
-
|
90
|
+
unless Rscons.phony_target?(target)
|
91
|
+
cache.mkdir_p(File.dirname(target))
|
92
|
+
FileUtils.rm_f(target)
|
93
|
+
end
|
92
94
|
return false unless env.execute(short_cmd_string, command)
|
93
95
|
cache.register_build(target, command, sources, env)
|
94
96
|
end
|
@@ -25,7 +25,8 @@ module Rscons
|
|
25
25
|
"_SOURCES" => sources,
|
26
26
|
})
|
27
27
|
command = env.build_command("${CMD}", vars)
|
28
|
-
|
28
|
+
cmd_desc = vars["CMD_DESC"] || "Command"
|
29
|
+
standard_build("#{cmd_desc} #{target}", target, command, sources, env, cache)
|
29
30
|
end
|
30
31
|
end
|
31
32
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Rscons
|
2
|
+
module Builders
|
3
|
+
# The Directory builder creates a directory.
|
4
|
+
class Directory < Builder
|
5
|
+
|
6
|
+
# Run the builder to produce a build target.
|
7
|
+
#
|
8
|
+
# @param target [String] Target file name.
|
9
|
+
# @param sources [Array<String>] Source file name(s).
|
10
|
+
# @param cache [Cache] The Cache object.
|
11
|
+
# @param env [Environment] The Environment executing the builder.
|
12
|
+
# @param vars [Hash,VarSet] Extra construction variables.
|
13
|
+
#
|
14
|
+
# @return [String,false]
|
15
|
+
# Name of the target file on success or false on failure.
|
16
|
+
def run(target, sources, cache, env, vars)
|
17
|
+
if File.directory?(target)
|
18
|
+
target
|
19
|
+
elsif File.exists?(target)
|
20
|
+
$stderr.puts "Error: `#{target}' already exists and is not a directory"
|
21
|
+
false
|
22
|
+
else
|
23
|
+
puts "Directory #{target}"
|
24
|
+
cache.mkdir_p(target)
|
25
|
+
target
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require "pathname"
|
2
|
+
|
3
|
+
module Rscons
|
4
|
+
module Builders
|
5
|
+
# The Install builder copies files/directories to new locations.
|
6
|
+
class Install < Builder
|
7
|
+
|
8
|
+
# Run the builder to produce a build target.
|
9
|
+
#
|
10
|
+
# @param target [String] Target file name.
|
11
|
+
# @param sources [Array<String>] Source file name(s).
|
12
|
+
# @param cache [Cache] The Cache object.
|
13
|
+
# @param env [Environment] The Environment executing the builder.
|
14
|
+
# @param vars [Hash,VarSet] Extra construction variables.
|
15
|
+
#
|
16
|
+
# @return [String,false]
|
17
|
+
# Name of the target file on success or false on failure.
|
18
|
+
def run(target, sources, cache, env, vars)
|
19
|
+
target_is_dir = (sources.length > 1) ||
|
20
|
+
Dir.exists?(sources.first) ||
|
21
|
+
Dir.exists?(target)
|
22
|
+
outdir = target_is_dir ? target : File.dirname(target)
|
23
|
+
# Collect the list of files to copy over.
|
24
|
+
file_map = {}
|
25
|
+
if target_is_dir
|
26
|
+
sources.each do |src|
|
27
|
+
if Dir.exists? src
|
28
|
+
Dir.glob("#{src}/**/*", File::FNM_DOTMATCH).select do |f|
|
29
|
+
File.file?(f)
|
30
|
+
end.each do |subfile|
|
31
|
+
subpath = Pathname.new(subfile).relative_path_from(Pathname.new(src)).to_s
|
32
|
+
file_map[subfile] = "#{outdir}/#{subpath}"
|
33
|
+
end
|
34
|
+
else
|
35
|
+
file_map[src] = "#{outdir}/#{File.basename(src)}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
else
|
39
|
+
file_map[sources.first] = target
|
40
|
+
end
|
41
|
+
printed_message = false
|
42
|
+
file_map.each do |src, dest|
|
43
|
+
# Check the cache and copy if necessary
|
44
|
+
unless cache.up_to_date?(dest, :Copy, [src], env)
|
45
|
+
unless printed_message
|
46
|
+
puts "#{name} #{target}"
|
47
|
+
printed_message = true
|
48
|
+
end
|
49
|
+
cache.mkdir_p(File.dirname(dest))
|
50
|
+
FileUtils.cp(src, dest, :preserve => true)
|
51
|
+
end
|
52
|
+
cache.register_build(dest, :Copy, [src], env)
|
53
|
+
end
|
54
|
+
target if (target_is_dir ? Dir.exists?(target) : File.exists?(target))
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
# The Copy builder is identical to the Install builder.
|
61
|
+
class Copy < Install; end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
@@ -1,7 +1,10 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
|
1
3
|
module Rscons
|
2
4
|
module Builders
|
3
5
|
# The Preprocess builder invokes the C preprocessor
|
4
6
|
class Preprocess < Builder
|
7
|
+
|
5
8
|
# Return default construction variables for the builder.
|
6
9
|
#
|
7
10
|
# @param env [Environment] The Environment using the builder.
|
@@ -9,7 +12,9 @@ module Rscons
|
|
9
12
|
# @return [Hash] Default construction variables for the builder.
|
10
13
|
def default_variables(env)
|
11
14
|
{
|
12
|
-
"CPP_CMD" => [
|
15
|
+
"CPP_CMD" => %w[
|
16
|
+
${_PREPROCESS_CC} -E ${_PREPROCESS_DEPGEN}
|
17
|
+
-o ${_TARGET} -I${CPPPATH} ${CPPFLAGS} ${_SOURCES}],
|
13
18
|
}
|
14
19
|
end
|
15
20
|
|
@@ -24,17 +29,32 @@ module Rscons
|
|
24
29
|
# @return [String,false]
|
25
30
|
# Name of the target file on success or false on failure.
|
26
31
|
def run(target, sources, cache, env, vars)
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
+
if sources.find {|s| s.end_with?(*env.expand_varref("${CXXSUFFIX}", vars))}
|
33
|
+
pp_cc = "${CXX}"
|
34
|
+
depgen = "${CXXDEPGEN}"
|
35
|
+
else
|
36
|
+
pp_cc = "${CC}"
|
37
|
+
depgen = "${CCDEPGEN}"
|
38
|
+
end
|
32
39
|
vars = vars.merge("_PREPROCESS_CC" => pp_cc,
|
40
|
+
"_PREPROCESS_DEPGEN" => depgen,
|
33
41
|
"_TARGET" => target,
|
34
|
-
"_SOURCES" => sources
|
42
|
+
"_SOURCES" => sources,
|
43
|
+
"_DEPFILE" => Rscons.set_suffix(target, env.expand_varref("${DEPFILESUFFIX}", vars)))
|
35
44
|
command = env.build_command("${CPP_CMD}", vars)
|
36
|
-
|
45
|
+
unless cache.up_to_date?(target, command, sources, env)
|
46
|
+
cache.mkdir_p(File.dirname(target))
|
47
|
+
return false unless env.execute("Preprocess #{target}", command)
|
48
|
+
deps = sources
|
49
|
+
if File.exists?(vars["_DEPFILE"])
|
50
|
+
deps += Environment.parse_makefile_deps(vars["_DEPFILE"], nil)
|
51
|
+
FileUtils.rm_f(vars["_DEPFILE"])
|
52
|
+
end
|
53
|
+
cache.register_build(target, command, deps.uniq, env)
|
54
|
+
end
|
55
|
+
target
|
37
56
|
end
|
57
|
+
|
38
58
|
end
|
39
59
|
end
|
40
60
|
end
|
data/lib/rscons/cache.rb
CHANGED
@@ -56,6 +56,9 @@ module Rscons
|
|
56
56
|
# Name of the file to store cache information in
|
57
57
|
CACHE_FILE = ".rsconscache"
|
58
58
|
|
59
|
+
# Prefix for phony cache entries.
|
60
|
+
PHONY_PREFIX = ":PHONY:"
|
61
|
+
|
59
62
|
# Create a Cache object and load in the previous contents from the cache
|
60
63
|
# file.
|
61
64
|
def initialize
|
@@ -92,7 +95,8 @@ module Rscons
|
|
92
95
|
|
93
96
|
# Check if target(s) are up to date.
|
94
97
|
#
|
95
|
-
# @param targets [String, Array<String>]
|
98
|
+
# @param targets [Symbol, String, Array<String>]
|
99
|
+
# The name(s) of the target file(s).
|
96
100
|
# @param command [String, Array, Hash]
|
97
101
|
# The command used to build the target. The command parameter can
|
98
102
|
# actually be a String, Array, or Hash and could contain information
|
@@ -120,19 +124,25 @@ module Rscons
|
|
120
124
|
# stored in the cache file
|
121
125
|
def up_to_date?(targets, command, deps, env, options = {})
|
122
126
|
Array(targets).each do |target|
|
123
|
-
|
124
|
-
|
127
|
+
cache_key = get_cache_key(target)
|
128
|
+
|
129
|
+
unless Rscons.phony_target?(target)
|
130
|
+
# target file must exist on disk
|
131
|
+
return false unless File.exists?(target)
|
132
|
+
end
|
125
133
|
|
126
134
|
# target must be registered in the cache
|
127
|
-
return false unless @cache["targets"].has_key?(
|
135
|
+
return false unless @cache["targets"].has_key?(cache_key)
|
128
136
|
|
129
|
-
|
130
|
-
|
137
|
+
unless Rscons.phony_target?(target)
|
138
|
+
# target must have the same checksum as when it was built last
|
139
|
+
return false unless @cache["targets"][cache_key]["checksum"] == lookup_checksum(target)
|
140
|
+
end
|
131
141
|
|
132
142
|
# command used to build target must be identical
|
133
|
-
return false unless @cache["targets"][
|
143
|
+
return false unless @cache["targets"][cache_key]["command"] == Digest::MD5.hexdigest(command.inspect)
|
134
144
|
|
135
|
-
cached_deps = @cache["targets"][
|
145
|
+
cached_deps = @cache["targets"][cache_key]["deps"] || []
|
136
146
|
cached_deps_fnames = cached_deps.map { |dc| dc["fname"] }
|
137
147
|
if options[:strict_deps]
|
138
148
|
# depedencies passed in must exactly equal those in the cache
|
@@ -144,7 +154,7 @@ module Rscons
|
|
144
154
|
|
145
155
|
# set of user dependencies must match
|
146
156
|
user_deps = env.get_user_deps(target) || []
|
147
|
-
cached_user_deps = @cache["targets"][
|
157
|
+
cached_user_deps = @cache["targets"][cache_key]["user_deps"] || []
|
148
158
|
cached_user_deps_fnames = cached_user_deps.map { |dc| dc["fname"] }
|
149
159
|
return false unless user_deps == cached_user_deps_fnames
|
150
160
|
|
@@ -159,7 +169,8 @@ module Rscons
|
|
159
169
|
|
160
170
|
# Store cache information about target(s) built by a builder.
|
161
171
|
#
|
162
|
-
# @param targets [String, Array<String>]
|
172
|
+
# @param targets [Symbol, String, Array<String>]
|
173
|
+
# The name of the target(s) built.
|
163
174
|
# @param command [String, Array, Hash]
|
164
175
|
# The command used to build the target. The command parameter can
|
165
176
|
# actually be a String, Array, or Hash and could contain information
|
@@ -172,9 +183,10 @@ module Rscons
|
|
172
183
|
# @return [void]
|
173
184
|
def register_build(targets, command, deps, env)
|
174
185
|
Array(targets).each do |target|
|
175
|
-
|
186
|
+
target_checksum = Rscons.phony_target?(target) ? "" : calculate_checksum(target)
|
187
|
+
@cache["targets"][get_cache_key(target)] = {
|
176
188
|
"command" => Digest::MD5.hexdigest(command.inspect),
|
177
|
-
"checksum" =>
|
189
|
+
"checksum" => target_checksum,
|
178
190
|
"deps" => deps.map do |dep|
|
179
191
|
{
|
180
192
|
"fname" => dep,
|
@@ -228,6 +240,21 @@ module Rscons
|
|
228
240
|
|
229
241
|
private
|
230
242
|
|
243
|
+
# Return a String key based on the target name to use in the on-disk cache.
|
244
|
+
#
|
245
|
+
# @param target_name [Symbol, String]
|
246
|
+
# Target name.
|
247
|
+
#
|
248
|
+
# @return [String]
|
249
|
+
# Key name.
|
250
|
+
def get_cache_key(target_name)
|
251
|
+
if Rscons.phony_target?(target_name)
|
252
|
+
PHONY_PREFIX + target_name.to_s
|
253
|
+
else
|
254
|
+
target_name
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
231
258
|
# Create a Cache object and load in the previous contents from the cache
|
232
259
|
# file.
|
233
260
|
def initialize!
|
data/lib/rscons/cli.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
require "rscons"
|
2
|
+
require "optparse"
|
3
|
+
|
4
|
+
module Rscons
|
5
|
+
# Command-Line Interface functionality.
|
6
|
+
module Cli
|
7
|
+
|
8
|
+
# Default files to look for to execute if none specified.
|
9
|
+
DEFAULT_RSCONSFILES = %w[Rsconsfile Rsconsfile.rb]
|
10
|
+
|
11
|
+
class << self
|
12
|
+
|
13
|
+
# Run the Rscons CLI.
|
14
|
+
#
|
15
|
+
# @param argv [Array]
|
16
|
+
# Command-line parameters.
|
17
|
+
#
|
18
|
+
# @return [void]
|
19
|
+
def run(argv)
|
20
|
+
argv = argv.dup
|
21
|
+
rsconsfile = nil
|
22
|
+
|
23
|
+
OptionParser.new do |opts|
|
24
|
+
opts.banner = "Usage: #{$0} [options]"
|
25
|
+
|
26
|
+
opts.separator ""
|
27
|
+
opts.separator "Options:"
|
28
|
+
|
29
|
+
opts.on("-c", "--clean", "Perform clean operation") do
|
30
|
+
Rscons.clean
|
31
|
+
exit 0
|
32
|
+
end
|
33
|
+
|
34
|
+
opts.on("-f FILE", "Execute FILE (default Rsconsfile)") do |f|
|
35
|
+
rsconsfile = f
|
36
|
+
end
|
37
|
+
|
38
|
+
opts.on_tail("--version", "Show version") do
|
39
|
+
puts "Rscons version #{Rscons::VERSION}"
|
40
|
+
exit 0
|
41
|
+
end
|
42
|
+
|
43
|
+
opts.on_tail("-h", "--help", "Show this help.") do
|
44
|
+
puts opts
|
45
|
+
exit 0
|
46
|
+
end
|
47
|
+
|
48
|
+
end.parse!(argv)
|
49
|
+
|
50
|
+
if rsconsfile
|
51
|
+
unless File.exists?(rsconsfile)
|
52
|
+
$stderr.puts "Cannot read #{rsconsfile}"
|
53
|
+
exit 1
|
54
|
+
end
|
55
|
+
else
|
56
|
+
rsconsfile = DEFAULT_RSCONSFILES.find do |f|
|
57
|
+
File.exists?(f)
|
58
|
+
end
|
59
|
+
unless rsconsfile
|
60
|
+
$stderr.puts "Could not find the Rsconsfile to execute."
|
61
|
+
$stderr.puts "Looked in: [#{DEFAULT_RSCONSFILES.join(", ")}]"
|
62
|
+
exit 1
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
begin
|
67
|
+
load rsconsfile
|
68
|
+
rescue Rscons::BuildError => e
|
69
|
+
$stderr.puts e.message
|
70
|
+
exit 1
|
71
|
+
end
|
72
|
+
|
73
|
+
exit 0
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/lib/rscons/environment.rb
CHANGED
@@ -280,33 +280,35 @@ module Rscons
|
|
280
280
|
#
|
281
281
|
# @return [void]
|
282
282
|
def process
|
283
|
-
expand_paths!
|
284
283
|
while @targets.size > 0
|
284
|
+
expand_paths!
|
285
285
|
targets = @targets
|
286
286
|
@targets = {}
|
287
287
|
cache = Cache.instance
|
288
288
|
cache.clear_checksum_cache!
|
289
|
-
targets_processed =
|
289
|
+
targets_processed = Set.new
|
290
290
|
process_target = proc do |target|
|
291
|
-
targets_processed
|
292
|
-
|
293
|
-
|
294
|
-
|
291
|
+
unless targets_processed.include?(target)
|
292
|
+
targets_processed << target
|
293
|
+
targets[target].each do |target_params|
|
294
|
+
target_params[:sources].each do |src|
|
295
|
+
if targets.include?(src) and not targets_processed.include?(src)
|
296
|
+
process_target.call(src)
|
297
|
+
end
|
298
|
+
end
|
299
|
+
result = run_builder(target_params[:builder],
|
300
|
+
target,
|
301
|
+
target_params[:sources],
|
302
|
+
cache,
|
303
|
+
target_params[:vars] || {})
|
304
|
+
unless result
|
305
|
+
raise BuildError.new("Failed to build #{target}")
|
295
306
|
end
|
296
307
|
end
|
297
|
-
result = run_builder(targets[target][:builder],
|
298
|
-
target,
|
299
|
-
targets[target][:sources],
|
300
|
-
cache,
|
301
|
-
targets[target][:vars] || {})
|
302
|
-
unless result
|
303
|
-
raise BuildError.new("Failed to build #{target}")
|
304
|
-
end
|
305
|
-
result
|
306
308
|
end
|
307
309
|
end
|
308
310
|
begin
|
309
|
-
targets.
|
311
|
+
targets.each_key do |target|
|
310
312
|
process_target.call(target)
|
311
313
|
end
|
312
314
|
ensure
|
@@ -404,7 +406,8 @@ module Rscons
|
|
404
406
|
#
|
405
407
|
# @return [void]
|
406
408
|
def add_target(target, builder, sources, vars, args)
|
407
|
-
@targets[target]
|
409
|
+
@targets[target] ||= []
|
410
|
+
@targets[target] << {
|
408
411
|
builder: builder,
|
409
412
|
sources: sources,
|
410
413
|
vars: vars,
|
@@ -679,14 +682,16 @@ module Rscons
|
|
679
682
|
#
|
680
683
|
# @return [void]
|
681
684
|
def expand_paths!
|
682
|
-
@targets = @targets.reduce({}) do |result, (target,
|
683
|
-
sources = target_params[:sources].map do |source|
|
684
|
-
source = expand_path(source) if @build_root
|
685
|
-
expand_varref(source)
|
686
|
-
end
|
685
|
+
@targets = @targets.reduce({}) do |result, (target, target_params_list)|
|
687
686
|
target = expand_path(target) if @build_root
|
688
687
|
target = expand_varref(target)
|
689
|
-
result[target] =
|
688
|
+
result[target] = target_params_list.map do |target_params|
|
689
|
+
sources = target_params[:sources].map do |source|
|
690
|
+
source = expand_path(source) if @build_root
|
691
|
+
expand_varref(source)
|
692
|
+
end.flatten
|
693
|
+
target_params.merge(sources: sources)
|
694
|
+
end
|
690
695
|
result
|
691
696
|
end
|
692
697
|
end
|
@@ -696,7 +701,8 @@ module Rscons
|
|
696
701
|
# This method is used internally by Rscons builders.
|
697
702
|
#
|
698
703
|
# @param mf_fname [String] File name of the Makefile to read.
|
699
|
-
# @param target [String]
|
704
|
+
# @param target [String, nil]
|
705
|
+
# Name of the target to gather dependencies for, nil for any/all.
|
700
706
|
#
|
701
707
|
# @return [Array<String>] Paths of dependency files.
|
702
708
|
def self.parse_makefile_deps(mf_fname, target)
|
@@ -709,7 +715,7 @@ module Rscons
|
|
709
715
|
buildup += ' ' + line
|
710
716
|
if buildup =~ /^(.*): (.*)$/
|
711
717
|
mf_target, mf_deps = $1.strip, $2
|
712
|
-
if mf_target == target
|
718
|
+
if target.nil? or mf_target == target
|
713
719
|
deps += mf_deps.split(' ').map(&:strip)
|
714
720
|
end
|
715
721
|
end
|
data/lib/rscons/varset.rb
CHANGED
data/lib/rscons/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rscons
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Holtrop
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-03-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -28,106 +28,111 @@ dependencies:
|
|
28
28
|
name: rspec
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - '>='
|
31
|
+
- - ! '>='
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - '>='
|
38
|
+
- - ! '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - '>='
|
45
|
+
- - ! '>='
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - '>='
|
52
|
+
- - ! '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: simplecov
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - '>='
|
59
|
+
- - ! '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - '>='
|
66
|
+
- - ! '>='
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: yard
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - '>='
|
73
|
+
- - ! '>='
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - '>='
|
80
|
+
- - ! '>='
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rdoc
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - '>='
|
87
|
+
- - ! '>='
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - '>='
|
94
|
+
- - ! '>='
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: redcarpet
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- - '>='
|
101
|
+
- - ! '>='
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '0'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- - '>='
|
108
|
+
- - ! '>='
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
description: Software construction library inspired by SCons and implemented in Ruby.
|
112
112
|
email:
|
113
113
|
- jholtrop@gmail.com
|
114
|
-
executables:
|
114
|
+
executables:
|
115
|
+
- rscons
|
115
116
|
extensions: []
|
116
117
|
extra_rdoc_files: []
|
117
118
|
files:
|
118
119
|
- LICENSE.txt
|
120
|
+
- bin/rscons
|
119
121
|
- lib/rscons.rb
|
120
122
|
- lib/rscons/build_target.rb
|
121
123
|
- lib/rscons/builder.rb
|
122
124
|
- lib/rscons/builders/cfile.rb
|
123
125
|
- lib/rscons/builders/command.rb
|
126
|
+
- lib/rscons/builders/directory.rb
|
124
127
|
- lib/rscons/builders/disassemble.rb
|
128
|
+
- lib/rscons/builders/install.rb
|
125
129
|
- lib/rscons/builders/library.rb
|
126
130
|
- lib/rscons/builders/object.rb
|
127
131
|
- lib/rscons/builders/preprocess.rb
|
128
132
|
- lib/rscons/builders/program.rb
|
129
133
|
- lib/rscons/builders/simple_builder.rb
|
130
134
|
- lib/rscons/cache.rb
|
135
|
+
- lib/rscons/cli.rb
|
131
136
|
- lib/rscons/environment.rb
|
132
137
|
- lib/rscons/varset.rb
|
133
138
|
- lib/rscons/version.rb
|
@@ -142,17 +147,17 @@ require_paths:
|
|
142
147
|
- lib
|
143
148
|
required_ruby_version: !ruby/object:Gem::Requirement
|
144
149
|
requirements:
|
145
|
-
- - '>='
|
150
|
+
- - ! '>='
|
146
151
|
- !ruby/object:Gem::Version
|
147
152
|
version: '0'
|
148
153
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
149
154
|
requirements:
|
150
|
-
- - '>='
|
155
|
+
- - ! '>='
|
151
156
|
- !ruby/object:Gem::Version
|
152
157
|
version: '0'
|
153
158
|
requirements: []
|
154
159
|
rubyforge_project:
|
155
|
-
rubygems_version: 2.4.
|
160
|
+
rubygems_version: 2.4.3
|
156
161
|
signing_key:
|
157
162
|
specification_version: 4
|
158
163
|
summary: Software construction library inspired by SCons and implemented in Ruby
|