rscons 1.4.3 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/lib/rscons.rb +75 -5
  2. data/lib/rscons/build_target.rb +36 -0
  3. data/lib/rscons/builder.rb +41 -3
  4. data/lib/rscons/builders/cfile.rb +15 -0
  5. data/lib/rscons/builders/disassemble.rb +15 -0
  6. data/lib/rscons/builders/library.rb +17 -2
  7. data/lib/rscons/builders/object.rb +37 -5
  8. data/lib/rscons/builders/preprocess.rb +15 -0
  9. data/lib/rscons/builders/program.rb +42 -2
  10. data/lib/rscons/cache.rb +26 -6
  11. data/lib/rscons/environment.rb +259 -19
  12. data/lib/rscons/varset.rb +33 -10
  13. data/lib/rscons/version.rb +1 -1
  14. data/rscons.gemspec +8 -10
  15. metadata +38 -103
  16. checksums.yaml +0 -15
  17. data/.gitignore +0 -18
  18. data/.rspec +0 -2
  19. data/Gemfile +0 -4
  20. data/README.md +0 -384
  21. data/Rakefile.rb +0 -26
  22. data/build_tests/build_dir/src/one/one.c +0 -6
  23. data/build_tests/build_dir/src/two/two.c +0 -7
  24. data/build_tests/build_dir/src/two/two.h +0 -6
  25. data/build_tests/clone_env/src/program.c +0 -6
  26. data/build_tests/custom_builder/program.c +0 -7
  27. data/build_tests/d/main.d +0 -6
  28. data/build_tests/header/header.c +0 -7
  29. data/build_tests/header/header.h +0 -6
  30. data/build_tests/library/one.c +0 -8
  31. data/build_tests/library/three.c +0 -0
  32. data/build_tests/library/two.c +0 -0
  33. data/build_tests/simple/simple.c +0 -6
  34. data/build_tests/simple_cc/simple.cc +0 -8
  35. data/build_tests/two_sources/one.c +0 -8
  36. data/build_tests/two_sources/two.c +0 -3
  37. data/spec/build_tests_spec.rb +0 -527
  38. data/spec/rscons/builders/cfile_spec.rb +0 -28
  39. data/spec/rscons/builders/disassemble_spec.rb +0 -17
  40. data/spec/rscons/builders/library_spec.rb +0 -18
  41. data/spec/rscons/builders/object_spec.rb +0 -23
  42. data/spec/rscons/builders/preprocess_spec.rb +0 -18
  43. data/spec/rscons/builders/program_spec.rb +0 -18
  44. data/spec/rscons/cache_spec.rb +0 -271
  45. data/spec/rscons/environment_spec.rb +0 -361
  46. data/spec/rscons/varset_spec.rb +0 -163
  47. data/spec/rscons_spec.rb +0 -26
  48. data/spec/spec_helper.rb +0 -7
@@ -1,3 +1,4 @@
1
+ require_relative "rscons/build_target"
1
2
  require_relative "rscons/builder"
2
3
  require_relative "rscons/cache"
3
4
  require_relative "rscons/environment"
@@ -14,6 +15,8 @@ require_relative "rscons/builders/program"
14
15
 
15
16
  # Namespace module for rscons classes
16
17
  module Rscons
18
+ # Names of the default builders which will be added to all newly created
19
+ # {Environment} objects.
17
20
  DEFAULT_BUILDERS = [
18
21
  :CFile,
19
22
  :Disassemble,
@@ -23,9 +26,10 @@ module Rscons
23
26
  :Program,
24
27
  ]
25
28
 
29
+ # Class to represent a fatal error while building a target.
26
30
  class BuildError < RuntimeError; end
27
31
 
28
- # Remove all generated files
32
+ # Remove all generated files.
29
33
  def self.clean
30
34
  cache = Cache.instance
31
35
  # remove all built files
@@ -42,16 +46,82 @@ module Rscons
42
46
  cache.clear
43
47
  end
44
48
 
45
- # Return whether the given path is an absolute filesystem path or not
46
- # @param path [String] the path to examine
49
+ # Return whether the given path is an absolute filesystem path.
50
+ #
51
+ # @param path [String] the path to examine.
52
+ #
53
+ # @return [Boolean] Whether the given path is an absolute filesystem path.
47
54
  def self.absolute_path?(path)
48
55
  path =~ %r{^(/|\w:[\\/])}
49
56
  end
50
57
 
51
58
  # Return a new path by changing the suffix in path to suffix.
52
- # @param path [String] the path to alter
53
- # @param suffix [String] the new filename suffix
59
+ #
60
+ # @param path [String] The path to alter.
61
+ # @param suffix [String] The new filename suffix, e.g. ".exe".
62
+ #
63
+ # @return [String] New path.
54
64
  def self.set_suffix(path, suffix)
55
65
  path.sub(/\.[^.]*$/, suffix)
56
66
  end
67
+
68
+ # Return the system shell and arguments for executing a shell command.
69
+ #
70
+ # @return [Array<String>] The shell and flag.
71
+ def self.get_system_shell
72
+ @@shell ||=
73
+ begin
74
+ test_shell = lambda do |*args|
75
+ begin
76
+ "success" == IO.popen([*args, "echo success"]) do |io|
77
+ io.read.strip
78
+ end
79
+ rescue
80
+ false
81
+ end
82
+ end
83
+ if ENV["SHELL"] and ENV["SHELL"] != "" and test_shell[ENV["SHELL"], "-c"]
84
+ [ENV["SHELL"], "-c"]
85
+ elsif Object.const_get("RUBY_PLATFORM") =~ /mingw/
86
+ if test_shell["sh", "-c"]
87
+ # Using Rscons from MSYS should use MSYS's shell.
88
+ ["sh", "-c"]
89
+ else
90
+ ["cmd", "/c"]
91
+ end
92
+ else
93
+ ["sh", "-c"]
94
+ end
95
+ end
96
+ end
97
+
98
+ # Return an Array containing a command used to execute commands.
99
+ #
100
+ # This will normally be an empty Array, but on Windows if Rscons detects
101
+ # that it is running in MSYS then ["env"] will be returned.
102
+ #
103
+ # @return [Array<String>] Command used to execute commands.
104
+ def self.command_executer
105
+ @@command_executer ||=
106
+ if Object.const_get("RUBY_PLATFORM") =~ /mingw/
107
+ if ENV.keys.find {|key| key =~ /MSYS/}
108
+ begin
109
+ if IO.popen(["env", "echo", "success"]) {|io| io.read.strip} == "success"
110
+ ["env"]
111
+ end
112
+ rescue
113
+ end
114
+ end
115
+ end || []
116
+ end
117
+
118
+ # Set the command executer array.
119
+ #
120
+ # @param val [Array<String>] Command used to execute commands.
121
+ def self.command_executer=(val)
122
+ @@command_executer = val
123
+ end
57
124
  end
125
+
126
+ # Unbuffer $stdout
127
+ $stdout.sync = true
@@ -0,0 +1,36 @@
1
+ module Rscons
2
+ # The BuildTarget class represents a single build target.
3
+ class BuildTarget
4
+ # Create a BuildTarget object.
5
+ #
6
+ # @param options [Hash] Options to create the BuildTarget with.
7
+ # @option options [Environment] :env
8
+ # The Environment.
9
+ # @option options [String] :target
10
+ # The user-supplied target name.
11
+ # @option options [Array<String>] :sources
12
+ # The user-supplied source file name(s).
13
+ def initialize(options)
14
+ @env = options[:env]
15
+ @target = options[:target]
16
+ end
17
+
18
+ # Manually record a given target as depending on the specified files.
19
+ #
20
+ # @param user_deps [Array<String>] Dependency files.
21
+ #
22
+ # @return [void]
23
+ def depends(*user_deps)
24
+ @env.depends(@target, *user_deps)
25
+ end
26
+
27
+ # Convert the BuildTarget to a String.
28
+ #
29
+ # This method always returns the target file name.
30
+ #
31
+ # @return [String] Target file name.
32
+ def to_s
33
+ @target
34
+ end
35
+ end
36
+ end
@@ -7,30 +7,68 @@ module Rscons
7
7
  # Class to hold an object that knows how to build a certain type of file.
8
8
  class Builder
9
9
  # Return the name of the builder.
10
+ #
10
11
  # If not overridden this defaults to the last component of the class name.
11
12
  def name
12
13
  self.class.name.split(":").last
13
14
  end
14
15
 
15
- # Return a set of default variable values for the Environment to use
16
- # unless the user overrides any.
16
+ # Return a set of default construction variables for the builder.
17
+ #
17
18
  # @param env [Environment] The Environment.
19
+ #
20
+ # @return [Hash] Default construction variables.
18
21
  def default_variables(env)
19
22
  {}
20
23
  end
21
24
 
25
+ # Create a BuildTarget object for this build target.
26
+ #
27
+ # Builder sub-classes can override this method to manipulate parameters
28
+ # (for example, add a suffix to the user-given target file name).
29
+ #
30
+ # @param options [Hash] Options to create the BuildTarget with.
31
+ # @option options [Environment] :env
32
+ # The Environment.
33
+ # @option options [String] :target
34
+ # The user-supplied target name.
35
+ # @option options [Array<String>] :sources
36
+ # The user-supplied source file name(s).
37
+ #
38
+ # @return [BuildTarget]
39
+ def create_build_target(options)
40
+ BuildTarget.new(options)
41
+ end
42
+
22
43
  # Return whether this builder object is capable of producing a given target
23
44
  # file name from a given source file name.
45
+ #
24
46
  # @param target [String] The target file name.
25
47
  # @param source [String, Array] The source file name(s).
26
48
  # @param env [Environment] The Environment.
49
+ #
50
+ # @return [Boolean]
51
+ # Whether this builder object is capable of producing a given target
52
+ # file name from a given source file name.
27
53
  def produces?(target, source, env)
28
54
  false
29
55
  end
30
56
 
31
57
  # Check if the cache is up to date for the target and if not execute the
32
58
  # build command.
33
- # Return the name of the target or false on failure.
59
+ #
60
+ # @param short_cmd_string [String]
61
+ # Short description of build action to be printed when env.echo ==
62
+ # :short.
63
+ # @param target [String] Name of the target file.
64
+ # @param command [Array<String>]
65
+ # The command to execute to build the target.
66
+ # @param sources [Array<String>] Source file name(s).
67
+ # @param env [Environment] The Environment executing the builder.
68
+ # @param cache [Cache] The Cache object.
69
+ #
70
+ # @return [String,false]
71
+ # The name of the target on success or false on failure.
34
72
  def standard_build(short_cmd_string, target, command, sources, env, cache)
35
73
  unless cache.up_to_date?(target, command, sources, env)
36
74
  cache.mkdir_p(File.dirname(target))
@@ -7,6 +7,11 @@ module Rscons
7
7
  # env.CFile("parser.tab.cc", "parser.yy")
8
8
  # env.CFile("lex.yy.cc", "parser.ll")
9
9
  class CFile < Builder
10
+ # Return default construction variables for the builder.
11
+ #
12
+ # @param env [Environment] The Environment using the builder.
13
+ #
14
+ # @return [Hash] Default construction variables for the builder.
10
15
  def default_variables(env)
11
16
  {
12
17
  "YACC" => "bison",
@@ -18,6 +23,16 @@ module Rscons
18
23
  }
19
24
  end
20
25
 
26
+ # Run the builder to produce a build target.
27
+ #
28
+ # @param target [String] Target file name.
29
+ # @param sources [Array<String>] Source file name(s).
30
+ # @param cache [Cache] The Cache object.
31
+ # @param env [Environment] The Environment executing the builder.
32
+ # @param vars [Hash,VarSet] Extra construction variables.
33
+ #
34
+ # @return [String,false]
35
+ # Name of the target file on success or false on failure.
21
36
  def run(target, sources, cache, env, vars)
22
37
  vars = vars.merge({
23
38
  "_TARGET" => target,
@@ -2,6 +2,11 @@ module Rscons
2
2
  module Builders
3
3
  # The Disassemble builder produces a disassembly listing of a source file.
4
4
  class Disassemble < Builder
5
+ # Return default construction variables for the builder.
6
+ #
7
+ # @param env [Environment] The Environment using the builder.
8
+ #
9
+ # @return [Hash] Default construction variables for the builder.
5
10
  def default_variables(env)
6
11
  {
7
12
  "OBJDUMP" => "objdump",
@@ -10,6 +15,16 @@ module Rscons
10
15
  }
11
16
  end
12
17
 
18
+ # Run the builder to produce a build target.
19
+ #
20
+ # @param target [String] Target file name.
21
+ # @param sources [Array<String>] Source file name(s).
22
+ # @param cache [Cache] The Cache object.
23
+ # @param env [Environment] The Environment executing the builder.
24
+ # @param vars [Hash,VarSet] Extra construction variables.
25
+ #
26
+ # @return [String,false]
27
+ # Name of the target file on success or false on failure.
13
28
  def run(target, sources, cache, env, vars)
14
29
  vars = vars.merge("_SOURCES" => sources)
15
30
  command = env.build_command("${DISASM_CMD}", vars)
@@ -2,15 +2,30 @@ module Rscons
2
2
  module Builders
3
3
  # A default Rscons builder that produces a static library archive.
4
4
  class Library < Builder
5
+ # Return default construction variables for the builder.
6
+ #
7
+ # @param env [Environment] The Environment using the builder.
8
+ #
9
+ # @return [Hash] Default construction variables for the builder.
5
10
  def default_variables(env)
6
11
  {
7
12
  'AR' => 'ar',
8
13
  'LIBSUFFIX' => '.a',
9
- 'ARFLAGS' => [],
10
- 'ARCMD' => ['${AR}', 'rcs', '${ARFLAGS}', '${_TARGET}', '${_SOURCES}']
14
+ 'ARFLAGS' => ['rcs'],
15
+ 'ARCMD' => ['${AR}', '${ARFLAGS}', '${_TARGET}', '${_SOURCES}']
11
16
  }
12
17
  end
13
18
 
19
+ # Run the builder to produce a build target.
20
+ #
21
+ # @param target [String] Target file name.
22
+ # @param sources [Array<String>] Source file name(s).
23
+ # @param cache [Cache] The Cache object.
24
+ # @param env [Environment] The Environment executing the builder.
25
+ # @param vars [Hash,VarSet] Extra construction variables.
26
+ #
27
+ # @return [String,false]
28
+ # Name of the target file on success or false on failure.
14
29
  def run(target, sources, cache, env, vars)
15
30
  # build sources to linkable objects
16
31
  objects = env.build_sources(sources, env.expand_varref(["${OBJSUFFIX}", "${LIBSUFFIX}"], vars).flatten, cache, vars)
@@ -3,6 +3,7 @@ module Rscons
3
3
  # A default Rscons builder which knows how to produce an object file from
4
4
  # various types of source files.
5
5
  class Object < Builder
6
+ # Mapping of known sources from which to build object files.
6
7
  KNOWN_SUFFIXES = {
7
8
  "AS" => "ASSUFFIX",
8
9
  "CC" => "CSUFFIX",
@@ -10,47 +11,78 @@ module Rscons
10
11
  "DC" => "DSUFFIX",
11
12
  }
12
13
 
14
+ # Return default construction variables for the builder.
15
+ #
16
+ # @param env [Environment] The Environment using the builder.
17
+ #
18
+ # @return [Hash] Default construction variables for the builder.
13
19
  def default_variables(env)
14
20
  {
15
21
  'OBJSUFFIX' => '.o',
16
22
 
23
+ 'CPPDEFPREFIX' => '-D',
24
+ 'INCPREFIX' => '-I',
25
+
17
26
  'AS' => '${CC}',
18
27
  'ASFLAGS' => [],
19
28
  'ASSUFFIX' => '.S',
20
29
  'ASPPPATH' => '${CPPPATH}',
21
30
  'ASPPFLAGS' => '${CPPFLAGS}',
22
31
  'ASDEPGEN' => ['-MMD', '-MF', '${_DEPFILE}'],
23
- 'ASCMD' => ['${AS}', '-c', '-o', '${_TARGET}', '${ASDEPGEN}', '-I${ASPPPATH}', '${ASPPFLAGS}', '${ASFLAGS}', '${_SOURCES}'],
32
+ 'ASCMD' => ['${AS}', '-c', '-o', '${_TARGET}', '${ASDEPGEN}', '${INCPREFIX}${ASPPPATH}', '${ASPPFLAGS}', '${ASFLAGS}', '${_SOURCES}'],
24
33
 
25
- 'CPPFLAGS' => [],
34
+ 'CPPFLAGS' => ['${CPPDEFPREFIX}${CPPDEFINES}'],
35
+ 'CPPDEFINES' => [],
26
36
  'CPPPATH' => [],
27
37
 
38
+ 'CCFLAGS' => [],
39
+
28
40
  'CC' => 'gcc',
29
41
  'CFLAGS' => [],
30
42
  'CSUFFIX' => '.c',
31
43
  'CCDEPGEN' => ['-MMD', '-MF', '${_DEPFILE}'],
32
- 'CCCMD' => ['${CC}', '-c', '-o', '${_TARGET}', '${CCDEPGEN}', '-I${CPPPATH}', '${CPPFLAGS}', '${CFLAGS}', '${_SOURCES}'],
44
+ 'CCCMD' => ['${CC}', '-c', '-o', '${_TARGET}', '${CCDEPGEN}', '${INCPREFIX}${CPPPATH}', '${CPPFLAGS}', '${CFLAGS}', '${CCFLAGS}', '${_SOURCES}'],
33
45
 
34
46
  'CXX' => 'g++',
35
47
  'CXXFLAGS' => [],
36
48
  'CXXSUFFIX' => '.cc',
37
49
  'CXXDEPGEN' => ['-MMD', '-MF', '${_DEPFILE}'],
38
- 'CXXCMD' =>['${CXX}', '-c', '-o', '${_TARGET}', '${CXXDEPGEN}', '-I${CPPPATH}', '${CPPFLAGS}', '${CXXFLAGS}', '${_SOURCES}'],
50
+ 'CXXCMD' =>['${CXX}', '-c', '-o', '${_TARGET}', '${CXXDEPGEN}', '${INCPREFIX}${CPPPATH}', '${CPPFLAGS}', '${CXXFLAGS}', '${CCFLAGS}', '${_SOURCES}'],
39
51
 
40
52
  'DC' => 'gdc',
41
53
  'DFLAGS' => [],
42
54
  'DSUFFIX' => '.d',
43
55
  'D_IMPORT_PATH' => [],
44
- 'DCCMD' => ['${DC}', '-c', '-o', '${_TARGET}', '-I${D_IMPORT_PATH}', '${DFLAGS}', '${_SOURCES}'],
56
+ 'DCCMD' => ['${DC}', '-c', '-o', '${_TARGET}', '${INCPREFIX}${D_IMPORT_PATH}', '${DFLAGS}', '${_SOURCES}'],
45
57
  }
46
58
  end
47
59
 
60
+ # Return whether this builder object is capable of producing a given target
61
+ # file name from a given source file name.
62
+ #
63
+ # @param target [String] The target file name.
64
+ # @param source [String, Array] The source file name(s).
65
+ # @param env [Environment] The Environment.
66
+ #
67
+ # @return [Boolean]
68
+ # Whether this builder object is capable of producing a given target
69
+ # file name from a given source file name.
48
70
  def produces?(target, source, env)
49
71
  target.end_with?(*env['OBJSUFFIX']) and KNOWN_SUFFIXES.find do |compiler, suffix_var|
50
72
  source.end_with?(*env[suffix_var])
51
73
  end
52
74
  end
53
75
 
76
+ # Run the builder to produce a build target.
77
+ #
78
+ # @param target [String] Target file name.
79
+ # @param sources [Array<String>] Source file name(s).
80
+ # @param cache [Cache] The Cache object.
81
+ # @param env [Environment] The Environment executing the builder.
82
+ # @param vars [Hash,VarSet] Extra construction variables.
83
+ #
84
+ # @return [String,false]
85
+ # Name of the target file on success or false on failure.
54
86
  def run(target, sources, cache, env, vars)
55
87
  vars = vars.merge({
56
88
  '_TARGET' => target,
@@ -2,12 +2,27 @@ module Rscons
2
2
  module Builders
3
3
  # The Preprocess builder invokes the C preprocessor
4
4
  class Preprocess < Builder
5
+ # Return default construction variables for the builder.
6
+ #
7
+ # @param env [Environment] The Environment using the builder.
8
+ #
9
+ # @return [Hash] Default construction variables for the builder.
5
10
  def default_variables(env)
6
11
  {
7
12
  "CPP_CMD" => ["${_PREPROCESS_CC}", "-E", "-o", "${_TARGET}", "-I${CPPPATH}", "${CPPFLAGS}", "${CFLAGS}", "${_SOURCES}"],
8
13
  }
9
14
  end
10
15
 
16
+ # Run the builder to produce a build target.
17
+ #
18
+ # @param target [String] Target file name.
19
+ # @param sources [Array<String>] Source file name(s).
20
+ # @param cache [Cache] The Cache object.
21
+ # @param env [Environment] The Environment executing the builder.
22
+ # @param vars [Hash,VarSet] Extra construction variables.
23
+ #
24
+ # @return [String,false]
25
+ # Name of the target file on success or false on failure.
11
26
  def run(target, sources, cache, env, vars)
12
27
  pp_cc = if sources.find {|s| s.end_with?(*env.expand_varref("${CXXSUFFIX}", vars))}
13
28
  "${CXX}"
@@ -3,18 +3,58 @@ module Rscons
3
3
  # A default Rscons builder that knows how to link object files into an
4
4
  # executable program.
5
5
  class Program < Builder
6
+ # Return default construction variables for the builder.
7
+ #
8
+ # @param env [Environment] The Environment using the builder.
9
+ #
10
+ # @return [Hash] Default construction variables for the builder.
6
11
  def default_variables(env)
7
12
  {
8
- 'LD' => nil,
9
13
  'OBJSUFFIX' => '.o',
14
+ 'PROGSUFFIX' => (Object.const_get("RUBY_PLATFORM") =~ /mingw|cygwin/ ? ".exe" : ""),
15
+ 'LD' => nil,
10
16
  'LIBSUFFIX' => '.a',
11
17
  'LDFLAGS' => [],
12
18
  'LIBPATH' => [],
19
+ 'LIBDIRPREFIX' => '-L',
20
+ 'LIBLINKPREFIX' => '-l',
13
21
  'LIBS' => [],
14
- 'LDCMD' => ['${LD}', '-o', '${_TARGET}', '${LDFLAGS}', '${_SOURCES}', '-L${LIBPATH}', '-l${LIBS}']
22
+ 'LDCMD' => ['${LD}', '-o', '${_TARGET}', '${LDFLAGS}', '${_SOURCES}', '${LIBDIRPREFIX}${LIBPATH}', '${LIBLINKPREFIX}${LIBS}']
15
23
  }
16
24
  end
17
25
 
26
+ # Create a BuildTarget object for this build target.
27
+ #
28
+ # The build target filename is given a ".exe" suffix if Rscons is
29
+ # executing on a Windows platform and no other suffix is given.
30
+ #
31
+ # @param options [Hash] Options to create the BuildTarget with.
32
+ # @option options [Environment] :env
33
+ # The Environment.
34
+ # @option options [String] :target
35
+ # The user-supplied target name.
36
+ # @option options [Array<String>] :sources
37
+ # The user-supplied source file name(s).
38
+ #
39
+ # @return [BuildTarget]
40
+ def create_build_target(options)
41
+ my_options = options.dup
42
+ unless my_options[:target] =~ /\./
43
+ my_options[:target] += options[:env].expand_varref("${PROGSUFFIX}")
44
+ end
45
+ super(my_options)
46
+ end
47
+
48
+ # Run the builder to produce a build target.
49
+ #
50
+ # @param target [String] Target file name.
51
+ # @param sources [Array<String>] Source file name(s).
52
+ # @param cache [Cache] The Cache object.
53
+ # @param env [Environment] The Environment executing the builder.
54
+ # @param vars [Hash,VarSet] Extra construction variables.
55
+ #
56
+ # @return [String,false]
57
+ # Name of the target file on success or false on failure.
18
58
  def run(target, sources, cache, env, vars)
19
59
  # build sources to linkable objects
20
60
  objects = env.build_sources(sources, env.expand_varref(["${OBJSUFFIX}", "${LIBSUFFIX}"], vars).flatten, cache, vars)