rscons 1.4.3 → 1.5.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.
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)