Compare commits

..
8 Commits
7 changed files with 75 additions and 56 deletions

No files matched your search

+44 -11
View File
@@ -27,7 +27,7 @@ called from your Rakefile.
### Example: Building a C Program ### Example: Building a C Program
```ruby ```ruby
RScons::Environment.new do |env| Rscons::Environment.new do |env|
env["CFLAGS"] << "-Wall" env["CFLAGS"] << "-Wall"
env.Program("program", Dir["**/*.c"]) env.Program("program", Dir["**/*.c"])
end end
@@ -36,7 +36,7 @@ end
### Example: Building a D Program ### Example: Building a D Program
```ruby ```ruby
RScons::Environment.new do |env| Rscons::Environment.new do |env|
env["DFLAGS"] << "-Wall" env["DFLAGS"] << "-Wall"
env.Program("program", Dir["**/*.d"]) env.Program("program", Dir["**/*.d"])
end end
@@ -45,7 +45,7 @@ end
### Example: Cloning an Environment ### Example: Cloning an Environment
```ruby ```ruby
main_env = RScons::Environment.new do |env| main_env = Rscons::Environment.new do |env|
# Store object files from sources under "src" in "build/main" # Store object files from sources under "src" in "build/main"
env.build_dir("src", "build/main") env.build_dir("src", "build/main")
env["CFLAGS"] = ["-DSOME_DEFINE", "-O3"] env["CFLAGS"] = ["-DSOME_DEFINE", "-O3"]
@@ -64,6 +64,11 @@ end
### Example: Custom Builder ### Example: Custom Builder
Custom builders are implemented as classes which extend from `Rscons::Builder`.
The builder must have a `run` method which is called to invoke the builder.
The `run` method should return the name of the target built on success, and
`false` on failure.
```ruby ```ruby
class GenerateFoo < Rscons::Builder class GenerateFoo < Rscons::Builder
def run(target, sources, cache, env, vars) def run(target, sources, cache, env, vars)
@@ -73,10 +78,12 @@ class GenerateFoo < Rscons::Builder
#define GENERATED 42 #define GENERATED 42
EOF EOF
end end
target
end end
end end
Rscons::Environment.new do |env| Rscons::Environment.new do |env|
env.add_builder(GenerateFoo.new)
env.GenerateFoo("foo.h", []) env.GenerateFoo("foo.h", [])
env.Program("a.out", Dir["*.c"]) env.Program("a.out", Dir["*.c"])
end end
@@ -93,16 +100,23 @@ class CmdBuilder < Rscons::Builder
system(cmd) system(cmd)
cache.register_build(target, cmd, sources, env) cache.register_build(target, cmd, sources, env)
end end
target
end end
end end
Rscons::Environment.new do |env| Rscons::Environment.new do |env|
env.add_builder(CmdBuilder.new)
env.CmdBuilder("foo.gen", "foo_gen.cfg") env.CmdBuilder("foo.gen", "foo_gen.cfg")
end end
``` ```
### Example: Custom Builder Using Builder#standard_build() ### Example: Custom Builder Using Builder#standard_build()
The `standard_build` method from the `Rscons::Builder` base class can be used
when the builder needs to execute a system command to produce the target file.
The `standard_build` method will return the correct value so its return value
can be used as the return value from the `run` method.
```ruby ```ruby
class CmdBuilder < Rscons::Builder class CmdBuilder < Rscons::Builder
def run(target, sources, cache, env, vars) def run(target, sources, cache, env, vars)
@@ -112,6 +126,7 @@ class CmdBuilder < Rscons::Builder
end end
Rscons::Environment.new do |env| Rscons::Environment.new do |env|
env.add_builder(CmdBuilder.new)
env.CmdBuilder("foo.gen", "foo_gen.cfg") env.CmdBuilder("foo.gen", "foo_gen.cfg")
end end
``` ```
@@ -131,6 +146,19 @@ Rscons::Environment.new do |env|
end end
``` ```
Each build hook block will be invoked for every build operation, so the block
should test the target or sources if its action should only apply to some
subset of build targets or source files.
The `build_op` parameter to the build hook block is a Hash describing the
build operation with the following keys:
* `:builder` - `Builder` instance in use
* `:target` - `String` name of the target file
* `:sources` - `Array` of the source files
* `:vars` - `Rscons::VarSet` containing the construction variables to use
The build hook can overwrite entries in `build_op[:vars]` to alter the
construction variables in use for this specific build operation.
### Example: Creating a static library ### Example: Creating a static library
```ruby ```ruby
@@ -149,8 +177,8 @@ Rscons ships with a number of default builders:
* Object, which compiles source files to produce an object file * Object, which compiles source files to produce an object file
* Program, which links object files to produce an executable * Program, which links object files to produce an executable
If you want to create an Environment that does not contain any (or select) If you want to create an Environment that does not contain any builders,
builders, you can use the `exclude_builders` key to the Environment constructor. you can use the `exclude_builders` key to the Environment constructor.
### Managing Environments ### Managing Environments
@@ -158,7 +186,8 @@ An Rscons::Environment consists of:
* a collection of construction variables * a collection of construction variables
* a collection of builders * a collection of builders
* a mapping of build directories * a mapping of build directories from source directories
* a default build root to apply if no build directories are matched
* a collection of targets to build * a collection of targets to build
* a collection of build hooks * a collection of build hooks
@@ -178,12 +207,16 @@ cloned_env["CPPPATH"] << "three"
`base_env["CPPPATH"]` will not include "three". `base_env["CPPPATH"]` will not include "three".
### Construction Variables ### Construction Variable Naming
The default construction variables that Rscons uses are named using uppercase * uppercase strings - the default construction variables that Rscons uses
strings. * lowercase symbols - Rscons options
Rscons options are lowercase symbols. * lowercase strings - reserved as user-defined construction variables
Lowercase strings are reserved as user-defined construction variables.
### API documentation
Documentation for the complete Rscons API can be found at
http://rubydoc.info/github/holtrop/rscons/frames.
## Contributing ## Contributing
+21 -10
View File
@@ -1,15 +1,13 @@
require "rscons/builder" require_relative "rscons/builder"
require "rscons/cache" require_relative "rscons/cache"
require "rscons/environment" require_relative "rscons/environment"
require "rscons/varset" require_relative "rscons/varset"
require "rscons/version" require_relative "rscons/version"
require "rscons/monkey/string"
# default builders # default builders
require "rscons/builders/library" require_relative "rscons/builders/library"
require "rscons/builders/object" require_relative "rscons/builders/object"
require "rscons/builders/program" require_relative "rscons/builders/program"
# Namespace module for rscons classes # Namespace module for rscons classes
module Rscons module Rscons
@@ -37,4 +35,17 @@ module Rscons
end end
Cache.clear Cache.clear
end end
# Return whether the given path is an absolute filesystem path or not
# @param path [String] the path to examine
def self.absolute_path?(path)
path =~ %r{^(/|\w:[\\/])}
end
# Return a new path by changing the suffix in path to suffix.
# @param path [String] the path to alter
# @param suffix [String] the new filename suffix
def self.set_suffix(path, suffix)
path.sub(/\.[^.]*$/, suffix)
end
end end
+4 -4
View File
@@ -46,8 +46,8 @@ module Rscons
end end
def produces?(target, source, env) def produces?(target, source, env)
target.has_suffix?(env['OBJSUFFIX']) and KNOWN_SUFFIXES.find do |compiler, suffix_var| target.end_with?(*env['OBJSUFFIX']) and KNOWN_SUFFIXES.find do |compiler, suffix_var|
source.has_suffix?(env[suffix_var]) source.end_with?(*env[suffix_var])
end end
end end
@@ -55,10 +55,10 @@ module Rscons
vars = vars.merge({ vars = vars.merge({
'_TARGET' => target, '_TARGET' => target,
'_SOURCES' => sources, '_SOURCES' => sources,
'_DEPFILE' => target.set_suffix('.mf'), '_DEPFILE' => Rscons.set_suffix(target, '.mf'),
}) })
com_prefix = KNOWN_SUFFIXES.find do |compiler, suffix_var| com_prefix = KNOWN_SUFFIXES.find do |compiler, suffix_var|
sources.first.has_suffix?(env[suffix_var]) sources.first.end_with?(*env[suffix_var])
end.tap do |v| end.tap do |v|
v.nil? and raise "Error: unknown input file type: #{sources.first.inspect}" v.nil? and raise "Error: unknown input file type: #{sources.first.inspect}"
end.first end.first
+2 -2
View File
@@ -21,9 +21,9 @@ module Rscons
return false unless objects return false unless objects
ld = if env["LD"] ld = if env["LD"]
env["LD"] env["LD"]
elsif sources.find {|s| s.has_suffix?(env["DSUFFIX"])} elsif sources.find {|s| s.end_with?(*env["DSUFFIX"])}
env["DC"] env["DC"]
elsif sources.find {|s| s.has_suffix?(env["CXXSUFFIX"])} elsif sources.find {|s| s.end_with?(*env["CXXSUFFIX"])}
env["CXX"] env["CXX"]
else else
env["CC"] env["CC"]
+3 -3
View File
@@ -102,7 +102,7 @@ module Rscons
# Return the file name to be built from source_fname with suffix suffix. # Return the file name to be built from source_fname with suffix suffix.
# This method takes into account the Environment's build directories. # This method takes into account the Environment's build directories.
def get_build_fname(source_fname, suffix) def get_build_fname(source_fname, suffix)
build_fname = source_fname.set_suffix(suffix).gsub('\\', '/') build_fname = Rscons.set_suffix(source_fname, suffix).gsub('\\', '/')
found_match = @build_dirs.find do |src_dir, obj_dir| found_match = @build_dirs.find do |src_dir, obj_dir|
if src_dir.is_a?(Regexp) if src_dir.is_a?(Regexp)
build_fname.sub!(src_dir, obj_dir) build_fname.sub!(src_dir, obj_dir)
@@ -111,7 +111,7 @@ module Rscons
end end
end end
if @build_root and not found_match if @build_root and not found_match
unless source_fname.absolute_path? or build_fname.start_with?("#{@build_root}/") unless Rscons.absolute_path?(source_fname) or build_fname.start_with?("#{@build_root}/")
build_fname = "#{@build_root}/#{build_fname}" build_fname = "#{@build_root}/#{build_fname}"
end end
end end
@@ -254,7 +254,7 @@ module Rscons
# Return a list of the converted file names. # Return a list of the converted file names.
def build_sources(sources, suffixes, cache, vars) def build_sources(sources, suffixes, cache, vars)
sources.map do |source| sources.map do |source|
if source.has_suffix?(suffixes) if source.end_with?(*suffixes)
source source
else else
converted = nil converted = nil
-25
View File
@@ -1,25 +0,0 @@
# Standard Ruby String class.
class String
# Check if the given string ends with any of the supplied suffixes
# @param suffix [String, Array] The suffix to look for.
# @return a true value if the string ends with one of the suffixes given.
def has_suffix?(suffix)
if suffix
suffix = [suffix] if suffix.is_a?(String)
suffix = suffix.flatten
suffix.find {|s| self.end_with?(s)}
end
end
# Return a new string with the suffix (dot character and extension) changed
# to the given suffix.
# @param suffix [String] The new suffix.
def set_suffix(suffix = '')
sub(/\.[^.]*$/, suffix)
end
# Return whether the string represents an absolute filesystem path
def absolute_path?
self =~ %r{^(/|\w:[\\/])}
end
end
+1 -1
View File
@@ -1,4 +1,4 @@
module Rscons module Rscons
# gem version # gem version
VERSION = "0.3.1" VERSION = "1.0.0"
end end