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
```ruby
RScons::Environment.new do |env|
Rscons::Environment.new do |env|
env["CFLAGS"] << "-Wall"
env.Program("program", Dir["**/*.c"])
end
@@ -36,7 +36,7 @@ end
### Example: Building a D Program
```ruby
RScons::Environment.new do |env|
Rscons::Environment.new do |env|
env["DFLAGS"] << "-Wall"
env.Program("program", Dir["**/*.d"])
end
@@ -45,7 +45,7 @@ end
### Example: Cloning an Environment
```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"
env.build_dir("src", "build/main")
env["CFLAGS"] = ["-DSOME_DEFINE", "-O3"]
@@ -64,6 +64,11 @@ end
### 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
class GenerateFoo < Rscons::Builder
def run(target, sources, cache, env, vars)
@@ -73,10 +78,12 @@ class GenerateFoo < Rscons::Builder
#define GENERATED 42
EOF
end
target
end
end
Rscons::Environment.new do |env|
env.add_builder(GenerateFoo.new)
env.GenerateFoo("foo.h", [])
env.Program("a.out", Dir["*.c"])
end
@@ -93,16 +100,23 @@ class CmdBuilder < Rscons::Builder
system(cmd)
cache.register_build(target, cmd, sources, env)
end
target
end
end
Rscons::Environment.new do |env|
env.add_builder(CmdBuilder.new)
env.CmdBuilder("foo.gen", "foo_gen.cfg")
end
```
### 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
class CmdBuilder < Rscons::Builder
def run(target, sources, cache, env, vars)
@@ -112,6 +126,7 @@ class CmdBuilder < Rscons::Builder
end
Rscons::Environment.new do |env|
env.add_builder(CmdBuilder.new)
env.CmdBuilder("foo.gen", "foo_gen.cfg")
end
```
@@ -131,6 +146,19 @@ Rscons::Environment.new do |env|
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
```ruby
@@ -149,8 +177,8 @@ Rscons ships with a number of default builders:
* Object, which compiles source files to produce an object file
* Program, which links object files to produce an executable
If you want to create an Environment that does not contain any (or select)
builders, you can use the `exclude_builders` key to the Environment constructor.
If you want to create an Environment that does not contain any builders,
you can use the `exclude_builders` key to the Environment constructor.
### Managing Environments
@@ -158,7 +186,8 @@ An Rscons::Environment consists of:
* a collection of construction variables
* 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 build hooks
@@ -178,12 +207,16 @@ cloned_env["CPPPATH"] << "three"
`base_env["CPPPATH"]` will not include "three".
### Construction Variables
### Construction Variable Naming
The default construction variables that Rscons uses are named using uppercase
strings.
Rscons options are lowercase symbols.
Lowercase strings are reserved as user-defined construction variables.
* uppercase strings - the default construction variables that Rscons uses
* lowercase symbols - Rscons options
* lowercase strings - 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
+21 -10
View File
@@ -1,15 +1,13 @@
require "rscons/builder"
require "rscons/cache"
require "rscons/environment"
require "rscons/varset"
require "rscons/version"
require "rscons/monkey/string"
require_relative "rscons/builder"
require_relative "rscons/cache"
require_relative "rscons/environment"
require_relative "rscons/varset"
require_relative "rscons/version"
# default builders
require "rscons/builders/library"
require "rscons/builders/object"
require "rscons/builders/program"
require_relative "rscons/builders/library"
require_relative "rscons/builders/object"
require_relative "rscons/builders/program"
# Namespace module for rscons classes
module Rscons
@@ -37,4 +35,17 @@ module Rscons
end
Cache.clear
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
+4 -4
View File
@@ -46,8 +46,8 @@ module Rscons
end
def produces?(target, source, env)
target.has_suffix?(env['OBJSUFFIX']) and KNOWN_SUFFIXES.find do |compiler, suffix_var|
source.has_suffix?(env[suffix_var])
target.end_with?(*env['OBJSUFFIX']) and KNOWN_SUFFIXES.find do |compiler, suffix_var|
source.end_with?(*env[suffix_var])
end
end
@@ -55,10 +55,10 @@ module Rscons
vars = vars.merge({
'_TARGET' => target,
'_SOURCES' => sources,
'_DEPFILE' => target.set_suffix('.mf'),
'_DEPFILE' => Rscons.set_suffix(target, '.mf'),
})
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|
v.nil? and raise "Error: unknown input file type: #{sources.first.inspect}"
end.first
+2 -2
View File
@@ -21,9 +21,9 @@ module Rscons
return false unless objects
ld = if env["LD"]
env["LD"]
elsif sources.find {|s| s.has_suffix?(env["DSUFFIX"])}
elsif sources.find {|s| s.end_with?(*env["DSUFFIX"])}
env["DC"]
elsif sources.find {|s| s.has_suffix?(env["CXXSUFFIX"])}
elsif sources.find {|s| s.end_with?(*env["CXXSUFFIX"])}
env["CXX"]
else
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.
# This method takes into account the Environment's build directories.
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|
if src_dir.is_a?(Regexp)
build_fname.sub!(src_dir, obj_dir)
@@ -111,7 +111,7 @@ module Rscons
end
end
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}"
end
end
@@ -254,7 +254,7 @@ module Rscons
# Return a list of the converted file names.
def build_sources(sources, suffixes, cache, vars)
sources.map do |source|
if source.has_suffix?(suffixes)
if source.end_with?(*suffixes)
source
else
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
# gem version
VERSION = "0.3.1"
VERSION = "1.0.0"
end