Commits

Trammell Hudson committed b069a3f

Added support for building and linking custom library

  • Participants
  • Parent commits 947fb16

Comments (0)

Files changed (4)

File Makefile.pebble

 LD := $(CC)
 OBJCOPY := $(GCC_PREFIX)objcopy
 SIZE := $(GCC_PREFIX)size
+AR := $(GCC_PREFIX)ar
 PYTHON := python
 
 # If no version is specified, use a default one
 VERSION ?= 0.1
 APP ?= pebble-app
 
+# TOP is the location with of this build tree
+TOP := $(dir $(lastword $(MAKEFILE_LIST)))
+
+# Our custom Pebble library shared with all our watch faces
+LIBPEBBLE_TH := $(TOP)lib/build/libpebble_th.a
+
 
 # Helper macros
 map = $(foreach f,$2,$(call $1,$f))
 	-fPIE \
 	-I$(PEBBLE_HOME)/include \
 	-I. \
-	-I../../common \
+	-I../../lib/src \
 	-I$O \
 	-DNDEBUG \
 	-Wp,-MMD,$(dir $@).$(notdir $@).d \
 		-o $@ \
 		-v \
 
+ifeq ($(LIB),)
+# Force all executables to depend on our pebble library
 all: $O/$(APP).pbw
+else
+# Libraries do not depend on anything external
+all: $O/$(LIB)
+endif
+
+
 
 #
 # Generate the list of object files from the SRCS list.
 
 $(foreach f,$(SRCS),$(call add_srcs,$f,$O/$(notdir $(f:.c=.o))))
 
+ifeq ($(LIB),)
+# Only build resource_ids.auto.h if we are making an application
 $(OBJS): $O/src/resource_ids.auto.h
+
 #$(eval $(info OBJS=$(OBJS)))
 
 $O/$(APP).pbw: $O/app_resources.pbpack
-$O/$(APP).elf: $(OBJS)
+$O/$(APP).elf: $(OBJS) $(LIBPEBBLE_TH)
 	$(LD) \
 		$(LDFLAGS) \
 		-o $@ \
 		$(LDLIBS)
 	$(SIZE) $@
 
+$(LIBPEBBLE_TH):
+	$(MAKE) -C $(dir $(LIBPEBBLE_TH))../src
+
+else
+# Libraries do not use resources, but do need to link everything together
+$O/$(LIB): $(OBJS)
+	$(RM) $@
+	$(AR) \
+		crv \
+		$@ \
+		$^
+	$(SIZE) $@
+endif
+
 $O/%.o:
 	$(CC) $(CFLAGS) -c -o $@ $<
 

File lib/src/Makefile

+#
+# Library for common functions in watch faces and apps.
+#
+
+SRCS += \
+	sprintf.c \
+
+LIB := libpebble_th.a
+
+include ../../Makefile.pebble

File lib/src/pebble_th.h

+/** \file
+ * Functions in libpblth.a.
+ */
+#ifndef _pblth_h_
+#define _pblth_h_
+
+#include <stdint.h>
+
+
+extern int
+__attribute__((__format__(printf, 2, 3)))
+pebble_sprintf(
+	char * buf,
+	const char * fmt,
+	...
+);
+
+#endif

File lib/src/sprintf.c

+/** \file
+ * Simple version of sprintf to avoid bringing in all of libc.
+ *
+ * Only supported: %d, %s, %x
+ */
+//#include <stdio.h>
+#include <stdarg.h>
+#include "pebble_th.h"
+
+
+static int
+fmt_int(
+	char * buf,
+	unsigned x,
+	int base,
+	int width,
+	int leading_zero
+)
+{
+	(void) width;
+	(void) leading_zero;
+
+	char tmp[16];
+	int offset = 0;
+	do {
+		int digit;
+		if (base == 16)
+		{
+			digit = x % 16;
+			x /= 16;
+		} else
+		//if (base == 10) // do it always
+		{
+			digit = x % 10;
+			x /= 10;
+		}
+
+		char c;
+		if (digit >=  0xA)
+			c = digit + 'A' - 0xA;
+		else
+			c = digit + '0';
+
+		tmp[offset++] = c;
+	} while (x);
+
+	tmp[offset] = '\0';
+
+	// reverse it into place
+	int i;
+	for (i = 0 ; i < offset ; i++)
+		buf[i] = tmp[offset - i - 1];
+
+	return offset;
+}
+
+
+int
+pebble_sprintf(
+	char * buf,
+	const char * fmt,
+	...
+)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	int offset = 0;
+
+	while (1)
+	{
+		const char c = *fmt++;
+		if (c == '\0')
+			break;
+		if (c != '%')
+		{
+			buf[offset++] = c;
+			continue;
+		}
+
+		// Look for a digit
+		int leading_zero = 0;
+		int width = 0;
+
+		char n = *fmt;
+		if ('0' <= n && n <= '9')
+		{
+			if (n == '0')
+			{
+				leading_zero = 1;
+				n = *++fmt;
+			}
+
+			while ('0' <= n && n <= '9')
+			{
+				width = width * 10 + n - '0';
+				n = *++fmt;
+			}
+		}
+
+		// width and leading zero are set.
+		// fmt now points at the type
+		const char type = *fmt++;
+
+		switch (type)
+		{
+		case 's':
+		{
+			// Width and zero are ignored for now
+			const char * s = va_arg(ap, const char *);
+			while (1)
+			{
+				const char c = *s++;
+				if (c == '\0')
+					break;
+				buf[offset++] = c;
+			}
+			break;
+		}
+
+		case 'd':
+		{
+			const int x = va_arg(ap, int);
+			offset += fmt_int(buf + offset, x, 10, width, leading_zero);
+			break;
+		}
+		case 'x':
+		{
+			const int x = va_arg(ap, int);
+			offset += fmt_int(buf + offset, x, 16, width, leading_zero);
+			break;
+		}
+		case '%':
+			buf[offset++] = '%';
+			break;
+		default:
+		{
+			va_arg(ap, int);
+			buf[offset++] = '?';
+			break;
+		}
+		}
+	}
+
+	va_end(ap);
+
+	buf[offset] = '\0';
+	return offset;
+}
+
+#if 0
+int main(void)
+{
+	char buf[64];
+
+	pebble_sprintf(buf, "hello: foo %s %% %d 0x%x 0x%08x\n",
+		"bar",
+		123,
+		0x9999,
+		0xdeadbeef
+	);
+
+	printf("%s", buf);
+	return 0;
+}
+#endif