rake-builder 0.0.18 → 0.0.19
Sign up to get free protection for your applications and to get access to all the features.
- 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
|