cxxproject 0.2

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/Rakefile.rb ADDED
@@ -0,0 +1,47 @@
1
+ require 'rake/gempackagetask'
2
+ require 'roodi'
3
+ require 'roodi_task'
4
+ require 'spec/rake/spectask'
5
+
6
+ desc "Default Task"
7
+ task :default => [:package, :roodi]
8
+
9
+ PKG_VERSION = '0.2'
10
+ PKG_FILES = FileList[
11
+ 'lib/**/*.rb',
12
+ 'Rakefile.rb',
13
+ 'spec/**/*.rb'
14
+ # 'doc/**/*'
15
+ ]
16
+
17
+ spec = Gem::Specification.new do |s|
18
+ s.name = 'cxxproject'
19
+ s.version = PKG_VERSION
20
+ s.summary = "Cpp Support for Rake."
21
+ s.description = <<-EOF
22
+ Some more high level building blocks for cpp projects.
23
+ EOF
24
+ s.files = PKG_FILES.to_a
25
+ s.require_path = 'lib'
26
+ s.author = ''
27
+ s.email = ''
28
+ s.homepage = ''
29
+ end
30
+
31
+ RoodiTask.new
32
+ Rake::GemPackageTask.new(spec) {|pkg|}
33
+
34
+ task :gem => [:spec, :roodi]
35
+
36
+ desc "Run all examples"
37
+ Spec::Rake::SpecTask.new() do |t|
38
+ t.spec_files = FileList['spec/**/*.rb']
39
+ end
40
+
41
+ task :default => [:install]
42
+
43
+ desc "install gem globally"
44
+ task :install => :gem do
45
+ sh "gem install pkg/#{spec.name}-#{spec.version}.gem"
46
+ end
47
+
@@ -0,0 +1,80 @@
1
+ class Compiler
2
+ def initialize(output_path)
3
+ @output_path = output_path
4
+ end
5
+
6
+ def include(name)
7
+ CLEAN.include(name)
8
+ # ALL.include(name)
9
+ end
10
+
11
+ def transitive_includes(lib)
12
+ res = Dependencies.transitive_dependencies([lib.name]).map do |i|
13
+ i.includes.map { |include| File.join(i.base, include) }
14
+ end
15
+ return res.flatten
16
+ end
17
+ def transitive_libs(from)
18
+ res = Dependencies.transitive_dependencies([from.name]).delete_if{|i|i.instance_of?(Exe)}.map do |i|
19
+ "#{@output_path}/lib#{i.name}.a"
20
+ end
21
+ return res
22
+ end
23
+
24
+ def create_object_file(lib, relative_source)
25
+ source = File.join(lib.base, relative_source)
26
+ out = File.join(@output_path, "#{source}.o")
27
+ outputdir = File.dirname(out)
28
+ directory outputdir
29
+ include(out)
30
+ desc "compiling #{source}"
31
+ res = file out => [source, outputdir] do |t|
32
+ includes = transitive_includes(lib)
33
+ include_string = includes.inject('') { | res, i | "#{res} -I#{i} " }
34
+ sh "g++ -c #{source} #{include_string} -o #{t.name}"
35
+ end
36
+ return res
37
+ end
38
+
39
+ def static_lib_path(name)
40
+ libname = "lib#{name}.a"
41
+ fullpath = File.join(@output_path, libname)
42
+ return fullpath
43
+ end
44
+
45
+ def create_source_lib(lib, objects)
46
+ fullpath = static_lib_path(lib.name)
47
+ command = objects.inject("ar -r #{fullpath}") do |command, o|
48
+ "#{command} #{o}"
49
+ end
50
+ include(fullpath)
51
+ deps = objects.dup
52
+ deps += lib.dependencies.map {|dep|static_lib_path(dep)}
53
+ desc "link lib #{lib.name}"
54
+ res = file fullpath => deps do
55
+ sh command
56
+ end
57
+ return res
58
+ end
59
+
60
+ def create_exe(exe, objects)
61
+ exename = "#{exe.name}.exe"
62
+ fullpath = File.join(@output_path, exename)
63
+ command = objects.inject("g++ -o #{fullpath}") do |command, o|
64
+ "#{command} #{o}"
65
+ end
66
+
67
+ dep_paths = exe.dependencies.map {|dep|static_lib_path(dep)}
68
+ include(fullpath)
69
+ deps = objects.dup
70
+ deps += dep_paths
71
+ desc "link exe #{exe.name}"
72
+ res = file fullpath => deps do
73
+ libs = transitive_libs(exe)
74
+ command = libs.inject(command) { |command, l| "#{command} #{l}" }
75
+ sh command
76
+ end
77
+ return res
78
+ end
79
+ end
80
+
@@ -0,0 +1,41 @@
1
+ class Dependencies
2
+
3
+ attr_reader :all_libs
4
+
5
+ def initialize(lib_strings)
6
+ @all_libs = []
7
+ lib_strings.each do |lib_string|
8
+ add(lib_string)
9
+ end
10
+ end
11
+
12
+ def self.transitive_dependencies(lib)
13
+ return Dependencies.new(lib).all_libs
14
+ end
15
+
16
+
17
+
18
+ def self.tr_libs(libs)
19
+ return LibHelper.new(libs).all_libs
20
+ end
21
+
22
+ def add_unique(lib)
23
+ @all_libs.delete(lib)
24
+ @all_libs.push(lib)
25
+ end
26
+
27
+ def add(lib)
28
+ bb = ALL_BUILDING_BLOCKS[lib]
29
+ if !bb
30
+ raise "dependency not found #{lib}"
31
+ end
32
+ add_unique(bb)
33
+ bb.dependencies.each do |dep|
34
+ add(dep)
35
+ end
36
+ end
37
+
38
+
39
+
40
+
41
+ end
@@ -0,0 +1,7 @@
1
+
2
+ class GccCompiler < Compiler
3
+ def initialize(output_path)
4
+ super(output_path)
5
+ end
6
+ end
7
+
@@ -0,0 +1,7 @@
1
+
2
+ class OsxCompiler < Compiler
3
+ def initialize(output_path)
4
+ super(output_path)
5
+ end
6
+ end
7
+
@@ -0,0 +1,15 @@
1
+
2
+ module OS
3
+ def OS.windows?
4
+ (RUBY_PLATFORM =~ /cygwin|mswin|mingw|bccwin|wince|emx/) != nil
5
+ end
6
+ def OS.mac?
7
+ (RUBY_PLATFORM =~ /darwin/) != nil
8
+ end
9
+ def OS.unix?
10
+ !OS.windows?
11
+ end
12
+ def OS.linux?
13
+ OS.unix? and not OS.mac?
14
+ end
15
+ end
data/lib/cxxproject.rb ADDED
@@ -0,0 +1,227 @@
1
+ require 'rake/clean'
2
+ require 'cxxproject/utils'
3
+ require 'cxxproject/dependencies'
4
+ require 'cxxproject/compiler'
5
+ require 'cxxproject/gcccompiler'
6
+ require 'cxxproject/osxcompiler'
7
+
8
+ module OS
9
+ def OS.windows?
10
+ (RUBY_PLATFORM =~ /cygwin|mswin|mingw|bccwin|wince|emx/) != nil
11
+ end
12
+ def OS.mac?
13
+ (RUBY_PLATFORM =~ /darwin/) != nil
14
+ end
15
+ def OS.unix?
16
+ !OS.windows?
17
+ end
18
+ def OS.linux?
19
+ OS.unix? and not OS.mac?
20
+ end
21
+ end
22
+
23
+ ALL_BUILDING_BLOCKS = {}
24
+
25
+ ALL = FileList.new
26
+
27
+ class BuildingBlock
28
+ attr_accessor :name, :base, :dependencies
29
+ def initialize(name)
30
+ @name = name
31
+ @dependencies = []
32
+ ALL_BUILDING_BLOCKS[@name] = self
33
+ end
34
+ def to_s
35
+ inspect
36
+ end
37
+ end
38
+
39
+ class LibraryBuildingBlock < BuildingBlock
40
+ attr_accessor :includes
41
+ def initialize(name)
42
+ super
43
+ @includes = ['.']
44
+ end
45
+ end
46
+
47
+ class SourceBuildingBlock < LibraryBuildingBlock
48
+ attr_accessor :sources
49
+
50
+ def initialize(name)
51
+ super(name)
52
+ @sources = []
53
+ @dependencies = []
54
+ end
55
+ end
56
+
57
+ class SourceLibrary < SourceBuildingBlock
58
+ attr_accessor :defines
59
+ def initialize(name)
60
+ super(name)
61
+ @defines = []
62
+ end
63
+ end
64
+
65
+ class Exe < SourceBuildingBlock
66
+ def initialize(name)
67
+ super(name)
68
+ end
69
+ end
70
+
71
+ class BinaryLibrary < LibraryBuildingBlock
72
+ def initialize(name)
73
+ super
74
+ @includes = ['']
75
+ end
76
+ end
77
+
78
+ class OsxCompiler
79
+ def initialize(output_path)
80
+ @output_path = output_path
81
+ end
82
+
83
+ def register(name)
84
+ CLEAN.include(name)
85
+ ALL.include(name)
86
+ end
87
+
88
+ def transitive_includes(lib)
89
+ res = Dependencies.transitive_dependencies([lib.name]).map do |i|
90
+ if (i.instance_of?(BinaryLibrary))
91
+ i.includes
92
+ else
93
+ i.includes.map { |include| File.join(i.base, include) }
94
+ end
95
+ end
96
+ return res.flatten.delete_if{|i|i.size == 0}
97
+ end
98
+
99
+ def transitive_libs(from)
100
+ res = Dependencies.transitive_dependencies([from.name]).delete_if{|i|i.instance_of?(Exe)}.map do |i|
101
+ if (i.instance_of?(BinaryLibrary))
102
+ "-L/opt/local/lib -l#{i.name}"
103
+ else
104
+ "osx/lib#{i.name}.a"
105
+ end
106
+ end
107
+ return res
108
+ end
109
+
110
+ def create_object_file(lib, relative_source)
111
+ source = File.join(lib.base, relative_source)
112
+ out = File.join(@output_path, "#{source}.o")
113
+ outputdir = File.dirname(out)
114
+ directory outputdir
115
+ register(out)
116
+ desc "compiling #{source}"
117
+ res = file out => [source, outputdir] do |t|
118
+ includes = transitive_includes(lib)
119
+ include_string = includes.inject('') { | res, i | "#{res} -I#{i} " }
120
+ sh "g++ -c #{source} #{include_string} -o #{t.name}"
121
+ end
122
+ return res
123
+ end
124
+
125
+ def static_lib_path(name)
126
+ libname = "lib#{name}.a"
127
+ fullpath = File.join(@output_path, libname)
128
+ return fullpath
129
+ end
130
+
131
+ def create_source_lib(lib, objects)
132
+ fullpath = static_lib_path(lib.name)
133
+ command = objects.inject("ar -r #{fullpath}") do |command, o|
134
+ "#{command} #{o}"
135
+ end
136
+ register(fullpath)
137
+ deps = objects.dup
138
+ deps += lib.dependencies.map {|dep|get_path_for_lib(dep)}
139
+ desc "link lib #{lib.name}"
140
+ res = file fullpath => deps do
141
+ sh command
142
+ end
143
+ return res
144
+ end
145
+
146
+ def get_path_for_lib(l)
147
+ lib = ALL_BUILDING_BLOCKS[l]
148
+ if !lib
149
+ raise "could not find buildingblock with name '#{l}'"
150
+ end
151
+ if (lib.instance_of?(BinaryLibrary))
152
+ "/opt/local/lib/lib#{lib.name}.a"
153
+ else
154
+ static_lib_path(lib.name)
155
+ end
156
+ end
157
+
158
+ def create_exe(exe, objects)
159
+ exename = "#{exe.name}.exe"
160
+ fullpath = File.join(@output_path, exename)
161
+ command = objects.inject("g++ -all_load -o #{fullpath}") do |command, o|
162
+ "#{command} #{o}"
163
+ end
164
+
165
+ dep_paths = exe.dependencies.map {|dep|get_path_for_lib(dep)}
166
+ register(fullpath)
167
+ deps = objects.dup
168
+ deps += dep_paths
169
+ desc "link exe #{exe.name}"
170
+ res = file fullpath => deps do
171
+ sh transitive_libs(exe).inject(command) {|command,l|"#{command} #{l}"}
172
+ end
173
+ return res
174
+ end
175
+ end
176
+
177
+
178
+ def build_source_lib(lib)
179
+ objects = lib.sources.map do |s|
180
+ Compiler.create_object_file(lib, File.basename(s))
181
+ end
182
+ Compiler.create_source_lib(lib, objects)
183
+ end
184
+
185
+ def build_exe(exe)
186
+ objects = exe.sources.map do |s|
187
+ Compiler.create_object_file(exe, File.basename(s))
188
+ end
189
+ Compiler.create_exe(exe, objects)
190
+ end
191
+
192
+ class CxxProject2Rake
193
+
194
+ def initialize(projects)
195
+ register_projects(projects)
196
+ convert_to_rake
197
+ end
198
+
199
+ def register_projects(projects)
200
+ projects.each do |project_file|
201
+ loadContext = Class.new
202
+ loadContext.module_eval(File.read(project_file))
203
+ c = loadContext.new
204
+ raise "no 'define_project' defined in project.rb" unless c.respond_to?(:define_project)
205
+ cd File.dirname(project_file) do | base_dir |
206
+ project = c.define_project
207
+ ALL_BUILDING_BLOCKS[project.name] = project
208
+ project.base = base_dir
209
+ project.to_s
210
+ end
211
+ end
212
+ end
213
+ def convert_to_rake
214
+ ALL_BUILDING_BLOCKS.values.each do |building_block|
215
+ if (building_block.instance_of?(SourceLibrary)) then
216
+ build_source_lib(building_block)
217
+ elsif (building_block.instance_of?(Exe)) then
218
+ build_exe(building_block)
219
+ elsif (building_block.instance_of?(BinaryLibrary)) then
220
+ else
221
+ raise 'unknown building_block'
222
+ end
223
+ end
224
+ task :default => ALL.to_a do
225
+ end
226
+ end
227
+ end
@@ -0,0 +1,19 @@
1
+ require 'cxxproject'
2
+
3
+ describe Dependencies do
4
+ it 'should build the right dependency-chain' do
5
+ lib1 = SourceLibrary.new('1')
6
+ lib2 = SourceLibrary.new('2')
7
+ lib2.dependencies = ['1']
8
+ lib3 = SourceLibrary.new('3')
9
+ lib3.dependencies = ['1']
10
+ lib4 = SourceLibrary.new('4')
11
+ lib4.dependencies = ['2', '3']
12
+ deps = Dependencies.transitive_dependencies(['4'])
13
+ deps.map {|d|d.name}.should == ['4', '2', '3', '1']
14
+ end
15
+ it 'should create .d files' do
16
+ pending
17
+ 1.should == 0
18
+ end
19
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cxxproject
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ version: "0.2"
9
+ platform: ruby
10
+ authors:
11
+ - ""
12
+ autorequire:
13
+ bindir: bin
14
+ cert_chain: []
15
+
16
+ date: 2010-04-09 00:00:00 +02:00
17
+ default_executable:
18
+ dependencies: []
19
+
20
+ description: " Some more high level building blocks for cpp projects.\n"
21
+ email: ""
22
+ executables: []
23
+
24
+ extensions: []
25
+
26
+ extra_rdoc_files: []
27
+
28
+ files:
29
+ - lib/cxxproject/compiler.rb
30
+ - lib/cxxproject/dependencies.rb
31
+ - lib/cxxproject/gcccompiler.rb
32
+ - lib/cxxproject/osxcompiler.rb
33
+ - lib/cxxproject/utils.rb
34
+ - lib/cxxproject.rb
35
+ - Rakefile.rb
36
+ - spec/dependencies_spec.rb
37
+ has_rdoc: true
38
+ homepage: ""
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options: []
43
+
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ segments:
51
+ - 0
52
+ version: "0"
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ requirements: []
61
+
62
+ rubyforge_project:
63
+ rubygems_version: 1.3.6
64
+ signing_key:
65
+ specification_version: 3
66
+ summary: Cpp Support for Rake.
67
+ test_files: []
68
+