mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #981 from vanhieubk/nhat_mixCompiler
Another way to mix c and cpp in user app with RIOT [native]
This commit is contained in:
commit
4615004fdf
@ -18,6 +18,7 @@ install:
|
||||
- sudo apt-get install gcc-msp430
|
||||
- sudo apt-get install pcregrep libpcre3
|
||||
- sudo apt-get install qemu-system-x86 python3
|
||||
- sudo apt-get install g++-multilib
|
||||
|
||||
script:
|
||||
- ./dist/tools/compile_test/compile_test.py
|
||||
|
@ -30,8 +30,19 @@ ASMOBJ += $(ASSMSRC:%.S=$(BINDIR)$(MODULE)/%.o)
|
||||
ifeq ($(strip $(SRC)),)
|
||||
SRC = $(wildcard *.c)
|
||||
endif
|
||||
OBJ = $(SRC:%.c=$(BINDIR)$(MODULE)/%.o)
|
||||
|
||||
ifeq ($(strip $(SRCXX)),)
|
||||
SRCXX = $(wildcard *.cpp)
|
||||
endif
|
||||
|
||||
OBJC = $(SRC:%.c=$(BINDIR)$(MODULE)/%.o)
|
||||
OBJCXX = $(SRCXX:%.cpp=$(BINDIR)$(MODULE)/%.o)
|
||||
|
||||
OBJ = $(OBJC)
|
||||
OBJ += $(OBJCXX)
|
||||
|
||||
DEP = $(SRC:%.c=$(BINDIR)$(MODULE)/%.d)
|
||||
DEP += $(SRCXX:%.cpp=$(BINDIR)$(MODULE)/%.d)
|
||||
|
||||
$(BINDIR)$(MODULE).a: $(OBJ) $(ASMOBJ) ${DIRS:%=ALL--%}
|
||||
@mkdir -p $(BINDIR)$(MODULE)
|
||||
@ -46,6 +57,10 @@ $(BINDIR)$(MODULE)/%.o: %.c
|
||||
@mkdir -p $(BINDIR)$(MODULE)
|
||||
$(AD)$(CC) $(CFLAGS) $(INCLUDES) -MD -MP -c -o $(BINDIR)$(MODULE)/$*.o $(abspath $*.c)
|
||||
|
||||
$(BINDIR)$(MODULE)/%.o: %.cpp
|
||||
@mkdir -p $(BINDIR)$(MODULE)
|
||||
$(AD)$(CXX) $(filter-out $(CXXUWFLAGS), $(CFLAGS)) $(CXXEXFLAGS) $(INCLUDES) -MD -MP -c -o $(BINDIR)$(MODULE)/$*.o $(abspath $*.cpp)
|
||||
|
||||
$(BINDIR)$(MODULE)/%.o: %.s
|
||||
@mkdir -p $(BINDIR)$(MODULE)
|
||||
$(AD)$(AS) $(ASFLAGS) $*.s -o $(BINDIR)$(MODULE)/$*.o
|
||||
|
@ -29,3 +29,6 @@ ifeq ($(shell $(CC) -Wstrict-prototypes -Werror=strict-prototypes -Wold-style-de
|
||||
# duplicated parameters don't hurt
|
||||
CFLAGS += -Wstrict-prototypes -Werror=strict-prototypes -Wold-style-definition -Werror=old-style-definition
|
||||
endif
|
||||
|
||||
# Unwanted flags for c++
|
||||
CXXUWFLAGS += -std=gnu99 -std=c99 -Wstrict-prototypes -Wold-style-definition
|
||||
|
@ -90,14 +90,19 @@ BASELIBS += $(USEPKG:%=${BINDIR}%.a)
|
||||
export ELFFILE ?= $(BINDIR)$(APPLICATION).elf
|
||||
export HEXFILE ?= $(ELFFILE:.elf=.hex)
|
||||
|
||||
# variables used to complie and link c++
|
||||
export CPPMIX ?= $(if $(wildcard *.cpp),1,)
|
||||
export CXXUWFLAGS
|
||||
export CXXEXFLAGS
|
||||
|
||||
## make script for your application. Build RIOT-base here!
|
||||
all: ..build-message $(USEPKG:%=${BINDIR}%.a) $(APPDEPS)
|
||||
$(AD)DIRS="$(DIRS)" "$(MAKE)" -C $(CURDIR) -f $(RIOTBASE)/Makefile.application
|
||||
ifeq (,$(RIOTNOLINK))
|
||||
ifeq ($(BUILDOSXNATIVE),1)
|
||||
$(AD)$(LINK) $(UNDEF) -o $(ELFFILE) $(BASELIBS) $(LINKFLAGS) -Wl,-no_pie
|
||||
$(AD)$(if $(CPPMIX),$(CXX),$(LINK)) $(UNDEF) -o $(ELFFILE) $(BASELIBS) $(LINKFLAGS) -Wl,-no_pie
|
||||
else
|
||||
$(AD)$(LINK) $(UNDEF) -o $(ELFFILE) -Wl,--start-group $(BASELIBS) -lm -Wl,--end-group -Wl,-Map=$(BINDIR)$(APPLICATION).map $(LINKFLAGS)
|
||||
$(AD)$(if $(CPPMIX),$(CXX),$(LINK)) $(UNDEF) -o $(ELFFILE) -Wl,--start-group $(BASELIBS) -lm -Wl,--end-group -Wl,-Map=$(BINDIR)$(APPLICATION).map $(LINKFLAGS)
|
||||
endif
|
||||
$(AD)$(SIZE) $(ELFFILE)
|
||||
$(AD)$(OBJCOPY) $(OFLAGS) $(ELFFILE) $(HEXFILE)
|
||||
|
@ -10,6 +10,7 @@ export ELF = $(BINDIR)$(APPLICATION).elf
|
||||
# toolchain:
|
||||
export PREFIX =
|
||||
export CC ?= $(PREFIX)gcc
|
||||
export CXX ?= $(PREFIX)g++
|
||||
export AR ?= $(PREFIX)ar
|
||||
export AS ?= $(PREFIX)as
|
||||
export LINK ?= $(PREFIX)gcc
|
||||
@ -31,6 +32,10 @@ export CFLAGS += -DCOMPAT_32BIT -L/usr/lib32 -B/usr/lib32
|
||||
endif
|
||||
endif
|
||||
|
||||
# unwanted (CXXUWFLAGS) and extra (CXXEXFLAGS) flags for c++
|
||||
export CXXUWFLAGS +=
|
||||
export CXXEXFLAGS +=
|
||||
|
||||
export LINKFLAGS += -m32
|
||||
ifeq ($(shell uname -s),FreeBSD)
|
||||
ifeq ($(shell uname -m),amd64)
|
||||
|
42
examples/riot_and_cpp/Makefile
Normal file
42
examples/riot_and_cpp/Makefile
Normal file
@ -0,0 +1,42 @@
|
||||
# name of your application
|
||||
export APPLICATION = riot_and_cpp
|
||||
|
||||
# If no BOARD is found in the environment, use this default:
|
||||
export BOARD ?= native
|
||||
|
||||
# This has to be the absolute path to the RIOT base directory:
|
||||
export RIOTBASE ?= $(CURDIR)/../..
|
||||
|
||||
# Uncomment these lines if you want to use platform support from external
|
||||
# repositories:
|
||||
#export RIOTCPU ?= $(CURDIR)/../../../thirdparty_cpu
|
||||
#export RIOTBOARD ?= $(CURDIR)/../../../thirdparty_boards
|
||||
|
||||
# Uncomment this to enable scheduler statistics for ps:
|
||||
#CFLAGS += -DSCHEDSTATISTICS
|
||||
|
||||
# If you want to use native with valgrind, you should recompile native
|
||||
# with the target all-valgrind instead of all:
|
||||
# make -B clean all-valgrind
|
||||
|
||||
# Uncomment this to enable code in RIOT that does safety checking
|
||||
# which is not needed in a production environment but helps in the
|
||||
# development process:
|
||||
#CFLAGS += -DDEVELHELP
|
||||
|
||||
# Change this to 0 show compiler invocation lines by default:
|
||||
export QUIET ?= 1
|
||||
|
||||
# Blacklist boards
|
||||
BOARD_BLACKLIST := arduino-due avsextrem chronos mbed_lpc1768 msb-430h msba2 redbee-econotag telosb wsn430-v1_3b wsn430-v1_4 msb-430 pttu udoo qemu-i386 z1
|
||||
# This example only works with native for now.
|
||||
# msb430-based boards: msp430-g++ is not provided in mspgcc.
|
||||
# (People who want use c++ can build c++ compiler from source, or get binaries from Energia http://energia.nu/)
|
||||
# msba2: some changes should be applied to successfully compile c++. (_kill_r, _kill, __dso_handle)
|
||||
# others: untested.
|
||||
|
||||
# If you want to add some extra flags when compile c++ files, add these flags
|
||||
# to CXXEXFLAGS variable
|
||||
CXXEXFLAGS +=
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
7
examples/riot_and_cpp/README.md
Normal file
7
examples/riot_and_cpp/README.md
Normal file
@ -0,0 +1,7 @@
|
||||
Using C++ and C in a program with RIOT
|
||||
======================================
|
||||
This project demonstrates how user can use both C++ and C in their application with RIOT.
|
||||
|
||||
Makefile Options
|
||||
----------------
|
||||
* CXXEXFLAGS : user's extra flags used to build c++ files should be defined here (e.g -std=gnu++11).
|
101
examples/riot_and_cpp/c_functions.c
Normal file
101
examples/riot_and_cpp/c_functions.c
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Ho Chi Minh city University of Technology (HCMUT)
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup examples
|
||||
* @{
|
||||
*
|
||||
* @file c_functions.c
|
||||
* @brief Some functions implementaion in C.
|
||||
*
|
||||
* @author DangNhat Pham-Huu <51002279@hcmut.edu.vn>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "c_functions.h"
|
||||
|
||||
#define IS_LEAP_YEAR(year) ((year%4 == 0) ? ((year%100 == 0) ? ((year%400 == 0) ? 1 : 0) : 1): 0)
|
||||
|
||||
int hello(void)
|
||||
{
|
||||
puts("Hello world in a C function");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int day_of_week(int day, int month, int year)
|
||||
{
|
||||
int count, sum_of_days;
|
||||
|
||||
/* 1/1/2000 is Saturday */
|
||||
int first_day = 6;
|
||||
|
||||
/* check input date */
|
||||
if (year < 2000) {
|
||||
printf("Sorry buddy, your date should be >= 1/1/2000!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
|
||||
if (day > 31 || day < 1) {
|
||||
printf("Sorry buddy, your date is not correct!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (month == 2) {
|
||||
|
||||
if (IS_LEAP_YEAR(year)) {
|
||||
if (day > 29 || day < 1) {
|
||||
printf("Sorry buddy, your date is not correct!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (day > 28 || day < 1) {
|
||||
printf("Sorry buddy, your date is not correct!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (day > 30 || day < 1) {
|
||||
printf("Sorry buddy, your date is not correct!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* date is okay, convert... */
|
||||
sum_of_days = 0;
|
||||
|
||||
for (count = 2000; count < year; count++) {
|
||||
sum_of_days += (((IS_LEAP_YEAR(count) == 1) ? 366 : 365)) % 7;
|
||||
}
|
||||
|
||||
for (count = 1; count < month; count++) {
|
||||
if (count == 1 || count == 3 || count == 5 || count == 7 || count == 8 || count == 10 || count == 12) {
|
||||
sum_of_days += 31 % 7;
|
||||
}
|
||||
else if (count == 2) {
|
||||
|
||||
if (IS_LEAP_YEAR(year)) {
|
||||
sum_of_days += 29 % 7;
|
||||
}
|
||||
else {
|
||||
sum_of_days += 28 % 7;
|
||||
}
|
||||
}
|
||||
else {
|
||||
sum_of_days += 30 % 7;
|
||||
}
|
||||
}
|
||||
|
||||
sum_of_days += (day - 1) % 7;
|
||||
|
||||
return (sum_of_days + first_day) % 7;
|
||||
}
|
50
examples/riot_and_cpp/c_functions.h
Normal file
50
examples/riot_and_cpp/c_functions.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Ho Chi Minh city University of Technology (HCMUT)
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup examples
|
||||
* @{
|
||||
*
|
||||
* @file c_functions.h
|
||||
* @brief Definitions for some c functions.
|
||||
*
|
||||
* @author DangNhat Pham-Huu <51002279@hcmut.edu.vn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef C_FUNCTIONS_H_
|
||||
#define C_FUNCTIONS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Print a hello message.
|
||||
*/
|
||||
int hello(void);
|
||||
|
||||
/**
|
||||
* @brief Get day of week from given date (day, month, year >= 1/1/2000).
|
||||
*
|
||||
* @param[in] day
|
||||
* @param[in] month
|
||||
* @param[in] year
|
||||
*
|
||||
* @return day of week (0 means Sunday, ... 6 means Saturday)
|
||||
*/
|
||||
int day_of_week(int day, int month, int year);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
#endif // _C_FUNCTIONS_H
|
55
examples/riot_and_cpp/cpp_class.cpp
Normal file
55
examples/riot_and_cpp/cpp_class.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Hamburg University of Applied Sciences (HAW)
|
||||
* Copyright (C) 2014 Ho Chi Minh city University of Technology (HCMUT)
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup examples
|
||||
* @{
|
||||
*
|
||||
* @file cpp_class.cpp
|
||||
* @brief implementation of declared functions of object cpp_class
|
||||
*
|
||||
* @author Martin Landsmann <martin.landsmann@haw-hamburg.de>
|
||||
* @author DangNhat Pham-Huu <51002279@hcmut.edu.vn>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "cpp_class.h"
|
||||
|
||||
cpp_class::cpp_class()
|
||||
{
|
||||
printf("Instanciating Object [constructor called]\n");
|
||||
greet();
|
||||
}
|
||||
|
||||
cpp_class::~cpp_class()
|
||||
{
|
||||
printf("Destroying Object [destructor called]\n");
|
||||
printf("Im shutting down!\n");
|
||||
}
|
||||
|
||||
void cpp_class::say_hello(void)
|
||||
{
|
||||
printf("Hello!\n");
|
||||
}
|
||||
|
||||
void cpp_class::say_hello(int n)
|
||||
{
|
||||
printf("Hello![int: %d]\n", n);
|
||||
}
|
||||
|
||||
void cpp_class::say_hello(float f)
|
||||
{
|
||||
printf("Hello![float: %f]\n", f);
|
||||
}
|
||||
|
||||
void cpp_class::greet(void)
|
||||
{
|
||||
printf("Im starting!\n");
|
||||
}
|
63
examples/riot_and_cpp/cpp_class.h
Normal file
63
examples/riot_and_cpp/cpp_class.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Hamburg University of Applied Sciences (HAW)
|
||||
* Copyright (C) 2014 Ho Chi Minh city University of Technology (HCMUT)
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup
|
||||
* @brief
|
||||
* @ingroup examples
|
||||
* @{
|
||||
*
|
||||
* @file cpp_class.h
|
||||
* @brief simple c++ object declaration with public and private functions
|
||||
*
|
||||
* @author Martin Landsmann <martin.landsmann@haw-hamburg.de>
|
||||
* @author DangNhat Pham-Huu <51002279@stu.hcmut.edu.vn>
|
||||
*/
|
||||
|
||||
#ifndef CPP_CLASS_H_
|
||||
#define CPP_CLASS_H_
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
class cpp_class
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief constructor
|
||||
*/
|
||||
cpp_class();
|
||||
|
||||
/**
|
||||
* @brief destructor
|
||||
*/
|
||||
~cpp_class();
|
||||
|
||||
/**
|
||||
* @brief public function
|
||||
*/
|
||||
void say_hello(void);
|
||||
|
||||
/**
|
||||
* @brief overloaded public function with int parameter
|
||||
*/
|
||||
void say_hello(int n);
|
||||
|
||||
/**
|
||||
* @brief overloaded public function with float parameter
|
||||
*/
|
||||
void say_hello(float f);
|
||||
private:
|
||||
/**
|
||||
* @brief private function
|
||||
*/
|
||||
void greet(void);
|
||||
};
|
||||
|
||||
/** @} */
|
||||
#endif //__CPP_CLASS__
|
107
examples/riot_and_cpp/main.cpp
Normal file
107
examples/riot_and_cpp/main.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Hamburg University of Applied Sciences (HAW)
|
||||
* Copyright (C) 2014 Ho Chi Minh University of Technology (HCMUT)
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file main.cpp
|
||||
* @brief Demonstration of mixed c++ and c user application with pure c RIOT
|
||||
* - mixing of c and c++ source to test name mangling
|
||||
* - introducing a namespace to declarative block, avoiding to qualify calls, e.g. std::vector
|
||||
* - using private and public member functions, e.g. 'cpp_obj.greet()' cannot be accessed from main.cpp
|
||||
* - overloading of function 'cpp_obj.say_hello(...)' for 'none', 'int' or 'float'
|
||||
* - demonstration of templated c++ container 'std::vector'
|
||||
* - usage of iterator to access elements of the container type
|
||||
*
|
||||
* @author Martin Landsmann <martin.landsmann@haw-hamburg.de>
|
||||
* @author DangNhat Pham-Huu <51002279@hcmut.edu.vn>
|
||||
*/
|
||||
|
||||
/*
|
||||
* all included headers defining c functions, i.e. all RIOT functions, must be marked as extern "C"
|
||||
*/
|
||||
extern "C" {
|
||||
#include "kernel.h"
|
||||
#include "thread.h"
|
||||
|
||||
#include "c_functions.h"
|
||||
}
|
||||
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
#include "cpp_class.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/* thread's stack */
|
||||
char threadA_stack [KERNEL_CONF_STACKSIZE_PRINTF];
|
||||
|
||||
/* thread's function */
|
||||
void threadA_func(void);
|
||||
|
||||
/* main */
|
||||
int main()
|
||||
{
|
||||
printf("\n************ RIOT and C++ demo program ***********\n");
|
||||
printf("\n");
|
||||
|
||||
/* create thread A */
|
||||
thread_create(threadA_stack, sizeof(threadA_stack), 0, CREATE_WOUT_YIELD, threadA_func, "thread A");
|
||||
|
||||
printf("******** Hello, you're in thread %s ********\n", thread_getname(thread_getpid()));
|
||||
printf("We'll test C++ class and methods here!\n");
|
||||
|
||||
cpp_class cpp_obj;
|
||||
printf("\n-= Test overloading functions =-\n");
|
||||
cpp_obj.say_hello();
|
||||
cpp_obj.say_hello(42);
|
||||
cpp_obj.say_hello(3.141592f);
|
||||
|
||||
printf("\n-= Test namespace =-\n");
|
||||
printf("typing std::vector is obsolete when 'using namespace std;'\n");
|
||||
vector<int> vInts;
|
||||
vInts.push_back(1);
|
||||
vInts.push_back(3);
|
||||
vInts.push_back(2);
|
||||
printf("The vector vInts has been filled with %d numbers.\n", vInts.size());
|
||||
|
||||
printf("\n-= Test iterator =-\n");
|
||||
printf("The content of vInts = { ");
|
||||
|
||||
for (vector<int>::iterator it = vInts.begin(); it != vInts.end(); ++it) {
|
||||
printf("%d ", *(it));
|
||||
}
|
||||
|
||||
printf("}\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* thread A function implemetation */
|
||||
void threadA_func(void)
|
||||
{
|
||||
int day = 13, month = 6, year = 2014;
|
||||
int ret_day;
|
||||
char day_of_week_table[][32] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
|
||||
|
||||
printf("\n******** Hello, now you're in %s ********\n", thread_getname(thread_getpid()));
|
||||
printf("We'll test some C functions here!\n");
|
||||
|
||||
printf("\n-= hello function =-\n");
|
||||
hello();
|
||||
|
||||
printf("\n-= day_of_week function =-\n");
|
||||
|
||||
printf("day %d, month %d, year %d is ", day, month, year);
|
||||
|
||||
ret_day = day_of_week(day, month, year);
|
||||
if (ret_day >= 0){
|
||||
printf("%s\n", day_of_week_table[ret_day]);
|
||||
}
|
||||
|
||||
printf("\nThis demo ends here, press Ctrl-C to exit (if you're on native)!\n");
|
||||
}
|
Loading…
Reference in New Issue
Block a user