mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-01-17 02:52:12 +01:00
ut: convert logfs unit test to gtest
Conflicts: Makefile make/unittest.mk
This commit is contained in:
parent
fb4a1d7b1b
commit
9b94eeb745
2
Makefile
2
Makefile
@ -786,7 +786,7 @@ ut_$(1)_%: $$(UT_OUT_DIR)
|
||||
\
|
||||
GTEST_DIR=$(GTEST_DIR) \
|
||||
\
|
||||
$$*
|
||||
$*
|
||||
|
||||
.PHONY: ut_$(1)_clean
|
||||
ut_$(1)_clean:
|
||||
|
@ -1,87 +0,0 @@
|
||||
#include <stdio.h> /* printf */
|
||||
#include <stdlib.h> /* abort */
|
||||
#include <string.h> /* memset */
|
||||
|
||||
#include "pios_flash.h" /* PIOS_FLASH_* API */
|
||||
#include "pios_flash_ut_priv.h"
|
||||
|
||||
const struct pios_flash_ut_cfg flash_config = {
|
||||
.size_of_flash = 0x00200000,
|
||||
.size_of_sector = 0x00010000,
|
||||
};
|
||||
|
||||
#include "pios_flashfs_logfs_priv.h"
|
||||
|
||||
const struct flashfs_logfs_cfg flashfs_config = {
|
||||
.fs_magic = 0x89abceef,
|
||||
.total_fs_size = 0x00200000, /* 2M bytes (32 sectors = entire chip) */
|
||||
.arena_size = 0x00010000, /* 256 * slot size */
|
||||
.slot_size = 0x00000100, /* 256 bytes */
|
||||
|
||||
.start_offset = 0, /* start at the beginning of the chip */
|
||||
.sector_size = 0x00010000, /* 64K bytes */
|
||||
.page_size = 0x00000100, /* 256 bytes */
|
||||
};
|
||||
|
||||
#include "pios_flashfs.h" /* PIOS_FLASHFS_* */
|
||||
|
||||
int main (int argc, char * argv[])
|
||||
{
|
||||
int32_t rc;
|
||||
|
||||
/* dd if=/dev/zero bs=1 count=2MiB | tr '\000' '\377' > theflash.bin */
|
||||
|
||||
uintptr_t flash_id;
|
||||
rc = PIOS_Flash_UT_Init(&flash_id, &flash_config);
|
||||
if (rc != 0) {
|
||||
printf ("flash init failed (%d)\n", rc);
|
||||
abort();
|
||||
}
|
||||
|
||||
uintptr_t fs_id;
|
||||
rc = PIOS_FLASHFS_Logfs_Init(&fs_id, &flashfs_config, &pios_ut_flash_driver, flash_id);
|
||||
if (rc != 0) {
|
||||
printf ("flash filesystem init failed (%d)\n", rc);
|
||||
abort();
|
||||
}
|
||||
|
||||
#define OBJ1_ID 0x12345678
|
||||
#define OBJ1_SIZE 76
|
||||
unsigned char obj1[OBJ1_SIZE];
|
||||
memset(obj1, 0xA5, sizeof(obj1));
|
||||
for (uint32_t i = 0; i < 10000; i++) {
|
||||
rc = PIOS_FLASHFS_ObjSave(fs_id, OBJ1_ID, 0, obj1, sizeof(obj1));
|
||||
if (rc != 0) {
|
||||
printf ("failed to save obj1 (%d)\n", rc);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char obj1_check[OBJ1_SIZE];
|
||||
memset(obj1_check, 0, sizeof(obj1_check));
|
||||
rc = PIOS_FLASHFS_ObjLoad(fs_id, OBJ1_ID, 0, obj1_check, sizeof(obj1_check));
|
||||
if (rc != 0) {
|
||||
printf ("failed to load obj1 (%d)\n", rc);
|
||||
abort();
|
||||
}
|
||||
|
||||
if (memcmp(obj1, obj1_check, sizeof(obj1)) != 0) {
|
||||
printf ("read-back of obj1 failed\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
rc = PIOS_FLASHFS_ObjDelete(fs_id, OBJ1_ID, 0);
|
||||
if (rc != 0) {
|
||||
printf ("failed to delete obj1 (%d)\n", rc);
|
||||
abort();
|
||||
}
|
||||
|
||||
rc = PIOS_FLASHFS_ObjLoad(fs_id, OBJ1_ID, 0, obj1_check, sizeof(obj1_check));
|
||||
if (rc == 0) {
|
||||
printf ("was able to load obj1 after delete!\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
}
|
||||
|
259
flight/tests/logfs/unittest.cpp
Normal file
259
flight/tests/logfs/unittest.cpp
Normal file
@ -0,0 +1,259 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <stdio.h> /* printf */
|
||||
#include <stdlib.h> /* abort */
|
||||
#include <string.h> /* memset */
|
||||
|
||||
extern "C" {
|
||||
|
||||
#include "pios_flash.h" /* PIOS_FLASH_* API */
|
||||
#include "pios_flash_ut_priv.h"
|
||||
|
||||
extern struct pios_flash_ut_cfg flash_config;
|
||||
|
||||
#include "pios_flashfs_logfs_priv.h"
|
||||
|
||||
extern struct flashfs_logfs_cfg flashfs_config;
|
||||
|
||||
#include "pios_flashfs.h" /* PIOS_FLASHFS_* */
|
||||
|
||||
}
|
||||
|
||||
#define OBJ0_ID 0xAA55AA55
|
||||
|
||||
#define OBJ1_ID 0x12345678
|
||||
#define OBJ1_SIZE 76
|
||||
|
||||
#define OBJ2_ID 0xABCDEFAB
|
||||
#define OBJ2_SIZE 123
|
||||
|
||||
#define OBJ3_ID 0x99999999
|
||||
#define OBJ3_SIZE (256 - 12) // leave room for the slot header
|
||||
|
||||
// To use a test fixture, derive a class from testing::Test.
|
||||
class LogfsTestRaw : public testing::Test {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
/* create an empty, appropriately sized flash filesystem */
|
||||
FILE * theflash = fopen("theflash.bin", "w");
|
||||
uint8_t sector[flash_config.size_of_sector];
|
||||
memset(sector, 0xFF, sizeof(sector));
|
||||
for (uint32_t i = 0; i < flash_config.size_of_flash / flash_config.size_of_sector; i++) {
|
||||
fwrite(sector, sizeof(sector), 1, theflash);
|
||||
}
|
||||
fclose(theflash);
|
||||
|
||||
/* Set up obj1 */
|
||||
for (uint32_t i = 0; i < sizeof(obj1); i++) {
|
||||
obj1[i] = 0x10 + (i % 10);
|
||||
}
|
||||
|
||||
/* Set up a second version of obj1 with different data */
|
||||
for (uint32_t i = 0; i < sizeof(obj1_alt); i++) {
|
||||
obj1_alt[i] = 0xA0 + (i % 10);
|
||||
}
|
||||
|
||||
/* Set up obj2 */
|
||||
for (uint32_t i = 0; i < sizeof(obj2); i++) {
|
||||
obj2[i] = 0x20 + (i % 10);
|
||||
}
|
||||
|
||||
/* Set up obj3 */
|
||||
for (uint32_t i = 0; i < sizeof(obj3); i++) {
|
||||
obj3[i] = 0x30 + (i % 10);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
unlink("theflash.bin");
|
||||
}
|
||||
|
||||
unsigned char obj1[OBJ1_SIZE];
|
||||
unsigned char obj1_alt[OBJ1_SIZE];
|
||||
unsigned char obj2[OBJ2_SIZE];
|
||||
unsigned char obj3[OBJ3_SIZE];
|
||||
};
|
||||
|
||||
TEST_F(LogfsTestRaw, FlashInit) {
|
||||
uintptr_t flash_id;
|
||||
EXPECT_EQ(0, PIOS_Flash_UT_Init(&flash_id, &flash_config));
|
||||
}
|
||||
|
||||
TEST_F(LogfsTestRaw, LogfsInit) {
|
||||
uintptr_t flash_id;
|
||||
EXPECT_EQ(0, PIOS_Flash_UT_Init(&flash_id, &flash_config));
|
||||
|
||||
uintptr_t fs_id;
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_Logfs_Init(&fs_id, &flashfs_config, &pios_ut_flash_driver, flash_id));
|
||||
}
|
||||
|
||||
class LogfsTestCooked : public LogfsTestRaw {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
/* First, we need to set up the super fixture (LogfsTestRaw) */
|
||||
LogfsTestRaw::SetUp();
|
||||
|
||||
/* Init the flash and the flashfs so we don't need to repeat this in every test */
|
||||
uintptr_t flash_id;
|
||||
EXPECT_EQ(0, PIOS_Flash_UT_Init(&flash_id, &flash_config));
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_Logfs_Init(&fs_id, &flashfs_config, &pios_ut_flash_driver, flash_id));
|
||||
}
|
||||
|
||||
uintptr_t fs_id;
|
||||
};
|
||||
|
||||
TEST_F(LogfsTestCooked, LogfsFormat) {
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_Format(fs_id));
|
||||
}
|
||||
|
||||
TEST_F(LogfsTestCooked, WriteOne) {
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ1_ID, 0, obj1, sizeof(obj1)));
|
||||
}
|
||||
|
||||
TEST_F(LogfsTestCooked, WriteVerifyOne) {
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ1_ID, 0, obj1, sizeof(obj1)));
|
||||
|
||||
unsigned char obj1_check[OBJ1_SIZE];
|
||||
memset(obj1_check, 0, sizeof(obj1_check));
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id, OBJ1_ID, 0, obj1_check, sizeof(obj1_check)));
|
||||
EXPECT_EQ(0, memcmp(obj1, obj1_check, sizeof(obj1)));
|
||||
}
|
||||
|
||||
TEST_F(LogfsTestCooked, WriteVerifyDeleteVerifyOne) {
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ1_ID, 0, obj1, sizeof(obj1)));
|
||||
|
||||
unsigned char obj1_check[OBJ1_SIZE];
|
||||
memset(obj1_check, 0, sizeof(obj1_check));
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id, OBJ1_ID, 0, obj1_check, sizeof(obj1_check)));
|
||||
EXPECT_EQ(0, memcmp(obj1, obj1_check, sizeof(obj1)));
|
||||
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjDelete(fs_id, OBJ1_ID, 0));
|
||||
|
||||
EXPECT_EQ(-2, PIOS_FLASHFS_ObjLoad(fs_id, OBJ1_ID, 0, obj1_check, sizeof(obj1_check)));
|
||||
}
|
||||
|
||||
TEST_F(LogfsTestCooked, WriteTwoVerifyOneA) {
|
||||
/* Write obj1 then obj2 */
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ1_ID, 0, obj1, sizeof(obj1)));
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ2_ID, 0, obj2, sizeof(obj2)));
|
||||
|
||||
/* Read back obj1 */
|
||||
unsigned char obj1_check[OBJ1_SIZE];
|
||||
memset(obj1_check, 0, sizeof(obj1_check));
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id, OBJ1_ID, 0, obj1_check, sizeof(obj1_check)));
|
||||
EXPECT_EQ(0, memcmp(obj1, obj1_check, sizeof(obj1)));
|
||||
}
|
||||
|
||||
TEST_F(LogfsTestCooked, WriteTwoVerifyOneB) {
|
||||
/* Write obj2 then obj1 */
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ2_ID, 0, obj2, sizeof(obj2)));
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ1_ID, 0, obj1, sizeof(obj1)));
|
||||
|
||||
/* Read back obj1 */
|
||||
unsigned char obj1_check[OBJ1_SIZE];
|
||||
memset(obj1_check, 0, sizeof(obj1_check));
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id, OBJ1_ID, 0, obj1_check, sizeof(obj1_check)));
|
||||
EXPECT_EQ(0, memcmp(obj1, obj1_check, sizeof(obj1)));
|
||||
}
|
||||
|
||||
TEST_F(LogfsTestCooked, WriteZeroSize) {
|
||||
/* Write a zero length object */
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ0_ID, 0, NULL, 0));
|
||||
}
|
||||
|
||||
TEST_F(LogfsTestCooked, WriteVerifyZeroLength) {
|
||||
/* Write a zero length object */
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ0_ID, 0, NULL, 0));
|
||||
|
||||
/* Read back a zero length object -- effectively an existence check */
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id, OBJ0_ID, 0, NULL, 0));
|
||||
}
|
||||
|
||||
TEST_F(LogfsTestCooked, WriteMaxSize) {
|
||||
/* Write a zero length object */
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ3_ID, 0, obj3, sizeof(obj3)));
|
||||
}
|
||||
|
||||
TEST_F(LogfsTestCooked, ReadNonexistent) {
|
||||
/* Read back a zero length object -- basically an existence check */
|
||||
unsigned char obj1_check[OBJ1_SIZE];
|
||||
memset(obj1_check, 0, sizeof(obj1_check));
|
||||
EXPECT_EQ(-2, PIOS_FLASHFS_ObjLoad(fs_id, OBJ1_ID, 0, obj1_check, sizeof(obj1_check)));
|
||||
}
|
||||
|
||||
TEST_F(LogfsTestCooked, WriteVerifyMultiInstance) {
|
||||
/* Write instance zero */
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ1_ID, 0, obj1, sizeof(obj1)));
|
||||
|
||||
/* Write a non-zero instance ID */
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ1_ID, 123, obj1_alt, sizeof(obj1_alt)));
|
||||
|
||||
unsigned char obj1_check[OBJ1_SIZE];
|
||||
|
||||
/* Read back instance 123 */
|
||||
memset(obj1_check, 0, sizeof(obj1_check));
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id, OBJ1_ID, 123, obj1_check, sizeof(obj1_check)));
|
||||
EXPECT_EQ(0, memcmp(obj1_alt, obj1_check, sizeof(obj1_alt)));
|
||||
|
||||
/* Read back instance 0 */
|
||||
memset(obj1_check, 0, sizeof(obj1_check));
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id, OBJ1_ID, 0, obj1_check, sizeof(obj1_check)));
|
||||
EXPECT_EQ(0, memcmp(obj1, obj1_check, sizeof(obj1)));
|
||||
}
|
||||
|
||||
TEST_F(LogfsTestCooked, FillFilesystemAndGarbageCollect) {
|
||||
/* Fill up the entire filesystem with multiple instances of obj1 */
|
||||
for (uint32_t i = 0; i < (flashfs_config.arena_size / flashfs_config.slot_size) - 1; i++) {
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ1_ID, i, obj1, sizeof(obj1)));
|
||||
}
|
||||
|
||||
/* Should fail to add a new object since the filesystem is full */
|
||||
EXPECT_EQ(-3, PIOS_FLASHFS_ObjSave(fs_id, OBJ2_ID, 0, obj2, sizeof(obj2)));
|
||||
|
||||
/* Now save a new version of an existing object which should trigger gc and succeed */
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ1_ID, 0, obj1_alt, sizeof(obj1_alt)));
|
||||
|
||||
/* Read back one of the original obj1 instances */
|
||||
unsigned char obj1_check[OBJ1_SIZE];
|
||||
memset(obj1_check, 0, sizeof(obj1_check));
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id, OBJ1_ID, 1, obj1_check, sizeof(obj1_check)));
|
||||
EXPECT_EQ(0, memcmp(obj1, obj1_check, sizeof(obj1)));
|
||||
|
||||
/* Read back the new version of obj1 written after gc */
|
||||
memset(obj1_check, 0, sizeof(obj1_check));
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id, OBJ1_ID, 0, obj1_check, sizeof(obj1_check)));
|
||||
EXPECT_EQ(0, memcmp(obj1_alt, obj1_check, sizeof(obj1_alt)));
|
||||
}
|
||||
|
||||
TEST_F(LogfsTestCooked, WriteManyVerify) {
|
||||
for (uint32_t i = 0; i < 10000; i++) {
|
||||
/* Write a collection of objects */
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ0_ID, 0, NULL, 0));
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ1_ID, 0, obj1, sizeof(obj1)));
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ1_ID, 123, obj1_alt, sizeof(obj1_alt)));
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ2_ID, 0, obj2, sizeof(obj2)));
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ3_ID, 0, obj3, sizeof(obj3)));
|
||||
}
|
||||
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id, OBJ0_ID, 0, NULL, 0));
|
||||
|
||||
unsigned char obj1_check[OBJ1_SIZE];
|
||||
memset(obj1_check, 0, sizeof(obj1_check));
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id, OBJ1_ID, 0, obj1_check, sizeof(obj1_check)));
|
||||
EXPECT_EQ(0, memcmp(obj1, obj1_check, sizeof(obj1)));
|
||||
|
||||
unsigned char obj1_alt_check[OBJ1_SIZE];
|
||||
memset(obj1_alt_check, 0, sizeof(obj1_alt_check));
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id, OBJ1_ID, 123, obj1_alt_check, sizeof(obj1_alt_check)));
|
||||
EXPECT_EQ(0, memcmp(obj1_alt, obj1_alt_check, sizeof(obj1_alt)));
|
||||
|
||||
unsigned char obj2_check[OBJ2_SIZE];
|
||||
memset(obj2_check, 0, sizeof(obj2_check));
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id, OBJ2_ID, 0, obj2_check, sizeof(obj2_check)));
|
||||
EXPECT_EQ(0, memcmp(obj2, obj2_check, sizeof(obj2)));
|
||||
|
||||
unsigned char obj3_check[OBJ3_SIZE];
|
||||
memset(obj3_check, 0, sizeof(obj3_check));
|
||||
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id, OBJ3_ID, 0, obj3_check, sizeof(obj3_check)));
|
||||
EXPECT_EQ(0, memcmp(obj3, obj3_check, sizeof(obj3)));
|
||||
}
|
26
flight/tests/logfs/unittest_init.c
Normal file
26
flight/tests/logfs/unittest_init.c
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* These need to be defined in a .c file so that we can use
|
||||
* designated initializer syntax which c++ doesn't support (yet).
|
||||
*/
|
||||
|
||||
#include "pios_flash_ut_priv.h"
|
||||
|
||||
|
||||
const struct pios_flash_ut_cfg flash_config = {
|
||||
.size_of_flash = 0x00200000,
|
||||
.size_of_sector = 0x00010000,
|
||||
};
|
||||
|
||||
#include "pios_flashfs_logfs_priv.h"
|
||||
|
||||
const struct flashfs_logfs_cfg flashfs_config = {
|
||||
.fs_magic = 0x89abceef,
|
||||
.total_fs_size = 0x00200000, /* 2M bytes (32 sectors = entire chip) */
|
||||
.arena_size = 0x00010000, /* 256 * slot size */
|
||||
.slot_size = 0x00000100, /* 256 bytes */
|
||||
|
||||
.start_offset = 0, /* start at the beginning of the chip */
|
||||
.sector_size = 0x00010000, /* 64K bytes */
|
||||
.page_size = 0x00000100, /* 256 bytes */
|
||||
};
|
||||
|
@ -3,7 +3,7 @@ TCHAIN_PREFIX ?= arm-none-eabi-
|
||||
|
||||
# Define toolchain component names.
|
||||
CC = $(TCHAIN_PREFIX)gcc
|
||||
CPP = $(TCHAIN_PREFIX)g++
|
||||
CXX = $(TCHAIN_PREFIX)g++
|
||||
AR = $(TCHAIN_PREFIX)ar
|
||||
OBJCOPY = $(TCHAIN_PREFIX)objcopy
|
||||
OBJDUMP = $(TCHAIN_PREFIX)objdump
|
||||
@ -43,8 +43,8 @@ MSG_SYMBOL_TABLE = ${quote} NM $(MSG_EXTRA) ${quote}
|
||||
MSG_LINKING = ${quote} LD $(MSG_EXTRA) ${quote}
|
||||
MSG_COMPILING = ${quote} CC ${MSG_EXTRA} ${quote}
|
||||
MSG_COMPILING_ARM = ${quote} CC-ARM $(MSG_EXTRA) ${quote}
|
||||
MSG_COMPILINGCPP = ${quote} CXX $(MSG_EXTRA) ${quote}
|
||||
MSG_COMPILINGCPP_ARM = ${quote} CXX-ARM $(MSG_EXTRA) ${quote}
|
||||
MSG_COMPILINGCXX = ${quote} CXX $(MSG_EXTRA) ${quote}
|
||||
MSG_COMPILINGCXX_ARM = ${quote} CXX-ARM $(MSG_EXTRA) ${quote}
|
||||
MSG_ASSEMBLING = ${quote} AS $(MSG_EXTRA) ${quote}
|
||||
MSG_ASSEMBLING_ARM = ${quote} AS-ARM $(MSG_EXTRA) ${quote}
|
||||
MSG_CLEANING = ${quote} CLEAN $(MSG_EXTRA) ${quote}
|
||||
@ -170,17 +170,17 @@ $(OUTDIR)/$(notdir $(basename $(1))).o : $(1)
|
||||
endef
|
||||
|
||||
# Compile: create object files from C++ source files.
|
||||
define COMPILE_CPP_TEMPLATE
|
||||
define COMPILE_CXX_TEMPLATE
|
||||
$(OUTDIR)/$(notdir $(basename $(1))).o : $(1)
|
||||
@echo $(MSG_COMPILINGCPP) $$(call toprel, $$<)
|
||||
$(V1) $(CC) -c $(THUMB) $$(CFLAGS) $$(CPPFLAGS) $$< -o $$@
|
||||
@echo $(MSG_COMPILINGCXX) $$(call toprel, $$<)
|
||||
$(V1) $(CXX) -c $(THUMB) $$(CFLAGS) $$(CPPFLAGS) $$(CXXFLAGS) $$< -o $$@
|
||||
endef
|
||||
|
||||
# Compile: create object files from C++ source files. ARM-only
|
||||
define COMPILE_CPP_ARM_TEMPLATE
|
||||
define COMPILE_CXX_ARM_TEMPLATE
|
||||
$(OUTDIR)/$(notdir $(basename $(1))).o : $(1)
|
||||
@echo $(MSG_COMPILINGCPP_ARM) $$(call toprel, $$<)
|
||||
$(V1) $(CC) -c $$(CFLAGS) $$(CPPFLAGS) $$< -o $$@
|
||||
@echo $(MSG_COMPILINGCXX_ARM) $$(call toprel, $$<)
|
||||
$(V1) $(CPP) -c $$(CFLAGS) $$(CPPFLAGS) $$(CXXFLAGS) $$< -o $$@
|
||||
endef
|
||||
|
||||
# Link: create ELF output file from object files.
|
||||
@ -194,6 +194,17 @@ $(1): $(2)
|
||||
$(V1) $(CC) $(THUMB) $$(CFLAGS) $(2) --output $$@ $$(LDFLAGS)
|
||||
endef
|
||||
|
||||
# Link: create ELF output file from object files.
|
||||
# $1 = elf file to produce
|
||||
# $2 = list of object files that make up the elf file
|
||||
define LINK_CXX_TEMPLATE
|
||||
.SECONDARY : $(1)
|
||||
.PRECIOUS : $(2)
|
||||
$(1): $(2)
|
||||
@echo $(MSG_LINKING) $$(call toprel, $$@)
|
||||
$(V1) $(CXX) $(THUMB) $$(CFLAGS) $(2) --output $$@ $$(LDFLAGS)
|
||||
endef
|
||||
|
||||
# Compile: create assembler files from C source files. ARM/Thumb
|
||||
define PARTIAL_COMPILE_TEMPLATE
|
||||
$($(1):.c=.s) : %.s : %.c
|
||||
|
@ -27,7 +27,7 @@
|
||||
CPPFLAGS += -I$(GTEST_DIR)/include
|
||||
|
||||
# Flags passed to the C++ compiler.
|
||||
CXXFLAGS += -g -Wall -Wextra
|
||||
CXXFLAGS += -g -Wall -Wextra -std=gnu++0x
|
||||
|
||||
# All Google Test headers.
|
||||
GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \
|
||||
@ -62,13 +62,6 @@ $(foreach src,$(ALLCPPSRC),$(eval $(call COMPILE_CXX_TEMPLATE,$(src))))
|
||||
|
||||
$(eval $(call LINK_CXX_TEMPLATE,$(OUTDIR)/$(TARGET).elf,$(ALLOBJ) $(GTEST_LIBS)))
|
||||
|
||||
.PHONY: tap
|
||||
tap: $(OUTDIR)/$(TARGET).tap
|
||||
|
||||
$(OUTDIR)/$(TARGET).tap: $(OUTDIR)/$(TARGET).elf
|
||||
$(V0) @echo " TAP $(MSG_EXTRA) $(call toprel, $@)"
|
||||
$(V1) $< > $@
|
||||
|
||||
.PHONY: run
|
||||
run: $(OUTDIR)/$(TARGET).elf
|
||||
$(V0) @echo " TAP RUN $(MSG_EXTRA) $(call toprel, $<)"
|
||||
|
Loading…
x
Reference in New Issue
Block a user