2061 lines
		
	
	
		
			77 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			2061 lines
		
	
	
		
			77 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
|   | [All code is copyright © 2010-2012 Ceedling Project | |||
|  | by Mike Karlesky, Mark VanderVoord, and Greg Williams. | |||
|  | 
 | |||
|  | This Documentation Is Released Under a | |||
|  | Creative Commons 3.0 Attribution Share-Alike License] | |||
|  | 
 | |||
|  | What the What? | |||
|  | 
 | |||
|  | Assembling build environments for C projects - especially with | |||
|  | automated unit tests - is a pain. Whether it's Make or Rake or Premake | |||
|  | or what-have-you, set up with an all-purpose build environment | |||
|  | tool is tedious and requires considerable glue code to pull together | |||
|  | the necessary tools and libraries. Ceedling allows you to generate | |||
|  | an entire test and build environment for a C project from a single | |||
|  | YAML configuration file. Ceedling is written in Ruby and works | |||
|  | with the Rake build tool plus other goodness like Unity and CMock | |||
|  | - the unit testing and mocking frameworks for C. Ceedling and | |||
|  | its complementary tools can support the tiniest of embedded | |||
|  | processors, the beefiest 64 bit power houses available, and | |||
|  | everything in between. | |||
|  | 
 | |||
|  | For a build project including unit tests and using the default | |||
|  | toolchain gcc, the configuration file could be as simple as this: | |||
|  | 
 | |||
|  | ```yaml | |||
|  | :project: | |||
|  |   :build_root: project/build/ | |||
|  |   :release_build: TRUE | |||
|  | 
 | |||
|  | :paths: | |||
|  |   :test: | |||
|  |     - tests/** | |||
|  |   :source: | |||
|  |     - source/** | |||
|  | ``` | |||
|  | 
 | |||
|  | From the command line, to build the release version of your project, | |||
|  | you would simply run `ceedling release`. To run all your unit tests, | |||
|  | you would run `ceedling test:all`. That's it! | |||
|  | 
 | |||
|  | Of course, many more advanced options allow you to configure | |||
|  | your project with a variety of features to meet a variety of needs. | |||
|  | Ceedling can work with practically any command line toolchain | |||
|  | and directory structure – all by way of the configuration file. | |||
|  | Further, because Ceedling piggy backs on Rake, you can add your | |||
|  | own Rake tasks to accomplish project tasks outside of testing | |||
|  | and release builds. A facility for plugins also allows you to | |||
|  | extend Ceedling's capabilities for needs such as custom code | |||
|  | metrics reporting and coverage testing. | |||
|  | 
 | |||
|  | What's with this Name? | |||
|  | 
 | |||
|  | Glad you asked. Ceedling is tailored for unit tested C projects | |||
|  | and is built upon / around Rake (Rake is a Make replacement implemented | |||
|  | in the Ruby scripting language). So, we've got C, our Rake, and | |||
|  | the fertile soil of a build environment in which to grow and tend | |||
|  | your project and its unit tests. Ta da - _Ceedling_. | |||
|  | 
 | |||
|  | What Do You Mean "tailored for unit tested C projects"? | |||
|  | 
 | |||
|  | Well, we like to write unit tests for our C code to make it lean and | |||
|  | mean (that whole [Test-Driven Development][tdd] | |||
|  | thing). Along the way, this style of writing C code spawned two | |||
|  | tools to make the job easier: a unit test framework for C called | |||
|  | _Unity_ and a mocking library called _CMock_. And, though it's | |||
|  | not directly related to testing, a C framework for exception | |||
|  | handling called _CException_ also came along. | |||
|  | 
 | |||
|  | [tdd]: http://en.wikipedia.org/wiki/Test-driven_development | |||
|  | 
 | |||
|  | These tools and frameworks are great, but they require quite | |||
|  | a bit of environment support to pull them all together in a convenient, | |||
|  | usable fashion. We started off with Rakefiles to assemble everything. | |||
|  | These ended up being quite complicated and had to be hand-edited | |||
|  | or created anew for each new project. Ceedling replaces all that | |||
|  | tedium and rework with a configuration file that ties everything | |||
|  | together. | |||
|  | 
 | |||
|  | Though Ceedling is tailored for unit testing, it can also go right ahead | |||
|  | and build your final binary release artifact for you as well. Or, | |||
|  | Ceedling and your tests can live alongside your existing release build | |||
|  | setup. That said, Ceedling is more powerful as a unit test build | |||
|  | environment than it is a general purpose release build environment; | |||
|  | complicated projects including separate bootloaders or multiple library | |||
|  | builds, etc. are not its strong suit. | |||
|  | 
 | |||
|  | Hold on. Back up. Ruby? Rake? YAML? Unity? CMock? CException? | |||
|  | 
 | |||
|  | Seem overwhelming? It's not bad at all, and for the benefits tests | |||
|  | bring us, it's all worth it. | |||
|  | 
 | |||
|  | [Ruby][] is a handy scripting | |||
|  | language like Perl or Python. It's a modern, full featured language | |||
|  | that happens to be quite handy for accomplishing tasks like code | |||
|  | generation or automating one's workflow while developing in | |||
|  | a compiled language such as C. | |||
|  | 
 | |||
|  | [Ruby]: http://www.ruby-lang.org/en/ | |||
|  | 
 | |||
|  | [Rake][] is a utility written in Ruby | |||
|  | for accomplishing dependency tracking and task automation | |||
|  | common to building software. It's a modern, more flexible replacement | |||
|  | for [Make][]). | |||
|  | Rakefiles are Ruby files, but they contain build targets similar | |||
|  | in nature to that of Makefiles (but you can also run Ruby code in | |||
|  | your Rakefile). | |||
|  | 
 | |||
|  | [Rake]: http://rubyrake.org/ | |||
|  | [Make]: http://en.wikipedia.org/wiki/Make_(software) | |||
|  | 
 | |||
|  | [YAML][] is a "human friendly data serialization standard for all | |||
|  | programming languages." It's kinda like a markup language, but don't | |||
|  | call it that. With a YAML library, you can [serialize][] data structures | |||
|  | to and from the file system in a textual, human readable form. Ceedling | |||
|  | uses a serialized data structure as its configuration input. | |||
|  | 
 | |||
|  | [YAML]: http://en.wikipedia.org/wiki/Yaml | |||
|  | [serialize]: http://en.wikipedia.org/wiki/Serialization | |||
|  | 
 | |||
|  | [Unity] is a [unit test framework][test] for C. It provides facilities | |||
|  | for test assertions, executing tests, and collecting / reporting test | |||
|  | results. Unity derives its name from its implementation in a single C | |||
|  | source file (plus two C header files) and from the nature of its | |||
|  | implementation - Unity will build in any C toolchain and is configurable | |||
|  | for even the very minimalist of processors. | |||
|  | 
 | |||
|  | [Unity]: http://github.com/ThrowTheSwitch/Unity | |||
|  | [test]: http://en.wikipedia.org/wiki/Unit_testing | |||
|  | 
 | |||
|  | [CMock] is a tool written in Ruby able to generate entire | |||
|  | [mock functions][mock] in C code from a given C header file. Mock | |||
|  | functions are invaluable in [interaction-based unit testing][ut]. | |||
|  | CMock's generated C code uses Unity. | |||
|  | 
 | |||
|  | [CMock]: http://github.com/ThrowTheSwitch/CMock | |||
|  | [mock]: http://en.wikipedia.org/wiki/Mock_object | |||
|  | [ut]: http://martinfowler.com/articles/mocksArentStubs.html | |||
|  | 
 | |||
|  | [CException] is a C source and header file that provide a simple | |||
|  | [exception mechanism][exn] for C by way of wrapping up the | |||
|  | [setjmp / longjmp][setjmp] standard library calls. Exceptions are a much | |||
|  | cleaner and preferable alternative to managing and passing error codes | |||
|  | up your return call trace. | |||
|  | 
 | |||
|  | [CException]: http://github.com/ThrowTheSwitch/CException | |||
|  | [exn]: http://en.wikipedia.org/wiki/Exception_handling | |||
|  | [setjmp]: http://en.wikipedia.org/wiki/Setjmp.h | |||
|  | 
 | |||
|  | Notes | |||
|  | ----- | |||
|  | 
 | |||
|  | * YAML support is included with Ruby - requires no special installation | |||
|  |   or configuration. | |||
|  | 
 | |||
|  | * Unity, CMock, and CException are bundled with Ceedling, and | |||
|  |   Ceedling is designed to glue them all together for your project | |||
|  |   as seamlessly as possible. | |||
|  | 
 | |||
|  | 
 | |||
|  | Installation & Setup: What Exactly Do I Need to Get Started? | |||
|  | ------------------------------------------------------------ | |||
|  | 
 | |||
|  | As a [Ruby gem](http://docs.rubygems.org/read/chapter/1): | |||
|  | 
 | |||
|  | 1. [Download and install Ruby](http://www.ruby-lang.org/en/downloads/) | |||
|  | 
 | |||
|  | 2. Use Ruby's command line gem package manager to install Ceedling: | |||
|  |    `gem install ceedling` | |||
|  |    (Unity, CMock, and CException come along with Ceedling for free) | |||
|  | 
 | |||
|  | 3. Execute Ceedling at command line to create example project | |||
|  |    or an empty Ceedling project in your filesystem (executing | |||
|  |    `ceedling help` first is, well, helpful). | |||
|  | 
 | |||
|  | Gem install notes: | |||
|  | 
 | |||
|  | 1. Steps 1-2 are a one time affair for your local environment. | |||
|  |    When steps 1-2 are completed once, only step 3 is needed for | |||
|  |    each new project. | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | General notes: | |||
|  | 
 | |||
|  | 1. Certain advanced features of Ceedling rely on gcc and cpp | |||
|  |    as preprocessing tools. In most *nix systems, these tools | |||
|  |    are already available. For Windows environments, we recommend | |||
|  |    the [mingw project](http://www.mingw.org/) (Minimalist | |||
|  |    GNU for Windows). This represents an optional, additional | |||
|  |    setup / installation step to complement the list above. Upon | |||
|  |    installing mingw ensure your system path is updated or set | |||
|  |    [:environment][:path] in your `project.yml` file (see | |||
|  |    environment section later in this document). | |||
|  | 
 | |||
|  | 2. To use a project file name other than the default `project.yml` | |||
|  |    or place the project file in a directory other than the one | |||
|  |    in which you'll run Rake, create an environment variable | |||
|  |    `CEEDLING_MAIN_PROJECT_FILE` with your desired project | |||
|  |    file path. | |||
|  | 
 | |||
|  | 3. To better understand Rake conventions, Rake execution, | |||
|  |    and Rakefiles, consult the [Rake tutorial, examples, and | |||
|  |    user guide](http://rubyrake.org/). | |||
|  | 
 | |||
|  | 4. When using Ceedling in Windows environments, a test file name may  | |||
|  |    not include the sequences “patch” or “setup”. The Windows Installer  | |||
|  |    Detection Technology (part of UAC), requires administrator  | |||
|  |    privileges to execute file names with these strings. | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | Now What? How Do I Make It GO? | |||
|  | ------------------------------ | |||
|  | 
 | |||
|  | We're getting a little ahead of ourselves here, but it's good | |||
|  | context on how to drive this bus. Everything is done via the command | |||
|  | line. We'll cover conventions and how to actually configure | |||
|  | your project in later sections. | |||
|  | 
 | |||
|  | To run tests, build your release artifact, etc., you will be interacting | |||
|  | with Rake on the command line. Ceedling works with Rake to present | |||
|  | you with named tasks that coordinate the file generation and | |||
|  | build steps needed to accomplish something useful. You can also | |||
|  | add your own independent Rake tasks or create plugins to extend | |||
|  | Ceedling (more on this later). | |||
|  | 
 | |||
|  | 
 | |||
|  | * `ceedling [no arguments]`: | |||
|  | 
 | |||
|  |   Run the default Rake task (conveniently recognized by the name default | |||
|  |   by Rake). Neither Rake nor Ceedling provide a default task. Rake will | |||
|  |   abort if run without arguments when no default task is defined. You can | |||
|  |   conveniently define a default task in the Rakefile discussed in the | |||
|  |   preceding setup & installation section of this document. | |||
|  | 
 | |||
|  | * `ceedling -T`: | |||
|  | 
 | |||
|  |   List all available Rake tasks with descriptions (Rake tasks without | |||
|  |   descriptions are not listed). -T is a command line switch for Rake and | |||
|  |   not the same as tasks that follow. | |||
|  | 
 | |||
|  | * `ceedling <tasks...> --trace`: | |||
|  | 
 | |||
|  |   For advanced users troubleshooting a confusing build error, debug | |||
|  |   Ceedling or a plugin, --trace provides a stack trace of dependencies | |||
|  |   walked during task execution and any Ruby failures along the way. Note | |||
|  |   that --trace is a command line switch for Rake and is not the same as | |||
|  |   tasks that follow. | |||
|  | 
 | |||
|  | * `ceedling environment`: | |||
|  | 
 | |||
|  |   List all configured environment variable names and string values. This | |||
|  |   task is helpful in verifying the evaluatio of any Ruby expressions in | |||
|  |   the [:environment] section of your config file.`: Note: Ceedling may | |||
|  |   set some convenience environment variables by default. | |||
|  | 
 | |||
|  | * `ceedling paths:*`: | |||
|  | 
 | |||
|  |   List all paths collected from [:paths] entries in your YAML config | |||
|  |   file where * is the name of any section contained in [:paths]. This | |||
|  |   task is helpful in verifying the expansion of path wildcards / globs | |||
|  |   specified in the [:paths] section of your config file. | |||
|  | 
 | |||
|  | * `ceedling files:assembly` | |||
|  | * `ceedling files:header` | |||
|  | * `ceedling files:source` | |||
|  | * `ceedling files:test` | |||
|  | 
 | |||
|  |   List all files and file counts collected from the relevant search | |||
|  |   paths specified by the [:paths] entries of your YAML config file. The | |||
|  |   files:assembly task will only be available if assembly support is | |||
|  |   enabled in the [:release_build] section of your configuration file. | |||
|  | 
 | |||
|  | * `ceedling options:*`: | |||
|  | 
 | |||
|  |   Load and merge configuration settings into the main project | |||
|  |   configuration. Each task is named after a *.yml file found in the | |||
|  |   configured options directory. See documentation for the configuration | |||
|  |   setting [:project][:options_path] and for options files in advanced | |||
|  |   topics. | |||
|  | 
 | |||
|  | * `ceedling test:all`: | |||
|  | 
 | |||
|  |   Run all unit tests (rebuilding anything that's changed along the way). | |||
|  | 
 | |||
|  | * `ceedling test:delta`: | |||
|  | 
 | |||
|  |   Run only those unit tests for which the source or test files have | |||
|  |   changed (i.e. incremental build). Note: with the | |||
|  |   [:project][:use_test_preprocessor] configuration file option set, | |||
|  |   runner files are always regenerated limiting the total efficiency this | |||
|  |   text execution option can afford. | |||
|  | 
 | |||
|  | * `ceedling test:*`: | |||
|  | 
 | |||
|  |   Execute the named test file or the named source file that has an | |||
|  |   accompanying test. No path. Examples: ceedling test:foo.c or ceed | |||
|  |   test:test_foo.c | |||
|  | 
 | |||
|  | * `ceedling test:pattern[*]`: | |||
|  | 
 | |||
|  |   Execute any tests whose name and/or path match the regular expression | |||
|  |   pattern (case sensitive). Example: ceedling "test:pattern[(I|i)nit]" will | |||
|  |   execute all tests named for initialization testing. Note: quotes may | |||
|  |   be necessary around the ceedling parameter to distinguish regex characters | |||
|  |   from command line operators. | |||
|  | 
 | |||
|  | * `ceedling test:path[*]`: | |||
|  | 
 | |||
|  |   Execute any tests whose path contains the given string (case | |||
|  |   sensitive). Example: ceedling test:path[foo/bar] will execute all tests | |||
|  |   whose path contains foo/bar. Note: both directory separator characters | |||
|  |   / and \ are valid. | |||
|  | 
 | |||
|  | * `ceedling release`: | |||
|  | 
 | |||
|  |   Build all source into a release artifact (if the release build option | |||
|  |   is configured). | |||
|  | 
 | |||
|  | * `ceedling release:compile:*`: | |||
|  | 
 | |||
|  |   Sometimes you just need to compile a single file dagnabit. Example: | |||
|  |   ceedling release:compile:foo.c | |||
|  | 
 | |||
|  | * `ceedling release:assemble:*`: | |||
|  | 
 | |||
|  |   Sometimes you just need to assemble a single file doggonit. Example: | |||
|  |   ceedling release:assemble:foo.s | |||
|  | 
 | |||
|  | * `ceedling module:create[Filename]`: | |||
|  | * `ceedling module:create[<Path:>Filename]`: | |||
|  | 
 | |||
|  |   It's often helpful to create a file automatically. What's better than | |||
|  |   that? Creating a source file, a header file, and a corresponding test | |||
|  |   file all in one step! | |||
|  | 
 | |||
|  |   There are also patterns which can be specified to automatically generate | |||
|  |   a bunch of files. Try `ceedling module:create[Poodles,mch]` for example! | |||
|  | 
 | |||
|  |   The module generator has several options you can configure. | |||
|  |   F.e. Generating the source/header/test file in a subdirectory (by adding <Path> when calling module:create). | |||
|  |   For more info, refer to the [Module Generator](https://github.com/ThrowTheSwitch/Ceedling/blob/master/docs/CeedlingPacket.md#module-generator) section. | |||
|  | 
 | |||
|  | * `ceedling logging <tasks...>`: | |||
|  | 
 | |||
|  |   Enable logging to <build path>/logs. Must come before test and release | |||
|  |   tasks to log their steps and output. Log names are a concatenation of | |||
|  |   project, user, and option files loaded. User and option files are | |||
|  |   documented in the advanced topics section of this document. | |||
|  | 
 | |||
|  | * `ceedling verbosity[x] <tasks...>`: | |||
|  | 
 | |||
|  |   Change the default verbosity level. [x] ranges from 0 (quiet) to 4 | |||
|  |   (obnoxious). Level [3] is the default. The verbosity task must precede | |||
|  |   all tasks in the command line list for which output is desired to be | |||
|  |   seen. Verbosity settings are generally most meaningful in conjunction | |||
|  |   with test and release tasks. | |||
|  | 
 | |||
|  | * `ceedling summary`: | |||
|  | 
 | |||
|  |   If plugins are enabled, this task will execute the summary method of | |||
|  |   any plugins supporting it. This task is intended to provide a quick | |||
|  |   roundup of build artifact metrics without re-running any part of the | |||
|  |   build. | |||
|  | 
 | |||
|  | * `ceedling clean`: | |||
|  | 
 | |||
|  |   Deletes all toolchain binary artifacts (object files, executables), | |||
|  |   test results, and any temporary files. Clean produces no output at the | |||
|  |   command line unless verbosity has been set to an appreciable level. | |||
|  | 
 | |||
|  | * `ceedling clobber`: | |||
|  | 
 | |||
|  |   Extends clean task's behavior to also remove generated files: test | |||
|  |   runners, mocks, preprocessor output. Clobber produces no output at the | |||
|  |   command line unless verbosity has been set to an appreciable level. | |||
|  | 
 | |||
|  | To better understand Rake conventions, Rake execution, and | |||
|  | Rakefiles, consult the [Rake tutorial, examples, and user guide][guide]. | |||
|  | 
 | |||
|  | [guide]: http://rubyrake.org/ | |||
|  | 
 | |||
|  | At present, none of Ceedling's commands provide persistence. | |||
|  | That is, they must each be specified at the command line each time | |||
|  | they are needed. For instance, Ceedling's verbosity command | |||
|  | only affects output at the time it's run. | |||
|  | 
 | |||
|  | Individual test and release file tasks | |||
|  | are not listed in `-T` output. Because so many files may be present | |||
|  | it's unwieldy to list them all. | |||
|  | 
 | |||
|  | Multiple rake tasks can be executed at the command line (order | |||
|  | is executed as provided). For example, `ceed | |||
|  | clobber test:all release` will removed all generated files; | |||
|  | build and run all tests; and then build all source - in that order. | |||
|  | If any Rake task fails along the way, execution halts before the | |||
|  | next task. | |||
|  | 
 | |||
|  | The `clobber` task removes certain build directories in the | |||
|  | course of deleting generated files. In general, it's best not | |||
|  | to add to source control any Ceedling generated directories | |||
|  | below the root of your top-level build directory. That is, leave | |||
|  | anything Ceedling & its accompanying tools generate out of source | |||
|  | control (but go ahead and add the top-level build directory that | |||
|  | holds all that stuff). Also, since Ceedling is pretty smart about | |||
|  | what it rebuilds and regenerates, you needn't clobber often. | |||
|  | 
 | |||
|  | Important Conventions | |||
|  | ===================== | |||
|  | 
 | |||
|  | Directory Structure, Filenames & Extensions | |||
|  | ------------------------------------------- | |||
|  | 
 | |||
|  | Much of Ceedling's functionality is driven by collecting files | |||
|  | matching certain patterns inside the paths it's configured | |||
|  | to search. See the documentation for the [:extensions] section | |||
|  | of your configuration file (found later in this document) to | |||
|  | configure the file extensions Ceedling uses to match and collect | |||
|  | files. Test file naming is covered later in this section. | |||
|  | 
 | |||
|  | Test files and source files must be segregated by directories. | |||
|  | Any directory structure will do. Tests can be held in subdirectories | |||
|  | within source directories, or tests and source directories | |||
|  | can be wholly separated at the top of your project's directory | |||
|  | tree. | |||
|  | 
 | |||
|  | Search Path Order | |||
|  | ----------------- | |||
|  | 
 | |||
|  | When Ceedling searches for files (e.g. looking for header files | |||
|  | to mock) or when it provides search paths to any of the default | |||
|  | gcc toolchain executables, it organizes / prioritizes its search | |||
|  | paths. The order is always: test paths, support paths, source | |||
|  | paths, and then include paths. This can be useful, for instance, | |||
|  | in certain testing scenarios where we desire Ceedling or a compiler | |||
|  | to find a stand-in header file in our support directory before | |||
|  | the actual source header file of the same name. | |||
|  | 
 | |||
|  | This convention only holds when Ceedling is using its default | |||
|  | tool configurations and / or when tests are involved. If you define | |||
|  | your own tools in the configuration file (see the [:tools] section | |||
|  | documented later in this here document), you have complete control | |||
|  | over what directories are searched and in what order. Further, | |||
|  | test and support directories are only searched when appropriate. | |||
|  | That is, when running a release build, test and support directories | |||
|  | are not used at all. | |||
|  | 
 | |||
|  | Source Files & Binary Release Artifacts | |||
|  | --------------------------------------- | |||
|  | 
 | |||
|  | Your binary release artifact results from the compilation and | |||
|  | linking of all source files Ceedling finds in the specified source | |||
|  | directories. At present only source files with a single (configurable) | |||
|  | extension are recognized. That is, *.c and *.cc files will not | |||
|  | both be recognized - only one or the other. See the configuration | |||
|  | options and defaults in the documentation for the [:extensions] | |||
|  | sections of your configuration file (found later in this document). | |||
|  | 
 | |||
|  | Test Files & Executable Test Fixtures | |||
|  | ------------------------------------- | |||
|  | 
 | |||
|  | Ceedling builds each individual test file with its accompanying | |||
|  | source file(s) into a single, monolithic test fixture executable. | |||
|  | Test files are recognized by a naming convention: a (configurable) | |||
|  | prefix such as "`test_`" in the file name with the same file extension | |||
|  | as used by your C source files. See the configuration options | |||
|  | and defaults in the documentation for the [:project] and [:extensions] | |||
|  | sections of your configuration file (found later in this document). | |||
|  | Depending on your configuration options, Ceedling can recognize | |||
|  | a variety of test file naming patterns in your test search paths. | |||
|  | For example: `test_some_super_functionality.c`, `TestYourSourceFile.cc`, | |||
|  | or `testing_MyAwesomeCode.C` could each be valid test file | |||
|  | names. Note, however, that Ceedling can recognize only one test | |||
|  | file naming convention per project. | |||
|  | 
 | |||
|  | Ceedling knows what files to compile and link into each individual | |||
|  | test executable by way of the #include list contained in each | |||
|  | test file. Any C source files in the configured search directories | |||
|  | that correspond to the header files included in a test file will | |||
|  | be compiled and linked into the resulting test fixture executable. | |||
|  | From this same #include list, Ceedling knows which files to mock | |||
|  | and compile and link into the test executable (if you use mocks | |||
|  | in your tests). That was a lot of clauses and information in a very | |||
|  | few sentences; the example that follows in a bit will make it clearer. | |||
|  | 
 | |||
|  | By naming your test functions according to convention, Ceedling | |||
|  | will extract and collect into a runner C file calls to all your | |||
|  | test case functions. This runner file handles all the execution | |||
|  | minutiae so that your test file can be quite simple and so that | |||
|  | you never forget to wire up a test function to be executed. In this | |||
|  | generated runner lives the `main()` entry point for the resulting | |||
|  | test executable. There are no configuration options for the | |||
|  | naming convention of your test case functions. A test case function | |||
|  | signature must have these three elements: void return, void | |||
|  | parameter list, and the function name prepended with lowercase | |||
|  | "`test`". In other words, a test function signature should look | |||
|  | like this: `void test``[any name you like]``(void)`. | |||
|  | 
 | |||
|  | A commented sample test file follows on the next page. Also, see | |||
|  | the sample project contained in the Ceedling documentation | |||
|  | bundle. | |||
|  | 
 | |||
|  | ```c | |||
|  | // test_foo.c ----------------------------------------------- | |||
|  | #include "unity.h"     // compile/link in Unity test framework
 | |||
|  | #include "types.h"     // header file with no *.c file -- no compilation/linking
 | |||
|  | #include "foo.h"       // source file foo.c under test
 | |||
|  | #include "mock_bar.h"  // bar.h will be found and mocked as mock_bar.c + compiled/linked in;
 | |||
|  |                        // foo.c includes bar.h and uses functions declared in it | |||
|  | #include "mock_baz.h"  // baz.h will be found and mocked as mock_baz.c + compiled/linked in
 | |||
|  |                        // foo.c includes baz.h and uses functions declared in it | |||
|  | 
 | |||
|  | 
 | |||
|  | void setUp(void) {}    // every test file requires this function; | |||
|  |                        // setUp() is called by the generated runner before each test case function | |||
|  | 
 | |||
|  | void tearDown(void) {} // every test file requires this function; | |||
|  |                        // tearDown() is called by the generated runner before each test case function | |||
|  | 
 | |||
|  | // a test case function | |||
|  | void test_Foo_Function1_should_Call_Bar_AndGrill(void) | |||
|  | { | |||
|  |     Bar_AndGrill_Expect();                    // setup function from mock_bar.c that instructs our | |||
|  |                                               // framework to expect Bar_AndGrill() to be called once | |||
|  |     TEST_ASSERT_EQUAL(0xFF, Foo_Function1()); // assertion provided by Unity | |||
|  |                                               // Foo_Function1() calls Bar_AndGrill() & returns a byte | |||
|  | } | |||
|  | 
 | |||
|  | // another test case function | |||
|  | void test_Foo_Function2_should_Call_Baz_Tec(void) | |||
|  | { | |||
|  |     Baz_Tec_ExpectAnd_Return(1);       // setup function provided by mock_baz.c that instructs our | |||
|  |                                        // framework to expect Baz_Tec() to be called once and return 1 | |||
|  |     TEST_ASSERT_TRUE(Foo_Function2()); // assertion provided by Unity | |||
|  | } | |||
|  | 
 | |||
|  | // end of test_foo.c ---------------------------------------- | |||
|  | ``` | |||
|  | 
 | |||
|  | From the test file specified above Ceedling will generate `test_foo_runner.c`; | |||
|  | this runner file will contain `main()` and call both of the example | |||
|  | test case functions. | |||
|  | 
 | |||
|  | The final test executable will be `test_foo.exe` (for Windows | |||
|  | machines or `test_foo.out` for *nix systems - depending on default | |||
|  | or configured file extensions). Based on the #include list above, | |||
|  | the test executable will be the output of the linker having processed | |||
|  | `unity.o`, `foo.o`, `mock_bar.o`, `mock_baz.o`, `test_foo.o`, | |||
|  | and `test_foo_runner.o`. Ceedling finds the files, generates | |||
|  | mocks, generates a runner, compiles all the files, and links | |||
|  | everything into the test executable. Ceedling will then run | |||
|  | the test executable and collect test results from it to be reported | |||
|  | to the developer at the command line. | |||
|  | 
 | |||
|  | For more on the assertions and mocks shown, consult the documentation | |||
|  | for Unity and CMock. | |||
|  | 
 | |||
|  | The Magic of Dependency Tracking | |||
|  | -------------------------------- | |||
|  | 
 | |||
|  | Ceedling is pretty smart in using Rake to build up your project's | |||
|  | dependencies. This means that Ceedling automagically rebuilds | |||
|  | all the appropriate files in your project when necessary: when | |||
|  | your configuration changes, Ceedling or any of the other tools | |||
|  | are updated, or your source or test files change. For instance, | |||
|  | if you modify a header file that is mocked, Ceedling will ensure | |||
|  | that the mock is regenerated and all tests that use that mock are | |||
|  | rebuilt and re-run when you initiate a relevant testing task. | |||
|  | When you see things rebuilding, it's for a good reason. Ceedling | |||
|  | attempts to regenerate and rebuild only what's needed for a given | |||
|  | execution of a task. In the case of large projects, assembling | |||
|  | dependencies and acting upon them can cause some delay in executing | |||
|  | tasks. | |||
|  | 
 | |||
|  | With one exception, the trigger to rebuild or regenerate a file | |||
|  | is always a disparity in timestamps between a target file and | |||
|  | its source - if an input file is newer than its target dependency, | |||
|  | the target is rebuilt or regenerated. For example, if the C source | |||
|  | file from which an object file is compiled is newer than that object | |||
|  | file on disk, recompilation will occur (of course, if no object | |||
|  | file exists on disk, compilation will always occur). The one | |||
|  | exception to this dependency behavior is specific to your input | |||
|  | configuration. Only if your logical configuration changes | |||
|  | will a system-wide rebuild occur. Reorganizing your input configuration | |||
|  | or otherwise updating its file timestamp without modifying | |||
|  | the values within the file will not trigger a rebuild. This behavior | |||
|  | handles the various ways in which your input configuration can | |||
|  | change (discussed later in this document) without having changed | |||
|  | your actual project YAML file. | |||
|  | 
 | |||
|  | Ceedling needs a bit of help to accomplish its magic with deep | |||
|  | dependencies. Shallow dependencies are straightforward: | |||
|  | a mock is dependent on the header file from which it's generated, | |||
|  | a test file is dependent upon the source files it includes (see | |||
|  | the preceding conventions section), etc. Ceedling handles | |||
|  | these "out of the box." Deep dependencies are specifically a | |||
|  | C-related phenomenon and occur as a consequence of include statements | |||
|  | within C source files. Say a source file includes a header file | |||
|  | and that header file in turn includes another header file which | |||
|  | includes still another header file. A change to the deepest header | |||
|  | file should trigger a recompilation of the source file, a relinking | |||
|  | of all the object files comprising a test fixture, and a new execution | |||
|  | of that test fixture. | |||
|  | 
 | |||
|  | Ceedling can handle deep dependencies but only with the help | |||
|  | of a C preprocessor. Ceedling is quite capable, but a full C preprocessor | |||
|  | it ain't. Your project can be configured to use a C preprocessor | |||
|  | or not. Simple projects or large projects constructed so as to | |||
|  | be quite flat in their include structure generally don't need | |||
|  | deep dependency preprocessing - and can enjoy the benefits of | |||
|  | faster execution. Legacy code, on the other hand, will almost | |||
|  | always want to be tested with deep preprocessing enabled. Set | |||
|  | up of the C preprocessor is covered in the documentation for the | |||
|  | [:project] and [:tools] section of the configuration file (later | |||
|  | in this document). Ceedling contains all the configuration | |||
|  | necessary to use the gcc preprocessor by default. That is, as | |||
|  | long as gcc is in your system search path, deep preprocessing | |||
|  | of deep dependencies is available to you by simply enabling it | |||
|  | in your project configuration file. | |||
|  | 
 | |||
|  | Ceedling's Build Output | |||
|  | ----------------------- | |||
|  | 
 | |||
|  | Ceedling requires a top-level build directory for all the stuff | |||
|  | that it, the accompanying test tools, and your toolchain generate. | |||
|  | That build directory's location is configured in the [:project] | |||
|  | section of your configuration file (discussed later). There | |||
|  | can be a ton of generated files. By and large, you can live a full | |||
|  | and meaningful life knowing absolutely nothing at all about | |||
|  | the files and directories generated below the root build directory. | |||
|  | 
 | |||
|  | As noted already, it's good practice to add your top-level build | |||
|  | directory to source control but nothing generated beneath it. | |||
|  | You'll spare yourself headache if you let Ceedling delete and | |||
|  | regenerate files and directories in a non-versioned corner | |||
|  | of your project's filesystem beneath the top-level build directory. | |||
|  | 
 | |||
|  | The `artifacts` directory is the one and only directory you may | |||
|  | want to know about beneath the top-level build directory. The | |||
|  | subdirectories beneath `artifacts` will hold your binary release | |||
|  | target output (if your project is configured for release builds) | |||
|  | and will serve as the conventional location for plugin output. | |||
|  | This directory structure was chosen specifically because it | |||
|  | tends to work nicely with Continuous Integration setups that | |||
|  | recognize and list build artifacts for retrieval / download. | |||
|  | 
 | |||
|  | The Almighty Project Configuration File (in Glorious YAML) | |||
|  | ---------------------------------------------------------- | |||
|  | 
 | |||
|  | Please consult YAML documentation for the finer points of format | |||
|  | and to understand details of our YAML-based configuration file. | |||
|  | We recommend [Wikipedia's entry on YAML](http://en.wikipedia.org/wiki/Yaml) | |||
|  | for this. A few highlights from that reference page: | |||
|  | 
 | |||
|  | * YAML streams are encoded using the set of printable Unicode | |||
|  |   characters, either in UTF-8 or UTF-16 | |||
|  | 
 | |||
|  | * Whitespace indentation is used to denote structure; however | |||
|  |   tab characters are never allowed as indentation | |||
|  | 
 | |||
|  | * Comments begin with the number sign ( # ), can start anywhere | |||
|  |   on a line, and continue until the end of the line unless enclosed | |||
|  |   by quotes | |||
|  | 
 | |||
|  | * List members are denoted by a leading hyphen ( - ) with one member | |||
|  |   per line, or enclosed in square brackets ( [ ] ) and separated | |||
|  |   by comma space ( , ) | |||
|  | 
 | |||
|  | * Hashes are represented using the colon space ( : ) in the form | |||
|  |   key: value, either one per line or enclosed in curly braces | |||
|  |   ( { } ) and separated by comma space ( , ) | |||
|  | 
 | |||
|  | * Strings (scalars) are ordinarily unquoted, but may be enclosed | |||
|  |   in double-quotes ( " ), or single-quotes ( ' ) | |||
|  | 
 | |||
|  | * YAML requires that colons and commas used as list separators | |||
|  |   be followed by a space so that scalar values containing embedded | |||
|  |   punctuation can generally be represented without needing | |||
|  |   to be enclosed in quotes | |||
|  | 
 | |||
|  | * Repeated nodes are initially denoted by an ampersand ( & ) and | |||
|  |   thereafter referenced with an asterisk ( * ) | |||
|  | 
 | |||
|  | 
 | |||
|  | Notes on what follows: | |||
|  | 
 | |||
|  | * Each of the following sections represent top-level entries | |||
|  |   in the YAML configuration file. | |||
|  | 
 | |||
|  | * Unless explicitly specified in the configuration file, default | |||
|  |   values are used by Ceedling. | |||
|  | 
 | |||
|  | * These three settings, at minimum, must be specified: | |||
|  |   * [:project][:build_root] | |||
|  |   * [:paths][:source] | |||
|  |   * [:paths][:test] | |||
|  | 
 | |||
|  | * As much as is possible, Ceedling validates your settings in | |||
|  |   properly formed YAML. | |||
|  | 
 | |||
|  | * Improperly formed YAML will cause a Ruby error when the YAML | |||
|  |   is parsed. This is usually accompanied by a complaint with | |||
|  |   line and column number pointing into the project file. | |||
|  | 
 | |||
|  | * Certain advanced features rely on gcc and cpp as preprocessing | |||
|  |   tools. In most *nix systems, these tools are already available. | |||
|  |   For Windows environments, we recommend the [mingw project](http://www.mingw.org/) | |||
|  |   (Minimalist GNU for Windows). | |||
|  | 
 | |||
|  | * Ceedling is primarily meant as a build tool to support automated | |||
|  |   unit testing. All the heavy lifting is involved there. Creating | |||
|  |   a simple binary release build artifact is quite trivial in | |||
|  |   comparison. Consequently, most default options and the construction | |||
|  |   of Ceedling itself is skewed towards supporting testing though | |||
|  |   Ceedling can, of course, build your binary release artifact | |||
|  |   as well. Note that complex binary release artifacts (e.g. | |||
|  |   application + bootloader or multiple libraries) are beyond | |||
|  |   Ceedling's release build ability. | |||
|  | 
 | |||
|  | 
 | |||
|  | Conventions / features of Ceedling-specific YAML: | |||
|  | 
 | |||
|  | * Any second tier setting keys anywhere in YAML whose names end | |||
|  |   in `_path` or `_paths` are automagically processed like all | |||
|  |   Ceedling-specific paths in the YAML to have consistent directory | |||
|  |   separators (i.e. "/") and to take advantage of inline Ruby | |||
|  |   string expansion (see [:environment] setting below for further | |||
|  |   explanation of string expansion). | |||
|  | 
 | |||
|  | 
 | |||
|  | **Let's Be Careful Out There:** Ceedling performs validation | |||
|  | on the values you set in your configuration file (this assumes | |||
|  | your YAML is correct and will not fail format parsing, of course). | |||
|  | That said, validation is limited to only those settings Ceedling | |||
|  | uses and those that can be reasonably validated. Ceedling does | |||
|  | not limit what can exist within your configuration file. In this | |||
|  | way, you can take full advantage of YAML as well as add sections | |||
|  | and values for use in your own custom plugins (documented later). | |||
|  | The consequence of this is simple but important. A misspelled | |||
|  | configuration section name or value name is unlikely to cause | |||
|  | Ceedling any trouble. Ceedling will happily process that section | |||
|  | or value and simply use the properly spelled default maintained | |||
|  | internally - thus leading to unexpected behavior without warning. | |||
|  | 
 | |||
|  | project: global project settings | |||
|  | 
 | |||
|  | 
 | |||
|  | * `build_root`: | |||
|  | 
 | |||
|  |   Top level directory into which generated path structure and files are | |||
|  |   placed. Note: this is one of the handful of configuration values that | |||
|  |   must be set. The specified path can be absolute or relative to your | |||
|  |   working directory. | |||
|  | 
 | |||
|  |   **Default**: (none) | |||
|  | 
 | |||
|  | * `use_exceptions`: | |||
|  | 
 | |||
|  |   Configures the build environment to make use of CException. Note that | |||
|  |   if you do not use exceptions, there's no harm in leaving this as its | |||
|  |   default value. | |||
|  | 
 | |||
|  |   **Default**: TRUE | |||
|  | 
 | |||
|  | * `use_mocks`: | |||
|  | 
 | |||
|  |   Configures the build environment to make use of CMock. Note that if | |||
|  |   you do not use mocks, there's no harm in leaving this setting as its | |||
|  |   default value. | |||
|  | 
 | |||
|  |   **Default**: TRUE | |||
|  | 
 | |||
|  | * `use_test_preprocessor`: | |||
|  | 
 | |||
|  |   This option allows Ceedling to work with test files that contain | |||
|  |   conditional compilation statements (e.g. #ifdef) and header files you | |||
|  |   wish to mock that contain conditional preprocessor statements and/or | |||
|  |   macros. | |||
|  | 
 | |||
|  |   Ceedling and CMock are advanced tools with sophisticated parsers. | |||
|  |   However, they do not include entire C language preprocessors. | |||
|  |   Consequently, with this option enabled, Ceedling will use gcc's | |||
|  |   preprocessing mode and the cpp preprocessor tool to strip down / | |||
|  |   expand test files and headers to their applicable content which can | |||
|  |   then be processed by Ceedling and CMock. | |||
|  | 
 | |||
|  |   With this option enabled, the gcc & cpp tools must exist in an | |||
|  |   accessible system search path and test runner files are always | |||
|  |   regenerated. | |||
|  | 
 | |||
|  |   **Default**: FALSE | |||
|  | 
 | |||
|  | * `use_deep_dependencies`: | |||
|  | 
 | |||
|  |   The base rules and tasks that Ceedling creates using Rake capture most | |||
|  |   of the dependencies within a standard project (e.g. when the source | |||
|  |   file accompanying a test file changes, the corresponding test fixture | |||
|  |   executable will be rebuilt when tests are re-run). However, deep | |||
|  |   dependencies cannot be captured this way. If a typedef or macro | |||
|  |   changes in a header file three levels of #include statements deep, | |||
|  |   this option allows the appropriate incremental build actions to occur | |||
|  |   for both test execution and release builds. | |||
|  | 
 | |||
|  |   This is accomplished by using the dependencies discovery mode of gcc. | |||
|  |   With this option enabled, gcc must exist in an accessible system | |||
|  |   search path. | |||
|  | 
 | |||
|  |   **Default**: FALSE | |||
|  | 
 | |||
|  | * `generate_deep_dependencies`: | |||
|  | 
 | |||
|  |   When `use_deep_dependencies` is set to TRUE, Ceedling will run a separate | |||
|  |   build step to generate the deep dependencies. If you are using gcc as your | |||
|  |   primary compiler, or another compiler that can generate makefile rules as | |||
|  |   a side effect of compilation, then you can set this to FALSE to avoid the | |||
|  |   extra build step but still use the deep dependencies data when deciding | |||
|  |   which source files to rebuild. | |||
|  | 
 | |||
|  |   **Default**: TRUE | |||
|  | 
 | |||
|  | * `test_file_prefix`: | |||
|  | 
 | |||
|  |   Ceedling collects test files by convention from within the test file | |||
|  |   search paths. The convention includes a unique name prefix and a file | |||
|  |   extension matching that of source files. | |||
|  | 
 | |||
|  |   Why not simply recognize all files in test directories as test files? | |||
|  |   By using the given convention, we have greater flexibility in what we | |||
|  |   do with C files in the test directories. | |||
|  | 
 | |||
|  |   **Default**: "test_" | |||
|  | 
 | |||
|  | * `options_paths`: | |||
|  | 
 | |||
|  |   Just as you may have various build configurations for your source | |||
|  |   codebase, you may need variations of your project configuration. | |||
|  | 
 | |||
|  |   By specifying options paths, Ceedling will search for other project | |||
|  |   YAML files, make command line tasks available (ceedling options:variation | |||
|  |   for a variation.yml file), and merge the project configuration of | |||
|  |   these option files in with the main project file at runtime. See | |||
|  |   advanced topics. | |||
|  | 
 | |||
|  |   Note these Rake tasks at the command line - like verbosity or logging | |||
|  |   control - must come before the test or release task they are meant to | |||
|  |   modify. | |||
|  | 
 | |||
|  |   **Default**: [] (empty) | |||
|  | 
 | |||
|  | * `release_build`: | |||
|  | 
 | |||
|  |   When enabled, a release Rake task is exposed. This configuration | |||
|  |   option requires a corresponding release compiler and linker to be | |||
|  |   defined (gcc is used as the default). | |||
|  | 
 | |||
|  |   More release configuration options are available in the release_build | |||
|  |   section. | |||
|  | 
 | |||
|  |   **Default**: FALSE | |||
|  | 
 | |||
|  | 
 | |||
|  | Example `[:project]` YAML blurb | |||
|  | 
 | |||
|  | ```yaml | |||
|  | :project: | |||
|  |   :build_root: project_awesome/build | |||
|  |   :use_exceptions: FALSE | |||
|  |   :use_test_preprocessor: TRUE | |||
|  |   :use_deep_dependencies: TRUE | |||
|  |   :options_paths: | |||
|  |     - project/options | |||
|  |     - external/shared/options | |||
|  |   :release_build: TRUE | |||
|  | ``` | |||
|  | 
 | |||
|  | Ceedling is primarily concerned with facilitating the somewhat | |||
|  | complicated mechanics of automating unit tests. The same mechanisms | |||
|  | are easily capable of building a final release binary artifact | |||
|  | (i.e. non test code; the thing that is your final working software | |||
|  | that you execute on target hardware). | |||
|  | 
 | |||
|  | 
 | |||
|  | * `output`: | |||
|  | 
 | |||
|  |   The name of your release build binary artifact to be found in <build | |||
|  |   path>/artifacts/release. Ceedling sets the default artifact file | |||
|  |   extension to that as is explicitly specified in the [:extensions] | |||
|  |   section or as is system specific otherwise. | |||
|  | 
 | |||
|  |   **Default**: `project.exe` or `project.out` | |||
|  | 
 | |||
|  | * `use_assembly`: | |||
|  | 
 | |||
|  |   If assembly code is present in the source tree, this option causes | |||
|  |   Ceedling to create appropriate build directories and use an assembler | |||
|  |   tool (default is the GNU tool as - override available in the [:tools] | |||
|  |   section. | |||
|  | 
 | |||
|  |   **Default**: FALSE | |||
|  | 
 | |||
|  | * `artifacts`: | |||
|  | 
 | |||
|  |   By default, Ceedling copies to the <build path>/artifacts/release | |||
|  |   directory the output of the release linker and (optionally) a map | |||
|  |   file. Many toolchains produce other important output files as well. | |||
|  |   Adding a file path to this list will cause Ceedling to copy that file | |||
|  |   to the artifacts directory. The artifacts directory is helpful for | |||
|  |   organizing important build output files and provides a central place | |||
|  |   for tools such as Continuous Integration servers to point to build | |||
|  |   output. Selectively copying files prevents incidental build cruft from | |||
|  |   needlessly appearing in the artifacts directory. Note that inline Ruby | |||
|  |   string replacement is available in the artifacts paths (see discussion | |||
|  |   in the [:environment] section). | |||
|  | 
 | |||
|  |   **Default**: [] (empty) | |||
|  | 
 | |||
|  | Example `[:release_build]` YAML blurb | |||
|  | 
 | |||
|  | ```yaml | |||
|  | :release_build: | |||
|  |   :output: top_secret.bin | |||
|  |   :use_assembly: TRUE | |||
|  |   :artifacts: | |||
|  |     - build/release/out/c/top_secret.s19 | |||
|  | ``` | |||
|  | 
 | |||
|  | **paths**: options controlling search paths for source and header | |||
|  | (and assembly) files | |||
|  | 
 | |||
|  | * `test`: | |||
|  | 
 | |||
|  |   All C files containing unit test code. Note: this is one of the | |||
|  |   handful of configuration values that must be set. | |||
|  | 
 | |||
|  |   **Default**: [] (empty) | |||
|  | 
 | |||
|  | * `source`: | |||
|  | 
 | |||
|  |   All C files containing release code (code to be tested). Note: this is | |||
|  |   one of the handful of configuration values that must be set. | |||
|  | 
 | |||
|  |   **Default**: [] (empty) | |||
|  | 
 | |||
|  | * `support`: | |||
|  | 
 | |||
|  |   Any C files you might need to aid your unit testing. For example, on | |||
|  |   occasion, you may need to create a header file containing a subset of | |||
|  |   function signatures matching those elsewhere in your code (e.g. a | |||
|  |   subset of your OS functions, a portion of a library API, etc.). Why? | |||
|  |   To provide finer grained control over mock function substitution or | |||
|  |   limiting the size of the generated mocks. | |||
|  | 
 | |||
|  |   **Default**: [] (empty) | |||
|  | 
 | |||
|  | * `include`: | |||
|  | 
 | |||
|  |   Any header files not already in the source search path. Note there's | |||
|  |     no practical distinction between this search path and the source | |||
|  |     search path; it's merely to provide options or to support any | |||
|  |     peculiar source tree organization. | |||
|  | 
 | |||
|  |   **Default**: [] (empty) | |||
|  | 
 | |||
|  | * `test_toolchain_include`: | |||
|  | 
 | |||
|  |   System header files needed by the test toolchain - should your | |||
|  |   compiler be unable to find them, finds the wrong system include search | |||
|  |   path, or you need a creative solution to a tricky technical problem. | |||
|  |   Note that if you configure your own toolchain in the [:tools] section, | |||
|  |   this search path is largely meaningless to you. However, this is a | |||
|  |   convenient way to control the system include path should you rely on | |||
|  |   the default gcc tools. | |||
|  | 
 | |||
|  |   **Default**: [] (empty) | |||
|  | 
 | |||
|  | * `release_toolchain_include`: | |||
|  | 
 | |||
|  |   Same as preceding albeit related to the release toolchain. | |||
|  | 
 | |||
|  |   **Default**: [] (empty) | |||
|  | 
 | |||
|  | * `<custom>` | |||
|  | 
 | |||
|  |   Any paths you specify for custom list. List is available to tool | |||
|  |   configurations and/or plugins. Note a distinction. The preceding names | |||
|  |   are recognized internally to Ceedling and the path lists are used to | |||
|  |   build collections of files contained in those paths. A custom list is | |||
|  |   just that - a custom list of paths. | |||
|  | 
 | |||
|  | Notes on path grammar within the [:paths] section: | |||
|  | 
 | |||
|  | * Order of search paths listed in [:paths] is preserved when used by an | |||
|  |   entry in the [:tools] section | |||
|  | 
 | |||
|  | * Wherever multiple path lists are combined for use Ceedling prioritizes | |||
|  |   path groups as follows: | |||
|  |   test paths, support paths, source paths, include paths. | |||
|  | 
 | |||
|  |   This can be useful, for instance, in certain testing scenarios where | |||
|  |   we desire Ceedling or the compiler to find a stand-in header file before | |||
|  |   the actual source header file of the same name. | |||
|  | 
 | |||
|  | * Paths: | |||
|  | 
 | |||
|  |   1. can be absolute or relative | |||
|  | 
 | |||
|  |   2. can be singly explicit - a single fully specified path | |||
|  | 
 | |||
|  |   3. can include a glob operator (more on this below) | |||
|  | 
 | |||
|  |   4. can use inline Ruby string replacement (see [:environment] | |||
|  |      section for more) | |||
|  | 
 | |||
|  |   5. default as an addition to a specific search list (more on this | |||
|  |      in the examples) | |||
|  | 
 | |||
|  |   6. can act to subtract from a glob included in the path list (more | |||
|  |      on this in the examples) | |||
|  | 
 | |||
|  | 
 | |||
|  | [Globs](http://ruby.about.com/od/beginningruby/a/dir2.htm) | |||
|  | as used by Ceedling are wildcards for specifying directories | |||
|  | without the need to list each and every required search path. | |||
|  | Ceedling globs operate just as Ruby globs except that they are | |||
|  | limited to matching directories and not files. Glob operators | |||
|  | include the following * ** ? [-] {,} (note: this list is space separated | |||
|  | and not comma separated as commas are used within the bracket | |||
|  | operators). | |||
|  | 
 | |||
|  | * `*`: | |||
|  | 
 | |||
|  |   All subdirectories of depth 1 below the parent path and including the | |||
|  |   parent path | |||
|  | 
 | |||
|  | * `**`: | |||
|  | 
 | |||
|  |   All subdirectories recursively discovered below the parent path and | |||
|  |   including the parent path | |||
|  | 
 | |||
|  | * `?`: | |||
|  | 
 | |||
|  |   Single alphanumeric character wildcard | |||
|  | 
 | |||
|  | * `[x-y]`: | |||
|  | 
 | |||
|  |   Single alphanumeric character as found in the specified range | |||
|  | 
 | |||
|  | * `{x,y}`: | |||
|  | 
 | |||
|  |   Single alphanumeric character from the specified list | |||
|  | 
 | |||
|  | Example [:paths] YAML blurbs | |||
|  | 
 | |||
|  | ```yaml | |||
|  | :paths: | |||
|  |   :source:              #together the following comprise all source search paths | |||
|  |     - project/source/*  #expansion yields all subdirectories of depth 1 plus parent directory | |||
|  |     - project/lib       #single path | |||
|  |   :test:                #all test search paths | |||
|  |     - project/**/test?  #expansion yields any subdirectory found anywhere in the project that | |||
|  |                         #begins with "test" and contains 5 characters | |||
|  | 
 | |||
|  | :paths: | |||
|  |   :source:                           #all source search paths | |||
|  |     - +:project/source/**            #all subdirectories recursively discovered plus parent directory | |||
|  |     - -:project/source/os/generated  #subtract os/generated directory from expansion of above glob | |||
|  |                                      #note that '+:' notation is merely aesthetic; default is to add | |||
|  | 
 | |||
|  |   :test:                             #all test search paths | |||
|  |     - project/test/bootloader        #explicit, single search paths (searched in the order specified) | |||
|  |     - project/test/application | |||
|  |     - project/test/utilities | |||
|  | 
 | |||
|  |   :custom:                           #custom path list | |||
|  |     - "#{PROJECT_ROOT}/other"        #inline Ruby string expansion | |||
|  | ``` | |||
|  | 
 | |||
|  | Globs and inline Ruby string expansion can require trial and | |||
|  | error to arrive at your intended results. Use the `ceedling paths:*` | |||
|  | command line options (documented in preceding section) to verify | |||
|  | your settings. | |||
|  | 
 | |||
|  | Ceedling relies on file collections automagically assembled | |||
|  | from paths, globs, and file extensions. File collections greatly | |||
|  | simplify project set up. However, sometimes you need to remove | |||
|  | from or add individual files to those collections. | |||
|  | 
 | |||
|  | 
 | |||
|  | * `test`: | |||
|  | 
 | |||
|  |   Modify the collection of unit test C files. | |||
|  | 
 | |||
|  |   **Default**: [] (empty) | |||
|  | 
 | |||
|  | * `source`: | |||
|  | 
 | |||
|  |   Modify the collection of all source files used in unit test builds and release builds. | |||
|  | 
 | |||
|  |   **Default**: [] (empty) | |||
|  | 
 | |||
|  | * `assembly`: | |||
|  | 
 | |||
|  |   Modify the (optional) collection of assembly files used in release builds. | |||
|  | 
 | |||
|  |   **Default**: [] (empty) | |||
|  | 
 | |||
|  | * `include`: | |||
|  | 
 | |||
|  |   Modify the collection of all source header files used in unit test builds (e.g. for mocking) and release builds. | |||
|  | 
 | |||
|  |   **Default**: [] (empty) | |||
|  | 
 | |||
|  | * `support`: | |||
|  | 
 | |||
|  |   Modify the collection of supporting C files available to unit tests builds. | |||
|  | 
 | |||
|  |   **Default**: [] (empty) | |||
|  | 
 | |||
|  | 
 | |||
|  | Note: All path grammar documented in [:paths] section applies | |||
|  | to [:files] path entries - albeit at the file path level and not | |||
|  | the directory level. | |||
|  | 
 | |||
|  | Example [:files] YAML blurb | |||
|  | 
 | |||
|  | ```yaml | |||
|  | :files: | |||
|  |   :source: | |||
|  |     - callbacks/comm.c        # entry defaults to file addition | |||
|  |     - +:callbacks/comm*.c     # add all comm files matching glob pattern | |||
|  |     - -:source/board/atm134.c # not our board | |||
|  |   :test: | |||
|  |     - -:test/io/test_output_manager.c # remove unit tests from test build | |||
|  | ``` | |||
|  | 
 | |||
|  | **environment:** inserts environment variables into the shell | |||
|  | instance executing configured tools | |||
|  | 
 | |||
|  | Ceedling creates environment variables from any key / value | |||
|  | pairs in the environment section. Keys become an environment | |||
|  | variable name in uppercase. The values are strings assigned | |||
|  | to those environment variables. These value strings are either | |||
|  | simple string values in YAML or the concatenation of a YAML array. | |||
|  | 
 | |||
|  | Ceedling is able to execute inline Ruby string substitution | |||
|  | code to set environment variables. This evaluation occurs when | |||
|  | the project file is first processed for any environment pair's | |||
|  | value string including the Ruby string substitution pattern | |||
|  | `#{…}`. Note that environment value strings that _begin_ with | |||
|  | this pattern should always be enclosed in quotes. YAML defaults | |||
|  | to processing unquoted text as a string; quoting text is optional. | |||
|  | If an environment pair's value string begins with the Ruby string | |||
|  | substitution pattern, YAML will interpret the string as a Ruby | |||
|  | comment (because of the `#`). Enclosing each environment value | |||
|  | string in quotes is a safe practice. | |||
|  | 
 | |||
|  | [:environment] entries are processed in the configured order | |||
|  | (later entries can reference earlier entries). | |||
|  | 
 | |||
|  | Special case: PATH handling | |||
|  | 
 | |||
|  | In the specific case of specifying an environment key named _path_, | |||
|  | an array of string values will be concatenated with the appropriate | |||
|  | platform-specific path separation character (e.g. ':' on *nix, | |||
|  | ';' on Windows). All other instances of environment keys assigned | |||
|  | YAML arrays use simple concatenation. | |||
|  | 
 | |||
|  | Example [:environment] YAML blurb | |||
|  | 
 | |||
|  | ```yaml | |||
|  | :environment: | |||
|  |   - :license_server: gizmo.intranet        #LICENSE_SERVER set with value "gizmo.intranet" | |||
|  |   - :license: "#{`license.exe`}"           #LICENSE set to string generated from shelling out to | |||
|  |                                            #execute license.exe; note use of enclosing quotes | |||
|  | 
 | |||
|  |   - :path:                                 #concatenated with path separator (see special case above) | |||
|  |      - Tools/gizmo/bin                     #prepend existing PATH with gizmo path | |||
|  |      - "#{ENV['PATH']}"                    #pattern #{…} triggers ruby evaluation string substitution | |||
|  |                                            #note: value string must be quoted because of '#' | |||
|  | 
 | |||
|  |   - :logfile: system/logs/thingamabob.log  #LOGFILE set with path for a log file | |||
|  | ``` | |||
|  | 
 | |||
|  | **extension**: configure file name extensions used to collect lists of files searched in [:paths] | |||
|  | 
 | |||
|  | * `header`: | |||
|  | 
 | |||
|  |   C header files | |||
|  | 
 | |||
|  |   **Default**: .h | |||
|  | 
 | |||
|  | * `source`: | |||
|  | 
 | |||
|  |   C code files (whether source or test files) | |||
|  | 
 | |||
|  |   **Default**: .c | |||
|  | 
 | |||
|  | * `assembly`: | |||
|  | 
 | |||
|  |   Assembly files (contents wholly assembly instructions) | |||
|  | 
 | |||
|  |   **Default**: .s | |||
|  | 
 | |||
|  | * `object`: | |||
|  | 
 | |||
|  |   Resulting binary output of C code compiler (and assembler) | |||
|  | 
 | |||
|  |   **Default**: .o | |||
|  | 
 | |||
|  | * `executable`: | |||
|  | 
 | |||
|  |   Binary executable to be loaded and executed upon target hardware | |||
|  | 
 | |||
|  |   **Default**: .exe or .out (Win or *nix) | |||
|  | 
 | |||
|  | * `testpass`: | |||
|  | 
 | |||
|  |   Test results file (not likely to ever need a new value) | |||
|  | 
 | |||
|  |   **Default**: .pass | |||
|  | 
 | |||
|  | * `testfail`: | |||
|  | 
 | |||
|  |   Test results file (not likely to ever need a new value) | |||
|  | 
 | |||
|  |   **Default**: .fail | |||
|  | 
 | |||
|  | * `dependencies`: | |||
|  | 
 | |||
|  |   File containing make-style dependency rules created by gcc preprocessor | |||
|  | 
 | |||
|  |   **Default**: .d | |||
|  | 
 | |||
|  | 
 | |||
|  | Example [:extension] YAML blurb | |||
|  | 
 | |||
|  |     :extension: | |||
|  |       :source: .cc | |||
|  |       :executable: .bin | |||
|  | 
 | |||
|  | **defines**: command line defines used in test and release compilation by configured tools | |||
|  | 
 | |||
|  | * `test`: | |||
|  | 
 | |||
|  |   Defines needed for testing. Useful for: | |||
|  | 
 | |||
|  |   1. test files containing conditional compilation statements (i.e. | |||
|  |   tests active in only certain contexts) | |||
|  | 
 | |||
|  |   2. testing legacy source wherein the isolation of source under test | |||
|  |   afforded by Ceedling and its complementary tools leaves certain | |||
|  |   symbols unset when source files are compiled in isolation | |||
|  | 
 | |||
|  |   **Default**: [] (empty) | |||
|  | 
 | |||
|  | * `test_preprocess`: | |||
|  | 
 | |||
|  |   If [:project][:use_test_preprocessor] or | |||
|  |   [:project][:use_deep_dependencies] is set and code is structured in a | |||
|  |   certain way, the gcc preprocessor may need symbol definitions to | |||
|  |   properly preprocess files to extract function signatures for mocking | |||
|  |   and extract deep dependencies for incremental builds. | |||
|  | 
 | |||
|  |   **Default**: [] (empty) | |||
|  | 
 | |||
|  | * `release`: | |||
|  | 
 | |||
|  |   Defines needed for the release build binary artifact. | |||
|  | 
 | |||
|  |   **Default**: [] (empty) | |||
|  | 
 | |||
|  | * `release_preprocess`: | |||
|  | 
 | |||
|  |   If [:project][:use_deep_dependencies] is set and code is structured in | |||
|  |   a certain way, the gcc preprocessor may need symbol definitions to | |||
|  |   properly preprocess files for incremental release builds due to deep | |||
|  |   dependencies. | |||
|  | 
 | |||
|  |   **Default**: [] (empty) | |||
|  | 
 | |||
|  | 
 | |||
|  | Example [:defines] YAML blurb | |||
|  | 
 | |||
|  | ```yaml | |||
|  | :defines: | |||
|  |   :test: | |||
|  |     - UNIT_TESTING  #for select cases in source to allow testing with a changed behavior or interface | |||
|  |     - OFF=0 | |||
|  |     - ON=1 | |||
|  |     - FEATURE_X=ON | |||
|  |   :source: | |||
|  |     - FEATURE_X=ON | |||
|  | ``` | |||
|  | 
 | |||
|  | 
 | |||
|  | **libraries**: command line defines used in test and release compilation by configured tools | |||
|  | 
 | |||
|  | Ceedling allows you to pull in specific libraries for the purpose of release and test builds. | |||
|  | It has a few levels of support for this. Start by adding a :libraries main section in your | |||
|  | configuration. In this section, you can optionally have the following subsections: | |||
|  | 
 | |||
|  | * `test`: | |||
|  | 
 | |||
|  |   Library files that should be injected into your tests when linking occurs. | |||
|  |   These can be specified as either relative or absolute paths. These files MUST | |||
|  |   exist when the test attempts to build. | |||
|  | 
 | |||
|  | * `source`: | |||
|  | 
 | |||
|  |   Library files that should be injected into your release when linking occurs. These | |||
|  |   can be specified as either relative or absolute paths. These files MUST exist when | |||
|  |   the release attempts to build UNLESS you are using the subprojects plugin. In that | |||
|  |   case, it will attempt to build that library for you as a dynamic dependency. | |||
|  | 
 | |||
|  | * `system`: | |||
|  | 
 | |||
|  |   These libraries are assumed to be in the tool path somewhere and shouldn't need to be | |||
|  |   specified. The libraries added here will be injected into releases and tests. | |||
|  | 
 | |||
|  | * `flag`: | |||
|  | 
 | |||
|  |   This is the method of adding an argument for each library. For example, gcc really likes | |||
|  |   it when you specify “-l${1}” | |||
|  | 
 | |||
|  | Notes: | |||
|  | 
 | |||
|  | * If you've specified your own link step, you are going to want to add ${4} to your argument | |||
|  | list in the place where library files should be added to the command call. For gcc, this is | |||
|  | often the very end. Other tools may vary. | |||
|  | 
 | |||
|  | 
 | |||
|  | **flags**: configure per-file compilation and linking flags | |||
|  | 
 | |||
|  | Ceedling tools (see later [:tools] section) are used to configure | |||
|  | compilation and linking of test and source files. These tool | |||
|  | configurations are a one-size-fits-all approach. Should individual files | |||
|  | require special compilation or linking flags, the settings in the | |||
|  | [:flags] section work in conjunction with tool definitions by way of | |||
|  | argument substitution to achieve this. | |||
|  | 
 | |||
|  | * `release`: | |||
|  | 
 | |||
|  |   [:compile] or [:link] flags for release build | |||
|  | 
 | |||
|  | * `test`: | |||
|  | 
 | |||
|  |   [:compile] or [:link] flags for test build | |||
|  | 
 | |||
|  | Notes: | |||
|  | 
 | |||
|  | * Ceedling works with the [:release] and [:test] build contexts | |||
|  |   as-is; plugins can add additional contexts | |||
|  | 
 | |||
|  | * Only [:compile] and [:link] are recognized operations beneath | |||
|  |   a context | |||
|  | 
 | |||
|  | * File specifiers do not include a path or file extension | |||
|  | 
 | |||
|  | * File specifiers are case sensitive (must match original file | |||
|  |   name) | |||
|  | 
 | |||
|  | * File specifiers do support regular expressions if encased in quotes | |||
|  | 
 | |||
|  | * '*' is a special (optional) file specifier to provide flags | |||
|  |   to all files not otherwise specified | |||
|  | 
 | |||
|  | 
 | |||
|  | Example [:flags] YAML blurb | |||
|  | 
 | |||
|  | ```yaml | |||
|  | :flags: | |||
|  |   :release: | |||
|  |     :compile: | |||
|  |       :main:       # add '-Wall' to compilation of main.c | |||
|  |         - -Wall | |||
|  |       :fan:        # add '--O2' to compilation of fan.c | |||
|  |         - --O2 | |||
|  |       :'test_.+':   # add '-pedantic' to all test-files | |||
|  |         - -pedantic | |||
|  |       :*:          # add '-foo' to compilation of all files not main.c or fan.c | |||
|  |         - -foo | |||
|  |   :test: | |||
|  |     :compile: | |||
|  |       :main:       # add '--O1' to compilation of main.c as part of test builds including main.c | |||
|  |         - --O1 | |||
|  |     :link: | |||
|  |       :test_main:  # add '--bar --baz' to linking of test_main.exe | |||
|  |         - --bar | |||
|  |         - --baz | |||
|  | ``` | |||
|  | 
 | |||
|  | Ceedling sets values for a subset of CMock settings. All CMock | |||
|  | options are available to be set, but only those options set by | |||
|  | Ceedling in an automated fashion are documented below. See CMock | |||
|  | documentation. | |||
|  | 
 | |||
|  | **cmock**: configure CMock's code generation options and set symbols used to modify CMock's compiled features | |||
|  | Ceedling sets values for a subset of CMock settings. All CMock options are available to be set, but only those options set by Ceedling in an automated fashion are documented below. See CMock documentation. | |||
|  | 
 | |||
|  | * `enforce_strict_ordering`: | |||
|  | 
 | |||
|  |   Tests fail if expected call order is not same as source order | |||
|  | 
 | |||
|  |   **Default**: TRUE | |||
|  | 
 | |||
|  | * `mock_path`: | |||
|  | 
 | |||
|  |   Path for generated mocks | |||
|  | 
 | |||
|  |   **Default**: <build path>/tests/mocks | |||
|  | 
 | |||
|  | * `defines`: | |||
|  | 
 | |||
|  |   List of conditional compilation symbols used to configure CMock's | |||
|  |   compiled features. See CMock documentation to understand available | |||
|  |   options. No symbols must be set unless defaults are inappropriate for | |||
|  |   your specific environment. All symbols are used only by Ceedling to | |||
|  |   compile CMock C code; contents of [:defines] are ignored by CMock's | |||
|  |   Ruby code when instantiated. | |||
|  | 
 | |||
|  |   **Default**: [] (empty) | |||
|  | 
 | |||
|  | * `verbosity`: | |||
|  | 
 | |||
|  |   If not set, defaults to Ceedling's verbosity level | |||
|  | 
 | |||
|  | * `plugins`: | |||
|  | 
 | |||
|  |   If [:project][:use_exceptions] is enabled, the internal plugins list is pre-populated with 'cexception'. | |||
|  | 
 | |||
|  |   Whether or not you have included [:cmock][:plugins] in your | |||
|  |   configuration file, Ceedling automatically adds 'cexception' to the | |||
|  |   plugin list if exceptions are enabled. To add to the list Ceedling | |||
|  |   provides CMock, simply add [:cmock][:plugins] to your configuration | |||
|  |   and specify your desired additional plugins. | |||
|  | 
 | |||
|  | * `includes`: | |||
|  | 
 | |||
|  |   If [:cmock][:unity_helper] set, pre-populated with unity_helper file | |||
|  |   name (no path). | |||
|  | 
 | |||
|  |   The [:cmock][:includes] list works identically to the plugins list | |||
|  |   above with regard to adding additional files to be inserted within | |||
|  |   mocks as #include statements. | |||
|  | 
 | |||
|  | 
 | |||
|  | The last four settings above are directly tied to other Ceedling | |||
|  | settings; hence, why they are listed and explained here. The | |||
|  | first setting above, [:enforce_strict_ordering], defaults | |||
|  | to FALSE within CMock. It is set to TRUE by default in Ceedling | |||
|  | as our way of encouraging you to use strict ordering. It's a teeny | |||
|  | bit more expensive in terms of code generated, test execution | |||
|  | time, and complication in deciphering test failures. However, | |||
|  | it's good practice. And, of course, you can always disable it | |||
|  | by overriding the value in the Ceedling YAML configuration file. | |||
|  | 
 | |||
|  | 
 | |||
|  | **cexception**: configure symbols used to modify CException's compiled features | |||
|  | 
 | |||
|  | * `defines`: | |||
|  | 
 | |||
|  |   List of conditional compilation symbols used to configure CException's | |||
|  |   features in its source and header files. See CException documentation | |||
|  |   to understand available options. No symbols must be set unless the | |||
|  |   defaults are inappropriate for your specific environment. | |||
|  | 
 | |||
|  |   **Default**: [] (empty) | |||
|  | 
 | |||
|  | 
 | |||
|  | **unity**: configure symbols used to modify Unity's compiled features | |||
|  | 
 | |||
|  | * `defines`: | |||
|  | 
 | |||
|  |   List of conditional compilation symbols used to configure Unity's | |||
|  |   features in its source and header files. See Unity documentation to | |||
|  |   understand available options. No symbols must be set unless the | |||
|  |   defaults are inappropriate for your specific environment. Most Unity  | |||
|  |   defines can be easily configured through the YAML file. | |||
|  | 
 | |||
|  |   **Default**: [] (empty) | |||
|  | 
 | |||
|  | Example [:unity] YAML blurbs | |||
|  | ```yaml | |||
|  | :unity: #itty bitty processor & toolchain with limited test execution options | |||
|  |   :defines: | |||
|  |     - UNITY_INT_WIDTH=16           #16 bit processor without support for 32 bit instructions | |||
|  |     - UNITY_EXCLUDE_FLOAT          #no floating point unit | |||
|  | 
 | |||
|  | :unity: #great big gorilla processor that grunts and scratches | |||
|  |   :defines: | |||
|  |     - UNITY_SUPPORT_64                    #big memory, big counters, big registers | |||
|  |     - UNITY_LINE_TYPE=\"unsigned int\"    #apparently we're using really long test files, | |||
|  |     - UNITY_COUNTER_TYPE=\"unsigned int\" #and we've got a ton of test cases in those test files | |||
|  |     - UNITY_FLOAT_TYPE=\"double\"         #you betcha | |||
|  | ``` | |||
|  | 
 | |||
|  | 
 | |||
|  | Notes on Unity configuration: | |||
|  | 
 | |||
|  | * **Verification** - Ceedling does no verification of your configuration | |||
|  |   values. In a properly configured setup, your Unity configuration | |||
|  |   values are processed, collected together with any test define symbols | |||
|  |   you specify elsewhere, and then passed to your toolchain during test | |||
|  |   compilation. Unity's conditional compilation statements, your | |||
|  |   toolchain's preprocessor, and/or your toolchain's compiler will | |||
|  |   complain appropriately if your specified configuration values are | |||
|  |   incorrect, incomplete, or incompatible. | |||
|  | 
 | |||
|  | * **Routing $stdout** - Unity defaults to using `putchar()` in C's | |||
|  |   standard library to display test results. For more exotic environments | |||
|  |   than a desktop with a terminal (e.g. running tests directly on a | |||
|  |   non-PC target), you have options. For example, you could create a | |||
|  |   routine that transmits a character via RS232 or USB. Once you have | |||
|  |   that routine, you can replace `putchar()` calls in Unity by overriding | |||
|  |   the function-like macro `UNITY_OUTPUT_CHAR`. Consult your toolchain | |||
|  |   and shell documentation. Eventhough this can also be defined in the YAML file | |||
|  |   most shell environments do not handle parentheses as command line arguments  | |||
|  |   very well. To still be able to add this functionality all necessary  | |||
|  |   options can be defined in the `unity_config.h`. Unity needs to be told to look for  | |||
|  |   the `unity_config.h` in the YAML file, though.  | |||
|  | 
 | |||
|  | Example [:unity] YAML blurbs | |||
|  | ```yaml | |||
|  | :unity: | |||
|  |   :defines: | |||
|  |   	- UNITY_INCLUDE_CONFIG_H | |||
|  | ``` | |||
|  | 
 | |||
|  | Example unity_config.h | |||
|  | ``` | |||
|  | #ifndef UNITY_CONFIG_H
 | |||
|  | #define UNITY_CONFIG_H
 | |||
|  | 
 | |||
|  | #include "uart_output.h" //Helper library for your custom environment
 | |||
|  | 
 | |||
|  | #define UNITY_INT_WIDTH 16
 | |||
|  | #define UNITY_OUTPUT_START() uart_init(F_CPU, BAUD) //Helperfunction to init UART
 | |||
|  | #define UNITY_OUTPUT_CHAR(a) uart_putchar(a) //Helperfunction to forward char via UART
 | |||
|  | #define UNITY_OUTPUT_COMPLETE() uart_complete() //Helperfunction to inform that test has ended
 | |||
|  | 
 | |||
|  | #endif
 | |||
|  | ``` | |||
|  | 
 | |||
|  | 
 | |||
|  | **tools**: a means for representing command line tools for use under | |||
|  | Ceedling's automation framework | |||
|  | 
 | |||
|  | Ceedling requires a variety of tools to work its magic. By default, | |||
|  | the GNU toolchain (gcc, cpp, as) are configured and ready for | |||
|  | use with no additions to the project configuration YAML file. | |||
|  | However, as most work will require a project-specific toolchain, | |||
|  | Ceedling provides a generic means for specifying / overriding | |||
|  | tools. | |||
|  | 
 | |||
|  | * `test_compiler`: | |||
|  | 
 | |||
|  |   Compiler for test & source-under-test code | |||
|  |   ${1}: input source ${2}: output object ${3}: optional output list ${4}: optional output dependencies file | |||
|  | 
 | |||
|  |   **Default**: gcc | |||
|  | 
 | |||
|  | * `test_linker`: | |||
|  | 
 | |||
|  |   Linker to generate test fixture executables | |||
|  |   ${1}: input objects ${2}: output binary ${3}: optional output map ${4}: optional library list | |||
|  | 
 | |||
|  |   **Default**: gcc | |||
|  | 
 | |||
|  | * `test_fixture`: | |||
|  | 
 | |||
|  |   Executable test fixture | |||
|  |   ${1}: simulator as executable with ${1} as input binary file argument or native test executable | |||
|  | 
 | |||
|  |   **Default**: ${1} | |||
|  | 
 | |||
|  | * `test_includes_preprocessor`: | |||
|  | 
 | |||
|  |   Extractor of #include statements | |||
|  |   ${1}: input source file | |||
|  | 
 | |||
|  |   **Default**: cpp | |||
|  | 
 | |||
|  | * `test_file_preprocessor`: | |||
|  | 
 | |||
|  |   Preprocessor of test files (macros, conditional compilation statements) | |||
|  |   ${1}: input source file ${2}: preprocessed output source file | |||
|  | 
 | |||
|  |   **Default**: gcc | |||
|  | 
 | |||
|  | * `test_dependencies_generator`: | |||
|  | 
 | |||
|  |   Discovers deep dependencies of source & test (for incremental builds) | |||
|  |   ${1}: input source file ${2}: compiled object filepath ${3}: output dependencies file | |||
|  | 
 | |||
|  |   **Default**: gcc | |||
|  | 
 | |||
|  | * `release_compiler`: | |||
|  | 
 | |||
|  |   Compiler for release source code | |||
|  |   ${1}: input source ${2}: output object ${3}: optional output list ${4}: optional output dependencies file | |||
|  | 
 | |||
|  |   **Default**: gcc | |||
|  | 
 | |||
|  | * `release_assembler`: | |||
|  | 
 | |||
|  |   Assembler for release assembly code | |||
|  |   ${1}: input assembly source file ${2}: output object file | |||
|  | 
 | |||
|  |   **Default**: as | |||
|  | 
 | |||
|  | * `release_linker`: | |||
|  | 
 | |||
|  |   Linker for release source code | |||
|  |   ${1}: input objects ${2}: output binary ${3}: optional output map ${4}: optional library list | |||
|  | 
 | |||
|  |   **Default**: gcc | |||
|  | 
 | |||
|  | * `release_dependencies_generator`: | |||
|  | 
 | |||
|  |   Discovers deep dependencies of source files (for incremental builds) | |||
|  |   ${1}: input source file ${2}: compiled object filepath ${3}: output dependencies file | |||
|  | 
 | |||
|  |   **Default**: gcc | |||
|  | 
 | |||
|  | 
 | |||
|  | A Ceedling tool has a handful of configurable elements: | |||
|  | 
 | |||
|  | 1. [:executable] (required) - Command line executable having | |||
|  |    the form of: | |||
|  | 
 | |||
|  | 2. [:arguments] (required) - List of command line arguments | |||
|  |    and substitutions | |||
|  | 
 | |||
|  | 3. [:name] - Simple name (e.g. "nickname") of tool beyond its | |||
|  |    executable name (if not explicitly set then Ceedling will | |||
|  |    form a name from the tool's YAML entry name) | |||
|  | 
 | |||
|  | 4. [:stderr_redirect] - Control of capturing $stderr messages | |||
|  |    {:none, :auto, :win, :unix, :tcsh}. | |||
|  |    Defaults to :none if unspecified; create a custom entry by | |||
|  |    specifying a simple string instead of any of the available | |||
|  |    symbols. | |||
|  | 
 | |||
|  | 5. [:background_exec] - Control execution as background process | |||
|  |    {:none, :auto, :win, :unix}. | |||
|  |    Defaults to :none if unspecified. | |||
|  | 
 | |||
|  | 
 | |||
|  | Tool Element Runtime Substitution | |||
|  | --------------------------------- | |||
|  | 
 | |||
|  | To accomplish useful work on multiple files, a configured tool will most | |||
|  | often require that some number of its arguments or even the executable | |||
|  | itself change for each run. Consequently, every tool's argument list and | |||
|  | executable field possess two means for substitution at runtime. Ceedling | |||
|  | provides two kinds of inline Ruby execution and a notation for | |||
|  | populating elements with dynamically gathered values within the build | |||
|  | environment. | |||
|  | 
 | |||
|  | Tool Element Runtime Substitution: Inline Ruby Execution | |||
|  | -------------------------------------------------------- | |||
|  | 
 | |||
|  | In-line Ruby execution works similarly to that demonstrated for the | |||
|  | [:environment] section except that substitution occurs as the tool is | |||
|  | executed and not at the time the configuration file is first scanned. | |||
|  | 
 | |||
|  | * `#{...}`: | |||
|  | 
 | |||
|  |   Ruby string substitution pattern wherein the containing string is | |||
|  |   expanded to include the string generated by Ruby code between the | |||
|  |   braces. Multiple instances of this expansion can occur within a single | |||
|  |   tool element entry string. Note that if this string substitution | |||
|  |   pattern occurs at the very beginning of a string in the YAML | |||
|  |   configuration the entire string should be enclosed in quotes (see the | |||
|  |   [:environment] section for further explanation on this point). | |||
|  | 
 | |||
|  | * `{...} `: | |||
|  | 
 | |||
|  |   If an entire tool element string is enclosed with braces, it signifies | |||
|  |   that Ceedling should execute the Ruby code contained within those | |||
|  |   braces. Say you have a collection of paths on disk and some of those | |||
|  |   paths include spaces. Further suppose that a single tool that must use | |||
|  |   those paths requires those spaces to be escaped, but all other uses of | |||
|  |   those paths requires the paths to remain unchanged. You could use this | |||
|  |   Ceedling feature to insert Ruby code that iterates those paths and | |||
|  |   escapes those spaces in the array as used by the tool of this example. | |||
|  | 
 | |||
|  | Tool Element Runtime Substitution: Notational Substitution | |||
|  | ---------------------------------------------------------- | |||
|  | 
 | |||
|  | A Ceedling tool's other form of dynamic substitution relies on a '$' | |||
|  | notation. These '$' operators can exist anywhere in a string and can be | |||
|  | decorated in any way needed. To use a literal '$', escape it as '\\$'. | |||
|  | 
 | |||
|  | * `$`: | |||
|  | 
 | |||
|  |   Simple substitution for value(s) globally available within the runtime | |||
|  |   (most often a string or an array). | |||
|  | 
 | |||
|  | * `${#}`: | |||
|  | 
 | |||
|  |   When a Ceedling tool's command line is expanded from its configured | |||
|  |   representation and used within Ceedling Ruby code, certain calls to | |||
|  |   that tool will be made with a parameter list of substitution values. | |||
|  |   Each numbered substitution corresponds to a position in a parameter | |||
|  |   list. Ceedling Ruby code expects that configured compiler and linker | |||
|  |   tools will contain ${1} and ${2} replacement arguments. In the case of | |||
|  |   a compiler ${1} will be a C code file path, and ${2} will be the file | |||
|  |   path of the resulting object file. For a linker ${1} will be an array | |||
|  |   of object files to link, and ${2} will be the resulting binary | |||
|  |   executable. For an executable test fixture ${1} is either the binary | |||
|  |   executable itself (when using a local toolchain such as gcc) or a | |||
|  |   binary input file given to a simulator in its arguments. | |||
|  | 
 | |||
|  | 
 | |||
|  | Example [:tools] YAML blurbs | |||
|  | 
 | |||
|  | ```yaml | |||
|  | :tools: | |||
|  |   :test_compiler: | |||
|  |      :executable: compiler              #exists in system search path | |||
|  |      :name: 'acme test compiler' | |||
|  |      :arguments: | |||
|  |         - -I"$": COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE               #expands to -I search paths | |||
|  |         - -I"$": COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR   #expands to -I search paths | |||
|  |         - -D$: COLLECTION_DEFINES_TEST_AND_VENDOR  #expands to all -D defined symbols | |||
|  |         - --network-license             #simple command line argument | |||
|  |         - -optimize-level 4             #simple command line argument | |||
|  |         - "#{`args.exe -m acme.prj`}"   #in-line ruby sub to shell out & build string of arguments | |||
|  |         - -c ${1}                       #source code input file (Ruby method call param list sub) | |||
|  |         - -o ${2}                       #object file output (Ruby method call param list sub) | |||
|  |   :test_linker: | |||
|  |      :executable: /programs/acme/bin/linker.exe    #absolute file path | |||
|  |      :name: 'acme test linker' | |||
|  |      :arguments: | |||
|  |         - ${1}               #list of object files to link (Ruby method call param list sub) | |||
|  |         - -l$-lib:           #inline yaml array substitution to link in foo-lib and bar-lib | |||
|  |            - foo | |||
|  |            - bar | |||
|  |         - -o ${2}            #executable file output (Ruby method call param list sub) | |||
|  |   :test_fixture: | |||
|  |      :executable: tools/bin/acme_simulator.exe  #relative file path to command line simulator | |||
|  |      :name: 'acme test fixture' | |||
|  |      :stderr_redirect: :win                     #inform Ceedling what model of $stderr capture to use | |||
|  |      :arguments: | |||
|  |         - -mem large   #simple command line argument | |||
|  |         - -f "${1}"    #binary executable input file to simulator (Ruby method call param list sub) | |||
|  | ``` | |||
|  | 
 | |||
|  | Resulting command line constructions from preceding example [:tools] YAML blurbs | |||
|  | 
 | |||
|  |     > compiler -I"/usr/include” -I”project/tests”
 | |||
|  |       -I"project/tests/support” -I”project/source” -I”project/include” | |||
|  |       -DTEST -DLONG_NAMES -network-license -optimize-level 4 arg-foo | |||
|  |       arg-bar arg-baz -c project/source/source.c -o | |||
|  |       build/tests/out/source.o | |||
|  | 
 | |||
|  | [notes: (1.) "arg-foo arg-bar arg-baz" is a fabricated example | |||
|  | string collected from $stdout as a result of shell execution | |||
|  | of args.exe | |||
|  | (2.) the -c and -o arguments are | |||
|  | fabricated examples simulating a single compilation step for | |||
|  | a test; ${1} & ${2} are single files] | |||
|  | 
 | |||
|  |     > \programs\acme\bin\linker.exe thing.o unity.o
 | |||
|  |       test_thing_runner.o test_thing.o mock_foo.o mock_bar.o -lfoo-lib | |||
|  |       -lbar-lib -o build\tests\out\test_thing.exe | |||
|  | 
 | |||
|  | [note: in this scenario ${1} is an array of all the object files | |||
|  | needed to link a test fixture executable] | |||
|  | 
 | |||
|  |     > tools\bin\acme_simulator.exe -mem large -f "build\tests\out\test_thing.bin 2>&1”
 | |||
|  | 
 | |||
|  | [note: (1.) :executable could have simply been ${1} - if we were compiling | |||
|  | and running native executables instead of cross compiling (2.) we're using | |||
|  | $stderr redirection to allow us to capture simulator error messages to | |||
|  | $stdout for display at the run's conclusion] | |||
|  | 
 | |||
|  | 
 | |||
|  | Notes: | |||
|  | 
 | |||
|  | * The upper case names are Ruby global constants that Ceedling | |||
|  |   builds | |||
|  | 
 | |||
|  | * "COLLECTION_" indicates that Ceedling did some work to assemble | |||
|  |   the list. For instance, expanding path globs, combining multiple | |||
|  |   path globs into a convenient summation, etc. | |||
|  | 
 | |||
|  | * At present, $stderr redirection is primarily used to capture | |||
|  |   errors from test fixtures so that they can be displayed at the | |||
|  |   conclusion of a test run. For instance, if a simulator detects | |||
|  |   a memory access violation or a divide by zero error, this notice | |||
|  |   might go unseen in all the output scrolling past in a terminal. | |||
|  | 
 | |||
|  | * The preprocessing tools can each be overridden with non-gcc | |||
|  |   equivalents. However, this is an advanced feature not yet | |||
|  |   documented and requires that the replacement toolchain conform | |||
|  |   to the same conventions used by gcc. | |||
|  | 
 | |||
|  | **Ceedling Collection Used in Compilation**: | |||
|  | 
 | |||
|  | * `COLLECTION_PATHS_TEST`: | |||
|  | 
 | |||
|  |   All test paths | |||
|  | 
 | |||
|  | * `COLLECTION_PATHS_SOURCE`: | |||
|  | 
 | |||
|  |   All source paths | |||
|  | 
 | |||
|  | * `COLLECTION_PATHS_INCLUDE`: | |||
|  | 
 | |||
|  |   All include paths | |||
|  | 
 | |||
|  | * `COLLECTION_PATHS_SUPPORT`: | |||
|  | 
 | |||
|  |   All test support paths | |||
|  | 
 | |||
|  | * `COLLECTION_PATHS_SOURCE_AND_INCLUDE`: | |||
|  | 
 | |||
|  |   All source and include paths | |||
|  | 
 | |||
|  | * `COLLECTION_PATHS_SOURCE_INCLUDE_VENDOR`: | |||
|  | 
 | |||
|  |   All source and include paths + applicable vendor paths (e.g. | |||
|  |   CException's source path if exceptions enabled) | |||
|  | 
 | |||
|  | * `COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE`: | |||
|  | 
 | |||
|  |   All test toolchain include paths | |||
|  | 
 | |||
|  | * `COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE`: | |||
|  | 
 | |||
|  |   All test, source, and include paths | |||
|  | 
 | |||
|  | * `COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR`: | |||
|  | 
 | |||
|  |   All test, source, include, and applicable vendor paths (e.g. Unity's | |||
|  |   source path plus CMock and CException's source paths if mocks and | |||
|  |   exceptions are enabled) | |||
|  | 
 | |||
|  | * `COLLECTION_PATHS_RELEASE_TOOLCHAIN_INCLUDE`: | |||
|  | 
 | |||
|  |   All release toolchain include paths | |||
|  | 
 | |||
|  | * `COLLECTION_DEFINES_TEST_AND_VENDOR`: | |||
|  | 
 | |||
|  |   All symbols specified in [:defines][:test] + symbols defined for | |||
|  |   enabled vendor tools - e.g. [:unity][:defines], [:cmock][:defines], | |||
|  |   and [:cexception][:defines] | |||
|  | 
 | |||
|  | * `COLLECTION_DEFINES_RELEASE_AND_VENDOR`: | |||
|  | 
 | |||
|  |   All symbols specified in [:defines][:release] plus symbols defined by | |||
|  | [:cexception][:defines] if exceptions are ena bled | |||
|  | 
 | |||
|  | 
 | |||
|  | Notes: | |||
|  | 
 | |||
|  | * Other collections exist within Ceedling. However, they are | |||
|  |   only useful for advanced features not yet documented. | |||
|  | 
 | |||
|  | * Wherever multiple path lists are combined for use Ceedling prioritizes | |||
|  |   path groups as follows: test paths, support paths, source paths, include | |||
|  |   paths. | |||
|  |   This can be useful, for instance, in certain testing scenarios | |||
|  |   where we desire Ceedling or the compiler to find a stand-in header file | |||
|  |   before the actual source header file of the same name. | |||
|  | 
 | |||
|  | 
 | |||
|  | **plugins**: Ceedling extensions | |||
|  | 
 | |||
|  | * `load_paths`: | |||
|  | 
 | |||
|  |   Base paths to search for plugin subdirectories or extra ruby functionalit | |||
|  | 
 | |||
|  |   **Default**: [] (empty) | |||
|  | 
 | |||
|  | * `enabled`: | |||
|  | 
 | |||
|  |   List of plugins to be used - a plugin's name is identical to the | |||
|  |   subdirectory that contains it (and the name of certain files within | |||
|  |   that subdirectory) | |||
|  | 
 | |||
|  |   **Default**: [] (empty) | |||
|  | 
 | |||
|  | 
 | |||
|  | Plugins can provide a variety of added functionality to Ceedling. In | |||
|  | general use, it's assumed that at least one reporting plugin will be | |||
|  | used to format test results. However, if no reporting plugins are | |||
|  | specified, Ceedling will print to `$stdout` the (quite readable) raw | |||
|  | test results from all test fixtures executed. | |||
|  | 
 | |||
|  | Example [:plugins] YAML blurb | |||
|  | 
 | |||
|  | ```yaml | |||
|  | :plugins: | |||
|  |   :load_paths: | |||
|  |     - project/tools/ceedling/plugins  #home to your collection of plugin directories | |||
|  |     - project/support                 #maybe home to some ruby code your custom plugins share | |||
|  |   :enabled: | |||
|  |     - stdout_pretty_tests_report      #nice test results at your command line | |||
|  |     - our_custom_code_metrics_report  #maybe you needed line count and complexity metrics, so you | |||
|  |                                       #created a plugin to scan all your code and collect that info | |||
|  | ``` | |||
|  | 
 | |||
|  | * `stdout_pretty_tests_report`: | |||
|  | 
 | |||
|  |   Prints to $stdout a well-formatted list of ignored and failed tests, | |||
|  |   final test counts, and any extraneous output (e.g. printf statements | |||
|  |   or simulator memory errors) collected from executing the test | |||
|  |   fixtures. Meant to be used with runs at the command line. | |||
|  | 
 | |||
|  | * `stdout_ide_tests_report`: | |||
|  | 
 | |||
|  |   Prints to $stdout simple test results formatted such that an IDE | |||
|  |   executing test-related Rake tasks can recognize file paths and line | |||
|  |   numbers in test failures, etc. Thus, you can click a test result in | |||
|  |   your IDE's execution window and jump to the failure (or ignored test) | |||
|  |   in your test file (obviously meant to be used with an [IDE like | |||
|  |   Eclipse][ide], etc). | |||
|  | 
 | |||
|  |   [ide]: http://throwtheswitch.org/white-papers/using-with-ides.html | |||
|  | 
 | |||
|  | * `xml_tests_report`: | |||
|  | 
 | |||
|  |   Creates an XML file of test results in the xUnit format (handy for | |||
|  |   Continuous Integration build servers or as input to other reporting | |||
|  |   tools). Produces a file report.xml in <build root>/artifacts/tests. | |||
|  | 
 | |||
|  | * `bullseye`: | |||
|  | 
 | |||
|  |   Adds additional Rake tasks to execute tests with the commercial code | |||
|  |   coverage tool provided by [Bullseye][]. See readme.txt inside the bullseye | |||
|  |   plugin directory for configuration and use instructions. Note: | |||
|  |   Bullseye only works with certain compilers and linkers (healthy list | |||
|  |   of supported toolchains though). | |||
|  | 
 | |||
|  |   [bullseye]: http://www.bullseye.com | |||
|  | 
 | |||
|  | * `gcov`: | |||
|  | 
 | |||
|  |   Adds additional Rake tasks to execute tests with the GNU code coverage | |||
|  |   tool [gcov][]. See readme.txt inside the gcov directory for configuration | |||
|  |   and use instructions. Only works with GNU compiler and linker. | |||
|  | 
 | |||
|  |   [gcov]: http://gcc.gnu.org/onlinedocs/gcc/Gcov.html | |||
|  | 
 | |||
|  | * `warnings_report`: | |||
|  | 
 | |||
|  |   Scans compiler and linker `$stdout / $stderr` output for the word | |||
|  |   'warning' (case insensitive). All code warnings (or tool warnings) are | |||
|  |   logged to a file warnings.log in the appropriate `<build | |||
|  |   root>/artifacts` directory (e.g. test/ for test tasks, `release/` for a | |||
|  |   release build, or even `bullseye/` for bullseye runs). | |||
|  | 
 | |||
|  | Module Generator | |||
|  | ======================== | |||
|  | Ceedling includes a plugin called module_generator that will create a source, header and test file for you. | |||
|  | There are several possibilities to configure this plugin through your project.yml to suit your project's needs. | |||
|  | 
 | |||
|  | Directory Structure | |||
|  | ------------------------------------------- | |||
|  | 
 | |||
|  | The default configuration for directory/project structure is: | |||
|  | ```yaml | |||
|  | :module_generator: | |||
|  |   :project_root: ./ | |||
|  |   :source_root: src/ | |||
|  |   :test_root: test/ | |||
|  | ``` | |||
|  | You can change these variables in your project.yml file to comply with your project's directory structure. | |||
|  | 
 | |||
|  | If you call `ceedling module:create`, it will create three files: | |||
|  | 1. A source file in the source_root | |||
|  | 2. A header file in the source_root | |||
|  | 3. A test file in the test_root | |||
|  | 
 | |||
|  | If you want your header file to be in another location, | |||
|  | you can specify the ':inc_root:" in your project.yml file: | |||
|  | ```yaml | |||
|  | :module_generator: | |||
|  |   :inc_root: inc/ | |||
|  | ``` | |||
|  | The module_generator will then create the header file in your defined ':inc_root:'. | |||
|  | By default, ':inc_root:' is not defined so the module_generator will use the source_root. | |||
|  | 
 | |||
|  | Sometimes, your project can't be divided into a single src, inc, and test folder. You have several directories | |||
|  | with sources/..., something like this for example: | |||
|  | <project_root> | |||
|  |  - myDriver | |||
|  |    - src | |||
|  |    - inc | |||
|  |    - test | |||
|  |  - myOtherDriver | |||
|  |    - src | |||
|  |    - inc | |||
|  |    - test | |||
|  |  - ... | |||
|  | 
 | |||
|  | Don't worry, you don't have to manually create the source/header/test files. | |||
|  | The module_generator can accept a path to create a source_root/inc_root/test_root folder with your files: | |||
|  | `ceedling module:create[<module_root_path>:<module_name>]` | |||
|  | 
 | |||
|  | F.e., applied to the above project structure: | |||
|  | `ceedling module:create[myOtherDriver:driver]` | |||
|  | This will make the module_generator run in the subdirectory 'myOtherDriver' and generate the module files | |||
|  | for you in that directory. So, this command will generate the following files: | |||
|  | 1. A source file 'driver.c' in <project_root>/myOtherDriver/<source_root> | |||
|  | 2. A header file 'driver.h' in <project_root>/myOtherDriver/<source_root> (or <inc_root> if specified) | |||
|  | 3. A test file 'test_driver.c' in <project_root>/myOtherDriver/<test_root> | |||
|  | 
 | |||
|  | Naming | |||
|  | ------------------------------------------- | |||
|  | By default, the module_generator will generate your files in lowercase. | |||
|  | `ceedling module:create[mydriver]` and `ceedling module:create[myDriver]`(note the uppercase) will generate the same files: | |||
|  | 1. mydriver.c | |||
|  | 2. mydriver.h | |||
|  | 3. test_mydriver.c | |||
|  | 
 | |||
|  | You can configure the module_generator to use a differect naming mechanism through the project.yml: | |||
|  | ```yaml | |||
|  | :module_generator: | |||
|  |   :naming: "camel" | |||
|  | ``` | |||
|  | There are other possibilities as well (bumpy, camel, snake, caps). | |||
|  | Refer to the unity module generator for more info (the unity module generator is used under the hood by module_generator). | |||
|  | 
 | |||
|  | Advanced Topics (Coming) | |||
|  | ======================== | |||
|  | 
 | |||
|  | Modifying Your Configuration without Modifying Your Project File: Option Files & User Files | |||
|  | ------------------------------------------------------------------------------------------- | |||
|  | 
 | |||
|  | Modifying your project file without modifying your project file | |||
|  | 
 | |||
|  | Debugging and/or printf() | |||
|  | ------------------------- | |||
|  | 
 | |||
|  | When you gotta get your hands dirty... | |||
|  | 
 | |||
|  | Ceedling Plays Nice with Others - Using Ceedling for Tests Alongside Another Release Build Setup | |||
|  | ------------------------------------------------------------------------------------------------ | |||
|  | 
 | |||
|  | You've got options. | |||
|  | 
 | |||
|  | Adding Handy Rake Tasks for Your Project (without Fancy Pants Custom Plugins) | |||
|  | ----------------------------------------------------------------------------- | |||
|  | 
 | |||
|  | Simple as snot. | |||
|  | 
 | |||
|  | Working with Non-Desktop Testing Environments | |||
|  | --------------------------------------------- | |||
|  | 
 | |||
|  | For those crazy platforms lacking command line simulators and for which | |||
|  | cross-compiling on the desktop just ain't gonna get it done. | |||
|  | 
 | |||
|  | Creating Custom Plugins | |||
|  | ----------------------- | |||
|  | 
 | |||
|  | Oh boy. This is going to take some explaining. |