require 'pathname'
require 'fileutils'
+verbose(ENV['verbose'] == '1')
+DEBUG = ENV['debug'] == '1'
+TESTING = ENV['testing'] == '1'
+
def pop_path(path)
Pathname(path).each_filename.to_a[1..-1]
end
# include a defaults file if present
load 'rakefile.defaults' if File.exists?('rakefile.defaults')
+if TESTING
+ BUILDTYPE= 'Testing'
+
+elsif DEBUG
+ BUILDTYPE= 'Debug'
+ ENABLE_DEBUG_MONITOR= '0'
+end
+
+# Set build type
+BUILDTYPE= ENV['BUILDTYPE'] || 'Checked' unless defined? BUILDTYPE
+puts "#{BUILDTYPE} build"
+
+ENABLE_DEBUG_MONITOR = ENV['ENABLE_DEBUG_MONITOR'] || '0' unless defined? ENABLE_DEBUG_MONITOR
+
+# set default baud rate
+DEFAULT_SERIAL_BAUD_RATE= ENV['BAUDRATE'] || '115200' unless defined? DEFAULT_SERIAL_BAUD_RATE
# set to true to eliminate all the network code
-NONETWORK= false unless defined? NONETWORK
+unless defined? NONETWORK
+ NONETWORK= false || TESTING
+end
# list of modules to exclude, include directory it is in
-EXCLUDE_MODULES= %w(tools/touchprobe) unless defined? EXCLUDE_MODULES
-
# e.g for a CNC machine
#EXCLUDE_MODULES = %w(tools/touchprobe tools/laser tools/temperaturecontrol tools/extruder)
nonetwork= false
end
-SRC = FileList['src/**/*.{c,cpp}'].exclude(/#{excludes.join('|')}/)
+# see if CNC build
+if ENV['CNC'] || CNC
+ cnc= true
+ excludes << 'panel\/screens\/3dprinter'
+ puts "CNC build"
+else
+ excludes << 'panel\/screens\/cnc'
+ cnc= false
+end
+
+if TESTING
+ # add modules to be tested here
+ TESTMODULES= %w(tools/temperatureswitch) unless defined? EXCLUDE_MODULES
+ puts "Modules under test: #{TESTMODULES}"
+ excludes << %w(Kernel.cpp main.cpp) # we replace these with mock versions in testframework
-puts "WARNING Excluding modules: #{EXCLUDE_MODULES.join(' ')}" unless exclude_defines.empty?
+ frameworkfiles= FileList['src/testframework/*.{c,cpp}', 'src/testframework/easyunit/*.{c,cpp}']
+ extrafiles= FileList['src/modules/communication/SerialConsole.cpp', 'src/modules/communication/utils/Gcode.cpp', 'src/modules/robot/Conveyor.cpp', 'src/modules/robot/Block.cpp']
+ testmodules= FileList['src/libs/**/*.{c,cpp}'].include(TESTMODULES.collect { |e| "src/modules/#{e}/**/*.{c,cpp}"}).include(TESTMODULES.collect { |e| "src/testframework/unittests/#{e}/*.{c,cpp}"}).exclude(/#{excludes.join('|')}/)
+ SRC = frameworkfiles + extrafiles + testmodules
+else
+ excludes << %w(testframework)
+ SRC = FileList['src/**/*.{c,cpp}'].exclude(/#{excludes.join('|')}/)
+ puts "WARNING Excluding modules: #{EXCLUDE_MODULES.join(' ')}" unless exclude_defines.empty?
+end
OBJDIR = 'OBJ'
OBJ = SRC.collect { |fn| File.join(OBJDIR, pop_path(File.dirname(fn)), File.basename(fn).ext('o')) } +
INCLUDE = (INCLUDE_DIRS+MBED_INCLUDE_DIRS).collect { |d| "-I#{d}" }.join(" ")
-MRI_ENABLE = true # set to false to disable MRI
-MRI_LIB = MRI_ENABLE ? './mri/mri.ar' : ''
+if ENABLE_DEBUG_MONITOR == '1'
+ # Can add MRI_UART_BAUD=115200 to next line if GDB fails to connect to MRI.
+ # Tends to happen on some Linux distros but not Windows and OS X.
+ MRI_UART = 'MRI_UART_0'
+ MRI_BREAK_ON_INIT = 1 unless defined? MRI_BREAK_ON_INIT
+else
+ MRI_UART = 'MRI_UART_0 MRI_UART_SHARE'
+ MRI_BREAK_ON_INIT = 0 unless defined? MRI_BREAK_ON_INIT
+end
+
+# Configure MRI variables based on BUILD_TYPE build type variable.
+case BUILDTYPE.downcase
+when 'release'
+ OPTIMIZATION = 2
+ MRI_ENABLE = 0
+ MRI_SEMIHOST_STDIO = 0 unless defined? MRI_SEMIHOST_STDIO
+when 'debug'
+ OPTIMIZATION = 0
+ MRI_ENABLE = 1
+ MRI_SEMIHOST_STDIO = 1 unless defined? MRI_SEMIHOST_STDIO
+when 'checked'
+ OPTIMIZATION = 2
+ MRI_ENABLE = 1
+ MRI_SEMIHOST_STDIO = 1 unless defined? MRI_SEMIHOST_STDIO
+when 'testing'
+ OPTIMIZATION = 0
+ MRI_ENABLE = 1
+ MRI_SEMIHOST_STDIO = 0 unless defined? MRI_SEMIHOST_STDIO
+end
+
+MRI_ENABLE = 1 unless defined? MRI_ENABLE # set to 0 to disable MRI
+MRI_LIB = MRI_ENABLE == 1 ? './mri/mri.ar' : ''
MBED_LIB = "#{MBED_DIR}/LPC1768/GCC_ARM/libmbed.a"
+
SYS_LIBS = '-lstdc++_s -lsupc++_s -lm -lgcc -lc_s -lgcc -lc_s -lnosys'
LIBS = [MBED_LIB, SYS_LIBS, MRI_LIB].join(' ')
-MRI_DEFINES = MRI_ENABLE ? %w(-DMRI_ENABLE=1 -DMRI_INIT_PARAMETERS='"MRI_UART_0 MRI_UART_SHARE"' -DMRI_BREAK_ON_INIT=0 -DMRI_SEMIHOST_STDIO=0) : %w(-DMRI_ENABLE=0)
+MRI_DEFINES = %W(-DMRI_ENABLE=#{MRI_ENABLE} -DMRI_INIT_PARAMETERS='"#{MRI_UART}"' -DMRI_BREAK_ON_INIT=#{MRI_BREAK_ON_INIT} -DMRI_SEMIHOST_STDIO=#{MRI_SEMIHOST_STDIO})
defines = %w(-DCHECKSUM_USE_CPP -D__LPC17XX__ -DTARGET_LPC1768 -DWRITE_BUFFER_DISABLE=0 -DSTACK_SIZE=3072 -DCHECKSUM_USE_CPP)
defines += exclude_defines.collect{|d| "-DNO_#{d}"}
defines += MRI_DEFINES
-
+defines << "-DDEFAULT_SERIAL_BAUD_RATE=#{DEFAULT_SERIAL_BAUD_RATE}"
+defines << '-DDEBUG' if OPTIMIZATION == 0
defines << '-DNONETWORK' if nonetwork
+defines << '-DCNC' if cnc
DEFINES= defines.join(' ')
# Compiler flags used to enable creation of header dependencies.
DEPFLAGS = '-MMD '
-CFLAGS = DEPFLAGS + '-Wall -Wextra -Wno-unused-parameter -Wcast-align -Wpointer-arith -Wredundant-decls -Wcast-qual -Wcast-align -O2 -g3 -mcpu=cortex-m3 -mthumb -mthumb-interwork -ffunction-sections -fdata-sections -fno-exceptions -fno-delete-null-pointer-checks'
-CPPFLAGS = CFLAGS + ' -fno-rtti -std=gnu++11'
+CFLAGS = DEPFLAGS + "-Wall -Wextra -Wno-unused-parameter -Wcast-align -Wpointer-arith -Wredundant-decls -Wcast-qual -Wcast-align -O#{OPTIMIZATION} -g3 -mcpu=cortex-m3 -mthumb -mthumb-interwork -ffunction-sections -fdata-sections -fno-delete-null-pointer-checks"
+CPPFLAGS = CFLAGS + ' -fno-rtti -std=gnu++11 -fno-exceptions'
+CXXFLAGS = CFLAGS + ' -fno-rtti -std=gnu++11 -fexceptions' # used for a .cxx file that needs to be compiled with exceptions
-MRI_WRAPS = MRI_ENABLE ? ',--wrap=_read,--wrap=_write,--wrap=semihost_connected' : ''
+MRI_WRAPS = MRI_ENABLE == 1 ? ',--wrap=_read,--wrap=_write,--wrap=semihost_connected' : ''
# Linker script to be used. Indicates what code should be placed where in memory.
LSCRIPT = "#{MBED_DIR}/LPC1768/GCC_ARM/LPC1768.ld"
end
file "#{OBJDIR}/mbed_custom.o" => ['./build/mbed_custom.cpp'] do |t|
- puts "Compiling #{t.source}"
+ puts "Compiling mbed_custom.cpp"
sh "#{CCPP} #{CPPFLAGS} #{INCLUDE} #{DEFINES} -c -o #{t.name} #{t.prerequisites[0]}"
end
end
file "#{PROG}.elf" => OBJ do |t|
- puts "Linking #{t.source}"
+ puts "Linking"
sh "#{LD} #{LDFLAGS} #{OBJ} #{LIBS} -o #{OBJDIR}/#{t.name}"
end
sh "#{CCPP} #{CPPFLAGS} #{INCLUDE} #{DEFINES} #{VERSION} -c -o #{t.name} #{t.source}"
end
+rule '.o' => lambda{ |objfile| obj2src(objfile, 'cxx') } do |t|
+ puts "Compiling #{t.source}"
+ sh "#{CCPP} #{CXXFLAGS} #{INCLUDE} #{DEFINES} #{VERSION} -c -o #{t.name} #{t.source}"
+end
+
rule '.o' => lambda{ |objfile| obj2src(objfile, 'c') } do |t|
puts "Compiling #{t.source}"
sh "#{CC} #{CFLAGS} #{INCLUDE} #{DEFINES} #{VERSION} -c -o #{t.name} #{t.source}"