---
title: "Tips and Tricks - Platform-specific C File Set"
canonical_url: https://developer.repebble.com/blog/2015/05/19/tips-and-tricks-platform-specific-c-file-sets/
last_updated: 2026-10-11
sdk_version: 4.33.1
---
# Tips and Tricks - Platform-specific C File Set

Source: https://developer.repebble.com/blog/2015/05/19/tips-and-tricks-platform-specific-c-file-sets/

This is the Pebble Developer Blog. For general Pebble news and announcements, visit the main blog at [repebble.com/blog](https://repebble.com/blog).

- 19 May 2015
- [Chris Lewis](https://developer.repebble.com/blog/authors/chrislewis/)
- [Beautiful Code](https://developer.repebble.com/blog/tags/beautiful-code/)
- [Comments](https://developer.repebble.com/blog/2015/05/19/tips-and-tricks-platform-specific-c-file-sets.md#comments)

In [the last Tips and Tricks blog post](https://developer.repebble.com/blog/2015/05/13/tips-and-tricks-transparent-images.md) we looked at drawing transparent images on both the Aplite and Basalt platforms.

This time around, we will look at a `wscript` modification that can allow you to build a Pebble project when you have two completely separate sets of C source files; one set for Aplite, and another for Basalt.

Note: This technique can be applied only to local SDK projects, where access to `wscript` is available. This means that it cannot be used in CloudPebble projects.

> Update 05/20/15: There was an error in the JS code sample given at the end of this post, which has now been corrected.

## The Preprocessor Approach

In the 3.0 Migration Guide we recommend using preprocessor directives such as `PBL_PLATFORM_APLITE` and `PBL_PLATFORM_BASALT` to mark code to be compiled only on that particular platform. This helps avoid the need to maintain two separate projects for one app, which is especially convenient when migrating a 2.x app to the Basalt platform.

```
#ifdef PBL\_PLATFORM\_APLITE// Aligns under the status barlayer\_set\_frame(s\_layer, GRect(0, 0, 144, 68));#elif PBL\_PLATFORM\_BASALT// Preserve alignment to status bar on Aplitelayer\_set\_frame(s\_layer, GRect(0, STATUS\_BAR\_LAYER\_HEIGHT, 144, 68));#endif
```

This is a good solution for small blocks of conditional code, but some developers may find that complicated conditional code can soon become more `#ifdef...#elif...#endif` than actual code itself!

## The Modified Wscript Approach

In these situations you may find it preferable to use a different approach. Instead of modifying your app code to use preprocessor statements whenever a platform-specific value is needed, you can modify your project's `wscript` file to limit each compilation pass to a certain folder of source files.

By default, you will probably have a project with this file structure:

```
my_project
  resources
    images
      banner~bw.png
      banner~color.png
  src
    main.c
    util.h
    util.c
  appinfo.json
  wscript
```

In this scenario, the `wscript` dictates that _any_ `.c` files found in `src` will be compiled for both platforms.

To use a different set of source files for each platform during compilation, modify the lines with the `**` wildcard (within the `for` loop) to point to a folder within `src` where the platform- specific files are then located:

```
forpinctx.env.TARGET\_PLATFORMS:ctx.set\_env(ctx.all\_envs[p])ctx.set\_group(ctx.env.PLATFORM\_NAME)app\_elf='{}/pebble-app.elf'.format(ctx.env.BUILD\_DIR)# MODIFY THIS LINE!# E.g.: When 'p' == 'aplite', look in 'src/aplite/'ctx.pbl\_program(source=ctx.path.ant\_glob('src/{}/\*\*/\*.c'.format(p)),target=app\_elf)ifbuild\_worker:worker\_elf='{}/pebble-worker.elf'.format(ctx.env.BUILD\_DIR)binaries.append({'platform':p,'app\_elf':app\_elf,'worker\_elf':worker\_elf})# MODIFY THIS LINE!# Also modify this line to look for platform-specific C files in `worker_src`ctx.pbl\_worker(source=ctx.path.ant\_glob('worker\_src/{}/\*\*/\*.c'.format(p)),target=worker\_elf)else:binaries.append({'platform':p,'app\_elf':app\_elf})
```

With this newly modified `wscript`, we must re-organise our `src` folder to match the new search pattern. This allows us to maintain two separate sets of source files, each free of any excessive `#ifdef` pollution.

```
my_project
  resources
    images
      banner~bw.png
      banner~color.png
  src
    aplite
      main.c      
      util.h
      util.c
    basalt
      main.c      
      util.h
      util.c
  appinfo.json
  wscript
```

## Sharing Files Between Platforms

Using the modified wscript approach as shown above still requires any files that are used on both platforms to be included twice: in the respective folder. You may wish to reduce this clutter by moving any platform-agnostic files that both platforms use to a `common` folder inside `src`.

You project might now look like this:

```
my_project
  resources
    images
      banner~bw.png
      banner~color.png
  src
    aplite
      main.c
    basalt
      main.c
    common
      util.h
      util.c
  appinfo.json
  wscript
```

To tell the SDK to look in this extra folder during compilation of each platform, further modify the two lines calling `ctx.pbl_program()` to include the `common` folder in the array of paths passed to [`ant_glob()`](https://waf.io/book/#_general_usage). This is shown in the code snipped below, with unchanged lines ommitted for brevity:

```
# Additionally modified to include the 'common' folderctx.pbl\_program(source=ctx.path.ant\_glob(['src/{}/\*\*/\*.c'.format(p),'src/common/\*\*/\*.c']),target=app\_elf)/\*Othercode\*/ifbuild\_worker:# Also modify this line to look for common files in '/worker\_src/common/'ctx.pbl\_worker(source=ctx.path.ant\_glob(['worker\_src/{}/\*\*/\*.c'.format(p),'worker\_src/common/\*\*/\*.c']),target=worker\_elf)else:/\*Othercode\*/
```

## Important Notes

While this new `wscript` allows us to keep our source files for each platform separated entirely, there are a couple of important limitations to take into account when using this method (without any further modification):

- There can still be only _one_ JavaScript file, in `src/js/pebble-js-app.js`. You can simulate two JS files using a platform check:

```
Pebble.addEventListener('ready', function() {if(Pebble.getActiveWatchInfo && Pebble.getActiveWatchInfo().platform === 'basalt') {// This is the Basalt platformconsole.log('PebbleKit JS ready on Basalt!');} else {// This is the Aplite platformconsole.log('PebbleKit JS ready on Aplite!');}});
```

- Each binary can be bundled with only the app resources required for that specific platform. To learn how to package app resources with only a certain platform, read the [_Platform-specific Resources_](https://developer.repebble.com/guides/app-resources/platform-specific.md) guide.

## Conclusion

With this modification to a Pebble project's `wscript`, developers now have two options when it comes to diverging their app code for Aplite- and Basalt- specific features **without** the need to maintain two completely separate projects.

You can see a simple example project that ses all these techniques over at [`pebble-examples/multi-platform-wscript`](https://github.com/pebble-examples/multi-platform-wscript).

* * *
