Class: Mkduino::MakefileAm

Inherits:
GeneratedFile show all
Defined in:
lib/makefile_am.rb

Instance Attribute Summary collapse

Attributes inherited from GeneratedFile

#backup_directory, #output_directory, #output_filename, #user_updates_file

Instance Method Summary collapse

Methods inherited from GeneratedFile

#apply_user_updates, #save_file, #save_user_updates, #write_file

Constructor Details

#initialize(output_filename, options) ⇒ MakefileAm

Returns a new instance of MakefileAm.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/makefile_am.rb', line 38

def initialize output_filename, options
  super output_filename, options
  @project_dir =  Dir.pwd
  @project_name = File.basename @project_dir
  @project_name.tr!('.-','__')
  @source_files = []
  @header_files = []
  @project_includes = ["."]
  @arduino_sources = []
  @arduino_includes = []
  @arduino_libraries = []
  @project_author = {}
  @git_project = nil

  @options = options
  @mcu = @options[:mcu] || "atmega328p"
  @clock_speed = @options[:clock_speed] || "16000000"
  @variant = @options[:variant] || "standard"
  @device = @options[:device] || "/dev/USB0"
  @baud_rate = @options[:baud_rate] || "57600"
  @programmer = @options[:programmer] || "arduino"

  @common_libraries = ['arduino', 'spi','wire']
  @libraries_to_skip = {
    'standard' => ['Esplora','GSM','Robot_Control','Robot_Motor','TFT','robot', 'WiFi'],
    'mega' => ['Esplora','GSM','Robot_Control','Robot_Motor','TFT','robot', 'WiFi']
  }
  @project_author[:username] = ENV['USERNAME']
  git_exists = `which git`.chomp
  if git_exists &&  git_exists.length > 0
    @project_author[:name] = `git config --get user.name`.chomp
    @project_author[:email] = `git config --get user.email`.chomp
    @git_project = `git remote show -n origin 2> /dev/null | grep 'Fetch URL:' | cut -f 5 -d ' '`.chomp
  else
    @project_author[:name] = @project_author[:username]
    @project_author[:email]= @project_author[:username]
    @git_project = "no_git_project"
  end
end

Instance Attribute Details

#arduino_sourcesObject

Returns the value of attribute arduino_sources.



28
29
30
# File 'lib/makefile_am.rb', line 28

def arduino_sources
  @arduino_sources
end

#baud_rateObject

Returns the value of attribute baud_rate.



32
33
34
# File 'lib/makefile_am.rb', line 32

def baud_rate
  @baud_rate
end

#clock_speedObject

Returns the value of attribute clock_speed.



32
33
34
# File 'lib/makefile_am.rb', line 32

def clock_speed
  @clock_speed
end

#common_includesObject

output the Makefile.am macro needed for some include files from libraries that are apparently always needed



119
120
121
# File 'lib/makefile_am.rb', line 119

def common_includes
  @common_includes
end

#deviceObject

Returns the value of attribute device.



32
33
34
# File 'lib/makefile_am.rb', line 32

def device
  @device
end

#git_projectObject

future stuff



35
36
37
# File 'lib/makefile_am.rb', line 35

def git_project
  @git_project
end

#header_filesObject

Returns the value of attribute header_files.



28
29
30
# File 'lib/makefile_am.rb', line 28

def header_files
  @header_files
end

#mcuObject

Returns the value of attribute mcu.



32
33
34
# File 'lib/makefile_am.rb', line 32

def mcu
  @mcu
end

#programmerObject

Returns the value of attribute programmer.



32
33
34
# File 'lib/makefile_am.rb', line 32

def programmer
  @programmer
end

#project_authorObject

Returns the value of attribute project_author.



29
30
31
# File 'lib/makefile_am.rb', line 29

def project_author
  @project_author
end

#project_dirObject

Returns the value of attribute project_dir.



29
30
31
# File 'lib/makefile_am.rb', line 29

def project_dir
  @project_dir
end

#project_includesObject

Returns the value of attribute project_includes.



30
31
32
# File 'lib/makefile_am.rb', line 30

def project_includes
  @project_includes
end

#project_nameObject

Returns the value of attribute project_name.



29
30
31
# File 'lib/makefile_am.rb', line 29

def project_name
  @project_name
end

#source_filesObject

Returns the value of attribute source_files.



28
29
30
# File 'lib/makefile_am.rb', line 28

def source_files
  @source_files
end

#variantObject

Returns the value of attribute variant.



32
33
34
# File 'lib/makefile_am.rb', line 32

def variant
  @variant
end

Instance Method Details

#add_arduino_library(library) ⇒ Object

As libraries are found, add them to our collection if they’re not already there



100
101
102
# File 'lib/makefile_am.rb', line 100

def add_arduino_library library
  @arduino_libraries << library  if !arduino_library library
end

#add_header_file(file) ⇒ Object



84
85
86
# File 'lib/makefile_am.rb', line 84

def add_header_file(file)
  @header_files << "../" + Pathname.new(file).relative_path_from(Pathname.new(@project_dir)).to_s
end

#add_include_path(file) ⇒ Object



88
89
90
91
92
93
# File 'lib/makefile_am.rb', line 88

def add_include_path file
  pn = Pathname.new(file)
  puts "!! ******** File #{file} not found ******** " unless pn.exist?
  include_dir = pn.file? ? pn.dirname : file
  @project_includes << include_dir.to_s unless @project_includes.include? include_dir.to_s
end

#add_source_file(file) ⇒ Object

Add a source file that we found in this directory



81
82
83
# File 'lib/makefile_am.rb', line 81

def add_source_file(file)
  @source_files << "../" + Pathname.new(file).relative_path_from(Pathname.new(@project_dir)).to_s
end

#arduino_library(library) ⇒ Object

fetch a library from our collection - nil if not there



108
109
110
111
112
113
# File 'lib/makefile_am.rb', line 108

def arduino_library library
  @arduino_libraries.each do |l|
    return l if l.name == library
  end
  nil
end

#arduino_library_namesObject

output a list of all the libraries that are needed here for Makefile.am. The project will depend on these



138
139
140
141
142
# File 'lib/makefile_am.rb', line 138

def arduino_library_names
  @arduino_libraries.collect do |l|
    l.library_name
  end
end

#arduino_linker_entriesObject

return the linker entries for all of the libraries that we know about



148
149
150
151
152
# File 'lib/makefile_am.rb', line 148

def arduino_linker_entries
  @arduino_libraries.collect do |l|
    "-l#{l.linker_name}"
  end
end

#find_arduino_libraries(libraries_dir) ⇒ Object



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/makefile_am.rb', line 174

def find_arduino_libraries libraries_dir
  lib = nil
  Find.find(libraries_dir) do |path|
    if FileTest.directory?(path)
      if File.basename(path)[0] == ?. || File.basename(path) == 'examples' ||
          (@libraries_to_skip[@variant] && @libraries_to_skip[@variant].include?(File.basename(path)) )
        Find.prune       # Don't look any further into this directory.
      else
        if File.dirname(path) == libraries_dir
          lib_name = path.split('/')[-1]
          lib = arduino_library(lib_name) || ArduinoLibrary.new(lib_name)
          add_arduino_library lib
        end
        next
      end
    elsif path =~ source_file_pattern
      lib.add_source_file path
    elsif path =~ header_file_pattern
      lib.add_include_path path
    end
  end
end

#find_source_filesObject



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
# File 'lib/makefile_am.rb', line 197

def find_source_files
  #
  # Root around for some source file
  # and add them to the Makefile.am
  #
  Find.find(Dir.pwd) do |path|
    if FileTest.directory?(path)
      if File.basename(path)[0] == ?.
        Find.prune       # Don't look any further into this directory.
      else
        next
      end
    elsif path =~ source_file_pattern
      add_source_file path
    elsif path =~ header_file_pattern
      add_header_file path
      add_include_path path

    end
  end

  #
  # If no source files were found, make
  # the src/ directory and put in a
  # sample main.cpp file
  #
  if source_files.length < 1
    `mkdir src`  unless Dir.exist?('src')
    File.open('src/main.cpp',"w") do |f|
      f.puts <<-MAIN_CPP
#include <Arduino.h>

extern "C" void __cxa_pure_virtual(void) {
while(1);
}

void setup() {
  Serial.begin(115200);
  Serial.println("Startup...");
}

void loop() {
}



int main(void)
{
  init();
  setup();
  for (;;){
loop();
  }
  return 0;
}
MAIN_CPP
    end
    add_source_file project_dir + '/src/main.cpp'
  end
end

#header_file_patternObject



130
131
132
# File 'lib/makefile_am.rb', line 130

def header_file_pattern
  /\.([h])(pp|)$/
end

#output_arduino_librariesObject

after finding all of the Arduino libraries, go through each one of them asking them to output themselves.



159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/makefile_am.rb', line 159

def output_arduino_libraries
  output = @arduino_libraries.collect do |l|
    l.makefile_am_output
  end.join("\n")
  #
  # After all of the library compile lines are output, output
  # a comprehensive list of all of the include directories associated
  # with the libraries.   Used for the source project
  #
  output += "\nLIBRARY_INCLUDES="
  output += @arduino_libraries.collect do |l|
    "$(lib#{l.name}_a_INCLUDES)"
  end.join(' ')
end

#source_file_patternObject



126
127
128
# File 'lib/makefile_am.rb', line 126

def source_file_pattern
  /\.([c])(pp|)$/
end

#write_makefile_amObject



261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
# File 'lib/makefile_am.rb', line 261

def write_makefile_am
  puts "Writing #{@output_file}"
  write_file do |f|
    f.puts <<-MAKEFILE_AM
## Process this file with automake to produce Makefile.in
bin_PROGRAMS=#{self.project_name}

MCU=#{self.mcu}
F_CPU=-DF_CPU=#{self.clock_speed}
ARDUINO_VERSION=-DARDUINO=105
ARDUINO_INSTALL=/usr/share/arduino/hardware/arduino
ARDUINO_CORES=$(ARDUINO_INSTALL)/cores/arduino
ARDUINO_VARIANTS=$(ARDUINO_INSTALL)/variants/#{self.variant}
ARDUINO_COMMON_INCLUDES=#{self.common_includes}
ARDUINO_INCLUDE_PATH=-I$(ARDUINO_VARIANTS) $(LIBRARY_INCLUDES)
nodist_#{self.project_name}_SOURCES=#{self.source_files.join(' ')}

#{self.project_name}_CFLAGS=-Wall $(#{self.project_name}_INCLUDES) $(ARDUINO_INCLUDE_PATH) -Wl,--gc-sections -fno-caller-saves -ffunction-sections -fdata-sections -gstabs -mmcu=$(MCU) $(F_CPU) $(ARDUINO_VERSION) -D__AVR_LIBC_DEPRECATED_ENABLE__
#{self.project_name}_CXXFLAGS=-Wall $(#{self.project_name}_INCLUDES) $(ARDUINO_INCLUDE_PATH) -Wl,--gc-sections -ffunction-sections -fdata-sections -gstabs -mmcu=$(MCU) $(F_CPU) $(ARDUINO_VERSION) -D__AVR_LIBC_DEPRECATED_ENABLE__
#{self.project_name}_LDFLAGS=-L.
#{self.project_name}_LDADD=#{self.arduino_linker_entries.join(' ')} -lm
#{self.project_name}_INCLUDES=-I#{self.project_includes.join("\\\n                    -I")}

lib_LIBRARIES=#{self.arduino_library_names.join(' ')}
#{self.output_arduino_libraries}


AM_LDFLAGS=
AM_CXXFLAGS=-g0 -Os
AM_CFLAGS=-g0 -Os
VPATH=/usr/share/arduino/hardware/arduino/cores/arduino

AVRDUDE_PORT = #{self.device}
AVRDUDE_PROGRAMMER = #{self.programmer}
UPLOAD_RATE = #{self.baud_rate}
FORMAT=ihex

AVRDUDE_WRITE_FLASH = -U flash:w:$(bin_PROGRAMS).hex
AVRDUDE_FLAGS = -q -D -C/etc/avrdude/avrdude.conf -p$(MCU) -P$(AVRDUDE_PORT) -c$(AVRDUDE_PROGRAMMER) -b$(UPLOAD_RATE)


.PHONY: upload hex
hex: all-am
	$(OBJCOPY) -S -O $(FORMAT) $(bin_PROGRAMS) $(bin_PROGRAMS).hex

upload: hex
	$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)
MAKEFILE_AM

  end
end