rake-builder 0.0.18 → 0.0.19
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.
- data/lib/rake/builder/autoconf/version.rb +51 -0
- data/lib/rake/builder/configure_ac.rb +51 -0
- data/lib/rake/builder/error.rb +17 -0
- data/lib/rake/builder/logger/formatter.rb +8 -0
- data/lib/rake/builder/presenters/makefile/builder_presenter.rb +75 -0
- data/lib/rake/builder/presenters/makefile_am/builder_collection_presenter.rb +6 -0
- data/lib/rake/builder/qt_builder.rb +3 -3
- data/lib/rake/builder/task_definer.rb +150 -0
- data/lib/rake/builder/version.rb +1 -1
- data/lib/rake/builder.rb +178 -436
- data/lib/rake/local_config.rb +1 -1
- data/spec/autoconf_spec.rb +1 -5
- data/spec/local_config_spec.rb +1 -1
- data/spec/target_spec.rb +2 -2
- data/spec/unit/rake/builder_spec.rb +36 -13
- metadata +9 -3
@@ -0,0 +1,51 @@
|
|
1
|
+
class Rake::Builder
|
2
|
+
class Version
|
3
|
+
def initialize(parameter_version = nil)
|
4
|
+
@parameter_version = parameter_version
|
5
|
+
end
|
6
|
+
|
7
|
+
def decide
|
8
|
+
acceptable_version_string = %r(^(\d+)\.(\d+)\.(\d+)$)
|
9
|
+
if @parameter_version && @parameter_version !~ acceptable_version_string
|
10
|
+
raise "The supplied version number '#{@parameter_version}' is badly formatted. It should consist of three numbers separated by ."
|
11
|
+
end
|
12
|
+
file_version = load_file_version
|
13
|
+
if file_version && file_version !~ acceptable_version_string
|
14
|
+
raise "Your VERSION file contains a version number '#{file_version}' which is badly formatted. It should consist of three numbers separated by ."
|
15
|
+
end
|
16
|
+
case
|
17
|
+
when @parameter_version.nil? && file_version.nil?
|
18
|
+
raise <<-EOT
|
19
|
+
This task requires a project version: major.minor.revision (e.g. 1.03.0567)
|
20
|
+
Please do one of the following:
|
21
|
+
- supply a version parameter: rake autoconf[project_name,version]
|
22
|
+
- create a VERSION file.
|
23
|
+
EOT
|
24
|
+
when file_version.nil?
|
25
|
+
save_file_version @parameter_version
|
26
|
+
return @parameter_version
|
27
|
+
when @parameter_version.nil?
|
28
|
+
return file_version
|
29
|
+
when file_version != @parameter_version
|
30
|
+
raise <<-EOT
|
31
|
+
The version parameter supplied is different to the value in the VERSION file
|
32
|
+
EOT
|
33
|
+
else
|
34
|
+
return file_version
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def load_file_version
|
41
|
+
return nil unless File.exist?('VERSION')
|
42
|
+
version = File.read('VERSION')
|
43
|
+
version.strip
|
44
|
+
end
|
45
|
+
|
46
|
+
def save_file_version(version)
|
47
|
+
File.open('VERSION', 'w') { |f| f.write "#{version}\n" }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
class Rake::Builder
|
2
|
+
class ConfigureAc
|
3
|
+
# source_file - the relative path to any one source file in the project
|
4
|
+
def initialize(project_title, version, source_file)
|
5
|
+
@project_title, @version, @source_file = project_title, version, source_file
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_s
|
9
|
+
<<EOT
|
10
|
+
AC_PREREQ(2.61)
|
11
|
+
AC_INIT(#{@project_title}, #{@version})
|
12
|
+
AC_CONFIG_SRCDIR([#{@source_file}])
|
13
|
+
AC_CONFIG_HEADER([config.h])
|
14
|
+
AM_INIT_AUTOMAKE([#{@project_title}], [#{@version}])
|
15
|
+
|
16
|
+
# Checks for programs.
|
17
|
+
AC_PROG_CXX
|
18
|
+
AC_PROG_CC
|
19
|
+
AC_PROG_RANLIB
|
20
|
+
|
21
|
+
# Checks for libraries.
|
22
|
+
|
23
|
+
# Checks for header files.
|
24
|
+
|
25
|
+
# Checks for typedefs, structures, and compiler characteristics.
|
26
|
+
AC_HEADER_STDBOOL
|
27
|
+
AC_C_CONST
|
28
|
+
AC_C_INLINE
|
29
|
+
AC_STRUCT_TM
|
30
|
+
|
31
|
+
# Checks for library functions.
|
32
|
+
AC_FUNC_LSTAT
|
33
|
+
AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK
|
34
|
+
AC_FUNC_MEMCMP
|
35
|
+
AC_HEADER_STDC
|
36
|
+
AC_CHECK_FUNCS([memset strcasecmp])
|
37
|
+
|
38
|
+
AC_CONFIG_FILES([Makefile])
|
39
|
+
|
40
|
+
AC_OUTPUT
|
41
|
+
EOT
|
42
|
+
end
|
43
|
+
|
44
|
+
def save
|
45
|
+
File.open('configure.ac', 'w') do |f|
|
46
|
+
f.write to_s
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Rake::Builder
|
2
|
+
class Error < StandardError
|
3
|
+
attr_accessor :namespace
|
4
|
+
|
5
|
+
def initialize(message, namespace = nil)
|
6
|
+
super(message)
|
7
|
+
@namespace = namespace
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
message = super
|
12
|
+
message = "#{@namespace}: #{message}" if @namespace
|
13
|
+
message
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Rake::Builder::Presenters; end
|
2
|
+
|
3
|
+
module Rake::Builder::Presenters::Makefile
|
4
|
+
class BuilderPresenter
|
5
|
+
def initialize(builder)
|
6
|
+
@builder = builder
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
objects = @builder.object_files.collect { |f| f.sub(@builder.objects_path, '$(OBJECT_DIR)') }
|
11
|
+
objects_list = objects.join( ' ' )
|
12
|
+
case @builder.target_type
|
13
|
+
when :executable
|
14
|
+
target_name = 'EXECUTABLE_TARGET'
|
15
|
+
target_ref = "$(#{target_name})"
|
16
|
+
target_actions =
|
17
|
+
" $(LINKER) $(LINK_FLAGS) -o #{target_ref} $(OBJECTS)
|
18
|
+
"
|
19
|
+
when :static_library
|
20
|
+
target_name = 'LIB_TARGET'
|
21
|
+
target_ref = "$(#{target_name})"
|
22
|
+
target_actions =
|
23
|
+
" rm -f #{target_ref}
|
24
|
+
ar -cq #{target_ref} $(OBJECTS)
|
25
|
+
ranlib #{target_ref}
|
26
|
+
"
|
27
|
+
when :shared_library
|
28
|
+
target_name = 'LIB_TARGET'
|
29
|
+
target_ref = "$(#{target_name})"
|
30
|
+
target_actions =
|
31
|
+
" $(LINKER) -shared -o #{target_ref} $(OBJECTS) $(LINK_FLAGS)
|
32
|
+
"
|
33
|
+
end
|
34
|
+
|
35
|
+
variables = <<EOT
|
36
|
+
COMPILER = #{@builder.compiler}
|
37
|
+
COMPILER_FLAGS = #{@builder.compiler_flags}
|
38
|
+
LINKER = #{@builder.linker}
|
39
|
+
LINK_FLAGS = #{@builder.link_flags}
|
40
|
+
OBJECT_DIR = #{@builder.objects_path}
|
41
|
+
OBJECTS = #{objects_list}
|
42
|
+
#{ target_name } = #{@builder.target}
|
43
|
+
EOT
|
44
|
+
rules = <<EOT
|
45
|
+
|
46
|
+
all: #{target_ref}
|
47
|
+
|
48
|
+
clean:
|
49
|
+
rm -f $(OBJECTS)
|
50
|
+
rm -f #{target_ref}
|
51
|
+
|
52
|
+
#{target_ref}: $(OBJECTS)
|
53
|
+
#{target_actions}
|
54
|
+
EOT
|
55
|
+
|
56
|
+
source_groups = group_files_by_path(@builder.source_files)
|
57
|
+
source_groups.each.with_index do | gp, i |
|
58
|
+
variables << "SOURCE_#{i + 1} = #{gp[0]}\n"
|
59
|
+
rules << <<EOT
|
60
|
+
|
61
|
+
$(OBJECT_DIR)/%.o: $(SOURCE_#{i + 1})/%.cpp
|
62
|
+
$(COMPILER) -c $(COMPILER_FLAGS) -o $@ $<
|
63
|
+
EOT
|
64
|
+
end
|
65
|
+
variables + rules
|
66
|
+
end
|
67
|
+
|
68
|
+
def save
|
69
|
+
File.open(@builder.makefile_name, 'w') do |file|
|
70
|
+
file.write to_s
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
@@ -10,6 +10,12 @@ module Rake; class Builder; module Presenters; module MakefileAm
|
|
10
10
|
programs_list + program_sections + libraries_list + library_sections
|
11
11
|
end
|
12
12
|
|
13
|
+
def save
|
14
|
+
File.open('Makefile.am', 'w') do |f|
|
15
|
+
f.write to_s
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
13
19
|
private
|
14
20
|
|
15
21
|
def programs
|
@@ -34,7 +34,7 @@ module Rake
|
|
34
34
|
@framework_paths = [ '/Library/Frameworks' ]
|
35
35
|
@moc_defines = [ '-D__APPLE__', '-D__GNUC__' ]
|
36
36
|
else
|
37
|
-
raise
|
37
|
+
raise Error.new( "Unrecognised platform" )
|
38
38
|
end
|
39
39
|
@compilation_defines = [ '-DQT_GUI_LIB', '-DQT_CORE_LIB', '-DQT_SHARED' ]
|
40
40
|
@resource_files = []
|
@@ -42,8 +42,8 @@ module Rake
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def configure
|
45
|
-
raise
|
46
|
-
raise
|
45
|
+
raise Error.new( 'programming_language must be C++' ) if @programming_language.downcase != 'c++'
|
46
|
+
raise Error.new( 'qt_version must be set' ) if ! @qt_version
|
47
47
|
|
48
48
|
super
|
49
49
|
|
@@ -0,0 +1,150 @@
|
|
1
|
+
require 'rake/file_task_alias'
|
2
|
+
require 'rake/local_config'
|
3
|
+
|
4
|
+
include Rake::DSL
|
5
|
+
|
6
|
+
class Rake::Builder
|
7
|
+
class TaskDefiner
|
8
|
+
def initialize(builder)
|
9
|
+
@builder = builder
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
if @builder.task_namespace
|
14
|
+
namespace @builder.task_namespace do
|
15
|
+
define
|
16
|
+
end
|
17
|
+
else
|
18
|
+
define
|
19
|
+
end
|
20
|
+
define_default
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def define
|
26
|
+
once_task :environment do
|
27
|
+
@builder.logger.level = Logger::DEBUG if ENV['DEBUG']
|
28
|
+
end
|
29
|
+
|
30
|
+
if @builder.target_type == :executable
|
31
|
+
desc "Run '#{@builder.target_basename}'"
|
32
|
+
task :run => :build do
|
33
|
+
@builder.run
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
desc "Compile and build '#{@builder.target_basename}'"
|
38
|
+
Rake::FileTaskAlias.define_task(:build, @builder.target)
|
39
|
+
|
40
|
+
desc "Build '#{@builder.target_basename}'"
|
41
|
+
microsecond_file @builder.target => [
|
42
|
+
scoped_task(:environment),
|
43
|
+
scoped_task(:compile),
|
44
|
+
*@builder.target_prerequisites
|
45
|
+
] do
|
46
|
+
@builder.build
|
47
|
+
end
|
48
|
+
|
49
|
+
desc "Compile all sources"
|
50
|
+
# Only import dependencies when we're compiling
|
51
|
+
# otherwise makedepend gets run on e.g. 'rake -T'
|
52
|
+
once_task :compile => [
|
53
|
+
scoped_task(:environment),
|
54
|
+
@builder.makedepend_file,
|
55
|
+
scoped_task(:load_makedepend),
|
56
|
+
*@builder.object_files
|
57
|
+
]
|
58
|
+
|
59
|
+
@builder.source_files.each do |src|
|
60
|
+
define_compile_task(src)
|
61
|
+
end
|
62
|
+
|
63
|
+
# TODO: Does this need to be microsecond?
|
64
|
+
microsecond_directory @builder.objects_path
|
65
|
+
|
66
|
+
file scoped_task(@builder.local_config) do
|
67
|
+
@builder.create_local_config
|
68
|
+
end
|
69
|
+
|
70
|
+
microsecond_file @builder.makedepend_file => [
|
71
|
+
scoped_task(:load_local_config),
|
72
|
+
scoped_task(:missing_headers),
|
73
|
+
@builder.objects_path,
|
74
|
+
*@builder.project_files
|
75
|
+
] do
|
76
|
+
@builder.create_makedepend_file
|
77
|
+
end
|
78
|
+
|
79
|
+
once_task scoped_task(:load_local_config) => scoped_task(@builder.local_config) do
|
80
|
+
@builder.load_local_config
|
81
|
+
end
|
82
|
+
|
83
|
+
once_task scoped_task(:missing_headers) => [*@builder.generated_headers] do
|
84
|
+
@builder.missing_headers
|
85
|
+
end
|
86
|
+
|
87
|
+
# Reimplemented mkdepend file loading to make objects depend on
|
88
|
+
# sources with the correct paths:
|
89
|
+
# the standard rake mkdepend loader doesn't do what we want,
|
90
|
+
# as it assumes files will be compiled in their own directory.
|
91
|
+
task :load_makedepend => @builder.makedepend_file do
|
92
|
+
@builder.load_makedepend
|
93
|
+
end
|
94
|
+
|
95
|
+
desc "List generated files (which are removed with 'rake #{scoped_task(:clean)}')"
|
96
|
+
task :generated_files do
|
97
|
+
puts @builder.generated_files.to_json
|
98
|
+
end
|
99
|
+
|
100
|
+
# Re-implement :clean locally for project and within namespace
|
101
|
+
# Standard :clean is a singleton
|
102
|
+
desc "Remove temporary files"
|
103
|
+
task :clean do
|
104
|
+
@builder.clean
|
105
|
+
end
|
106
|
+
|
107
|
+
desc "Install '#{@builder.target_basename}' in '#{@builder.install_path}'"
|
108
|
+
task :install, [] => [scoped_task(:build)] do
|
109
|
+
@builder.install
|
110
|
+
end
|
111
|
+
|
112
|
+
desc "Uninstall '#{@builder.target_basename}' from '#{@builder.install_path}'"
|
113
|
+
task :uninstall, [] => [] do
|
114
|
+
@builder.uninstall
|
115
|
+
end
|
116
|
+
|
117
|
+
desc "Create a '#{@builder.makefile_name}' to build the project"
|
118
|
+
file "#{@builder.makefile_name}" => [@builder.makedepend_file, scoped_task(:load_makedepend)] do
|
119
|
+
Rake::Builder::Presenters::Makefile::BuilderPresenter.new(@builder).save
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def define_default
|
124
|
+
name = scoped_task(@builder.default_task)
|
125
|
+
desc "Equivalent to 'rake #{name}'"
|
126
|
+
if @builder.task_namespace
|
127
|
+
task @builder.task_namespace => [name]
|
128
|
+
else
|
129
|
+
task :default => [name]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def define_compile_task(source)
|
134
|
+
object = @builder.object_path(source)
|
135
|
+
@builder.generated_files << object
|
136
|
+
file object => [ source ] do |t|
|
137
|
+
@builder.compile(source, object)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def scoped_task(task)
|
142
|
+
if @builder.task_namespace
|
143
|
+
"#{@builder.task_namespace}:#{task}"
|
144
|
+
else
|
145
|
+
task
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
data/lib/rake/builder/version.rb
CHANGED
data/lib/rake/builder.rb
CHANGED
@@ -3,11 +3,15 @@ require 'logger'
|
|
3
3
|
require 'rake'
|
4
4
|
require 'rake/tasklib'
|
5
5
|
|
6
|
+
require 'rake/builder/autoconf/version'
|
7
|
+
require 'rake/builder/configure_ac'
|
8
|
+
require 'rake/builder/error'
|
9
|
+
require 'rake/builder/logger/formatter'
|
10
|
+
require 'rake/builder/presenters/makefile/builder_presenter'
|
6
11
|
require 'rake/builder/presenters/makefile_am/builder_presenter'
|
7
12
|
require 'rake/builder/presenters/makefile_am/builder_collection_presenter'
|
13
|
+
require 'rake/builder/task_definer'
|
8
14
|
require 'rake/path'
|
9
|
-
require 'rake/local_config'
|
10
|
-
require 'rake/file_task_alias'
|
11
15
|
require 'rake/microsecond'
|
12
16
|
require 'rake/once_task'
|
13
17
|
require 'compiler'
|
@@ -15,33 +19,9 @@ require 'compiler'
|
|
15
19
|
include Rake::DSL
|
16
20
|
|
17
21
|
module Rake
|
18
|
-
|
19
|
-
class Formatter < Logger::Formatter
|
20
|
-
def call(severity, time, progname, msg)
|
21
|
-
msg2str(msg) << "\n"
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
class Builder < TaskLib
|
26
|
-
|
27
|
-
class BuilderError < StandardError
|
28
|
-
attr_accessor :namespace
|
29
|
-
|
30
|
-
def initialize( message, namespace = nil )
|
31
|
-
super( message )
|
32
|
-
@namespace = namespace
|
33
|
-
end
|
34
|
-
|
35
|
-
def to_s
|
36
|
-
message = super
|
37
|
-
message = "#{ @namespace }: #{ message }" if @namespace
|
38
|
-
message
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
22
|
+
class Builder
|
42
23
|
# Error indicating that the project failed to build.
|
43
|
-
class BuildFailure <
|
44
|
-
end
|
24
|
+
class BuildFailure < Error; end
|
45
25
|
|
46
26
|
# The file to be built
|
47
27
|
attr_accessor :target
|
@@ -57,6 +37,8 @@ module Rake
|
|
57
37
|
# processor type: 'i386', 'x86_64', 'ppc' or 'ppc64'.
|
58
38
|
attr_accessor :architecture
|
59
39
|
|
40
|
+
attr_accessor :compiler_data
|
41
|
+
|
60
42
|
# The programming language: 'c++', 'c' or 'objective-c' (default 'c++')
|
61
43
|
# This also sets defaults for source_file_extension
|
62
44
|
attr_accessor :programming_language
|
@@ -182,122 +164,125 @@ module Rake
|
|
182
164
|
@instances
|
183
165
|
end
|
184
166
|
|
185
|
-
def self.
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
if File.exist?('configure.ac')
|
191
|
-
raise "The file 'configure.ac' already exists"
|
192
|
-
end
|
193
|
-
if File.exist?('Makefile.am')
|
194
|
-
raise "The file 'Makefile.am' already exists"
|
195
|
-
end
|
196
|
-
create_configure_ac project_title, version
|
197
|
-
create_makefile_am
|
167
|
+
def self.create_autoconf(project_title, version, source_file)
|
168
|
+
raise "Please supply a project_title parameter" if project_title.nil?
|
169
|
+
version = Rake::Builder::Version.new(version).decide
|
170
|
+
if File.exist?('configure.ac')
|
171
|
+
raise "The file 'configure.ac' already exists"
|
198
172
|
end
|
173
|
+
if File.exist?('Makefile.am')
|
174
|
+
raise "The file 'Makefile.am' already exists"
|
175
|
+
end
|
176
|
+
ConfigureAc.new(project_title, version, source_file).save
|
177
|
+
Presenters::MakefileAm::BuilderCollectionPresenter.new(instances).save
|
178
|
+
end
|
179
|
+
|
180
|
+
desc "Create input files for configure script creation"
|
181
|
+
task :autoconf, [:project_title, :version] => [] do |task, args|
|
182
|
+
source = Rake::Path.relative_path(instances[0].source_files[0], instances[0].rakefile_path)
|
183
|
+
create_autoconf(args.project_title, args.version, source)
|
199
184
|
end
|
200
185
|
|
201
|
-
def
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
AM_INIT_AUTOMAKE([#{project_title}], [#{ version }])
|
210
|
-
|
211
|
-
# Checks for programs.
|
212
|
-
AC_PROG_CXX
|
213
|
-
AC_PROG_CC
|
214
|
-
AC_PROG_RANLIB
|
186
|
+
def initialize( &block )
|
187
|
+
save_rakefile_info( block )
|
188
|
+
set_defaults
|
189
|
+
block.call( self )
|
190
|
+
configure
|
191
|
+
TaskDefiner.new(self).run
|
192
|
+
self.class.instances << self
|
193
|
+
end
|
215
194
|
|
216
|
-
|
195
|
+
def run
|
196
|
+
command = "cd #{rakefile_path} && #{target}"
|
197
|
+
puts shell(command, Logger::INFO)
|
198
|
+
end
|
217
199
|
|
218
|
-
|
200
|
+
def build
|
201
|
+
system "rm -f #{target}"
|
202
|
+
build_commands.each do |command|
|
203
|
+
stdout, stderr = shell(command)
|
204
|
+
raise BuildFailure.new("Error: command '#{command}' failed: #{stderr} #{stdout}") if not $?.success?
|
205
|
+
end
|
206
|
+
raise BuildFailure.new("'#{target}' not created") if not File.exist?(target)
|
207
|
+
end
|
219
208
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
209
|
+
def create_local_config
|
210
|
+
logger.add(Logger::DEBUG, "Creating file '#{local_config }'")
|
211
|
+
added_includes = compiler_data.include_paths(missing_headers)
|
212
|
+
config = Rake::LocalConfig.new(local_config)
|
213
|
+
config.include_paths = added_includes
|
214
|
+
config.save
|
215
|
+
end
|
225
216
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
217
|
+
def create_makedepend_file
|
218
|
+
system('which makedepend >/dev/null')
|
219
|
+
raise 'makedepend not found' unless $?.success?
|
220
|
+
logger.add(Logger::DEBUG, "Analysing dependencies")
|
221
|
+
command = "makedepend -f- -- #{include_path} -- #{file_list(source_files)} 2>/dev/null > #{makedepend_file}"
|
222
|
+
shell command
|
223
|
+
end
|
232
224
|
|
233
|
-
|
225
|
+
def load_local_config
|
226
|
+
config = Rake::LocalConfig.new(local_config)
|
227
|
+
config.load
|
228
|
+
@include_paths += Rake::Path.expand_all_with_root(config.include_paths, rakefile_path)
|
229
|
+
@compilation_options += config.compilation_options
|
230
|
+
end
|
234
231
|
|
235
|
-
|
236
|
-
|
232
|
+
def load_makedepend
|
233
|
+
object_to_source = source_files.inject({}) do |memo, source|
|
234
|
+
mapped_object = source.gsub('.' + source_file_extension, '.o')
|
235
|
+
memo[mapped_object] = source
|
236
|
+
memo
|
237
|
+
end
|
238
|
+
File.open(makedepend_file).each_line do |line|
|
239
|
+
next if line !~ /:\s/
|
240
|
+
mapped_object_file = $`
|
241
|
+
header_files = $'.chomp
|
242
|
+
# TODO: Why does it work,
|
243
|
+
# if I make the object (not the source) depend on the header?
|
244
|
+
source_file = object_to_source[mapped_object_file]
|
245
|
+
object_file = object_path(source_file)
|
246
|
+
object_file_task = Rake.application[object_file]
|
247
|
+
object_file_task.enhance(header_files.split(' '))
|
237
248
|
end
|
238
249
|
end
|
239
250
|
|
240
|
-
def
|
241
|
-
|
242
|
-
|
243
|
-
f.write presenter.to_s
|
251
|
+
def clean
|
252
|
+
generated_files.each do |file|
|
253
|
+
system "rm -f #{file}"
|
244
254
|
end
|
245
255
|
end
|
246
256
|
|
247
|
-
|
248
|
-
|
257
|
+
def install
|
258
|
+
destination = File.join(install_path, target_basename)
|
259
|
+
install_file(target, destination)
|
260
|
+
install_headers if target_type == :static_library
|
261
|
+
end
|
249
262
|
|
250
|
-
def
|
251
|
-
|
252
|
-
if
|
253
|
-
|
263
|
+
def uninstall
|
264
|
+
destination = File.join(install_path, target_basename)
|
265
|
+
if not File.exist?(destination)
|
266
|
+
logger.add(Logger::INFO, "The file '#{destination}' does not exist")
|
267
|
+
return
|
254
268
|
end
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
case
|
260
|
-
when parameter_version.nil? && file_version.nil?
|
261
|
-
raise <<-EOT
|
262
|
-
This task requires a project version: major.minor.revision (e.g. 1.03.0567)
|
263
|
-
Please do one of the following:
|
264
|
-
- supply a version parameter: rake autoconf[project_name,version]
|
265
|
-
- create a VERSION file.
|
266
|
-
EOT
|
267
|
-
when file_version.nil?
|
268
|
-
save_file_version parameter_version
|
269
|
-
return parameter_version
|
270
|
-
when parameter_version.nil?
|
271
|
-
return file_version
|
272
|
-
when file_version != parameter_version
|
273
|
-
raise <<-EOT
|
274
|
-
The version parameter supplied is different to the value in the VERSION file
|
275
|
-
EOT
|
276
|
-
else
|
277
|
-
return file_version
|
269
|
+
begin
|
270
|
+
shell "rm '#{destination}'", Logger::INFO
|
271
|
+
rescue Errno::EACCES => e
|
272
|
+
raise Error.new("You do not have permission to uninstall '#{destination}'\nTry re-running the command with 'sudo'", task_namespace)
|
278
273
|
end
|
279
274
|
end
|
280
275
|
|
281
|
-
def
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
def self.save_file_version( version )
|
288
|
-
File.open('VERSION', 'w') { |f| f.write "#{version}\n" }
|
276
|
+
def compile(source, object)
|
277
|
+
logger.add(Logger::DEBUG, "Compiling '#{source}'")
|
278
|
+
command = "#{compiler} -c #{compiler_flags} -o #{object} #{source}"
|
279
|
+
stdout, stderr = shell(command)
|
280
|
+
raise BuildFailure.new("Error: command '#{command}' failed: #{stderr} #{stdout}") if not $?.success?
|
289
281
|
end
|
290
|
-
|
291
|
-
self.define_global
|
292
282
|
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
block.call( self )
|
297
|
-
configure
|
298
|
-
define_tasks
|
299
|
-
define_default
|
300
|
-
self.class.instances << self
|
283
|
+
# TODO: make private
|
284
|
+
def file_list( files, delimiter = ' ' )
|
285
|
+
files.join( delimiter )
|
301
286
|
end
|
302
287
|
|
303
288
|
# Source files found in source_search_paths
|
@@ -328,9 +313,18 @@ EOT
|
|
328
313
|
source_files.map{ |file| Rake::Path.relative_path(file, rakefile_path) }
|
329
314
|
end
|
330
315
|
|
316
|
+
def object_files
|
317
|
+
source_files.map { |file| object_path(file) }
|
318
|
+
end
|
319
|
+
|
320
|
+
def object_path(source_path_name)
|
321
|
+
o_name = File.basename(source_path_name).gsub('.' + source_file_extension, '.o')
|
322
|
+
Rake::Path.expand_with_root(o_name, objects_path)
|
323
|
+
end
|
324
|
+
|
331
325
|
def compiler_flags
|
332
326
|
flags = include_path
|
333
|
-
options = compilation_options.join(
|
327
|
+
options = compilation_options.join(' ')
|
334
328
|
flags << ' ' + options if options != ''
|
335
329
|
flags << ' ' + architecture_option if RUBY_PLATFORM =~ /darwin/i
|
336
330
|
flags
|
@@ -340,12 +334,42 @@ EOT
|
|
340
334
|
@library_dependencies.map { |lib| "-l#{ lib }"}.join('')
|
341
335
|
end
|
342
336
|
|
337
|
+
def target_basename
|
338
|
+
File.basename(@target)
|
339
|
+
end
|
340
|
+
|
341
|
+
def makefile_name
|
342
|
+
extension = if ! task_namespace.nil? && ! task_namespace.to_s.empty?
|
343
|
+
'.' + task_namespace.to_s
|
344
|
+
else
|
345
|
+
''
|
346
|
+
end
|
347
|
+
"Makefile#{ extension }"
|
348
|
+
end
|
349
|
+
|
350
|
+
def project_files
|
351
|
+
source_files + header_files
|
352
|
+
end
|
353
|
+
|
354
|
+
def generated_headers
|
355
|
+
[]
|
356
|
+
end
|
357
|
+
|
358
|
+
# Discovery
|
359
|
+
|
360
|
+
def missing_headers
|
361
|
+
return @missing_headers if @missing_headers
|
362
|
+
default_includes = @compiler_data.default_include_paths( @programming_language )
|
363
|
+
all_includes = default_includes + @include_paths
|
364
|
+
@missing_headers = @compiler_data.missing_headers( all_includes, source_files )
|
365
|
+
end
|
366
|
+
|
343
367
|
private
|
344
368
|
|
345
|
-
def
|
369
|
+
def set_defaults
|
346
370
|
@architecture = 'i386'
|
347
|
-
@compiler_data = Compiler::Base.for(
|
348
|
-
@logger = Logger.new(
|
371
|
+
@compiler_data = Compiler::Base.for(:gcc)
|
372
|
+
@logger = Logger.new(STDOUT)
|
349
373
|
@logger.level = Logger::UNKNOWN
|
350
374
|
@logger.formatter = Formatter.new
|
351
375
|
@programming_language = 'c++'
|
@@ -354,8 +378,8 @@ EOT
|
|
354
378
|
@library_paths = []
|
355
379
|
@library_dependencies = []
|
356
380
|
@target_prerequisites = []
|
357
|
-
@source_search_paths = [
|
358
|
-
@header_search_paths = [
|
381
|
+
@source_search_paths = [@rakefile_path.dup]
|
382
|
+
@header_search_paths = [@rakefile_path.dup]
|
359
383
|
@target = 'a.out'
|
360
384
|
@generated_files = []
|
361
385
|
@compilation_options = []
|
@@ -363,11 +387,11 @@ EOT
|
|
363
387
|
end
|
364
388
|
|
365
389
|
def configure
|
366
|
-
@compilation_options += [
|
390
|
+
@compilation_options += [architecture_option] if RUBY_PLATFORM =~ /apple/i
|
367
391
|
@compilation_options.uniq!
|
368
392
|
|
369
393
|
@programming_language = @programming_language.to_s.downcase
|
370
|
-
raise
|
394
|
+
raise Error.new( "Don't know how to build '#{ @programming_language }' programs", task_namespace ) if KNOWN_LANGUAGES[ @programming_language ].nil?
|
371
395
|
@compiler ||= KNOWN_LANGUAGES[ @programming_language ][ :compiler ]
|
372
396
|
@linker ||= KNOWN_LANGUAGES[ @programming_language ][ :linker ]
|
373
397
|
@ar ||= KNOWN_LANGUAGES[ @programming_language ][ :ar ]
|
@@ -378,12 +402,14 @@ EOT
|
|
378
402
|
@header_search_paths = Rake::Path.expand_all_with_root( @header_search_paths, @rakefile_path )
|
379
403
|
@library_paths = Rake::Path.expand_all_with_root( @library_paths, @rakefile_path )
|
380
404
|
|
381
|
-
raise
|
382
|
-
raise
|
405
|
+
raise Error.new( "The target name cannot be nil", task_namespace ) if @target.nil?
|
406
|
+
raise Error.new( "The target name cannot be an empty string", task_namespace ) if @target == ''
|
383
407
|
@objects_path = Rake::Path.expand_with_root( @objects_path, @rakefile_path )
|
408
|
+
|
384
409
|
@target = File.expand_path( @target, @rakefile_path )
|
385
410
|
@target_type ||= to_target_type( @target )
|
386
|
-
raise
|
411
|
+
raise Error.new( "Building #{ @target_type } targets is not supported", task_namespace ) if ! TARGET_TYPES.include?( @target_type )
|
412
|
+
@generated_files << @target
|
387
413
|
|
388
414
|
@install_path ||= default_install_path( @target_type )
|
389
415
|
|
@@ -397,264 +423,9 @@ EOT
|
|
397
423
|
@local_config = Rake::Path.expand_with_root( '.rake-builder', @rakefile_path )
|
398
424
|
|
399
425
|
@makedepend_file = @objects_path + '/.' + target_basename + '.depend.mf'
|
400
|
-
|
401
|
-
raise BuilderError.new( "No source files found", task_namespace ) if source_files.length == 0
|
402
|
-
end
|
403
|
-
|
404
|
-
def define_tasks
|
405
|
-
if @task_namespace
|
406
|
-
namespace @task_namespace do
|
407
|
-
define
|
408
|
-
end
|
409
|
-
else
|
410
|
-
define
|
411
|
-
end
|
412
|
-
end
|
413
|
-
|
414
|
-
def define_default
|
415
|
-
name = scoped_task( @default_task )
|
416
|
-
desc "Equivalent to 'rake #{ name }'"
|
417
|
-
if @task_namespace
|
418
|
-
task @task_namespace => [ name ]
|
419
|
-
else
|
420
|
-
task :default => [ name ]
|
421
|
-
end
|
422
|
-
end
|
423
|
-
|
424
|
-
def define
|
425
|
-
once_task :environment do
|
426
|
-
logger.level = Logger::DEBUG if ENV[ 'DEBUG' ]
|
427
|
-
end
|
428
|
-
|
429
|
-
if @target_type == :executable
|
430
|
-
desc "Run '#{ target_basename }'"
|
431
|
-
task :run => :build do
|
432
|
-
command = "cd #{ @rakefile_path } && #{ @target }"
|
433
|
-
puts shell( command, Logger::INFO )
|
434
|
-
end
|
435
|
-
end
|
436
|
-
|
437
|
-
desc "Compile and build '#{ target_basename }'"
|
438
|
-
FileTaskAlias.define_task( :build, @target )
|
439
|
-
|
440
|
-
desc "Build '#{ target_basename }'"
|
441
|
-
microsecond_file @target => [ scoped_task( :environment ),
|
442
|
-
scoped_task( :compile ),
|
443
|
-
*@target_prerequisites ] do | t |
|
444
|
-
shell "rm -f #{ t.name }"
|
445
|
-
build_commands.each do | command |
|
446
|
-
stdout, stderr = shell(command)
|
447
|
-
raise BuildFailure.new("Error: command '#{command}' failed: #{stderr} #{stdout}") if not $?.success?
|
448
|
-
end
|
449
|
-
raise BuildFailure.new("'#{@target}' not created") if not File.exist?(@target)
|
450
|
-
end
|
451
|
-
|
452
|
-
desc "Compile all sources"
|
453
|
-
# Only import dependencies when we're compiling
|
454
|
-
# otherwise makedepend gets run on e.g. 'rake -T'
|
455
|
-
once_task :compile => [ scoped_task( :environment ),
|
456
|
-
@makedepend_file,
|
457
|
-
scoped_task( :load_makedepend ),
|
458
|
-
*object_files ]
|
459
|
-
|
460
|
-
source_files.each do |src|
|
461
|
-
define_compile_task( src )
|
462
|
-
end
|
463
|
-
|
464
|
-
microsecond_directory @objects_path
|
465
|
-
|
466
|
-
file scoped_task( local_config ) do
|
467
|
-
@logger.add( Logger::DEBUG, "Creating file '#{ local_config }'" )
|
468
|
-
added_includes = @compiler_data.include_paths( missing_headers )
|
469
|
-
config = Rake::LocalConfig.new( local_config )
|
470
|
-
config.include_paths = added_includes
|
471
|
-
config.save
|
472
|
-
end
|
473
|
-
|
474
|
-
microsecond_file @makedepend_file => [
|
475
|
-
scoped_task( :load_local_config ),
|
476
|
-
scoped_task( :missing_headers ),
|
477
|
-
@objects_path,
|
478
|
-
*project_files
|
479
|
-
] do
|
480
|
-
system('which makedepend >/dev/null')
|
481
|
-
raise 'makedepend not found' unless $?.success?
|
482
|
-
@logger.add( Logger::DEBUG, "Analysing dependencies" )
|
483
|
-
command = "makedepend -f- -- #{ include_path } -- #{ file_list( source_files ) } 2>/dev/null > #{ @makedepend_file }"
|
484
|
-
shell command
|
485
|
-
end
|
486
|
-
|
487
|
-
once_task scoped_task( :load_local_config ) => scoped_task( local_config ) do
|
488
|
-
config = LocalConfig.new( local_config )
|
489
|
-
config.load
|
490
|
-
@include_paths += Rake::Path.expand_all_with_root( config.include_paths, @rakefile_path )
|
491
|
-
@compilation_options += config.compilation_options
|
492
|
-
end
|
493
|
-
|
494
|
-
once_task scoped_task( :missing_headers ) => [ *generated_headers ] do
|
495
|
-
missing_headers
|
496
|
-
end
|
497
|
-
|
498
|
-
# Reimplemented mkdepend file loading to make objects depend on
|
499
|
-
# sources with the correct paths:
|
500
|
-
# the standard rake mkdepend loader doesn't do what we want,
|
501
|
-
# as it assumes files will be compiled in their own directory.
|
502
|
-
task :load_makedepend => @makedepend_file do
|
503
|
-
object_to_source = source_files.inject( {} ) do | memo, source |
|
504
|
-
mapped_object = source.gsub( '.' + @source_file_extension, '.o' )
|
505
|
-
memo[ mapped_object ] = source
|
506
|
-
memo
|
507
|
-
end
|
508
|
-
File.open( @makedepend_file ).each_line do |line|
|
509
|
-
next if line !~ /:\s/
|
510
|
-
mapped_object_file = $`
|
511
|
-
header_files = $'.chomp
|
512
|
-
# TODO: Why does it work,
|
513
|
-
# if I make the object (not the source) depend on the header?
|
514
|
-
source_file = object_to_source[ mapped_object_file ]
|
515
|
-
object_file = object_path( source_file )
|
516
|
-
object_file_task = Rake.application[ object_file ]
|
517
|
-
object_file_task.enhance(header_files.split(' '))
|
518
|
-
end
|
519
|
-
end
|
520
|
-
|
521
|
-
desc "List generated files (which are removed with 'rake #{ scoped_task( :clean ) }')"
|
522
|
-
task :generated_files do
|
523
|
-
puts generated_files.to_json
|
524
|
-
end
|
525
|
-
|
526
|
-
# Re-implement :clean locally for project and within namespace
|
527
|
-
# Standard :clean is a singleton
|
528
|
-
desc "Remove temporary files"
|
529
|
-
task :clean do
|
530
|
-
generated_files.each do |file|
|
531
|
-
shell "rm -f #{ file }"
|
532
|
-
end
|
533
|
-
end
|
534
|
-
|
535
|
-
@generated_files << @target
|
536
426
|
@generated_files << @makedepend_file
|
537
427
|
|
538
|
-
|
539
|
-
task :install, [] => [ scoped_task( :build ) ] do
|
540
|
-
destination = File.join( @install_path, target_basename )
|
541
|
-
install( @target, destination )
|
542
|
-
install_headers if @target_type == :static_library
|
543
|
-
end
|
544
|
-
|
545
|
-
desc "Uninstall '#{ target_basename }' from '#{ @install_path }'"
|
546
|
-
task :uninstall, [] => [] do
|
547
|
-
destination = File.join( @install_path, target_basename )
|
548
|
-
if ! File.exist?( destination )
|
549
|
-
@logger.add( Logger::INFO, "The file '#{ destination }' does not exist" )
|
550
|
-
next
|
551
|
-
end
|
552
|
-
begin
|
553
|
-
shell "rm '#{ destination }'", Logger::INFO
|
554
|
-
rescue Errno::EACCES => e
|
555
|
-
raise BuilderError.new( "You do not have permission to uninstall '#{ destination }'\nTry\n $ sudo rake #{ scoped_task( :uninstall ) }", task_namespace )
|
556
|
-
end
|
557
|
-
end
|
558
|
-
|
559
|
-
desc "Create a '#{ makefile_name }' to build the project"
|
560
|
-
file "#{ makefile_name }" => [ @makedepend_file, scoped_task( :load_makedepend ) ] do | t |
|
561
|
-
objects = object_files.collect { | f | f.sub( "#{ @objects_path }", '$(OBJECT_DIR)' ) }
|
562
|
-
objects_list = objects.join( ' ' )
|
563
|
-
case @target_type
|
564
|
-
when :executable
|
565
|
-
target_name = 'EXECUTABLE_TARGET'
|
566
|
-
target_ref = "$(#{ target_name })"
|
567
|
-
target_actions =
|
568
|
-
" $(LINKER) $(LINK_FLAGS) -o #{ target_ref } $(OBJECTS)
|
569
|
-
"
|
570
|
-
when :static_library
|
571
|
-
target_name = 'LIB_TARGET'
|
572
|
-
target_ref = "$(#{ target_name })"
|
573
|
-
target_actions =
|
574
|
-
" rm -f #{ target_ref }
|
575
|
-
ar -cq #{ target_ref } $(OBJECTS)
|
576
|
-
ranlib #{ target_ref }
|
577
|
-
"
|
578
|
-
when :shared_library
|
579
|
-
target_name = 'LIB_TARGET'
|
580
|
-
target_ref = "$(#{ target_name })"
|
581
|
-
target_actions =
|
582
|
-
" $(LINKER) -shared -o #{ target_ref } $(OBJECTS) $(LINK_FLAGS)
|
583
|
-
"
|
584
|
-
end
|
585
|
-
|
586
|
-
variables = <<EOT
|
587
|
-
COMPILER = #{ @compiler }
|
588
|
-
COMPILER_FLAGS = #{ compiler_flags }
|
589
|
-
LINKER = #{ @linker }
|
590
|
-
LINK_FLAGS = #{ link_flags }
|
591
|
-
OBJECT_DIR = #{ @objects_path }
|
592
|
-
OBJECTS = #{ objects_list }
|
593
|
-
#{ target_name } = #{ @target }
|
594
|
-
EOT
|
595
|
-
rules = <<EOT
|
596
|
-
|
597
|
-
all: #{ target_ref }
|
598
|
-
|
599
|
-
clean:
|
600
|
-
rm -f $(OBJECTS)
|
601
|
-
rm -f #{ target_ref }
|
602
|
-
|
603
|
-
#{ target_ref }: $(OBJECTS)
|
604
|
-
#{ target_actions }
|
605
|
-
EOT
|
606
|
-
|
607
|
-
source_groups = group_files_by_path( source_files )
|
608
|
-
source_groups.each.with_index do | gp, i |
|
609
|
-
variables << "SOURCE_#{ i + 1 } = #{ gp[ 0 ] }\n"
|
610
|
-
rules << <<EOT
|
611
|
-
|
612
|
-
$(OBJECT_DIR)/%.o: $(SOURCE_#{ i + 1 })/%.cpp
|
613
|
-
$(COMPILER) -c $(COMPILER_FLAGS) -o $@ $<
|
614
|
-
EOT
|
615
|
-
end
|
616
|
-
|
617
|
-
File.open( t.name, 'w' ) do | file |
|
618
|
-
file.write variables
|
619
|
-
file.write rules
|
620
|
-
end
|
621
|
-
end
|
622
|
-
|
623
|
-
end
|
624
|
-
|
625
|
-
def generated_headers
|
626
|
-
[]
|
627
|
-
end
|
628
|
-
|
629
|
-
def scoped_task( task )
|
630
|
-
if @task_namespace
|
631
|
-
"#{ task_namespace }:#{ task }"
|
632
|
-
else
|
633
|
-
task
|
634
|
-
end
|
635
|
-
end
|
636
|
-
|
637
|
-
def define_compile_task( source )
|
638
|
-
object = object_path( source )
|
639
|
-
@generated_files << object
|
640
|
-
file object => [ source ] do |t|
|
641
|
-
@logger.add( Logger::DEBUG, "Compiling '#{ source }'" )
|
642
|
-
command = "#{ @compiler } -c #{ compiler_flags } -o #{ object } #{ source }"
|
643
|
-
stdout, stderr = shell(command)
|
644
|
-
raise BuildFailure.new("Error: command '#{command}' failed: #{stderr} #{stdout}") if not $?.success?
|
645
|
-
end
|
646
|
-
end
|
647
|
-
|
648
|
-
def build_commands
|
649
|
-
case @target_type
|
650
|
-
when :executable
|
651
|
-
[ "#{ @linker } -o #{ @target } #{ file_list( object_files ) } #{ link_flags }" ]
|
652
|
-
when :static_library
|
653
|
-
[ "#{ @ar } -cq #{ @target } #{ file_list( object_files ) }",
|
654
|
-
"#{ @ranlib } #{ @target }" ]
|
655
|
-
when :shared_library
|
656
|
-
[ "#{ @linker } -shared -o #{ @target } #{ file_list( object_files ) } #{ link_flags }" ]
|
657
|
-
end
|
428
|
+
raise Error.new( "No source files found", task_namespace ) if source_files.length == 0
|
658
429
|
end
|
659
430
|
|
660
431
|
def to_target_type(target)
|
@@ -668,15 +439,6 @@ EOT
|
|
668
439
|
end
|
669
440
|
end
|
670
441
|
|
671
|
-
# Discovery
|
672
|
-
|
673
|
-
def missing_headers
|
674
|
-
return @missing_headers if @missing_headers
|
675
|
-
default_includes = @compiler_data.default_include_paths( @programming_language )
|
676
|
-
all_includes = default_includes + @include_paths
|
677
|
-
@missing_headers = @compiler_data.missing_headers( all_includes, source_files )
|
678
|
-
end
|
679
|
-
|
680
442
|
# Compiling and linking parameters
|
681
443
|
|
682
444
|
def include_path
|
@@ -707,11 +469,6 @@ EOT
|
|
707
469
|
@rakefile_path = File.dirname( @rakefile )
|
708
470
|
end
|
709
471
|
|
710
|
-
def object_path( source_path_name )
|
711
|
-
o_name = File.basename( source_path_name ).gsub( '.' + @source_file_extension, '.o' )
|
712
|
-
Rake::Path.expand_with_root( o_name, @objects_path )
|
713
|
-
end
|
714
|
-
|
715
472
|
def default_install_path( target_type )
|
716
473
|
case target_type
|
717
474
|
when :executable
|
@@ -730,39 +487,12 @@ EOT
|
|
730
487
|
|
731
488
|
# Files
|
732
489
|
|
733
|
-
def target_basename
|
734
|
-
File.basename( @target )
|
735
|
-
end
|
736
|
-
|
737
|
-
def makefile_name
|
738
|
-
extension = if ! task_namespace.nil? && ! task_namespace.to_s.empty?
|
739
|
-
'.' + task_namespace.to_s
|
740
|
-
else
|
741
|
-
''
|
742
|
-
end
|
743
|
-
"Makefile#{ extension }"
|
744
|
-
end
|
745
|
-
|
746
490
|
# Lists of files
|
747
491
|
|
748
492
|
def find_files( paths, extension )
|
749
493
|
files = Rake::Path.find_files( paths, extension )
|
750
494
|
Rake::Path.expand_all_with_root( files, @rakefile_path )
|
751
495
|
end
|
752
|
-
|
753
|
-
# TODO: make this return a FileList, not a plain Array
|
754
|
-
def object_files
|
755
|
-
source_files.map { |file| object_path( file ) }
|
756
|
-
end
|
757
|
-
|
758
|
-
def project_files
|
759
|
-
source_files + header_files
|
760
|
-
end
|
761
|
-
public :project_files
|
762
|
-
|
763
|
-
def file_list( files, delimiter = ' ' )
|
764
|
-
files.join( delimiter )
|
765
|
-
end
|
766
496
|
|
767
497
|
def library_paths_list
|
768
498
|
@library_paths.map { | path | "-L#{ path }" }.join( " " )
|
@@ -777,9 +507,9 @@ EOT
|
|
777
507
|
begin
|
778
508
|
`mkdir -p '#{ destination_path }'`
|
779
509
|
rescue Errno::EACCES => e
|
780
|
-
raise
|
510
|
+
raise Error.new( "Permission denied to created directory '#{ destination_path }'", task_namespace )
|
781
511
|
end
|
782
|
-
|
512
|
+
install_file( installable_header[ :source_file ], destination_path )
|
783
513
|
end
|
784
514
|
end
|
785
515
|
|
@@ -811,12 +541,26 @@ EOT
|
|
811
541
|
end
|
812
542
|
end
|
813
543
|
|
814
|
-
def
|
544
|
+
def build_commands
|
545
|
+
case target_type
|
546
|
+
when :executable
|
547
|
+
[ "#{ linker } -o #{ target } #{ file_list( object_files ) } #{ link_flags }" ]
|
548
|
+
when :static_library
|
549
|
+
[ "#{ ar } -cq #{ target } #{ file_list( object_files ) }",
|
550
|
+
"#{ ranlib } #{ target }" ]
|
551
|
+
when :shared_library
|
552
|
+
[ "#{ linker } -shared -o #{ target } #{ file_list( object_files ) } #{ link_flags }" ]
|
553
|
+
else
|
554
|
+
# TODO: raise an error
|
555
|
+
end
|
556
|
+
end
|
557
|
+
|
558
|
+
def install_file(source_pathname, destination_path)
|
815
559
|
begin
|
816
560
|
shell "cp '#{ source_pathname }' '#{ destination_path }'", Logger::INFO
|
817
561
|
rescue Errno::EACCES => e
|
818
562
|
source_filename = File.basename( source_pathname ) rescue '????'
|
819
|
-
raise
|
563
|
+
raise Error.new( "You do not have permission to install '#{ source_filename }' to '#{ destination_path }'\nTry\n $ sudo rake install", task_namespace )
|
820
564
|
end
|
821
565
|
end
|
822
566
|
|
@@ -829,8 +573,6 @@ EOT
|
|
829
573
|
$stdout, $stderr = *originals
|
830
574
|
[stdout.read, stderr.read]
|
831
575
|
end
|
832
|
-
|
833
576
|
end
|
834
|
-
|
835
577
|
end
|
836
578
|
|
data/lib/rake/local_config.rb
CHANGED
@@ -22,7 +22,7 @@ module Rake
|
|
22
22
|
@include_paths = config[:include_paths]
|
23
23
|
@compilation_options = config[:compilation_options]
|
24
24
|
if not VERSIONS.find_index(version)
|
25
|
-
raise Rake::Builder::
|
25
|
+
raise Rake::Builder::Error.new('Config file version incorrect')
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
data/spec/autoconf_spec.rb
CHANGED
@@ -5,9 +5,6 @@ describe 'autoconf' do
|
|
5
5
|
include RakeBuilderHelper
|
6
6
|
|
7
7
|
before :each do
|
8
|
-
Rake::Task.clear
|
9
|
-
Rake::Builder.define_global
|
10
|
-
|
11
8
|
@project = cpp_task(:executable)
|
12
9
|
|
13
10
|
@args = Rake::TaskArguments.new(
|
@@ -160,11 +157,10 @@ describe 'autoconf' do
|
|
160
157
|
|
161
158
|
context 'Makefile.am' do
|
162
159
|
it 'is created' do
|
163
|
-
Rake::Builder.should_receive(:
|
160
|
+
Rake::Builder.should_receive(:create_autoconf)
|
164
161
|
|
165
162
|
Rake::Task['autoconf'].execute(@args)
|
166
163
|
end
|
167
164
|
end
|
168
|
-
|
169
165
|
end
|
170
166
|
|
data/spec/local_config_spec.rb
CHANGED
@@ -36,7 +36,7 @@ describe 'local config files' do
|
|
36
36
|
lambda do
|
37
37
|
config = Rake::LocalConfig.new( @local_config_file )
|
38
38
|
config.load
|
39
|
-
end.should raise_error(
|
39
|
+
end.should raise_error(Rake::Builder::Error, 'Config file version incorrect')
|
40
40
|
end
|
41
41
|
|
42
42
|
context 'dependencies' do
|
data/spec/target_spec.rb
CHANGED
@@ -16,7 +16,7 @@ describe 'when creating tasks' do
|
|
16
16
|
builder.target = ''
|
17
17
|
builder.source_search_paths = [ 'cpp_project' ]
|
18
18
|
end
|
19
|
-
end.should raise_error(
|
19
|
+
end.should raise_error(Rake::Builder::Error, 'The target name cannot be an empty string')
|
20
20
|
end
|
21
21
|
|
22
22
|
it 'raises an error when the target is set to nil' do
|
@@ -25,7 +25,7 @@ describe 'when creating tasks' do
|
|
25
25
|
builder.target = nil
|
26
26
|
builder.source_search_paths = [ 'cpp_project' ]
|
27
27
|
end
|
28
|
-
end.should raise_error(
|
28
|
+
end.should raise_error(Rake::Builder::Error, 'The target name cannot be nil')
|
29
29
|
end
|
30
30
|
|
31
31
|
it 'sets the target to \'a.out\' if it is not set' do
|
@@ -1,28 +1,51 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Rake::Builder do
|
4
|
-
context '.
|
5
|
-
let(:
|
4
|
+
context '.create_autoconf' do
|
5
|
+
let(:version) { stub('Rake::Builder::Autoconf::Version', :decide => 'qux') }
|
6
|
+
let(:presenter) { stub('Rake::Builder::Presenters::MakefileAm::BuilderCollectionPresenter', :save => nil) }
|
7
|
+
let(:configure_ac) { stub('Rake::Builder::ConfigureAc', :save => nil) }
|
6
8
|
|
7
9
|
before do
|
10
|
+
Rake::Builder::Version.stub(:new).and_return(version)
|
11
|
+
File.stub(:exist?).with('configure.ac').and_return(false)
|
12
|
+
File.stub(:exist?).with('Makefile.am').and_return(false)
|
13
|
+
Rake::Builder::ConfigureAc.stub(:new => configure_ac)
|
8
14
|
Rake::Builder::Presenters::MakefileAm::BuilderCollectionPresenter.stub(:new).and_return(presenter)
|
9
|
-
File.stub(:open).with('Makefile.am', 'w')
|
10
15
|
end
|
11
16
|
|
12
|
-
it '
|
13
|
-
|
17
|
+
it 'fails if project_title is nil' do
|
18
|
+
expect {
|
19
|
+
Rake::Builder.create_autoconf(nil, 'bar', 'baz')
|
20
|
+
}.to raise_error(RuntimeError, 'Please supply a project_title parameter')
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'fails if configure.ac exists' do
|
24
|
+
File.should_receive(:exist?).with('configure.ac').and_return(true)
|
25
|
+
|
26
|
+
expect {
|
27
|
+
Rake::Builder.create_autoconf('foo', 'bar', 'baz')
|
28
|
+
}.to raise_error(RuntimeError, "The file 'configure.ac' already exists")
|
29
|
+
end
|
14
30
|
|
15
|
-
|
31
|
+
it 'fails if Makefile.am exists' do
|
32
|
+
File.should_receive(:exist?).with('Makefile.am').and_return(true)
|
33
|
+
|
34
|
+
expect {
|
35
|
+
Rake::Builder.create_autoconf('foo', 'bar', 'baz')
|
36
|
+
}.to raise_error(RuntimeError, "The file 'Makefile.am' already exists")
|
16
37
|
end
|
17
38
|
|
18
|
-
it '
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
39
|
+
it 'creates configure.ac' do
|
40
|
+
Rake::Builder::ConfigureAc.should_receive(:new).and_return(configure_ac)
|
41
|
+
|
42
|
+
Rake::Builder.create_autoconf('foo', 'bar', 'baz')
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'creates Makefile.am' do
|
46
|
+
Rake::Builder::Presenters::MakefileAm::BuilderCollectionPresenter.should_receive(:new).and_return(presenter)
|
24
47
|
|
25
|
-
Rake::Builder.
|
48
|
+
Rake::Builder.create_autoconf('foo', 'bar', 'baz')
|
26
49
|
end
|
27
50
|
end
|
28
51
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rake-builder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.19
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -90,10 +90,16 @@ files:
|
|
90
90
|
- lib/rake/once_task.rb
|
91
91
|
- lib/rake/microsecond.rb
|
92
92
|
- lib/rake/file_task_alias.rb
|
93
|
+
- lib/rake/builder/logger/formatter.rb
|
93
94
|
- lib/rake/builder/qt_builder.rb
|
95
|
+
- lib/rake/builder/error.rb
|
94
96
|
- lib/rake/builder/version.rb
|
97
|
+
- lib/rake/builder/task_definer.rb
|
98
|
+
- lib/rake/builder/autoconf/version.rb
|
95
99
|
- lib/rake/builder/presenters/makefile_am/builder_presenter.rb
|
96
100
|
- lib/rake/builder/presenters/makefile_am/builder_collection_presenter.rb
|
101
|
+
- lib/rake/builder/presenters/makefile/builder_presenter.rb
|
102
|
+
- lib/rake/builder/configure_ac.rb
|
97
103
|
- lib/rake/local_config.rb
|
98
104
|
- lib/rake/path.rb
|
99
105
|
- lib/rake/builder.rb
|
@@ -165,7 +171,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
165
171
|
version: '0'
|
166
172
|
segments:
|
167
173
|
- 0
|
168
|
-
hash:
|
174
|
+
hash: 1943333437698493637
|
169
175
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
170
176
|
none: false
|
171
177
|
requirements:
|
@@ -174,7 +180,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
174
180
|
version: '0'
|
175
181
|
segments:
|
176
182
|
- 0
|
177
|
-
hash:
|
183
|
+
hash: 1943333437698493637
|
178
184
|
requirements: []
|
179
185
|
rubyforge_project: nowarning
|
180
186
|
rubygems_version: 1.8.23
|