cxx 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ pkg
@@ -0,0 +1,3 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ task :package => :build
data/bin/cxx ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'cxx/wizard/project_wizard'
4
+
5
+ if ARGV.size < 1
6
+ puts "usage: cxx project-dir"
7
+ exit 0
8
+ end
9
+ prepare_project(ARGV[0])
@@ -0,0 +1,18 @@
1
+ spec = Gem::Specification.new do |s|
2
+ s.name = 'cxx'
3
+ s.description = 'ruby-based dsl for cxxproject'
4
+ s.summary = 'defines the method cxx_configuration'
5
+ s.version = '0.1.5'
6
+ s.author = 'christian koestlin'
7
+ s.email = 'christian.koestlin@gmail.com'
8
+ s.platform = Gem::Platform::RUBY
9
+ s.files = `git ls-files`.split($\)
10
+ s.require_path = 'lib'
11
+
12
+ s.add_dependency 'cxxproject'
13
+ s.add_dependency 'highline'
14
+
15
+ s.executables = ['cxx']
16
+
17
+ s.has_rdoc = false
18
+ end
@@ -0,0 +1,223 @@
1
+ require 'rubygems'
2
+
3
+ require 'cxxproject/cxxproject'
4
+ require 'logger'
5
+ require 'pp'
6
+ require 'pathname'
7
+ require 'cxxproject/ext/rake'
8
+ require 'cxxproject/buildingblocks/module'
9
+ require 'cxxproject/buildingblocks/makefile'
10
+ require 'cxxproject/buildingblocks/executable'
11
+ require 'cxxproject/buildingblocks/source_library'
12
+ require 'cxxproject/buildingblocks/single_source'
13
+ require 'cxxproject/buildingblocks/binary_library'
14
+ require 'cxxproject/buildingblocks/custom_building_block'
15
+ require 'cxxproject/buildingblocks/command_line'
16
+ require 'cxxproject/toolchain/colorizing_formatter'
17
+ require 'cxxproject/plugin_context'
18
+ require 'cxx/eval_context'
19
+
20
+ module Cxx
21
+
22
+ class RubyDsl
23
+ attr_accessor :base_dir, :all_tasks, :build_dir
24
+
25
+ def initialize(projects, build_dir, toolchain_name, base_dir='.', &option_block)
26
+ @build_dir = build_dir
27
+ option_block.call if option_block
28
+ toolchain = Cxxproject::Toolchain::Provider[toolchain_name]
29
+ raise "no provider with name \"#{toolchain_name}\" found" unless toolchain
30
+ @base_dir = base_dir
31
+ cd(@base_dir, :verbose => false) do
32
+ @projects = projects.to_a
33
+ end
34
+
35
+ # TODO: this should be cleaned up somehow...
36
+ if Cxxproject::Utils::OS.linux?
37
+ toolchain[:LINKER][:LIB_PREFIX_FLAGS] = "-Wl,--whole-archive"
38
+ toolchain[:LINKER][:LIB_POSTFIX_FLAGS] = "-Wl,--no-whole-archive"
39
+ end
40
+
41
+ Rake::application.deriveIncludes = true
42
+
43
+ initialize_logging(build_dir)
44
+ @all_tasks = instantiate_tasks(toolchain, build_dir)
45
+
46
+ create_generic_tasks
47
+ create_console_colorization
48
+ create_multitask
49
+ create_dont_bail_on_first_task
50
+ describe_clean_task
51
+
52
+ load_nontoolchain_plugins
53
+ end
54
+
55
+ def load_nontoolchain_plugins
56
+ registry = Frazzle::Registry.new('cxxproject', '_', '-')
57
+ registry.get_all_plugins.select { |name|name.index('toolchain') == nil }.each do |plugin|
58
+ registry.load_plugin(plugin, Cxxproject::PluginContext.new(self, Cxxproject::ALL_BUILDING_BLOCKS, @log))
59
+ end
60
+ end
61
+
62
+ def initialize_logging(build_dir)
63
+ @log = Logger.new(STDOUT)
64
+ @log.formatter = proc { |severity, datetime, progname, msg|
65
+ "#{severity}: #{msg}\n"
66
+ }
67
+ # Logger loglevels: fatal, error, warn, info, debug
68
+ # Rake --verbose -> info
69
+ # Rake --trace -> debug
70
+ @log.level = Logger::ERROR
71
+ @log.level = Logger::INFO if RakeFileUtils.verbose == true
72
+ @log.level = Logger::DEBUG if Rake::application.options.trace
73
+ @log.debug "initializing for build_dir: \"#{build_dir}\", base_dir: \"#{@base_dir}\""
74
+ end
75
+
76
+ def describe_clean_task
77
+ Rake::Task[:clean].add_description('clean')
78
+ end
79
+
80
+ def create_dont_bail_on_first_task
81
+ desc 'dont bail on first error'
82
+ task :dont_bail_on_first_error do
83
+ Rake::Task.bail_on_first_error = false
84
+ end
85
+ end
86
+
87
+ def create_multitask
88
+ desc 'set parallelization of multitask'
89
+ task :multitask, :threads do |t, args|
90
+ arg = args.threads
91
+ if arg
92
+ Rake::application.max_parallel_tasks = arg.to_i
93
+ end
94
+ end
95
+ end
96
+
97
+ def create_console_colorization
98
+ # default is on
99
+ Cxxproject::ColorizingFormatter.enabled = true
100
+ desc 'Toggle colorization of console output (use true|t|yes|y|1|on for true ... everything else is false)'
101
+ task :toggle_colorize, :on_off do |t, args|
102
+ arg = args[:on_off] || 'false'
103
+ on_off = arg.match(/(true|t|yes|y|1|on)$/) != nil
104
+ Cxxproject::ColorizingFormatter.enabled = on_off
105
+ end
106
+ end
107
+
108
+ def create_generic_tasks
109
+ tasks = [:lib, :exe, :run]
110
+ tasks << nil
111
+ tasks.each { |i| create_filter_task_with_namespace(i) }
112
+ end
113
+
114
+ def create_filter_task_with_namespace(basename)
115
+ if basename
116
+ desc "invoke #{basename} with filter"
117
+ namespace basename do
118
+ create_filter_task("#{basename}:")
119
+ end
120
+ else
121
+ desc 'invoke with filter'
122
+ create_filter_task('')
123
+ end
124
+ end
125
+
126
+ def create_filter_task(basename)
127
+ task :filter, :filter do |t, args|
128
+ filter = ".*"
129
+ if args[:filter]
130
+ filter = "#{args[:filter]}"
131
+ end
132
+ filter = Regexp.new("#{basename}#{filter}")
133
+ Rake::Task.tasks.each do |to_check|
134
+ name = to_check.name
135
+ if ("#{basename}:filter" != name)
136
+ match = filter.match(name)
137
+ if match
138
+ to_check.invoke
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
144
+
145
+ def instantiate_tasks(toolchain, build_dir)
146
+ check_for_project_configs
147
+
148
+ if @log.debug?
149
+ @log.debug "project_configs:"
150
+ @projects.each { |c| @log.debug " * #{c}" }
151
+ end
152
+ register_projects()
153
+ Cxxproject::ALL_BUILDING_BLOCKS.values.each do |block|
154
+ prepare_block(block, toolchain, build_dir)
155
+ end
156
+ Cxxproject::ALL_BUILDING_BLOCKS.values.inject([]) do |memo,block|
157
+ @log.debug "creating tasks for block: #{block.name}/taskname: #{block.get_task_name} (#{block})"
158
+ memo << block.convert_to_rake()
159
+ end
160
+ end
161
+
162
+ def check_for_project_configs
163
+ cd(@base_dir, :verbose => false) do
164
+ @projects.each do |p|
165
+ abort "project config #{p} cannot be found!" unless File.exists?(p)
166
+ end
167
+ end
168
+ end
169
+
170
+ def prepare_block(block, toolchain, build_dir)
171
+ block.set_tcs(toolchain) unless block.has_tcs?
172
+ block.set_output_dir(Dir.pwd + "/" + build_dir)
173
+ block.complete_init()
174
+ end
175
+
176
+ def register_projects()
177
+ cd(@base_dir,:verbose => false) do |b|
178
+ @projects.each_with_index do |project_file, i|
179
+ @log.debug "register project #{project_file}"
180
+ dirname = File.dirname(project_file)
181
+ @log.debug "dirname for project was: #{dirname}"
182
+ cd(dirname,:verbose => false) do | base_dir |
183
+ @log.debug "register project #{project_file} from within directory: #{Dir.pwd}"
184
+ eval_file(b, File.basename(project_file))
185
+ end
186
+ end
187
+ end
188
+ end
189
+
190
+ def eval_file(b, project_file)
191
+ loadContext = EvalContext.new
192
+ begin
193
+ loadContext.eval_project(File.read(File.basename(project_file)), project_file, Dir.pwd)
194
+ rescue Exception => e
195
+ puts "problems with #{File.join(b, project_file)} in dir: #{Dir.pwd}"
196
+ raise e
197
+ end
198
+
199
+ loadContext.all_blocks.each do |block|
200
+ block.
201
+ set_project_dir(Dir.pwd).
202
+ set_config_files([Dir.pwd + "/" + project_file])
203
+ if block.respond_to?(:sources) && block.sources.instance_of?(Rake::FileList)
204
+ block.set_sources(block.sources.to_a)
205
+ end
206
+ end
207
+ end
208
+
209
+ def define_project_info_task
210
+ desc "shows your defined projects"
211
+ task :project_info do
212
+ Cxxproject::ALL_BUILDING_BLOCKS.each_value do |bb|
213
+ pp bb
214
+ end
215
+ end
216
+ end
217
+
218
+ end
219
+ end
220
+
221
+ def cxx(projects, output_dir, toolchain_name, base_dir, &block)
222
+ Cxx::RubyDsl.new(projects, output_dir, toolchain_name, base_dir, &block)
223
+ end
@@ -0,0 +1,126 @@
1
+ require 'cxxproject/context'
2
+ require 'cxxproject/cxxproject'
3
+ require 'cxxproject/utils/utils'
4
+
5
+ module Cxx
6
+ class BinaryLibs
7
+ class << self
8
+ def [](*libs)
9
+ libraries = Array.new
10
+ libs.each do |x|
11
+ libraries << Cxxproject::BinaryLibrary.new(x)
12
+ end
13
+ libraries
14
+ end
15
+ end
16
+ end
17
+
18
+ class EvalContext
19
+ include Cxxproject::Context
20
+
21
+ attr_accessor :all_blocks
22
+
23
+ # must be called to add building blocks
24
+ def cxx_configuration(&block)
25
+ @all_blocks = []
26
+ block.call
27
+ end
28
+
29
+ def eval_project(project_text, project_file, pwd)
30
+ @current_project_file = project_file
31
+ @current_working_dir = pwd
32
+ instance_eval(project_text)
33
+ end
34
+
35
+ # specify an executable
36
+ # hash supports:
37
+ # * :sources
38
+ # * :includes
39
+ # * :dependencies
40
+ # * :libpath
41
+ # * :output_dir
42
+ def exe(name, hash)
43
+ raise "not a hash" unless hash.is_a?(Hash)
44
+ check_hash(hash,[:sources,:includes,:dependencies,:libpath,:output_dir])
45
+ bblock = Cxxproject::Executable.new(name)
46
+ bblock.set_sources(hash[:sources]) if hash.has_key?(:sources)
47
+ bblock.set_includes(get_as_array(hash, :includes)) if hash.has_key?(:includes)
48
+ calc_lib_searchpath(hash).each { |sp| bblock.add_lib_element(Cxxproject::HasLibraries::SEARCH_PATH, sp) }
49
+ if hash.has_key?(:dependencies)
50
+ bblock.set_dependencies(hash[:dependencies])
51
+ hash[:dependencies].each { |d| bblock.add_lib_element(Cxxproject::HasLibraries::DEPENDENCY, d) }
52
+ end
53
+ bblock.set_output_dir(hash[:output_dir]) if hash.has_key?(:output_dir)
54
+ all_blocks << bblock
55
+ end
56
+
57
+ def calc_lib_searchpath(hash)
58
+ if hash.has_key?(:libpath)
59
+ hash[:libpath]
60
+ else
61
+ if Cxxproject::Utils::OS.linux? || Cxxproject::Utils::OS.mac?
62
+ ["/usr/local/lib","/usr/lib"]
63
+ elsif Cxxproject::Utils::OS.windows?
64
+ ["C:/tool/cygwin/lib", "C:/Tool/cygwin/usr/local/lib"]
65
+ end
66
+ end
67
+ end
68
+
69
+ # specify a sourcelib
70
+ # hash supports:
71
+ # * :sources
72
+ # * :includes
73
+ # * :dependencies
74
+ # * :toolchain
75
+ # * :file_dependencies
76
+ # * :output_dir
77
+ def source_lib(name, hash)
78
+ raise "not a hash" unless hash.is_a?(Hash)
79
+ check_hash(hash,[:sources, :includes, :dependencies, :toolchain, :file_dependencies, :output_dir])
80
+ raise ":sources need to be defined" unless hash.has_key?(:sources)
81
+ bblock = Cxxproject::SourceLibrary.new(name)
82
+ bblock.set_sources(hash[:sources])
83
+ bblock.set_includes(get_as_array(hash, :includes)) if hash.has_key?(:includes)
84
+ bblock.set_tcs(hash[:toolchain]) if hash.has_key?(:toolchain)
85
+ if hash.has_key?(:dependencies)
86
+ bblock.set_dependencies(hash[:dependencies])
87
+ hash[:dependencies].each { |d| bblock.add_lib_element(Cxxproject::HasLibraries::DEPENDENCY, d) }
88
+ end
89
+ bblock.file_dependencies = hash[:file_dependencies] if hash.has_key?(:file_dependencies)
90
+ bblock.set_output_dir(hash[:output_dir]) if hash.has_key?(:output_dir)
91
+ all_blocks << bblock
92
+ end
93
+
94
+ # specify some binary libs
95
+ # returns all binary libs as array
96
+ def bin_libs(*names)
97
+ res = []
98
+ mapped = names.map{|n|n.to_s}
99
+ mapped.each do |name|
100
+ res << Cxxproject::BinaryLibrary.new(name)
101
+ end
102
+ mapped
103
+ end
104
+
105
+ def compile(name, hash)
106
+ raise "not a hash" unless hash.is_a?(Hash)
107
+ check_hash(hash,[:sources,:includes])
108
+ bblock = Cxxproject::SingleSource.new(name)
109
+ bblock.set_sources(hash[:sources]) if hash.has_key?(:sources)
110
+ bblock.set_includes(hash[:includes]) if hash.has_key?(:includes)
111
+ all_blocks << bblock
112
+ end
113
+
114
+ def custom(name, hash)
115
+ raise "not a hash" unless hash.is_a?(Hash)
116
+ check_hash(hash,[:execute, :dependencies])
117
+ bblock = Cxxproject::CustomBuildingBlock.new(name)
118
+ bblock.set_actions(hash[:execute]) if hash.has_key?(:execute)
119
+ if hash.has_key?(:dependencies)
120
+ bblock.set_dependencies(hash[:dependencies])
121
+ end
122
+ all_blocks << bblock
123
+ end
124
+
125
+ end
126
+ end
@@ -0,0 +1,11 @@
1
+ require 'cxx'
2
+
3
+ unittest_flags = {
4
+ :DEFINES => ['UNIT_TEST','CPPUNIT_MAIN=main'],
5
+ :FLAGS => "-O0 -g3 -Wall"
6
+ }
7
+
8
+ cxx(Dir['**/project.rb'], 'out', "<%= toolchain %>", './') do
9
+ Provider.modify_cpp_compiler("<%= toolchain %>", unittest_flags)
10
+ end
11
+
@@ -0,0 +1,6 @@
1
+ cxx_configuration do
2
+ <%= building_block %> "<%= name %>",
3
+ :sources => FileList['**/*.cpp'],
4
+ :includes => ['include'],
5
+ :dependencies => []
6
+ end
@@ -0,0 +1,113 @@
1
+ require 'rake'
2
+ require 'erb'
3
+ require 'rubygems'
4
+
5
+ def prepare_project(dir_name)
6
+ begin
7
+ require 'highline/import'
8
+
9
+ say "This will create a new cxx-project in directory: '#{dir_name}'"
10
+ if confirm("Are you sure you want to continue") then
11
+ building_block = choose_building_block
12
+ generate_makefile = confirm("Do you also whant to generate a rakefile", building_block.eql?("exe"))
13
+
14
+ toolchain = nil
15
+ if generate_makefile then
16
+ toolchain = choose_toolchain
17
+ return unless toolchain
18
+ end
19
+
20
+ create_project(dir_name, building_block, toolchain, generate_makefile)
21
+ say "Completed project-setup ;-)"
22
+ else
23
+ say "Stopped project-setup!"
24
+ end
25
+
26
+ rescue Interrupt
27
+ say "\nStopped project-setup!"
28
+ rescue LoadError
29
+ say "Please run 'gem install highline'"
30
+ end
31
+ end
32
+
33
+ def choose_building_block
34
+ res = nil
35
+ choose do |menu|
36
+ say "What building-block do you whant to create?"
37
+ menu.choice(:exe) { res = "exe" }
38
+ menu.choice(:lib) { res = "source_lib" }
39
+ menu.prompt = "Select a building-block: "
40
+ end
41
+ res
42
+ end
43
+
44
+ def choose_toolchain
45
+ res = nil
46
+ toolchains = []
47
+ toolchain_pattern = /cxxproject_(.*)toolchain/
48
+ Gem::Specification.latest_specs.each do |gem|
49
+ if gem.name =~ toolchain_pattern then
50
+ toolchains << $1
51
+ end
52
+ end
53
+ if toolchains.length > 0 then
54
+ choose do |menu|
55
+ say "What toolchain do you whant to use?"
56
+ toolchains.each do |toolchain|
57
+ menu.choice(toolchain.to_sym) { res = toolchain }
58
+ end
59
+ menu.prompt = "Select a toolchain: "
60
+ end
61
+ else
62
+ say "No toolchains installed!"
63
+ candidates = `gem list --remote "cxxproject_.*toolchain"`
64
+ say "You need at least one toolchain-plugin,- candidates are:\n#{candidates}"
65
+ end
66
+ res
67
+ end
68
+
69
+ def create_project(dir_name, building_block, toolchain, generate_rakefile)
70
+ rakefile_template = IO.read(File.join(File.dirname(__FILE__),"Rakefile.rb.template"))
71
+ project_template = IO.read(File.join(File.dirname(__FILE__),"project.rb.template"))
72
+ binding = create_binding("new-item", building_block, toolchain)
73
+
74
+ if !File.directory?(dir_name) then
75
+ mkdir_p(dir_name, :verbose => false)
76
+ end
77
+
78
+ rakefile_file = "#{dir_name}/Rakefile.rb"
79
+ if generate_rakefile && (!File.exists?(rakefile_file) || confirm("Override existing '#{rakefile_file}'")) then
80
+ write_template(rakefile_file, rakefile_template, binding)
81
+ end
82
+
83
+ project_file = "#{dir_name}/project.rb"
84
+ if !File.exists?(project_file) || confirm("Override existing '#{project_file}'") then
85
+ write_template(project_file, project_template, binding)
86
+ end
87
+ end
88
+
89
+ def create_binding(name, building_block, toolchain)
90
+ return binding()
91
+ end
92
+
93
+ def write_template(file_name, template, binding)
94
+ say "...write: '#{file_name}'"
95
+ File.open(file_name, 'w') do |f|
96
+ f.write ERB.new(template).result(binding)
97
+ end
98
+ end
99
+
100
+ def confirm(question, default = true)
101
+ res = nil
102
+ while res == nil
103
+ confirm = ask("#{question}? ") { |q| q.default = default ? "Y/n" : "y/N" }
104
+ if confirm.eql?("Y/n") || confirm.downcase.eql?("yes") || confirm.downcase.eql?("y") then
105
+ res = true
106
+ elsif confirm.eql?("y/N") || confirm.downcase.eql?("no") || confirm.downcase.eql?("n") then
107
+ res = false
108
+ else
109
+ say "Please enter \"yes\" or \"no\"."
110
+ end
111
+ end
112
+ return res
113
+ end
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cxx
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.5
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - christian koestlin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-16 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: cxxproject
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: highline
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: ruby-based dsl for cxxproject
47
+ email: christian.koestlin@gmail.com
48
+ executables:
49
+ - cxx
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - Rakefile.rb
55
+ - bin/cxx
56
+ - cxx.gemspec
57
+ - lib/cxx.rb
58
+ - lib/cxx/eval_context.rb
59
+ - lib/cxx/wizard/Rakefile.rb.template
60
+ - lib/cxx/wizard/project.rb.template
61
+ - lib/cxx/wizard/project_wizard.rb
62
+ homepage:
63
+ licenses: []
64
+ post_install_message:
65
+ rdoc_options: []
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ! '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ requirements: []
81
+ rubyforge_project:
82
+ rubygems_version: 1.8.24
83
+ signing_key:
84
+ specification_version: 3
85
+ summary: defines the method cxx_configuration
86
+ test_files: []