CooCox论坛上时不时有人问:CoIDE是否支持C++?

CoIDE默认支持C语言,工程中的*.cpp或*.C(大写的C,会默认为cpp文件)不参与编译。这让不少惯用C++的用户觉得可惜。

好在这个世界上解决问题的方法永远比问题多得多,感谢用户Yury Kuchura的贡献和分享,现在只需要几处改动,CoIDE中就能使用C++了。步骤如下:

Step 1. 修改build.xml文件,使*.cpp文件能被编译
<fileset dir=".">
<include name="**/*.c"/>
<include name="**/*.cpp"/>
<include name="**/*.s"/>
</fileset>

Step 2. 修改link.ld文件,使连接时C++所需的段能被识别
/* Section Definitions */
SECTIONS

    .text :
    {
        KEEP(*(.isr_vector .isr_vector.*))
        *(.text .text.* .gnu.linkonce.t.*)       
        *(.glue_7t) *(.glue_7)                 
        *(.rodata .rodata* .gnu.linkonce.r.*) 
       
        /* C++ Static constructors/destructors (eabi) */
  . = ALIGN(4);
  KEEP(*(.init))
  
  . = ALIGN(4);
  __preinit_array_start = .;
  KEEP (*(.preinit_array))
  __preinit_array_end = .;
  
  . = ALIGN(4);
  __init_array_start = .;
  KEEP (*(SORT(.init_array.*)))
  KEEP (*(.init_array))
  __init_array_end = .;
  
  . = ALIGN(4);
  KEEP(*(.fini))
  
  . = ALIGN(4);
  __fini_array_start = .;
  KEEP (*(.fini_array))
  KEEP (*(SORT(.fini_array.*)))
  __fini_array_end = .;
  
  /* C++ Static constructors/destructors (elf) */
  . = ALIGN(4);
  _ctor_start = .;
  KEEP (*crtbegin.o(.ctors))
  KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
  KEEP (*(SORT(.ctors.*)))
  KEEP (*crtend.o(.ctors))
  _ctor_end = .;
  
  . = ALIGN(4);
  KEEP (*crtbegin.o(.dtors))
  KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
  KEEP (*(SORT(.dtors.*)))
  KEEP (*crtend.o(.dtors))                       
    } > rom
    
    .ARM.extab :
    {
        *(.ARM.extab* .gnu.linkonce.armextab.*)
} > rom


    /* stack section */
    .co_stack (NOLOAD):
    {
        . = ALIGN(8);
        *(.co_stack .co_stack.*)
    } > ram
    
    __exidx_start = .;
    .ARM.exidx :
    {
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > rom
    __exidx_end = .;
    
       
    . = ALIGN(4);
    _end = . ;
}

Step 3. 修改启动代码,使构造和析构函数能被正确调用

extern unsigned long __preinit_array_start;
extern unsigned long __preinit_array_end;
extern unsigned long __init_array_start;
extern unsigned long __init_array_end;
extern unsigned long _ctor_start;
extern unsigned long _ctor_end;
static void call_constructors(unsigned long *start, unsigned long *end) __attribute__((noinline));
static void call_constructors(unsigned long *start, unsigned long *end)
{
  unsigned long *i;
  void (*funcptr)();
  for ( i = start; i < end; i++)
  {
    funcptr=(void (*)())(*i);
    funcptr();
  }
}

void Default_Reset_Handler(void)
{

  /* Setup the microcontroller system. */
  SystemInit();
    
  //Initialize CoOS (in order the new/delete operators to work properly
  //prior to calling constructors). Comment it out if you don't use CoOS!
  CoInitOS();

  //Call C++ global constructors
  call_constructors(&__preinit_array_start, &__preinit_array_end);
  call_constructors(&__init_array_start, &__init_array_end);
  call_constructors(&_ctor_start, &_ctor_end);

  /* Call the application's entry point.*/
  main();
}

Step 4. 在组件页勾选C Library和Retarget printf,之后注释掉printf.c文件中的如下语句,以避免重定义_impure_ptr
// struct _reent *_impure_ptr = &r;

Step 5. 在工程配置(Project configuration)中添加Linked Libraries libstdc++和libsupc++,它们可以从GCC tool chain的库中找到

来源:
https://www.coocox.org/Forum/topic.php?id=730
https://www.coocox.org/Forum/topic.php?id=873

例程:103vb_cpp.zip
STM32103vb + CoIDE 1.3.1 + 闪灯
说明——因CoIDE 1.4.0存在bug“修改build.xml文件后无法保存”,故使用CoIDE 1.3.1版本。此bug在新版CoIDE中将被修复。

欢迎大家常来CooCox论坛交流讨论~