cxx 0.1.5

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.
@@ -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: []