SlideShare uma empresa Scribd logo
1 de 68
Baixar para ler offline
2015 Pebble Developer Retreat
waf, wscript & Your Pebble App
Cherie Williams - Troublemaker
Agenda
• Why modify my wscript?
• Pebble SDK & Fat PBW
• What is this “waf” thing?
• Why is Pebble using waf?
• wscript
• Why do I care about waf?
• wscript Recipes
• Debugging
Why modify my wscript?
Making the Pebble SDK build system work for you
You can…
• Add C compiler flags
• Add custom defines for your apps (eg. #ifdef
NOLOG)
• Concatenate multiple JS files or do other file
manipulations at build time
You can…
• Collect & build source from a non-standard
project
• Add a linter (or two!)
• Run arbitrary scripts at build time to modify
resources or other files
You can…
• Add automatic testing
• Profile builds or add build visualizations
• Read in arbitrary text at build (eg. appinfo.json)
You can…
• Include an external library
• Build libraries for distribution
…the possibilities are endless!
Fine Print
Recipes + content from today’s talk are
*not* compatible with CloudPebble
Pebble SDK & Fat PBW
SDK: Capabilities Today
• Builds for up to 3 Pebble platforms
• Can build apps, as well as workers
• Handles platform-specific resources
• Packages a single PBW for distribution
aplite
Pebble Classic
Pebble Steel
basalt
Pebble Time
Pebble Time Steel
chalk Pebble Time Round
What is this “waf” thing?
A brief introduction to the Pebble build system
Introducing waf, a Python build system
• Open source, actively maintained
• Active community on Google Groups
• Task parallelization & dependency handling
• Language agnostic, but includes C compiler support
• Integrates with Eclipse, Visual Studio and Xcode
• Includes framework to build & distribute custom build
systems
Why is Pebble using waf?
This guy
Why Pebble uses waf
• Efficiently handles dependencies for large, complex
projects (such as Pebble firmware)
• Python!!
• Easy method overriding
• Can package & distribute additional scripts in the SDK
• Convenience modules for Logs, Node and methods
for easy file substitutions
wscript
The build script behind waf
Basic wscript (non-Pebble)
def configure(ctx):
print "Configure"
def build(ctx):
print "Build"
Basic wscript
$ waf configure build
Setting top to : /Users/cherie/waf-demo/
default
Setting out to : /Users/cherie/waf-demo/
default/build
Configure
'configure' finished successfully (0.009s)
Waf: Entering directory '/Users/cherie/waf-demo/default/build'
Build
Waf: Leaving directory '/Users/cherie/waf-demo/default/build'
'build' finished successfully (0.009s)
Invoking waf via the pebble-tool
pebble clean waf distclean
pebble build waf configure build (-v)
pebble build (-- --other-flags) waf configure build (--other-flags)
Standard Pebble wscript
def options(ctx):
ctx.load('pebble_sdk')
def configure(ctx):
ctx.load('pebble_sdk')
def build(ctx):
ctx.load('pebble_sdk')
build_worker = os.path.exists('worker_src')
binaries = []
for p in ctx.env.TARGET_PLATFORMS:
ctx.set_env(ctx.all_envs[p])
ctx.set_group(ctx.env.PLATFORM_NAME)
app_elf='{}/pebble-app.elf'.format(ctx.env.BUILD_DIR)
ctx.pbl_program(source=ctx.path.ant_glob('src/**/*.c'), target=app_elf)
if build_worker:
worker_elf='{}/pebble-worker.elf'.format(ctx.env.BUILD_DIR)
binaries.append({'platform': p, 'app_elf': app_elf, 'worker_elf': worker_elf})
ctx.pbl_worker(source=ctx.path.ant_glob('worker_src/**/*.c'), target=worker_elf)
else:
binaries.append({'platform': p, 'app_elf': app_elf})
ctx.set_group('bundle')
ctx.pbl_bundle(binaries=binaries, js=ctx.path.ant_glob('src/js/**/*.js'))
Read in command line options
Configure environment for build
Run build
For each HW platform:
• Create app binary
• Create worker binary (optional)
Bundle into PBW
Why do I care about waf?
Understanding how your Pebble project is built
wscript
The build script behind waf
Basic wscript (non-Pebble)
def configure(ctx):
print "Configure"
def build(ctx):
print "Build"
Glossary
Context
An object for each command executed that stores all the
information necessary for the command execution
BuildContext
The build context holds all the information necessary for a
build
Basic wscript (non-Pebble)
def configure(ctx):
print "Configure"
def build(ctx):
print "Build"
Modified Basic wscript
def configure(ctx):
ctx.env.MESSAGE = "Hello World"
def build(ctx):
pass
Glossary
Environment
A group of settings and variables that are stored in a
Context and that is cached between execution of
commands
NOTE: A single Context can have many, arbitrary
environments
build/c4che/*.py
AR = 'arm-none-eabi-gcc-ar'
ARFLAGS = 'rcs'
AS = 'arm-none-eabi-gcc'
BINDIR = '/usr/local/bin'
BUILD_DIR = 'basalt'
CC = ['arm-none-eabi-gcc']
CCLNK_SRC_F = []
CCLNK_TGT_F = ['-o']
CC_NAME = 'gcc'
CC_SRC_F = []
CC_TGT_F = ['-c', '-o']
CC_VERSION = ('4', '8', '4')
CFLAGS = ['-std=c99', '-mcpu=cortex-m3', '-mthumb', '-ffunction-sections', '-
fdata-sections', '-g', '-Os', '-D_TIME_H_', '-Wall', '-Wextra', '-Werror', '-Wno-
unused-parameter', '-Wno-error=unused-function', '-Wno-error=unused-variable']
CFLAGS_MACBUNDLE = ['-fPIC']
CFLAGS_cshlib = ['-fPIC']
CPPPATH_ST = '-I%s'
DEFINES = ['RELEASE', 'PBL_PLATFORM_BASALT', 'PBL_COLOR', 'PBL_RECT', 'PBL_SDK_3']
DEFINES_ST = '-D%s'
DEST_BINFMT = 'elf'
DEST_CPU = 'arm'
DEST_OS = 'darwin'
INCLUDES = ['basalt']
LD = 'arm-none-eabi-ld'
LIBDIR = '/usr/local/lib'
LIBPATH_ST = '-L%s'
LIB_ST = ‘-l%s'
LINKFLAGS = ['-mcpu=cortex-m3', '-mthumb', '-Wl,--gc-sections', '-Wl,--warn-
common', '-Os']
LINKFLAGS_MACBUNDLE = ['-bundle', '-undefined', 'dynamic_lookup']
LINKFLAGS_cshlib = ['-shared']
LINKFLAGS_cstlib = ['-Wl,-Bstatic']
LINK_CC = ['arm-none-eabi-gcc']
MESSAGE = ‘Hello World'
PBW_BIN_DIR = 'basalt'
PEBBLE_SDK = '/Users/cherie/pebble-dev/PebbleSDK-dev/Pebble/basalt'
PEBBLE_SDK_COMMON = '/Users/cherie/pebble-dev/PebbleSDK-dev/Pebble/common'
PLATFORM = {'PBW_BIN_DIR': 'basalt', 'TAGS': ['basalt', 'color', 'rect'],
'ADDITIONAL_TEXT_LINES_FOR_PEBBLE_H': [], 'MAX_APP_BINARY_SIZE': 65536,
'MAX_RESOURCES_SIZE': 1048576, 'MAX_APP_MEMORY_SIZE': 65536,
'MAX_WORKER_MEMORY_SIZE': 10240, 'NAME': 'basalt', 'BUILD_DIR': 'basalt',
'MAX_RESOURCES_SIZE_APPSTORE': 262144, 'DEFINES': ['PBL_PLATFORM_BASALT',
'PBL_COLOR', 'PBL_RECT']}
PLATFORM_NAME = 'basalt'
PREFIX = '/usr/local'
RPATH_ST = '-Wl,-rpath,%s'
SDK_VERSION_MAJOR = 5
SDK_VERSION_MINOR = 70
SHLIB_MARKER = None
SIZE = 'arm-none-eabi-size'
SONAME_ST = '-Wl,-h,%s'
STLIBPATH_ST = '-L%s'
STLIB_MARKER = None
STLIB_ST = '-l%s'
TARGET_PLATFORMS = [u'basalt', u'aplite']
cprogram_PATTERN = '%s'
cshlib_PATTERN = 'lib%s.so'
cstlib_PATTERN = 'lib%s.a'
macbundle_PATTERN = '%s.bundle'
Modified Basic wscript
def configure(ctx):
ctx.env.MESSAGE = "Hello World"
def build(ctx):
ctx(rule="echo ${MESSAGE}",
source='', target='')
Glossary
Task Generator
An object that handles the creation of task instances, and
helps simplify the creation of ordering constraints
Task
An object that represents the production of something
during the build (files, in general) and may be executed in
sequence or in parallel
${MESSAGE} is shorthand for ctx.env.MESSAGE
Modified Basic wscript
$ ../Pebble/waf configure build
Setting top to : /Users/cherie/waf-demo/
default
Setting out to : /Users/cherie/waf-demo/
default/build
'configure' finished successfully (0.002s)
Waf: Entering directory '/Users/cherie/waf-demo/default/build'
[1/1] echo ${MESSAGE}:
Hello World
Waf: Leaving directory '/Users/cherie/waf-demo/default/build'
'build' finished successfully (0.030s)
Modified Basic wscript w/Dependency
def build(ctx):
ctx(rule="echo 'hello' > ${TGT}",
source='',
target='message.txt')
ctx(rule="cp ${SRC} ${TGT}",
source='message.txt',
target='copy.txt')
Glossary
Build Order
The sequence in which tasks must be executed.
Dependency
A dependency represents the conditions by which a task can be
considered up-to-date or not, and can be explicit (dependency
on file inputs & outputs) or abstract (dependency on a value). waf
uses dependencies to determine whether tasks need to be run
(changed checksum of source files) and the build order of tasks.
${SRC} and ${TGT} are shorthand for source and target
Pebble Project Build
Let’s see how dependencies work
Glossary
Node
A data structure used to represent the filesystem. Nodes
may represent files or folders. File nodes are associated
with signatures, which can be hashes of the file contents
(source files) or task signatures (build files)
Node != Existing File
Glossary
Command
A function defined in the wscript file that is executed
when its name is given on the command-line, and can be
chained with other commands
Ex:
waf distclean (`pebble clean`)
waf configure build (`pebble build`)
Agenda
• Why modify my wscript?
• Pebble SDK & Fat PBW
• What is this “waf” thing?
• Why is Pebble using waf?
• wscript
• Why do I care about waf?
• wscript Recipes
• Debugging
wscript Recipes
https://developer.getpebble.com/build
Recipe #1
Add compile time flags
Create waftools/pedantic.py
def configure(ctx):
ctx.env.append_value('CFLAGS', '-pedantic')
def configure(ctx):
ctx.load('pebble_sdk')
+ ctx.load('pedantic', tooldir='waftools')
Add to wscript
[23/35] c: src/default.c -> build/src/default.c.18.o
In file included from ../src/default.c:1:0:
/Users/cherie/pebble-dev/PebbleSDK-dev/Pebble/aplite/include/pebble.h:
974:33: error: ISO C does not permit named variadic macros [-
Werror=variadic-macros]
#define APP_LOG(level, fmt, args...) 
^
/Users/cherie/pebble-dev/PebbleSDK-dev/Pebble/aplite/include/pebble.h:
1121:3: error: type of bit-field 'type' is a GCC extension [-
Werror=pedantic]
TupleType type:8;
^
/Users/cherie/pebble-dev/PebbleSDK-dev/Pebble/aplite/include/pebble.h:
1132:13: error: ISO C forbids zero-size array 'data' [-Werror=pedantic]
uint8_t data[0];
^
Recipe #2
Add build options & associated defines
Create waftools/defines.py
def options(ctx):
ctx.add_option('--no-log', action='store_true', default=False,
help="Mark a build to exclude app logging output")
def configure(ctx):
if ctx.options.no_log:
ctx.env.append_value('DEFINES', 'NOLOG')
Add to wscript for options & configure
ctx.load('defines', tooldir='waftools')
Add to main project.c file
#include <pebble.h>
#if defined(NOLOG)
#undef APP_LOG
#define APP_LOG(...)
#endif
Before
$ pebble install --emulator aplite --logs
Installing app...
App install succeeded.
[22:45:45] default.c:60> Done initializing, pushed window: 0x2001a5fc
[22:45:50] javascript> Ready!
$ pebble build -- --no-logs
…
$ pebble install --emulator aplite --logs
Installing app...
App install succeeded.
[22:49:34] javascript> Ready!
After
Recipe #3
Add a linter
Create waftools/linter.py
def options(ctx):
ctx.add_option('--jshint', action='store_true',
help="Run JSHint on the JS files in the build")
def configure(ctx):
if ctx.options.jshint:
try:
ctx.find_program('jshint', var='JSHINT')
except ctx.errors.ConfigurationError:
print "jshint was not found"
def build(ctx):
if ctx.env.JSHINT:
ctx(rule='${JSHINT} ${SRC}', source=ctx.path.ant_glob('src/**/*.js'))
Add to wscript
def options(ctx):
ctx.load('pebble_sdk')
+ ctx.load('linter', tooldir='waftools')
def configure(ctx):
ctx.load(‘pebble_sdk')
+ ctx.load('linter', tooldir='waftools')
def build(ctx):
ctx.load('pebble_sdk')
+ ctx.load('linter', tooldir='waftools')
$ pebble build -- --jshint
[25/36] jshint ${SRC}: src/js/another.js src/js/pebble-js-
app.js
../src/js/pebble-js-app.js: line 2, col 24, Missing semicolon.
1 error
Waf: Leaving directory `/Users/cherie/pebble-apps/default/
build'
Build failed
-> task in '' failed (exit status 2):
{task 4343355600: jshint ${SRC} another.js,pebble-js-
app.js -> }
' jshint ../src/js/another.js ../src/js/pebble-js-app.js '
Recipe #4
Use source code from multiple folders (2.x + 3.x)
Modify wscript
def build(ctx):
for p in ctx.env.TARGET_PLATFORMS:
- ctx.pbl_program(source=ctx.path.ant_glob('src/**/*.c'),
target=app_elf)
+ ctx.pbl_program(source=ctx.path.ant_glob('src/{}/**/*.c'.format(p)),
target=app_elf)
if build_worker:
- ctx.pbl_worker(source=ctx.path.ant_glob('worker_src/**/*.c'),
target=worker_elf)
+ ctx.pbl_worker(source=ctx.path.ant_glob('worker_src/{}/'
'**/*.c'.format(p)),
target=worker_elf)
Recipe #5
Concatenate multiple JS files
Modify wscript
def build(ctx):
ctx.set_group('bundle')
+ js_files = ctx.path.ant_glob('src/**/*.js')
+ if js_files:
+ ctx(rule='cat ${SRC} > ${TGT}', source=js_files, target='pebble-js-
app.js')
- ctx.pbl_bundle(binaries=binaries, js=ctx.path.ant_glob('src/js/**/
*.js'))
+ ctx.pbl_bundle(binaries=binaries, js='pebble-js-app.js' if js_files else
[])
A Word on Future
Proofing
Sometimes the SDK default wscript will be updated, but by
abstracting code out of wscript and into waf tools, it will be
much easier to maintain customizations!
Debugging
When your wscript changes go wrong
`pebble -v` (waf -v) for command-lines
[ 6/41] c: src/concentricity.c -> build/src/concentricity.c.16.o
21:27:05 runner ['arm-none-eabi-gcc', '-std=c99', '-mcpu=cortex-m3', '-
mthumb', '-ffunction-sections', '-fdata-sections', '-g', '-Os', '-D_TIME_H_',
'-Wall', '-Wextra', '-Werror', '-Wno-unused-parameter', '-Wno-error=unused-
function', '-Wno-error=unused-variable', '-fPIE', '-I/Users/cherie/pebble-
apps/pebble-dev/PebbleSDK-dev/Pebble/chalk/include', '-I/Users/cherie/pebble-
dev/PebbleSDK-dev/Pebble/chalk/include', '-I/Users/cherie/pebble-apps/
concentricity/build', '-I/Users/cherie/pebble-apps/concentricity', '-I/Users/
cherie/pebble-apps/concentricity/build/src', '-I/Users/cherie/pebble-apps/
concentricity/src', '-I/Users/cherie/pebble-apps/concentricity/build/chalk',
'-I/Users/cherie/pebble-apps/concentricity/chalk', '-DRELEASE', '-
DPBL_PLATFORM_CHALK', '-DPBL_COLOR', '-DPBL_ROUND', '-DPBL_SDK_3', '-
D__FILE_NAME__="concentricity.c"', '../src/concentricity.c', '-c', '-o',
'src/concentricity.c.16.o']
`pebble -vvv` (waf -vvv) for complete
21:51:50 preproc reading file '/Users/cherie/pebble-apps/
concentricity/build/chalk/src/resource_ids.auto.h'
21:51:50 deps deps for [/Users/cherie/pebble-apps/concentricity/
build/chalk/appinfo.auto.c]: [/Users/cherie/pebble-apps/
concentricity/build/chalk/src/resource_ids.auto.h]; unresolved
['pebble_process_info.h']
21:51:50 task task {task 4344651216: c appinfo.auto.c ->
appinfo.auto.c.16.o} must run as it was never run before or the
task code changed
21:51:50 runner_env kw={'shell': False, 'cwd': '/Users/cherie/
pebble-apps/concentricity/build', 'env': None}
21:51:50 envhash d751713988987e9331980363e24189ce []
Zone Description
runner command-lines executed (same as -v)
deps implicit dependencies found
task_gen task creation & task generator method execution
action functions to execute for building the targets
env environment contents
envhash hashes of the environment objects
build build context operations, like filesystem access
preproc preprocessor execution
group groups & task generators
$ pebble build -- --zones=deps
23:01:45 deps deps for [/Users/cherie/pebble-apps/concentricity/src/
concentricity.c]: [/Users/cherie/pebble-apps/concentricity/src/ui.h];
unresolved ['pebble.h']
Helpful waf Links
• Pebble Recipes
• https://developer.getpebble.com/build
• GitHub Project
• https://github.com/waf-project/waf
• Google Group
• https://groups.google.com/forum/#!forum/waf-users
• Book
• https://waf.io/book/
2015 Pebble Developer Retreat
Questions?
https://developer.getpebble.com/build

Mais conteúdo relacionado

Mais procurados

Going to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific LanguagesGoing to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific LanguagesGuillaume Laforge
 
Gradle in a Polyglot World
Gradle in a Polyglot WorldGradle in a Polyglot World
Gradle in a Polyglot WorldSchalk Cronjé
 
Developing IT infrastructures with Puppet
Developing IT infrastructures with PuppetDeveloping IT infrastructures with Puppet
Developing IT infrastructures with PuppetAlessandro Franceschi
 
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)ngotogenome
 
Golang Project Layout and Practice
Golang Project Layout and PracticeGolang Project Layout and Practice
Golang Project Layout and PracticeBo-Yi Wu
 
Puppet Systems Infrastructure Construction Kit
Puppet Systems Infrastructure Construction KitPuppet Systems Infrastructure Construction Kit
Puppet Systems Infrastructure Construction KitAlessandro Franceschi
 
carrow - Go bindings to Apache Arrow via C++-API
carrow - Go bindings to Apache Arrow via C++-APIcarrow - Go bindings to Apache Arrow via C++-API
carrow - Go bindings to Apache Arrow via C++-APIYoni Davidson
 
Practical Testing of Ruby Core
Practical Testing of Ruby CorePractical Testing of Ruby Core
Practical Testing of Ruby CoreHiroshi SHIBATA
 
Fluentd - road to v1 -
Fluentd - road to v1 -Fluentd - road to v1 -
Fluentd - road to v1 -N Masahiro
 
Writing Ansible Modules (CLT'19)
Writing Ansible Modules (CLT'19)Writing Ansible Modules (CLT'19)
Writing Ansible Modules (CLT'19)Martin Schütte
 
Modules of the twenties
Modules of the twentiesModules of the twenties
Modules of the twentiesPuppet
 
Bolt C++ Standard Template Libary for HSA by Ben Sanders, AMD
Bolt C++ Standard Template Libary for HSA  by Ben Sanders, AMDBolt C++ Standard Template Libary for HSA  by Ben Sanders, AMD
Bolt C++ Standard Template Libary for HSA by Ben Sanders, AMDHSA Foundation
 
Build microservice with gRPC in golang
Build microservice with gRPC in golangBuild microservice with gRPC in golang
Build microservice with gRPC in golangTing-Li Chou
 
MongoDB & Hadoop: Flexible Hourly Batch Processing Model
MongoDB & Hadoop: Flexible Hourly Batch Processing ModelMongoDB & Hadoop: Flexible Hourly Batch Processing Model
MongoDB & Hadoop: Flexible Hourly Batch Processing ModelTakahiro Inoue
 
Experiments in Sharing Java VM Technology with CRuby
Experiments in Sharing Java VM Technology with CRubyExperiments in Sharing Java VM Technology with CRuby
Experiments in Sharing Java VM Technology with CRubyMatthew Gaudet
 

Mais procurados (20)

Going to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific LanguagesGoing to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific Languages
 
Gradle in a Polyglot World
Gradle in a Polyglot WorldGradle in a Polyglot World
Gradle in a Polyglot World
 
Developing IT infrastructures with Puppet
Developing IT infrastructures with PuppetDeveloping IT infrastructures with Puppet
Developing IT infrastructures with Puppet
 
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
 
Golang Project Layout and Practice
Golang Project Layout and PracticeGolang Project Layout and Practice
Golang Project Layout and Practice
 
Scripting Embulk Plugins
Scripting Embulk PluginsScripting Embulk Plugins
Scripting Embulk Plugins
 
Puppet Systems Infrastructure Construction Kit
Puppet Systems Infrastructure Construction KitPuppet Systems Infrastructure Construction Kit
Puppet Systems Infrastructure Construction Kit
 
carrow - Go bindings to Apache Arrow via C++-API
carrow - Go bindings to Apache Arrow via C++-APIcarrow - Go bindings to Apache Arrow via C++-API
carrow - Go bindings to Apache Arrow via C++-API
 
Practical Testing of Ruby Core
Practical Testing of Ruby CorePractical Testing of Ruby Core
Practical Testing of Ruby Core
 
Fluentd - road to v1 -
Fluentd - road to v1 -Fluentd - road to v1 -
Fluentd - road to v1 -
 
Writing Ansible Modules (CLT'19)
Writing Ansible Modules (CLT'19)Writing Ansible Modules (CLT'19)
Writing Ansible Modules (CLT'19)
 
How DSL works on Ruby
How DSL works on RubyHow DSL works on Ruby
How DSL works on Ruby
 
AngularDart - Meetup 15/03/2017
AngularDart - Meetup 15/03/2017AngularDart - Meetup 15/03/2017
AngularDart - Meetup 15/03/2017
 
Puppet: From 0 to 100 in 30 minutes
Puppet: From 0 to 100 in 30 minutesPuppet: From 0 to 100 in 30 minutes
Puppet: From 0 to 100 in 30 minutes
 
Modules of the twenties
Modules of the twentiesModules of the twenties
Modules of the twenties
 
Bolt C++ Standard Template Libary for HSA by Ben Sanders, AMD
Bolt C++ Standard Template Libary for HSA  by Ben Sanders, AMDBolt C++ Standard Template Libary for HSA  by Ben Sanders, AMD
Bolt C++ Standard Template Libary for HSA by Ben Sanders, AMD
 
Embuk internals
Embuk internalsEmbuk internals
Embuk internals
 
Build microservice with gRPC in golang
Build microservice with gRPC in golangBuild microservice with gRPC in golang
Build microservice with gRPC in golang
 
MongoDB & Hadoop: Flexible Hourly Batch Processing Model
MongoDB & Hadoop: Flexible Hourly Batch Processing ModelMongoDB & Hadoop: Flexible Hourly Batch Processing Model
MongoDB & Hadoop: Flexible Hourly Batch Processing Model
 
Experiments in Sharing Java VM Technology with CRuby
Experiments in Sharing Java VM Technology with CRubyExperiments in Sharing Java VM Technology with CRuby
Experiments in Sharing Java VM Technology with CRuby
 

Semelhante a #PDR15 - waf, wscript and Your Pebble App

An introduction to maven gradle and sbt
An introduction to maven gradle and sbtAn introduction to maven gradle and sbt
An introduction to maven gradle and sbtFabio Fumarola
 
Road to sbt 1.0 paved with server
Road to sbt 1.0   paved with serverRoad to sbt 1.0   paved with server
Road to sbt 1.0 paved with serverEugene Yokota
 
Cloud Foundry V2 | Intermediate Deep Dive
Cloud Foundry V2 | Intermediate Deep DiveCloud Foundry V2 | Intermediate Deep Dive
Cloud Foundry V2 | Intermediate Deep DiveKazuto Kusama
 
Continuous Integration/Deployment with Docker and Jenkins
Continuous Integration/Deployment with Docker and JenkinsContinuous Integration/Deployment with Docker and Jenkins
Continuous Integration/Deployment with Docker and JenkinsFrancesco Bruni
 
Road to sbt 1.0: Paved with server (2015 Amsterdam)
Road to sbt 1.0: Paved with server (2015 Amsterdam)Road to sbt 1.0: Paved with server (2015 Amsterdam)
Road to sbt 1.0: Paved with server (2015 Amsterdam)Eugene Yokota
 
Testing NodeJS with Mocha, Should, Sinon, and JSCoverage
Testing NodeJS with Mocha, Should, Sinon, and JSCoverageTesting NodeJS with Mocha, Should, Sinon, and JSCoverage
Testing NodeJS with Mocha, Should, Sinon, and JSCoveragemlilley
 
Dockercon EU 2014
Dockercon EU 2014Dockercon EU 2014
Dockercon EU 2014Rafe Colton
 
SenchaCon 2016: Develop, Test & Deploy with Docker - Jonas Schwabe
SenchaCon 2016: Develop, Test & Deploy with Docker - Jonas Schwabe SenchaCon 2016: Develop, Test & Deploy with Docker - Jonas Schwabe
SenchaCon 2016: Develop, Test & Deploy with Docker - Jonas Schwabe Sencha
 
introduction to node.js
introduction to node.jsintroduction to node.js
introduction to node.jsorkaplan
 
Scala, docker and testing, oh my! mario camou
Scala, docker and testing, oh my! mario camouScala, docker and testing, oh my! mario camou
Scala, docker and testing, oh my! mario camouJ On The Beach
 
The Docker "Gauntlet" - Introduction, Ecosystem, Deployment, Orchestration
The Docker "Gauntlet" - Introduction, Ecosystem, Deployment, OrchestrationThe Docker "Gauntlet" - Introduction, Ecosystem, Deployment, Orchestration
The Docker "Gauntlet" - Introduction, Ecosystem, Deployment, OrchestrationErica Windisch
 
Kolla talk at OpenStack Summit 2017 in Sydney
Kolla talk at OpenStack Summit 2017 in SydneyKolla talk at OpenStack Summit 2017 in Sydney
Kolla talk at OpenStack Summit 2017 in SydneyVikram G Hosakote
 
The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...
The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...
The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...Docker, Inc.
 
OSCON 2011 - Node.js Tutorial
OSCON 2011 - Node.js TutorialOSCON 2011 - Node.js Tutorial
OSCON 2011 - Node.js TutorialTom Croucher
 
Programming in Linux Environment
Programming in Linux EnvironmentProgramming in Linux Environment
Programming in Linux EnvironmentDongho Kang
 
Setting Up a TIG Stack for Your Testing
Setting Up a TIG Stack for Your TestingSetting Up a TIG Stack for Your Testing
Setting Up a TIG Stack for Your TestingJet Liu
 
Cloud Foundry Summit Europe 2018 - Deveveloper Experience with Cloud Foundry ...
Cloud Foundry Summit Europe 2018 - Deveveloper Experience with Cloud Foundry ...Cloud Foundry Summit Europe 2018 - Deveveloper Experience with Cloud Foundry ...
Cloud Foundry Summit Europe 2018 - Deveveloper Experience with Cloud Foundry ...Neven Cvetković
 
Build Your Own CaaS (Container as a Service)
Build Your Own CaaS (Container as a Service)Build Your Own CaaS (Container as a Service)
Build Your Own CaaS (Container as a Service)HungWei Chiu
 

Semelhante a #PDR15 - waf, wscript and Your Pebble App (20)

An introduction to maven gradle and sbt
An introduction to maven gradle and sbtAn introduction to maven gradle and sbt
An introduction to maven gradle and sbt
 
Road to sbt 1.0 paved with server
Road to sbt 1.0   paved with serverRoad to sbt 1.0   paved with server
Road to sbt 1.0 paved with server
 
Gradle como alternativa a maven
Gradle como alternativa a mavenGradle como alternativa a maven
Gradle como alternativa a maven
 
Cloud Foundry V2 | Intermediate Deep Dive
Cloud Foundry V2 | Intermediate Deep DiveCloud Foundry V2 | Intermediate Deep Dive
Cloud Foundry V2 | Intermediate Deep Dive
 
Continuous Integration/Deployment with Docker and Jenkins
Continuous Integration/Deployment with Docker and JenkinsContinuous Integration/Deployment with Docker and Jenkins
Continuous Integration/Deployment with Docker and Jenkins
 
Road to sbt 1.0: Paved with server (2015 Amsterdam)
Road to sbt 1.0: Paved with server (2015 Amsterdam)Road to sbt 1.0: Paved with server (2015 Amsterdam)
Road to sbt 1.0: Paved with server (2015 Amsterdam)
 
Testing NodeJS with Mocha, Should, Sinon, and JSCoverage
Testing NodeJS with Mocha, Should, Sinon, and JSCoverageTesting NodeJS with Mocha, Should, Sinon, and JSCoverage
Testing NodeJS with Mocha, Should, Sinon, and JSCoverage
 
Dockercon EU 2014
Dockercon EU 2014Dockercon EU 2014
Dockercon EU 2014
 
Play framework
Play frameworkPlay framework
Play framework
 
SenchaCon 2016: Develop, Test & Deploy with Docker - Jonas Schwabe
SenchaCon 2016: Develop, Test & Deploy with Docker - Jonas Schwabe SenchaCon 2016: Develop, Test & Deploy with Docker - Jonas Schwabe
SenchaCon 2016: Develop, Test & Deploy with Docker - Jonas Schwabe
 
introduction to node.js
introduction to node.jsintroduction to node.js
introduction to node.js
 
Scala, docker and testing, oh my! mario camou
Scala, docker and testing, oh my! mario camouScala, docker and testing, oh my! mario camou
Scala, docker and testing, oh my! mario camou
 
The Docker "Gauntlet" - Introduction, Ecosystem, Deployment, Orchestration
The Docker "Gauntlet" - Introduction, Ecosystem, Deployment, OrchestrationThe Docker "Gauntlet" - Introduction, Ecosystem, Deployment, Orchestration
The Docker "Gauntlet" - Introduction, Ecosystem, Deployment, Orchestration
 
Kolla talk at OpenStack Summit 2017 in Sydney
Kolla talk at OpenStack Summit 2017 in SydneyKolla talk at OpenStack Summit 2017 in Sydney
Kolla talk at OpenStack Summit 2017 in Sydney
 
The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...
The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...
The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...
 
OSCON 2011 - Node.js Tutorial
OSCON 2011 - Node.js TutorialOSCON 2011 - Node.js Tutorial
OSCON 2011 - Node.js Tutorial
 
Programming in Linux Environment
Programming in Linux EnvironmentProgramming in Linux Environment
Programming in Linux Environment
 
Setting Up a TIG Stack for Your Testing
Setting Up a TIG Stack for Your TestingSetting Up a TIG Stack for Your Testing
Setting Up a TIG Stack for Your Testing
 
Cloud Foundry Summit Europe 2018 - Deveveloper Experience with Cloud Foundry ...
Cloud Foundry Summit Europe 2018 - Deveveloper Experience with Cloud Foundry ...Cloud Foundry Summit Europe 2018 - Deveveloper Experience with Cloud Foundry ...
Cloud Foundry Summit Europe 2018 - Deveveloper Experience with Cloud Foundry ...
 
Build Your Own CaaS (Container as a Service)
Build Your Own CaaS (Container as a Service)Build Your Own CaaS (Container as a Service)
Build Your Own CaaS (Container as a Service)
 

Mais de Pebble Technology

#PDR15 - Awesome Appstore Assets
#PDR15 - Awesome Appstore Assets#PDR15 - Awesome Appstore Assets
#PDR15 - Awesome Appstore AssetsPebble Technology
 
#PDR15 - Smartstrap Workshop
#PDR15 - Smartstrap Workshop#PDR15 - Smartstrap Workshop
#PDR15 - Smartstrap WorkshopPebble Technology
 
#PDR15 - Data Analytics and Pebble
#PDR15 - Data Analytics and Pebble#PDR15 - Data Analytics and Pebble
#PDR15 - Data Analytics and PebblePebble Technology
 
#PDR15 - Best Use Cases For Timeline
#PDR15 - Best Use Cases For Timeline#PDR15 - Best Use Cases For Timeline
#PDR15 - Best Use Cases For TimelinePebble Technology
 
#PDR15 - Developing for Round
#PDR15 - Developing for Round#PDR15 - Developing for Round
#PDR15 - Developing for RoundPebble Technology
 
#PDR15 - Designing for Pebble
#PDR15 - Designing for Pebble#PDR15 - Designing for Pebble
#PDR15 - Designing for PebblePebble Technology
 
Connecting Pebble to the World
Connecting Pebble to the WorldConnecting Pebble to the World
Connecting Pebble to the WorldPebble Technology
 
Guest Presentation - Strap | Pebble Developer Retreat 2014
Guest Presentation - Strap | Pebble Developer Retreat 2014Guest Presentation - Strap | Pebble Developer Retreat 2014
Guest Presentation - Strap | Pebble Developer Retreat 2014Pebble Technology
 
Battery Life | Pebble Developer Retreat 2014
Battery Life | Pebble Developer Retreat 2014Battery Life | Pebble Developer Retreat 2014
Battery Life | Pebble Developer Retreat 2014Pebble Technology
 
Thomas Sarlandie Kickoff Talk | Pebble Developer Retreat 2014
Thomas Sarlandie Kickoff Talk | Pebble Developer Retreat 2014Thomas Sarlandie Kickoff Talk | Pebble Developer Retreat 2014
Thomas Sarlandie Kickoff Talk | Pebble Developer Retreat 2014Pebble Technology
 
Advanced Techniques: Size | Pebble Developer Retreat 2014
Advanced Techniques: Size | Pebble Developer Retreat 2014Advanced Techniques: Size | Pebble Developer Retreat 2014
Advanced Techniques: Size | Pebble Developer Retreat 2014Pebble Technology
 
Advanced Techniques: Graphics | Pebble Developer Retreat 2014
Advanced Techniques: Graphics | Pebble Developer Retreat 2014Advanced Techniques: Graphics | Pebble Developer Retreat 2014
Advanced Techniques: Graphics | Pebble Developer Retreat 2014Pebble Technology
 

Mais de Pebble Technology (18)

#PDR15 - Awesome Appstore Assets
#PDR15 - Awesome Appstore Assets#PDR15 - Awesome Appstore Assets
#PDR15 - Awesome Appstore Assets
 
#PDR15 - Smartstrap Workshop
#PDR15 - Smartstrap Workshop#PDR15 - Smartstrap Workshop
#PDR15 - Smartstrap Workshop
 
#PDR15 - Data Analytics and Pebble
#PDR15 - Data Analytics and Pebble#PDR15 - Data Analytics and Pebble
#PDR15 - Data Analytics and Pebble
 
#PDR15 - Best Use Cases For Timeline
#PDR15 - Best Use Cases For Timeline#PDR15 - Best Use Cases For Timeline
#PDR15 - Best Use Cases For Timeline
 
#PDR15 - PebbleKit iOS 3.0
#PDR15 - PebbleKit iOS 3.0#PDR15 - PebbleKit iOS 3.0
#PDR15 - PebbleKit iOS 3.0
 
#PDR15 - Voice API
#PDR15 - Voice API#PDR15 - Voice API
#PDR15 - Voice API
 
#PDR15 - Developing for Round
#PDR15 - Developing for Round#PDR15 - Developing for Round
#PDR15 - Developing for Round
 
#PDR15 - Designing for Pebble
#PDR15 - Designing for Pebble#PDR15 - Designing for Pebble
#PDR15 - Designing for Pebble
 
#PDR15 Kick-Off
#PDR15 Kick-Off#PDR15 Kick-Off
#PDR15 Kick-Off
 
Pebble Slate Workshop
Pebble Slate WorkshopPebble Slate Workshop
Pebble Slate Workshop
 
Connecting Pebble to the World
Connecting Pebble to the WorldConnecting Pebble to the World
Connecting Pebble to the World
 
Guest Presentation - Strap | Pebble Developer Retreat 2014
Guest Presentation - Strap | Pebble Developer Retreat 2014Guest Presentation - Strap | Pebble Developer Retreat 2014
Guest Presentation - Strap | Pebble Developer Retreat 2014
 
Battery Life | Pebble Developer Retreat 2014
Battery Life | Pebble Developer Retreat 2014Battery Life | Pebble Developer Retreat 2014
Battery Life | Pebble Developer Retreat 2014
 
Thomas Sarlandie Kickoff Talk | Pebble Developer Retreat 2014
Thomas Sarlandie Kickoff Talk | Pebble Developer Retreat 2014Thomas Sarlandie Kickoff Talk | Pebble Developer Retreat 2014
Thomas Sarlandie Kickoff Talk | Pebble Developer Retreat 2014
 
Advanced Techniques: Size | Pebble Developer Retreat 2014
Advanced Techniques: Size | Pebble Developer Retreat 2014Advanced Techniques: Size | Pebble Developer Retreat 2014
Advanced Techniques: Size | Pebble Developer Retreat 2014
 
Advanced Techniques: Graphics | Pebble Developer Retreat 2014
Advanced Techniques: Graphics | Pebble Developer Retreat 2014Advanced Techniques: Graphics | Pebble Developer Retreat 2014
Advanced Techniques: Graphics | Pebble Developer Retreat 2014
 
Pebble wearables devcon
Pebble wearables devconPebble wearables devcon
Pebble wearables devcon
 
Announcing Pebble SDK 2.0
Announcing Pebble SDK 2.0Announcing Pebble SDK 2.0
Announcing Pebble SDK 2.0
 

Último

Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfhans926745
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 

Último (20)

Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 

#PDR15 - waf, wscript and Your Pebble App

  • 1. 2015 Pebble Developer Retreat waf, wscript & Your Pebble App Cherie Williams - Troublemaker
  • 2. Agenda • Why modify my wscript? • Pebble SDK & Fat PBW • What is this “waf” thing? • Why is Pebble using waf? • wscript • Why do I care about waf? • wscript Recipes • Debugging
  • 3. Why modify my wscript? Making the Pebble SDK build system work for you
  • 4. You can… • Add C compiler flags • Add custom defines for your apps (eg. #ifdef NOLOG) • Concatenate multiple JS files or do other file manipulations at build time
  • 5. You can… • Collect & build source from a non-standard project • Add a linter (or two!) • Run arbitrary scripts at build time to modify resources or other files
  • 6. You can… • Add automatic testing • Profile builds or add build visualizations • Read in arbitrary text at build (eg. appinfo.json)
  • 7. You can… • Include an external library • Build libraries for distribution …the possibilities are endless!
  • 8. Fine Print Recipes + content from today’s talk are *not* compatible with CloudPebble
  • 9. Pebble SDK & Fat PBW
  • 10. SDK: Capabilities Today • Builds for up to 3 Pebble platforms • Can build apps, as well as workers • Handles platform-specific resources • Packages a single PBW for distribution aplite Pebble Classic Pebble Steel basalt Pebble Time Pebble Time Steel chalk Pebble Time Round
  • 11.
  • 12. What is this “waf” thing? A brief introduction to the Pebble build system
  • 13. Introducing waf, a Python build system • Open source, actively maintained • Active community on Google Groups • Task parallelization & dependency handling • Language agnostic, but includes C compiler support • Integrates with Eclipse, Visual Studio and Xcode • Includes framework to build & distribute custom build systems
  • 14. Why is Pebble using waf?
  • 16. Why Pebble uses waf • Efficiently handles dependencies for large, complex projects (such as Pebble firmware) • Python!! • Easy method overriding • Can package & distribute additional scripts in the SDK • Convenience modules for Logs, Node and methods for easy file substitutions
  • 18. Basic wscript (non-Pebble) def configure(ctx): print "Configure" def build(ctx): print "Build"
  • 19. Basic wscript $ waf configure build Setting top to : /Users/cherie/waf-demo/ default Setting out to : /Users/cherie/waf-demo/ default/build Configure 'configure' finished successfully (0.009s) Waf: Entering directory '/Users/cherie/waf-demo/default/build' Build Waf: Leaving directory '/Users/cherie/waf-demo/default/build' 'build' finished successfully (0.009s)
  • 20. Invoking waf via the pebble-tool pebble clean waf distclean pebble build waf configure build (-v) pebble build (-- --other-flags) waf configure build (--other-flags)
  • 21. Standard Pebble wscript def options(ctx): ctx.load('pebble_sdk') def configure(ctx): ctx.load('pebble_sdk') def build(ctx): ctx.load('pebble_sdk') build_worker = os.path.exists('worker_src') binaries = [] for p in ctx.env.TARGET_PLATFORMS: ctx.set_env(ctx.all_envs[p]) ctx.set_group(ctx.env.PLATFORM_NAME) app_elf='{}/pebble-app.elf'.format(ctx.env.BUILD_DIR) ctx.pbl_program(source=ctx.path.ant_glob('src/**/*.c'), target=app_elf) if build_worker: worker_elf='{}/pebble-worker.elf'.format(ctx.env.BUILD_DIR) binaries.append({'platform': p, 'app_elf': app_elf, 'worker_elf': worker_elf}) ctx.pbl_worker(source=ctx.path.ant_glob('worker_src/**/*.c'), target=worker_elf) else: binaries.append({'platform': p, 'app_elf': app_elf}) ctx.set_group('bundle') ctx.pbl_bundle(binaries=binaries, js=ctx.path.ant_glob('src/js/**/*.js')) Read in command line options Configure environment for build Run build For each HW platform: • Create app binary • Create worker binary (optional) Bundle into PBW
  • 22.
  • 23.
  • 24. Why do I care about waf? Understanding how your Pebble project is built
  • 26. Basic wscript (non-Pebble) def configure(ctx): print "Configure" def build(ctx): print "Build"
  • 27. Glossary Context An object for each command executed that stores all the information necessary for the command execution BuildContext The build context holds all the information necessary for a build
  • 28. Basic wscript (non-Pebble) def configure(ctx): print "Configure" def build(ctx): print "Build"
  • 29. Modified Basic wscript def configure(ctx): ctx.env.MESSAGE = "Hello World" def build(ctx): pass
  • 30. Glossary Environment A group of settings and variables that are stored in a Context and that is cached between execution of commands NOTE: A single Context can have many, arbitrary environments
  • 31. build/c4che/*.py AR = 'arm-none-eabi-gcc-ar' ARFLAGS = 'rcs' AS = 'arm-none-eabi-gcc' BINDIR = '/usr/local/bin' BUILD_DIR = 'basalt' CC = ['arm-none-eabi-gcc'] CCLNK_SRC_F = [] CCLNK_TGT_F = ['-o'] CC_NAME = 'gcc' CC_SRC_F = [] CC_TGT_F = ['-c', '-o'] CC_VERSION = ('4', '8', '4') CFLAGS = ['-std=c99', '-mcpu=cortex-m3', '-mthumb', '-ffunction-sections', '- fdata-sections', '-g', '-Os', '-D_TIME_H_', '-Wall', '-Wextra', '-Werror', '-Wno- unused-parameter', '-Wno-error=unused-function', '-Wno-error=unused-variable'] CFLAGS_MACBUNDLE = ['-fPIC'] CFLAGS_cshlib = ['-fPIC'] CPPPATH_ST = '-I%s' DEFINES = ['RELEASE', 'PBL_PLATFORM_BASALT', 'PBL_COLOR', 'PBL_RECT', 'PBL_SDK_3'] DEFINES_ST = '-D%s' DEST_BINFMT = 'elf' DEST_CPU = 'arm' DEST_OS = 'darwin' INCLUDES = ['basalt'] LD = 'arm-none-eabi-ld' LIBDIR = '/usr/local/lib' LIBPATH_ST = '-L%s' LIB_ST = ‘-l%s' LINKFLAGS = ['-mcpu=cortex-m3', '-mthumb', '-Wl,--gc-sections', '-Wl,--warn- common', '-Os'] LINKFLAGS_MACBUNDLE = ['-bundle', '-undefined', 'dynamic_lookup'] LINKFLAGS_cshlib = ['-shared'] LINKFLAGS_cstlib = ['-Wl,-Bstatic'] LINK_CC = ['arm-none-eabi-gcc'] MESSAGE = ‘Hello World' PBW_BIN_DIR = 'basalt' PEBBLE_SDK = '/Users/cherie/pebble-dev/PebbleSDK-dev/Pebble/basalt' PEBBLE_SDK_COMMON = '/Users/cherie/pebble-dev/PebbleSDK-dev/Pebble/common' PLATFORM = {'PBW_BIN_DIR': 'basalt', 'TAGS': ['basalt', 'color', 'rect'], 'ADDITIONAL_TEXT_LINES_FOR_PEBBLE_H': [], 'MAX_APP_BINARY_SIZE': 65536, 'MAX_RESOURCES_SIZE': 1048576, 'MAX_APP_MEMORY_SIZE': 65536, 'MAX_WORKER_MEMORY_SIZE': 10240, 'NAME': 'basalt', 'BUILD_DIR': 'basalt', 'MAX_RESOURCES_SIZE_APPSTORE': 262144, 'DEFINES': ['PBL_PLATFORM_BASALT', 'PBL_COLOR', 'PBL_RECT']} PLATFORM_NAME = 'basalt' PREFIX = '/usr/local' RPATH_ST = '-Wl,-rpath,%s' SDK_VERSION_MAJOR = 5 SDK_VERSION_MINOR = 70 SHLIB_MARKER = None SIZE = 'arm-none-eabi-size' SONAME_ST = '-Wl,-h,%s' STLIBPATH_ST = '-L%s' STLIB_MARKER = None STLIB_ST = '-l%s' TARGET_PLATFORMS = [u'basalt', u'aplite'] cprogram_PATTERN = '%s' cshlib_PATTERN = 'lib%s.so' cstlib_PATTERN = 'lib%s.a' macbundle_PATTERN = '%s.bundle'
  • 32. Modified Basic wscript def configure(ctx): ctx.env.MESSAGE = "Hello World" def build(ctx): ctx(rule="echo ${MESSAGE}", source='', target='')
  • 33. Glossary Task Generator An object that handles the creation of task instances, and helps simplify the creation of ordering constraints Task An object that represents the production of something during the build (files, in general) and may be executed in sequence or in parallel
  • 34. ${MESSAGE} is shorthand for ctx.env.MESSAGE
  • 35. Modified Basic wscript $ ../Pebble/waf configure build Setting top to : /Users/cherie/waf-demo/ default Setting out to : /Users/cherie/waf-demo/ default/build 'configure' finished successfully (0.002s) Waf: Entering directory '/Users/cherie/waf-demo/default/build' [1/1] echo ${MESSAGE}: Hello World Waf: Leaving directory '/Users/cherie/waf-demo/default/build' 'build' finished successfully (0.030s)
  • 36. Modified Basic wscript w/Dependency def build(ctx): ctx(rule="echo 'hello' > ${TGT}", source='', target='message.txt') ctx(rule="cp ${SRC} ${TGT}", source='message.txt', target='copy.txt')
  • 37. Glossary Build Order The sequence in which tasks must be executed. Dependency A dependency represents the conditions by which a task can be considered up-to-date or not, and can be explicit (dependency on file inputs & outputs) or abstract (dependency on a value). waf uses dependencies to determine whether tasks need to be run (changed checksum of source files) and the build order of tasks.
  • 38. ${SRC} and ${TGT} are shorthand for source and target
  • 39. Pebble Project Build Let’s see how dependencies work
  • 40.
  • 41. Glossary Node A data structure used to represent the filesystem. Nodes may represent files or folders. File nodes are associated with signatures, which can be hashes of the file contents (source files) or task signatures (build files)
  • 43. Glossary Command A function defined in the wscript file that is executed when its name is given on the command-line, and can be chained with other commands Ex: waf distclean (`pebble clean`) waf configure build (`pebble build`)
  • 44.
  • 45. Agenda • Why modify my wscript? • Pebble SDK & Fat PBW • What is this “waf” thing? • Why is Pebble using waf? • wscript • Why do I care about waf? • wscript Recipes • Debugging
  • 47. Recipe #1 Add compile time flags
  • 48. Create waftools/pedantic.py def configure(ctx): ctx.env.append_value('CFLAGS', '-pedantic') def configure(ctx): ctx.load('pebble_sdk') + ctx.load('pedantic', tooldir='waftools') Add to wscript
  • 49. [23/35] c: src/default.c -> build/src/default.c.18.o In file included from ../src/default.c:1:0: /Users/cherie/pebble-dev/PebbleSDK-dev/Pebble/aplite/include/pebble.h: 974:33: error: ISO C does not permit named variadic macros [- Werror=variadic-macros] #define APP_LOG(level, fmt, args...) ^ /Users/cherie/pebble-dev/PebbleSDK-dev/Pebble/aplite/include/pebble.h: 1121:3: error: type of bit-field 'type' is a GCC extension [- Werror=pedantic] TupleType type:8; ^ /Users/cherie/pebble-dev/PebbleSDK-dev/Pebble/aplite/include/pebble.h: 1132:13: error: ISO C forbids zero-size array 'data' [-Werror=pedantic] uint8_t data[0]; ^
  • 50. Recipe #2 Add build options & associated defines
  • 51. Create waftools/defines.py def options(ctx): ctx.add_option('--no-log', action='store_true', default=False, help="Mark a build to exclude app logging output") def configure(ctx): if ctx.options.no_log: ctx.env.append_value('DEFINES', 'NOLOG') Add to wscript for options & configure ctx.load('defines', tooldir='waftools')
  • 52. Add to main project.c file #include <pebble.h> #if defined(NOLOG) #undef APP_LOG #define APP_LOG(...) #endif
  • 53. Before $ pebble install --emulator aplite --logs Installing app... App install succeeded. [22:45:45] default.c:60> Done initializing, pushed window: 0x2001a5fc [22:45:50] javascript> Ready! $ pebble build -- --no-logs … $ pebble install --emulator aplite --logs Installing app... App install succeeded. [22:49:34] javascript> Ready! After
  • 54. Recipe #3 Add a linter
  • 55. Create waftools/linter.py def options(ctx): ctx.add_option('--jshint', action='store_true', help="Run JSHint on the JS files in the build") def configure(ctx): if ctx.options.jshint: try: ctx.find_program('jshint', var='JSHINT') except ctx.errors.ConfigurationError: print "jshint was not found" def build(ctx): if ctx.env.JSHINT: ctx(rule='${JSHINT} ${SRC}', source=ctx.path.ant_glob('src/**/*.js'))
  • 56. Add to wscript def options(ctx): ctx.load('pebble_sdk') + ctx.load('linter', tooldir='waftools') def configure(ctx): ctx.load(‘pebble_sdk') + ctx.load('linter', tooldir='waftools') def build(ctx): ctx.load('pebble_sdk') + ctx.load('linter', tooldir='waftools')
  • 57. $ pebble build -- --jshint [25/36] jshint ${SRC}: src/js/another.js src/js/pebble-js- app.js ../src/js/pebble-js-app.js: line 2, col 24, Missing semicolon. 1 error Waf: Leaving directory `/Users/cherie/pebble-apps/default/ build' Build failed -> task in '' failed (exit status 2): {task 4343355600: jshint ${SRC} another.js,pebble-js- app.js -> } ' jshint ../src/js/another.js ../src/js/pebble-js-app.js '
  • 58. Recipe #4 Use source code from multiple folders (2.x + 3.x)
  • 59. Modify wscript def build(ctx): for p in ctx.env.TARGET_PLATFORMS: - ctx.pbl_program(source=ctx.path.ant_glob('src/**/*.c'), target=app_elf) + ctx.pbl_program(source=ctx.path.ant_glob('src/{}/**/*.c'.format(p)), target=app_elf) if build_worker: - ctx.pbl_worker(source=ctx.path.ant_glob('worker_src/**/*.c'), target=worker_elf) + ctx.pbl_worker(source=ctx.path.ant_glob('worker_src/{}/' '**/*.c'.format(p)), target=worker_elf)
  • 61. Modify wscript def build(ctx): ctx.set_group('bundle') + js_files = ctx.path.ant_glob('src/**/*.js') + if js_files: + ctx(rule='cat ${SRC} > ${TGT}', source=js_files, target='pebble-js- app.js') - ctx.pbl_bundle(binaries=binaries, js=ctx.path.ant_glob('src/js/**/ *.js')) + ctx.pbl_bundle(binaries=binaries, js='pebble-js-app.js' if js_files else [])
  • 62. A Word on Future Proofing Sometimes the SDK default wscript will be updated, but by abstracting code out of wscript and into waf tools, it will be much easier to maintain customizations!
  • 63. Debugging When your wscript changes go wrong
  • 64. `pebble -v` (waf -v) for command-lines [ 6/41] c: src/concentricity.c -> build/src/concentricity.c.16.o 21:27:05 runner ['arm-none-eabi-gcc', '-std=c99', '-mcpu=cortex-m3', '- mthumb', '-ffunction-sections', '-fdata-sections', '-g', '-Os', '-D_TIME_H_', '-Wall', '-Wextra', '-Werror', '-Wno-unused-parameter', '-Wno-error=unused- function', '-Wno-error=unused-variable', '-fPIE', '-I/Users/cherie/pebble- apps/pebble-dev/PebbleSDK-dev/Pebble/chalk/include', '-I/Users/cherie/pebble- dev/PebbleSDK-dev/Pebble/chalk/include', '-I/Users/cherie/pebble-apps/ concentricity/build', '-I/Users/cherie/pebble-apps/concentricity', '-I/Users/ cherie/pebble-apps/concentricity/build/src', '-I/Users/cherie/pebble-apps/ concentricity/src', '-I/Users/cherie/pebble-apps/concentricity/build/chalk', '-I/Users/cherie/pebble-apps/concentricity/chalk', '-DRELEASE', '- DPBL_PLATFORM_CHALK', '-DPBL_COLOR', '-DPBL_ROUND', '-DPBL_SDK_3', '- D__FILE_NAME__="concentricity.c"', '../src/concentricity.c', '-c', '-o', 'src/concentricity.c.16.o']
  • 65. `pebble -vvv` (waf -vvv) for complete 21:51:50 preproc reading file '/Users/cherie/pebble-apps/ concentricity/build/chalk/src/resource_ids.auto.h' 21:51:50 deps deps for [/Users/cherie/pebble-apps/concentricity/ build/chalk/appinfo.auto.c]: [/Users/cherie/pebble-apps/ concentricity/build/chalk/src/resource_ids.auto.h]; unresolved ['pebble_process_info.h'] 21:51:50 task task {task 4344651216: c appinfo.auto.c -> appinfo.auto.c.16.o} must run as it was never run before or the task code changed 21:51:50 runner_env kw={'shell': False, 'cwd': '/Users/cherie/ pebble-apps/concentricity/build', 'env': None} 21:51:50 envhash d751713988987e9331980363e24189ce []
  • 66. Zone Description runner command-lines executed (same as -v) deps implicit dependencies found task_gen task creation & task generator method execution action functions to execute for building the targets env environment contents envhash hashes of the environment objects build build context operations, like filesystem access preproc preprocessor execution group groups & task generators $ pebble build -- --zones=deps 23:01:45 deps deps for [/Users/cherie/pebble-apps/concentricity/src/ concentricity.c]: [/Users/cherie/pebble-apps/concentricity/src/ui.h]; unresolved ['pebble.h']
  • 67. Helpful waf Links • Pebble Recipes • https://developer.getpebble.com/build • GitHub Project • https://github.com/waf-project/waf • Google Group • https://groups.google.com/forum/#!forum/waf-users • Book • https://waf.io/book/
  • 68. 2015 Pebble Developer Retreat Questions? https://developer.getpebble.com/build