comet-build 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +59 -0
- data/.rspec +1 -0
- data/.rubocop.yml +14 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +58 -0
- data/LICENSE +9 -0
- data/README.md +311 -0
- data/Rakefile +1 -0
- data/bin/comet +30 -0
- data/comet-build.gemspec +26 -0
- data/lib/comet/dsl/bin_output.rb +19 -0
- data/lib/comet/dsl/c/source.rb +57 -0
- data/lib/comet/dsl/cpp/source.rb +57 -0
- data/lib/comet/dsl/elf_output.rb +19 -0
- data/lib/comet/dsl/firmware.rb +65 -0
- data/lib/comet/dsl/hardware.rb +56 -0
- data/lib/comet/dsl/helpers.rb +9 -0
- data/lib/comet/dsl/hex_output.rb +19 -0
- data/lib/comet/dsl/include_walker.rb +42 -0
- data/lib/comet/dsl/library.rb +21 -0
- data/lib/comet/dsl/linker.rb +45 -0
- data/lib/comet/dsl/map_output.rb +19 -0
- data/lib/comet/dsl/native/source.rb +44 -0
- data/lib/comet/dsl/options.rb +44 -0
- data/lib/comet/dsl/software.rb +42 -0
- data/lib/comet/dsl/source.rb +24 -0
- data/lib/comet/dsl/target.rb +64 -0
- data/lib/comet/makefile.rb +129 -0
- data/lib/comet/parser.rb +114 -0
- data/lib/comet/rules/alias.rb +29 -0
- data/lib/comet/rules/build.rb +118 -0
- data/lib/comet/rules/clean.rb +29 -0
- data/lib/comet/rules/codegen.rb +51 -0
- data/lib/comet/rules/compile.rb +72 -0
- data/lib/comet/rules/error.rb +33 -0
- data/lib/comet/rules/link.rb +74 -0
- data/lib/comet/rules/merge.rb +37 -0
- data/lib/comet/rules/objcopy.rb +41 -0
- data/lib/comet/rules/tmpdir.rb +39 -0
- data/lib/comet/version.rb +3 -0
- data/lib/comet.rb +76 -0
- data/spec/comet/complex_c_program/Makefile +57 -0
- data/spec/comet/complex_c_program/comet.rb +43 -0
- data/spec/comet/complex_c_program/include/public_api.h +2 -0
- data/spec/comet/complex_c_program/src/common.h +3 -0
- data/spec/comet/complex_c_program/src/library.h +2 -0
- data/spec/comet/complex_c_program/src/main.c +6 -0
- data/spec/comet/complex_c_program/src/module_a/impl.c +1 -0
- data/spec/comet/complex_c_program/src/module_a/impl.h +1 -0
- data/spec/comet/complex_c_program/src/module_b/impl.c +1 -0
- data/spec/comet/complex_c_program/src/module_b/impl.h +1 -0
- data/spec/comet/empty_build_file/Makefile +10 -0
- data/spec/comet/empty_build_file/comet.rb +0 -0
- data/spec/comet/empty_build_file/folder/.keep +0 -0
- data/spec/comet/generator_spec.rb +67 -0
- data/spec/comet/nested_circular_reference/Makefile +5 -0
- data/spec/comet/nested_circular_reference/comet.rb +8 -0
- data/spec/comet/no_build_file/Makefile +5 -0
- data/spec/comet/self_referential/Makefile +5 -0
- data/spec/comet/self_referential/comet.rb +5 -0
- data/spec/comet/simple_c_program/Makefile +30 -0
- data/spec/comet/simple_c_program/comet.rb +15 -0
- data/spec/comet/simple_c_program/main.c +5 -0
- data/spec/comet/simple_c_program/stuff.h +0 -0
- metadata +215 -0
data/lib/comet/parser.rb
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
module Comet
|
2
|
+
class Parser
|
3
|
+
include Comet::DSL::Helpers
|
4
|
+
alias inject instance_exec
|
5
|
+
|
6
|
+
def software(name, depends:, &block)
|
7
|
+
raise "software `#{name}' redefined" if @software.key? name
|
8
|
+
@software[name] = DSL::Software.new(name, depends: depends, &block)
|
9
|
+
end
|
10
|
+
|
11
|
+
def hardware(name, targets:, &block)
|
12
|
+
if hardware_defined? name, targets
|
13
|
+
raise "hardware `#{name}' redefined for `#{targets}'"
|
14
|
+
end
|
15
|
+
@hardware[name].push DSL::Hardware.new(name, targets: targets, &block)
|
16
|
+
end
|
17
|
+
|
18
|
+
def firmware(name, imports:, &block)
|
19
|
+
raise "firmware `#{name}' redefined" if firmware_defined? name
|
20
|
+
@firmware.push DSL::Firmware.new(name, imports: imports, &block)
|
21
|
+
end
|
22
|
+
|
23
|
+
def array_hash
|
24
|
+
Hash.new { |h, k| h[k] = [] }
|
25
|
+
end
|
26
|
+
|
27
|
+
def plain_hash
|
28
|
+
{}
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize(filename)
|
32
|
+
@software = plain_hash
|
33
|
+
@hardware = array_hash
|
34
|
+
@firmware = []
|
35
|
+
@filename = filename
|
36
|
+
end
|
37
|
+
|
38
|
+
attr_reader :filename
|
39
|
+
|
40
|
+
def targets
|
41
|
+
parse_file! if @targets.nil?
|
42
|
+
@targets ||= compute_targets
|
43
|
+
end
|
44
|
+
|
45
|
+
def compute_targets
|
46
|
+
@firmware.flat_map do |firmware|
|
47
|
+
firmware.validate!
|
48
|
+
|
49
|
+
firmware.targets.map do |device|
|
50
|
+
[firmware, device]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def resolve_dependencies!(firmware)
|
58
|
+
seen = {}
|
59
|
+
|
60
|
+
firmware.imports = firmware.imports.flat_map do |name|
|
61
|
+
resolve! name, seen
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def resolve!(name, seen)
|
66
|
+
if seen[name] == :temporary
|
67
|
+
raise "circular dependency involving `#{name}' detected"
|
68
|
+
end
|
69
|
+
|
70
|
+
object = object_by_name name
|
71
|
+
return object if seen[name] == :permanent
|
72
|
+
resolve_software! name, object, seen if @software.key? name
|
73
|
+
seen[name] = :permanent
|
74
|
+
|
75
|
+
object
|
76
|
+
end
|
77
|
+
|
78
|
+
def resolve_software!(name, software, seen)
|
79
|
+
seen[name] = :temporary
|
80
|
+
software.depends = software.depends.flat_map do |dependency|
|
81
|
+
resolve! dependency, seen
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def object_by_name(name)
|
86
|
+
if @software[name].nil? && @hardware[name].empty?
|
87
|
+
raise "software or hardware `#{name}' undefined"
|
88
|
+
end
|
89
|
+
|
90
|
+
@software[name] || @hardware[name]
|
91
|
+
end
|
92
|
+
|
93
|
+
def resolve_all_dependencies!
|
94
|
+
@firmware.each do |firmware|
|
95
|
+
resolve_dependencies! firmware
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def parse_file!
|
100
|
+
instance_eval File.read(@filename)
|
101
|
+
resolve_all_dependencies!
|
102
|
+
end
|
103
|
+
|
104
|
+
def hardware_defined?(name, targets)
|
105
|
+
@hardware[name].any? do |hardware|
|
106
|
+
hardware.targets == targets
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def firmware_defined?(name)
|
111
|
+
@firmware.map(&:name).include? name
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Comet
|
2
|
+
module Rules
|
3
|
+
class Alias
|
4
|
+
def initialize(name, dependencies)
|
5
|
+
@name = name
|
6
|
+
@dependencies = dependencies
|
7
|
+
end
|
8
|
+
|
9
|
+
def target
|
10
|
+
@name
|
11
|
+
end
|
12
|
+
|
13
|
+
def contents
|
14
|
+
[
|
15
|
+
".PHONY: #{target}",
|
16
|
+
"#{target}: #{@dependencies.map(&:target).uniq.join ' '}"
|
17
|
+
]
|
18
|
+
end
|
19
|
+
|
20
|
+
def rules
|
21
|
+
[]
|
22
|
+
end
|
23
|
+
|
24
|
+
def commands
|
25
|
+
{}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module Comet
|
2
|
+
module Rules
|
3
|
+
class Build
|
4
|
+
def initialize(firmware, device)
|
5
|
+
@firmware = firmware
|
6
|
+
@device = device
|
7
|
+
end
|
8
|
+
|
9
|
+
def target
|
10
|
+
@target ||= Comet::Makefile.fingerprint Hash[
|
11
|
+
dependencies: Set[rules.map(&:target).uniq]
|
12
|
+
], extension: :phony
|
13
|
+
end
|
14
|
+
|
15
|
+
def contents
|
16
|
+
contents = [
|
17
|
+
".PHONY: #{target}",
|
18
|
+
"#{target}: #{rules.map(&:target).uniq.join ' '}"
|
19
|
+
]
|
20
|
+
|
21
|
+
if fw_target.elf?
|
22
|
+
contents.push "\t$(COMET_CP) #{link.target} #{fw_target.elf_output.path}"
|
23
|
+
end
|
24
|
+
|
25
|
+
if fw_target.bin?
|
26
|
+
contents.push "\t$(COMET_CP) #{bin.target} #{fw_target.bin_output.path}"
|
27
|
+
end
|
28
|
+
|
29
|
+
if fw_target.hex?
|
30
|
+
contents.push "\t$(COMET_CP) #{hex.target} #{fw_target.hex_output.path}"
|
31
|
+
end
|
32
|
+
|
33
|
+
if fw_target.map?
|
34
|
+
contents.push "\t$(COMET_CP) #{link.map_file} #{fw_target.map_output.path}"
|
35
|
+
end
|
36
|
+
|
37
|
+
contents
|
38
|
+
end
|
39
|
+
|
40
|
+
def rules
|
41
|
+
@rules ||= [link, bin, hex].compact
|
42
|
+
end
|
43
|
+
|
44
|
+
def commands
|
45
|
+
{ COMET_CP: 'cp' }
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def fw_target
|
51
|
+
@firmware.target_for @device
|
52
|
+
end
|
53
|
+
|
54
|
+
def bin
|
55
|
+
ObjCopy.new linker, link, 'binary', 'bin' if fw_target.bin?
|
56
|
+
end
|
57
|
+
|
58
|
+
def hex
|
59
|
+
ObjCopy.new linker, link, 'ihex', 'hex' if fw_target.hex?
|
60
|
+
end
|
61
|
+
|
62
|
+
def link
|
63
|
+
@link ||= Link.new linker, codegen, libraries, native_sources
|
64
|
+
end
|
65
|
+
|
66
|
+
def linker
|
67
|
+
@firmware.hardware_for(@device).detect(&:linker?).linker_
|
68
|
+
end
|
69
|
+
|
70
|
+
def native_sources
|
71
|
+
@firmware.hardware_for(@device).flat_map do |hardware|
|
72
|
+
hardware.sources.select(&:native?).flat_map(&:files)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def libraries
|
77
|
+
@firmware.hardware_for(@device).flat_map(&:libraries).uniq(&:name)
|
78
|
+
end
|
79
|
+
|
80
|
+
def codegen
|
81
|
+
@codegen ||= Codegen.new linker, merge
|
82
|
+
end
|
83
|
+
|
84
|
+
def merge
|
85
|
+
@merge ||= Merge.new compile
|
86
|
+
end
|
87
|
+
|
88
|
+
def compile
|
89
|
+
@compile ||= @firmware.imports.flat_map do |software|
|
90
|
+
compile_software software
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def compile_software(software)
|
95
|
+
software.depends.flat_map do |depends|
|
96
|
+
if depends.is_a? Comet::DSL::Software
|
97
|
+
compile_software depends
|
98
|
+
else
|
99
|
+
compile_hardware depends
|
100
|
+
end
|
101
|
+
end + software.sources.reject(&:native?).flat_map do |source|
|
102
|
+
source.files.map do |file|
|
103
|
+
Compile.new source, file, linker
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def compile_hardware(hardware)
|
109
|
+
return [] unless hardware.targets == @device
|
110
|
+
hardware.sources.reject(&:native?).flat_map do |source|
|
111
|
+
source.files.map do |file|
|
112
|
+
Compile.new source, file, linker
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Comet
|
2
|
+
module Rules
|
3
|
+
class Clean
|
4
|
+
def initialize(folder)
|
5
|
+
@folder = folder
|
6
|
+
end
|
7
|
+
|
8
|
+
def target
|
9
|
+
'clean'
|
10
|
+
end
|
11
|
+
|
12
|
+
def contents
|
13
|
+
[
|
14
|
+
".PHONY: #{target}",
|
15
|
+
"#{target}:",
|
16
|
+
"\t$(COMET_RM) -rf #{@folder}"
|
17
|
+
]
|
18
|
+
end
|
19
|
+
|
20
|
+
def rules
|
21
|
+
[]
|
22
|
+
end
|
23
|
+
|
24
|
+
def commands
|
25
|
+
{ COMET_RM: 'rm' }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Comet
|
2
|
+
module Rules
|
3
|
+
class Codegen
|
4
|
+
def initialize(linker, bitcode)
|
5
|
+
@linker = linker
|
6
|
+
@bitcode = bitcode
|
7
|
+
end
|
8
|
+
|
9
|
+
def target
|
10
|
+
@target ||= Comet::Makefile.fingerprint Hash[
|
11
|
+
command: clang_link_command,
|
12
|
+
target: @bitcode.target,
|
13
|
+
triple: @linker.triple,
|
14
|
+
isa: @linker.isa,
|
15
|
+
cpu: @linker.cpu,
|
16
|
+
opt: @linker.opt
|
17
|
+
], extension: :s
|
18
|
+
end
|
19
|
+
|
20
|
+
def contents
|
21
|
+
[
|
22
|
+
"#{target}: #{@bitcode.target} | #{Comet::TMPDIR}",
|
23
|
+
"\t#{llvm_codegen} -o $@ $<"
|
24
|
+
]
|
25
|
+
end
|
26
|
+
|
27
|
+
def rules
|
28
|
+
@rules ||= [@bitcode]
|
29
|
+
end
|
30
|
+
|
31
|
+
def commands
|
32
|
+
{ COMET_OPT: 'clang' }
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def llvm_codegen
|
38
|
+
[
|
39
|
+
*clang_link_command,
|
40
|
+
"--target=#{@linker.triple}",
|
41
|
+
"-march=#{@linker.isa}",
|
42
|
+
"-mcpu=#{@linker.cpu}"
|
43
|
+
].join ' '
|
44
|
+
end
|
45
|
+
|
46
|
+
def clang_link_command
|
47
|
+
['$(COMET_OPT)', '-S', "-O#{@linker.opt}"]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Comet
|
2
|
+
module Rules
|
3
|
+
class Compile
|
4
|
+
def initialize(source, file, linker)
|
5
|
+
@source = source
|
6
|
+
@file = file
|
7
|
+
@linker = linker
|
8
|
+
end
|
9
|
+
|
10
|
+
def target
|
11
|
+
@target ||= Comet::Makefile.fingerprint Hash[
|
12
|
+
file: @file,
|
13
|
+
triple: @linker.triple,
|
14
|
+
isa: @linker.isa,
|
15
|
+
cpu: @linker.cpu,
|
16
|
+
flags: Set[formatted_flags],
|
17
|
+
headers: formatted_headers,
|
18
|
+
dependencies: Set[dependencies]
|
19
|
+
], extension: :ll
|
20
|
+
end
|
21
|
+
|
22
|
+
def contents
|
23
|
+
[
|
24
|
+
"#{target}: #{@file} #{dependencies.join ' '} | #{Comet::TMPDIR}",
|
25
|
+
"\t#{clang_compile} #{formatted_flags.join ' '} -o $@ -c $<"
|
26
|
+
]
|
27
|
+
end
|
28
|
+
|
29
|
+
def rules
|
30
|
+
[]
|
31
|
+
end
|
32
|
+
|
33
|
+
def commands
|
34
|
+
{ COMET_CC: 'clang' }
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def formatted_flags
|
40
|
+
@formatted_flags ||= @source.options.format
|
41
|
+
end
|
42
|
+
|
43
|
+
def dependencies
|
44
|
+
@dependencies ||= find_dependencies
|
45
|
+
end
|
46
|
+
|
47
|
+
def find_dependencies
|
48
|
+
Comet::DSL::IncludeWalker.includes_for(@file, @source.headers)
|
49
|
+
end
|
50
|
+
|
51
|
+
def clang_compile
|
52
|
+
[
|
53
|
+
'$(COMET_CC)',
|
54
|
+
'-x',
|
55
|
+
'c',
|
56
|
+
"--target=#{@linker.triple}",
|
57
|
+
"-march=#{@linker.isa}",
|
58
|
+
"-mcpu=#{@linker.cpu}",
|
59
|
+
'-S',
|
60
|
+
'-flto',
|
61
|
+
*formatted_headers
|
62
|
+
].join ' '
|
63
|
+
end
|
64
|
+
|
65
|
+
def formatted_headers
|
66
|
+
@source.headers.map do |header|
|
67
|
+
"-I#{header}"
|
68
|
+
end.join
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Comet
|
2
|
+
module Rules
|
3
|
+
class Error
|
4
|
+
def initialize(message)
|
5
|
+
@message = message
|
6
|
+
end
|
7
|
+
|
8
|
+
def target
|
9
|
+
nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def contents
|
13
|
+
["$(error #{pretty_message})"]
|
14
|
+
end
|
15
|
+
|
16
|
+
def rules
|
17
|
+
[]
|
18
|
+
end
|
19
|
+
|
20
|
+
def commands
|
21
|
+
{}
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def pretty_message
|
27
|
+
words = @message.split
|
28
|
+
words.first.capitalize!
|
29
|
+
words.join ' '
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Comet
|
2
|
+
module Rules
|
3
|
+
class Link
|
4
|
+
def initialize(linker, dependency, libraries, native_sources)
|
5
|
+
@linker = linker
|
6
|
+
@dependency = dependency
|
7
|
+
@libraries = libraries
|
8
|
+
@native_sources = native_sources
|
9
|
+
end
|
10
|
+
|
11
|
+
def target
|
12
|
+
@target ||= Comet::Makefile.fingerprint Hash[
|
13
|
+
dependency: @dependency.target,
|
14
|
+
triple: @linker.triple,
|
15
|
+
isa: @linker.isa,
|
16
|
+
cpu: @linker.cpu,
|
17
|
+
script: @linker.script_,
|
18
|
+
libraries: formatted_libraries,
|
19
|
+
native_sources: @native_sources,
|
20
|
+
flags: formatted_flags
|
21
|
+
], extension: :elf
|
22
|
+
end
|
23
|
+
|
24
|
+
def map_file
|
25
|
+
target.gsub(/.elf$/, '.map')
|
26
|
+
end
|
27
|
+
|
28
|
+
def contents
|
29
|
+
[
|
30
|
+
"#{target}: #{@dependency.target} #{@native_sources.join ' '} | #{Comet::TMPDIR}",
|
31
|
+
"\t#{clang_link} #{formatted_script} #{formatted_flags.join ' '} -Wl,-Map=#{map_file} -o $@ $^ #{formatted_libraries}"
|
32
|
+
]
|
33
|
+
end
|
34
|
+
|
35
|
+
def rules
|
36
|
+
[@dependency]
|
37
|
+
end
|
38
|
+
|
39
|
+
def commands
|
40
|
+
{ COMET_LD: 'clang' }
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def formatted_script
|
46
|
+
return '' if @linker.script_.nil?
|
47
|
+
"-T#{@linker.script_}"
|
48
|
+
end
|
49
|
+
|
50
|
+
def formatted_flags
|
51
|
+
@formatted_flags ||= @linker.options.format
|
52
|
+
end
|
53
|
+
|
54
|
+
def clang_link
|
55
|
+
[
|
56
|
+
'$(COMET_LD)',
|
57
|
+
"--target=#{@linker.triple}",
|
58
|
+
"-march=#{@linker.isa}",
|
59
|
+
"-mcpu=#{@linker.cpu}"
|
60
|
+
].join ' '
|
61
|
+
end
|
62
|
+
|
63
|
+
def formatted_libraries
|
64
|
+
@libraries.flat_map do |library|
|
65
|
+
if library.path.nil?
|
66
|
+
"-l#{library.name}"
|
67
|
+
else
|
68
|
+
["-L#{File.join library.path, library.name}"]
|
69
|
+
end
|
70
|
+
end.join ' '
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Comet
|
2
|
+
module Rules
|
3
|
+
class Merge
|
4
|
+
def initialize(dependencies)
|
5
|
+
@dependencies = dependencies
|
6
|
+
end
|
7
|
+
|
8
|
+
def target
|
9
|
+
@target ||= Comet::Makefile.fingerprint Hash[
|
10
|
+
command: llvm_link,
|
11
|
+
dependencies: Set[@dependencies.map(&:target).uniq]
|
12
|
+
], extension: :ll
|
13
|
+
end
|
14
|
+
|
15
|
+
def contents
|
16
|
+
[
|
17
|
+
"#{target}: #{@dependencies.map(&:target).uniq.join ' '} | #{Comet::TMPDIR}",
|
18
|
+
"\t#{llvm_link.join ' '} -o $@ $^"
|
19
|
+
]
|
20
|
+
end
|
21
|
+
|
22
|
+
def rules
|
23
|
+
@dependencies
|
24
|
+
end
|
25
|
+
|
26
|
+
def commands
|
27
|
+
{ COMET_LINK: 'llvm-link' }
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def llvm_link
|
33
|
+
['$(COMET_LINK)', '-S']
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Comet
|
2
|
+
module Rules
|
3
|
+
class ObjCopy
|
4
|
+
def initialize(linker, elf, format, extension)
|
5
|
+
@linker = linker
|
6
|
+
@elf = elf
|
7
|
+
@format = format
|
8
|
+
@extension = extension
|
9
|
+
end
|
10
|
+
|
11
|
+
def target
|
12
|
+
@target ||= Comet::Makefile.fingerprint Hash[
|
13
|
+
triple: @linker.triple,
|
14
|
+
format: @format,
|
15
|
+
elf: @elf.target
|
16
|
+
], extension: @extension
|
17
|
+
end
|
18
|
+
|
19
|
+
def contents
|
20
|
+
[
|
21
|
+
"#{target}: #{@elf.target} | #{Comet::TMPDIR}",
|
22
|
+
"\t#{objcopy}"
|
23
|
+
]
|
24
|
+
end
|
25
|
+
|
26
|
+
def rules
|
27
|
+
[@elf]
|
28
|
+
end
|
29
|
+
|
30
|
+
def commands
|
31
|
+
{ COMET_OBJCOPY: 'objcopy' }
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def objcopy
|
37
|
+
Comet::Makefile.select_command "#{@linker.triple}-$(COMET_OBJCOPY)", '$(COMET_OBJCOPY)', ['-O', @format, '$<', '$@']
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Comet
|
2
|
+
module Rules
|
3
|
+
class TmpDir
|
4
|
+
def target
|
5
|
+
Comet::TMPDIR
|
6
|
+
end
|
7
|
+
|
8
|
+
def contents
|
9
|
+
[
|
10
|
+
".PHONY: #{target}",
|
11
|
+
"#{target}:",
|
12
|
+
"\tif #{exists?} || #{valid?}; then #{create}; fi"
|
13
|
+
]
|
14
|
+
end
|
15
|
+
|
16
|
+
def rules
|
17
|
+
[]
|
18
|
+
end
|
19
|
+
|
20
|
+
def commands
|
21
|
+
{ COMET_LN: 'ln' }
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def exists?
|
27
|
+
'[ ! -d "$@" ]'
|
28
|
+
end
|
29
|
+
|
30
|
+
def valid?
|
31
|
+
"[ ! -d \"`readlink #{target}`\" ]"
|
32
|
+
end
|
33
|
+
|
34
|
+
def create
|
35
|
+
'$(COMET_LN) -sf `mktemp -d` $@'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|