diff --git a/tools/export/gnuarmeclipse/.cproject.tmpl b/tools/export/gnuarmeclipse/.cproject.tmpl
index 1071573afd..7146db0eda 100644
--- a/tools/export/gnuarmeclipse/.cproject.tmpl
+++ b/tools/export/gnuarmeclipse/.cproject.tmpl
@@ -19,24 +19,128 @@
+
+
+
+ {% if options['common']['arm.target.thumbinterwork'] %}
+
+ {% endif %}
+ {% if options['common']['arm.target.endianness'] %}
+
+ {% endif %}
+ {% if options['common']['arm.target.fpu.abi'] %}
+
+ {% endif %}
+ {% if options['common']['arm.target.fpu.unit'] %}
+
+ {% endif %}
+ {% if options['common']['arm.target.unalignedaccess'] %}
+
+ {% endif %}
+
+ {% if options['common']['optimization.messagelength'] %}
+ {% endif %}
+ {% if options['common']['optimization.signedchar'] %}
+ {% endif %}
+ {% if options['common']['optimization.functionsections'] %}
+ {% endif %}
+ {% if options['common']['optimization.datasections'] %}
+ {% endif %}
+ {% if options['common']['optimization.nocommon'] %}
+
+ {% endif %}
+ {% if options['common']['optimization.noinlinefunctions'] %}
+
+ {% endif %}
+ {% if options['common']['optimization.freestanding'] %}
+
+ {% endif %}
+ {% if options['common']['optimization.nobuiltin'] %}
+
+ {% endif %}
+ {% if options['common']['optimization.spconstant'] %}
+
+ {% endif %}
+ {% if options['common']['optimization.PIC'] %}
+
+ {% endif %}
+
+ {% if options['common']['optimization.other'] != '' %}
+
+ {% endif %}
+
+ {% if options['common']['warnings.syntaxonly'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.pedantic'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.pedanticerrors'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.nowarn'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.unused'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.uninitialized'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.allwarn'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.extrawarn'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.missingdeclaration'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.conversion'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.pointerarith'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.padded'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.shadow'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.logicalop'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.agreggatereturn'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.floatequal'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.toerrors'] %}
+
+ {% endif %}
+
+ {% if options['common']['warnings.other'] != '' %}
+
+ {% endif %}
+
-
-
- {% if target_fpu_unit %}
-
+
+ {% if options['common']['debugging.prof'] %}
+
{% endif %}
-
-
-
+ {% if options['common']['debugging.gprof'] %}
+
+ {% endif %}
+
-
-
@@ -51,93 +155,205 @@
+ {% if options['as']['usepreprocessor'] %}
+ {% endif %}
+ {% if options['as']['nostdinc'] %}
+
+ {% endif %}
+ {% if options['as']['otherwarnings'] != '' %}
+
+ {% endif %}
+ {% if options['as']['verbose'] %}
+
+ {% endif %}
+ {% if options['as']['other'] != '' %}
+
+ {% endif %}
+ {% if options['c']['nostdinc'] %}
+
+ {% endif %}
+ {% if options['c']['compiler.std'] %}
+
+ {% endif %}
+ {% if options['c']['otheroptimizations'] != '' %}
+
+ {% endif %}
+ {% if options['c']['warnings.missingprototypes'] %}
+
+ {% endif %}
+ {% if options['c']['warnings.strictprototypes'] %}
+
+ {% endif %}
+ {% if options['c']['warnings.badfunctioncast'] %}
+
+ {% endif %}
+ {% if options['c']['otherwarnings'] != '' %}
+
+ {% endif %}
+ {% if options['c']['verbose'] %}
+
+ {% endif %}
+ {% if options['c']['other'] != '' %}
+
+ {% endif %}
+ {% if options['cpp']['nostdinc'] %}
+
+ {% endif %}
+ {% if options['cpp']['nostdincpp'] %}
+
+ {% endif %}
-
-
-
-
+ {% if options['cpp']['compiler.std'] %}
+
+ {% endif %}
+
+ {% if options['cpp']['optimization.noexceptions'] %}
+
+ {% endif %}
+ {% if options['cpp']['optimization.nortti'] %}
+
+ {% endif %}
+ {% if options['cpp']['optimization.nousecxaatexit'] %}
+
+ {% endif %}
+ {% if options['cpp']['optimization.nothreadsafestatics'] %}
+
+ {% endif %}
+ {% if options['cpp']['otheroptimizations'] != '' %}
+
+ {% endif %}
+
+ {% if options['cpp']['warnabi'] %}
+
+ {% endif %}
+ {% if options['cpp']['warnings.ctordtorprivacy'] %}
+
+ {% endif %}
+ {% if options['cpp']['warnings.noexcept'] %}
+
+ {% endif %}
+ {% if options['cpp']['warnings.nonvirtualdtor'] %}
+
+ {% endif %}
+ {% if options['cpp']['warnings.strictnullsentinel'] %}
+
+ {% endif %}
+ {% if options['cpp']['warnings.signpromo'] %}
+
+ {% endif %}
+ {% if options['cpp']['warneffc'] %}
+
+ {% endif %}
+ {% if options['cpp']['otherwarnings'] != '' %}
+
+ {% endif %}
+
+ {% if options['cpp']['verbose'] %}
+
+ {% endif %}
+ {% if options['cpp']['other'] != '' %}
+
+ {% endif %}
-
-
-
-
-
-
-
-
+ {% if options['ld']['gcsections'] %}
+
+ {% endif %}
+
+ {% if options['ld']['nostart'] %}
-
+ {% endif %}
+ {% if options['ld']['nodeflibs'] %}
+
+ {% endif %}
+ {% if options['ld']['nostdlibs'] %}
+
+ {% endif %}
+
+
+ {% if options['ld']['other'] != '' %}
+
+ {% endif %}
@@ -158,7 +374,7 @@
-
+
@@ -180,23 +396,135 @@
-
-
-
-
-
-
-
-
-
- {% if target_fpu_unit %}
-
+
+
+
+
+ {% if options['common']['arm.target.thumbinterwork'] %}
+
{% endif %}
+ {% if options['common']['arm.target.endianness'] %}
+
+ {% endif %}
+
+ {% if options['common']['arm.target.fpu.abi'] %}
+
+ {% endif %}
+ {% if options['common']['arm.target.fpu.unit'] %}
+
+ {% endif %}
+ {% if options['common']['arm.target.unalignedaccess'] %}
+
+ {% endif %}
+
+ {% if options['common']['optimization.messagelength'] %}
+
+ {% endif %}
+ {% if options['common']['optimization.signedchar'] %}
+
+ {% endif %}
+ {% if options['common']['optimization.functionsections'] %}
+
+ {% endif %}
+ {% if options['common']['optimization.datasections'] %}
+
+ {% endif %}
+ {% if options['common']['optimization.nocommon'] %}
+
+ {% endif %}
+ {% if options['common']['optimization.noinlinefunctions'] %}
+
+ {% endif %}
+ {% if options['common']['optimization.freestanding'] %}
+
+ {% endif %}
+ {% if options['common']['optimization.nobuiltin'] %}
+
+ {% endif %}
+ {% if options['common']['optimization.spconstant'] %}
+
+ {% endif %}
+ {% if options['common']['optimization.PIC'] %}
+
+ {% endif %}
+ {% if options['common']['optimization.nomoveloopinvariants'] %}
+
+ {% endif %}
+ {% if options['common']['optimization.other'] != '' %}
+
+ {% endif %}
+
+ {% if options['common']['warnings.syntaxonly'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.pedantic'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.pedanticerrors'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.nowarn'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.unused'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.uninitialized'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.allwarn'] %}
+ {% endif %}
+ {% if options['common']['warnings.extrawarn'] %}
+ {% endif %}
+ {% if options['common']['warnings.missingdeclaration'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.conversion'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.pointerarith'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.padded'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.shadow'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.logicalop'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.agreggatereturn'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.floatequal'] %}
+
+ {% endif %}
+ {% if options['common']['warnings.toerrors'] %}
+
+ {% endif %}
+
+ {% if options['common']['warnings.other'] != '' %}
+
+ {% endif %}
+
+ {% if options['common']['debugging.level'] != 'none' %}
+
+ {% endif %}
+ {% if options['common']['debugging.format'] != '' %}
+
+ {% endif %}
+
+ {% if options['common']['debugging.prof'] %}
+
+ {% endif %}
+ {% if options['common']['debugging.gprof'] %}
+
+ {% endif %}
+
-
-
@@ -211,90 +539,203 @@
+ {% if options['as']['usepreprocessor'] %}
+ {% endif %}
+ {% if options['as']['nostdinc'] %}
+
+ {% endif %}
+ {% if options['as']['otherwarnings'] != '' %}
+
+ {% endif %}
+ {% if options['as']['verbose'] %}
+
+ {% endif %}
+ {% if options['as']['other'] != '' %}
+
+ {% endif %}
+ {% if options['c']['nostdinc'] %}
+
+ {% endif %}
+ {% if options['c']['compiler.std'] %}
+
+ {% endif %}
+ {% if options['c']['otheroptimizations'] != '' %}
+
+ {% endif %}
+ {% if options['c']['warnings.missingprototypes'] %}
+
+ {% endif %}
+ {% if options['c']['warnings.strictprototypes'] %}
+
+ {% endif %}
+ {% if options['c']['warnings.badfunctioncast'] %}
+
+ {% endif %}
+ {% if options['c']['otherwarnings'] != '' %}
+
+ {% endif %}
+ {% if options['c']['verbose'] %}
+
+ {% endif %}
+ {% if options['c']['other'] != '' %}
+
+ {% endif %}
+ {% if options['cpp']['nostdinc'] %}
+
+ {% endif %}
+ {% if options['cpp']['nostdincpp'] %}
+
+ {% endif %}
-
-
-
-
+
+ {% if options['cpp']['compiler.std'] %}
+
+ {% endif %}
+
+ {% if options['cpp']['optimization.noexceptions'] %}
+
+ {% endif %}
+ {% if options['cpp']['optimization.nortti'] %}
+
+ {% endif %}
+ {% if options['cpp']['optimization.nousecxaatexit'] %}
+
+ {% endif %}
+ {% if options['cpp']['optimization.nothreadsafestatics'] %}
+
+ {% endif %}
+ {% if options['cpp']['otheroptimizations'] != '' %}
+
+ {% endif %}
+
+ {% if options['cpp']['warnabi'] %}
+
+ {% endif %}
+ {% if options['cpp']['warnings.ctordtorprivacy'] %}
+
+ {% endif %}
+ {% if options['cpp']['warnings.noexcept'] %}
+
+ {% endif %}
+ {% if options['cpp']['warnings.nonvirtualdtor'] %}
+
+ {% endif %}
+ {% if options['cpp']['warnings.strictnullsentinel'] %}
+
+ {% endif %}
+ {% if options['cpp']['warnings.signpromo'] %}
+
+ {% endif %}
+ {% if options['cpp']['warneffc'] %}
+
+ {% endif %}
+ {% if options['cpp']['otherwarnings'] != '' %}
+
+ {% endif %}
+
+ {% if options['cpp']['verbose'] %}
+
+ {% endif %}
+ {% if options['cpp']['other'] != '' %}
+
+ {% endif %}
-
-
-
-
-
-
-
-
+ {% if options['ld']['gcsections'] %}
+
+ {% endif %}
+
+ {% if options['ld']['nostart'] %}
-
+ {% endif %}
+ {% if options['ld']['nodeflibs'] %}
+
+ {% endif %}
+ {% if options['ld']['nostdlibs'] %}
+
+ {% endif %}
+
+
+ {% if options['ld']['other'] != '' %}
+
+ {% endif %}
@@ -315,7 +756,7 @@
-
+
diff --git a/tools/export/gnuarmeclipse/NOTES.md b/tools/export/gnuarmeclipse/NOTES.md
new file mode 100644
index 0000000000..6c3068eec8
--- /dev/null
+++ b/tools/export/gnuarmeclipse/NOTES.md
@@ -0,0 +1,488 @@
+# GNU ARM Eclipse
+
+The [GNU ARM Eclipse](http://gnuarmeclipse.github.io) is an open source project that includes a family of Eclipse plug-ins and tools for multi-platform embedded ARM development, based on GNU toolchains. The project is hosted on [GitHub](https://github.com/gnuarmeclipse).
+
+This exporter aims to create managed GNU ARM Eclipse projects, ready to build, and with as many options properly identified and set in the Eclipse C/C++ Build -> Settings page.
+
+## Build plug-in configuration options
+
+All options are prefixed by `ilg.gnuarmeclipse.managedbuild.cross.option.`.
+
+### Target Processor
+
+- `arm.target.family` enumerated
+ - **ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.mcpu.cortex-m3** '-mcpu=cortex-m3'
+ - cortex-m0 '-mcpu=%s'
+ - cortex-m0-small-multiply '-mcpu=%s'
+ - cortex-m0plus '-mcpu=%s'
+ - cortex-m0plus-small-multiply '-mcpu=%s'
+ - cortex-m1 '-mcpu=%s'
+ - cortex-m1-small-multiply '-mcpu=%s'
+ - cortex-m4 '-mcpu=%s'
+ - cortex-m7 '-mcpu=%s'
+
+- `arm.target.architecture` enumerated
+ - **ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.arch.none** ''
+ - armv6-m '-march=%s'
+ - armv7-m '-march=%s'
+
+- `arm.target.instructionset` enumerated
+ - **ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.thumb** '-mthumb'
+ - arm '-marm'
+
+- `arm.target.thumbinterwork` bool
+ - true `-mthumb-interwork`
+
+- `arm.target.endianness` enumerated
+ - **ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.endianness.default**
+ - little `-mlittle-endian`
+ - big `-mbig-endian`
+
+- `arm.target.fpu.abi` enumerated
+ - **ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.abi.default**
+ - soft '-mfloat-abi=soft'
+ - softfp '-mfloat-abi=softfp'
+ - hard '-mfloat-abi=hard'
+
+- `arm.target.fpu.unit` enumerated
+ - **ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.unit.default**
+ - fpv4spd16 '-mfpu=fpv4-sp-d16'
+ - fpv5d16 '-mfpu=fpv5-d16'
+ - fpv5spd16 '-mfpu=fpv5-sp-d16'
+ - ...
+
+- `arm.target.unalignedaccess`
+ - **ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.unalignedaccess.default**
+ - enabled '-munaligned-access'
+ - disabled '-mno-unaligned-access'
+
+- `target.other` string
+
+### Optimization
+
+- `optimization.level` enumerated
+ - **ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.more** '-O2'
+ - none '-O0'
+ - optimize '-O1'
+ - most '-O3'
+ - size '-Os'
+ - debug '-Og'
+
+- `optimization.messagelength` bool
+ - **false** ''
+ - true '-fmessage-length=0'
+
+- `optimization.signedchar` bool
+ - **false**
+ - true '-fsigned-char'
+
+- `optimization.functionsections` bool
+ - **false**
+ - true '-ffunction-sections'
+
+- `optimization.datasections` bool
+ - **false**
+ - true '-fdata-sections'
+
+- `optimization.nocommon` bool
+ - **false**
+ - true '-fno-common'
+
+- `optimization.noinlinefunctions` bool
+ - **false** ''
+ - true '-fno-inline-functions'
+
+- `optimization.freestanding` bool
+ - **false** ''
+ - true '-ffreestanding'
+
+- `optimization.nobuiltin` bool
+ - **false** ''
+ - true '-fno-builtin'
+
+- `optimization.spconstant` bool
+ - **false** ''
+ - true '-fsingle-precision-constant'
+
+- `optimization.PIC` bool
+ - **false** ''
+ - true '-fPIC'
+
+- `optimization.lto` bool
+ - **false** ''
+ - true '-flto'
+
+- `optimization.nomoveloopinvariants` bool
+ - **false** ''
+ - true '-fno-move-loop-invariants'
+
+- `optimization.other` string
+
+- `` bool
+ - **false** ''
+ - true ''
+
+### Warnings
+
+- `warnings.syntaxonly` bool
+ - **false** ''
+ - true '-fsyntax-only'
+
+- `warnings.pedantic` bool
+ - **false** ''
+ - true '-pedantic'
+
+- `warnings.pedanticerrors` bool
+ - **false** ''
+ - true '-pedantic-errors'
+
+- `warnings.nowarn` bool
+ - **false** ''
+ - true '-w'
+
+- `warnings.unused` bool
+ - **false** ''
+ - true '-Wunused'
+
+- `warnings.uninitialized` bool
+ - **false** ''
+ - true '-Wuninitialized'
+
+- `warnings.allwarn` bool
+ - **false** ''
+ - true '-Wall'
+
+- `warnings.extrawarn` bool
+ - **false** ''
+ - true '-Wextra'
+
+- `warnings.missingdeclaration` bool
+ - **false** ''
+ - true '-Wmissing-declarations'
+
+- `warnings.conversion` bool
+ - **false** ''
+ - true '-Wconversion'
+
+- `warnings.pointerarith` bool
+ - **false** ''
+ - true '-Wpointer-arith'
+
+- `warnings.padded` bool
+ - **false** ''
+ - true '-Wpadded'
+
+- `warnings.shadow` bool
+ - **false** ''
+ - true '-Wshadow'
+
+- `warnings.logicalop` bool
+ - **false** ''
+ - true '-Wlogical-op'
+
+- `warnings.agreggatereturn` bool
+ - **false** ''
+ - true '-Waggregate-return'
+
+- `warnings.floatequal` bool
+ - **false** ''
+ - true '-Wfloat-equal'
+
+- `warnings.toerrors` bool
+ - **false** ''
+ - true '-Werror'
+
+- `warnings.other` string
+
+### Debugging
+
+- `debugging.level` enumerated
+ - **ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.default** '-g'
+ - none ''
+ - minimal '-g1'
+ - max '-g3'
+
+- `debugging.format` enumerated
+ - **ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format.default** ''
+ - gdb '-ggdb'
+ - stabs '-gstabs'
+ - stabsplus '-gstabs+'
+ - dwarf2 '-gdwarf-2'
+ - dwarf3 '-gdwarf-3'
+ - dwarf4 '-gdwarf-4'
+ - dwarf5 '-gdwarf-5'
+
+- `debugging.prof` bool
+ - **false** ''
+ - true '-p'
+
+- `debugging.gprof` bool
+ - **false** ''
+ - true '-pg'
+
+- `debugging.other` string
+
+
+### Compiler common options
+
+- `verbose` bool
+ - **false** ''
+ - true '-v'
+
+- `savetemps` bool
+ - **false** ''
+ - true '--save-temps'
+
+- `nostdinc` bool
+ - **false** ''
+ - true '-nostdinc'
+
+- `asmlisting` bool
+ - **false** ''
+ - true '-Wa,-adhlns="$@.lst"'
+
+- `preprocessor.preprocessonly` bool
+ - **false** ''
+ - true '-E'
+
+- `dirs.include.files`
+ - '-include%s'
+
+- `compiler.other` string
+
+### Linker common options
+
+- `mapfilename` string
+ - '-Wl,-Map,"${BuildArtifactFileBaseName}.map"'
+
+- `linker.scriptfile`
+ - '-T %s'
+
+- `cref` bool
+ - **false** ''
+ - true '-Xlinker --cref'
+
+- `printmap` bool
+ - **false** ''
+ - true '-Xlinker --print-map'
+
+- `linker.nostart` bool
+ - **false** ''
+ - true '-nostartfiles'
+
+- `linker.nodeflibs` bool
+ - **false** ''
+ - true '-nodefaultlibs'
+
+- `linker.nostdlibs` bool
+ - **false** ''
+ - true '-nostdlib'
+
+- `linker.gcsections` bool
+ - **false** ''
+ - true '-Xlinker --gc-sections'
+
+- `linker.printgcsections` bool
+ - **false** ''
+ - true '-Xlinker --print-gc-sections'
+
+- `linker.strip` bool
+ - **false** ''
+ - true '-s'
+
+- `linker.other` string
+
+- `linker.usenewlibnano` bool
+ - **false** ''
+ - true '--specs=nano.specs'
+
+- `linker.useprintffloat` bool
+ - **false** ''
+ - true '-u \_printf\_float'
+
+- `linker.usescanffloat` bool
+ - **false** ''
+ - true '-u \_scanf\_float'
+
+
+### Cross ARM GNU Assembler
+
+#### Preprocessor
+
+- `nostdinc` bool
+ - **false** ''
+ - true '-nostdinc'
+
+#### Includes
+
+#### Warnings
+
+#### Miscellaneous
+
+- `verbose` bool
+ - **false** ''
+ - true '-v'
+
+- `assembler.other` string
+
+### Cross ARM GNU C Compiler
+
+#### Preprocessor
+
+- `nostdinc` bool
+ - **false** ''
+ - true '-nostdinc'
+
+#### Includes
+
+#### Optimization
+
+- `c.compiler.std` enumerated
+ - **ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.std.default** ''
+ - ansi '-ansi'
+ - c90 '-std=c90' (c89)
+ - gnu90 '-std=gnu90' (gnu89)
+ - c99 '-std=c99' (c9x)
+ - gnu99 '-std=gnu99' (gnu9x)
+ - c11 '-std=c11' (c1x)
+ - gnu11 '-std=gnu11' (gnu1x)
+
+#### Warnings
+
+- `c.compiler.warning.missingprototypes` bool
+ - **false** ''
+ - true '-Wmissing-prototypes'
+
+- `c.compiler.warning.strictprototypes` bool
+ - **false** ''
+ - true '-Wstrict-prototypes'
+
+- `c.compiler.warning.badfunctioncast` bool
+ - **false** ''
+ - true '-Wbad-function-cast'
+
+#### Miscellaneous
+
+- `verbose` bool
+ - **false** ''
+ - true '-v'
+
+- `c.compiler.other` string
+
+### Cross ARM GNU C++ Compiler
+
+#### Preprocessor
+
+- `nostdinc` bool
+ - **false** ''
+ - true '-nostdinc'
+
+- `nostdincpp` bool
+ - **false** ''
+ - true '-nostdinc++'
+
+#### Includes
+
+#### Optimization
+
+- `cpp.compiler.std` enumerated
+ - **ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.std.default** ''
+ - ansi (-ansi)
+ - cpp98 '-std=c++98' (c++03)
+ - gnucpp98 '-std=gnu++98' (gnu++03)
+ - cpp0x '-std=c++0x'
+ - gnucpp0x '-std=gnu++0x'
+ - cpp11 '-std=c++11'
+ - gnucpp11 '-std=gnu++11'
+ - cpp1y '-std=c++1y'
+ - gnucpp1y '-std=gnu++1y'
+ - cpp14 '-std=c++14'
+ - gnucpp1 4'-std=gnu++14'
+ - cpp1z '-std=c++1z'
+ - gnucpp1z '-std=gnu++1z'
+
+- `cpp.compiler.abiversion` enumerated
+ - **ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.abiversion.0** '-fabi-version=0'
+ - default ''
+ - 1 '-fabi-version=1'
+ - 2 '-fabi-version=2'
+ - 3 '-fabi-version=3'
+ - 4 '-fabi-version=4'
+ - 5 '-fabi-version=5'
+ - 6 '-fabi-version=6'
+
+- `cpp.compiler.noexceptions` bool
+ - **false** ''
+ - true '-fno-exceptions'
+
+- `cpp.compiler.nortti` bool
+ - **false** ''
+ - true '-fno-rtti'
+
+- `cpp.compiler.nousecxaatexit` bool
+ - **false** ''
+ - true '-fno-use-cxa-atexit'
+
+- `cpp.compiler.nothreadsafestatics` bool
+ - **false** ''
+ - true '-fno-threadsafe-statics'
+
+
+#### Warnings
+
+- `cpp.compiler.warnabi` bool
+ - **false** '-Wabi'
+
+- `cpp.compiler.warning.ctordtorprivacy` bool
+ - **false** '-Wctor-dtor-privacy'
+
+- `cpp.compiler.warning.noexcept` bool
+ - **false** '-Wnoexcept'
+
+- `cpp.compiler.warning.nonvirtualdtor` bool
+ - **false** '-Wnon-virtual-dtor'
+
+- `cpp.compiler.warning.strictnullsentinel` bool
+ - **false** '-Wstrict-null-sentinel'
+
+- `cpp.compiler.warning.signpromo` bool
+ - **false** '-Wsign-promo'
+
+- `cpp.compiler.warneffc` bool
+ - **false** ''
+ - true '-Weffc++'
+
+#### Miscellaneous
+
+- `verbose` bool
+ - **false** ''
+ - true '-v'
+
+- `cpp.compiler.other` string
+
+### Cross ARM GNU C++ Linker
+
+#### General
+
+- `cpp.linker.nostart`
+ - **false** ''
+ - true '-nostartfiles'
+
+- `cpp.linker.nodeflibs`
+ - **false** ''
+ - true '-nodefaultlibs'
+
+- `cpp.linker.nostdlibs`
+ - **false** ''
+ - true '-nostdlib'
+
+#### Libraries
+
+#### Miscellaneous
+
+
+## Template
+
+- `` bool
+ - **false** ''
+ - true ''
diff --git a/tools/export/gnuarmeclipse/__init__.py b/tools/export/gnuarmeclipse/__init__.py
index 8f751f88e7..c67c6267ba 100644
--- a/tools/export/gnuarmeclipse/__init__.py
+++ b/tools/export/gnuarmeclipse/__init__.py
@@ -26,10 +26,13 @@ from os.path import splitext, basename, relpath, dirname
from random import randint
import os
import copy
+# import logging
from tools.targets import TARGET_MAP
from tools.utils import NotSupportedException
+# =============================================================================
+
class UID:
"""
@@ -44,6 +47,8 @@ class UID:
# Each invocation generates a new number.
u = UID()
+# =============================================================================
+
class GNUARMEclipse(Exporter):
NAME = 'GNU ARM Eclipse'
@@ -53,17 +58,7 @@ class GNUARMEclipse(Exporter):
TARGETS = [target for target, obj in TARGET_MAP.iteritems()
if 'GCC_ARM' in obj.supported_toolchains]
- @staticmethod
- def filter_dot(s):
- """
- Remove the './' prefix, if present.
- """
- if s == None:
- return None
- if s[:2] == './':
- return s[2:]
- return s
-
+ # override
@property
def flags(self):
"""Returns a dictionary of toolchain flags.
@@ -88,48 +83,184 @@ class GNUARMEclipse(Exporter):
config_header)
return flags
- def dump_tree(self, node, depth=0):
- for k in node.keys():
- n = node[k]
- pn = n['parent']['name'] if 'parent' in n.keys() else ''
- print ' ' * depth, n['name'], n['is_used'], pn
- if len(n['children'].keys()) != 0:
- self.dump_tree(n['children'], depth + 1)
-
- def dump_paths(self, node, depth=0):
- for k in node.keys():
- n = node[k]
- x = []
- ni = n
- while True:
- x.insert(0, ni['name'])
- if 'parent' not in ni:
- break
- ni = ni['parent']
- path = '/'.join(x)
- print path, n['is_used']
- self.dump_paths(n['children'], depth + 1)
-
- def recurse_excludings(self, node):
+ # override
+ def generate(self):
"""
- Recurse the tree and collect all unused folders; descend
- the hierarchy only for used nodes.
+ Generate the .project and .cproject files.
"""
- for k in node.keys():
- n = node[k]
- if n['is_used'] == False:
- x = []
- ni = n
- while True:
- x.insert(0, ni['name'])
- if 'parent' not in ni:
- break
- ni = ni['parent']
- path = '/'.join(x)
- # print path
- self.excluded_folders.append(path)
- else:
- self.recurse_excludings(n['children'])
+ if not self.resources.linker_script:
+ raise NotSupportedException("No linker script found.")
+
+ print
+ print '[Create a GNU ARM Eclipse C++ managed project]'
+ print 'Project name: {0}'.format(self.project_name)
+ print 'Build configurations: Debug & Release'
+
+ self.resources.win_to_unix()
+
+ # TODO: use some logger to display additional info if verbose
+
+ # There are 4 categories of options, a category common too
+ # all tools and a specific category for each of the tools.
+ self.options = {}
+ self.options['common'] = {}
+ self.options['as'] = {}
+ self.options['c'] = {}
+ self.options['cpp'] = {}
+ self.options['ld'] = {}
+
+ libraries = []
+ # print 'libraries'
+ # print self.resources.libraries
+ for lib in self.resources.libraries:
+ l, _ = splitext(basename(lib))
+ libraries.append(l[3:])
+
+ self.system_libraries = [
+ 'stdc++', 'supc++', 'm', 'c', 'gcc', 'nosys'
+ ]
+
+ # TODO: get the list from existing .cproject
+ build_folders = ['Debug', 'Release', 'BUILD']
+
+ objects = [self.filter_dot(s) for s in self.resources.objects]
+ for bf in build_folders:
+ objects = [o for o in objects if not o.startswith(bf + '/')]
+ # print 'objects'
+ # print objects
+
+ self.compute_exclusions()
+
+ self.process_options()
+
+ self.options['as']['defines'] = self.toolchain.get_symbols(True)
+ self.options['c']['defines'] = self.toolchain.get_symbols()
+ self.options['cpp']['defines'] = self.toolchain.get_symbols()
+ print 'Symbols: {0}'.format(len(self.options['cpp']['defines']))
+
+ self.options['common']['include_paths'] = [
+ self.filter_dot(s) for s in self.resources.inc_dirs]
+ print 'Include folders: {0}'.format(len(self.options['common']['include_paths']))
+ self.options['common']['excluded_folders'] = '|'.join(
+ self.excluded_folders)
+
+ self.options['ld']['library_paths'] = [
+ self.filter_dot(s) for s in self.resources.lib_dirs]
+
+ self.options['ld']['object_files'] = objects
+
+ self.options['ld']['user_libraries'] = libraries
+
+ self.options['ld']['system_libraries'] = self.system_libraries
+
+ self.options['ld']['script'] = self.filter_dot(
+ self.resources.linker_script)
+ print 'Linker script: {0}'.format(self.options['ld']['script'])
+
+ ctx = {
+ 'name': self.project_name,
+
+ # Compiler & linker command line options
+ 'options': self.options,
+
+ # Unique IDs used in multiple places.
+ # Those used only once are implemented with {{u.id}}.
+ 'debug_config_uid': u.id,
+ 'debug_tool_c_compiler_uid': u.id,
+ 'debug_tool_c_compiler_input_uid': u.id,
+ 'debug_tool_cpp_compiler_uid': u.id,
+ 'debug_tool_cpp_compiler_input_uid': u.id,
+ 'release_config_uid': u.id,
+ 'release_tool_c_compiler_uid': u.id,
+ 'release_tool_c_compiler_input_uid': u.id,
+ 'release_tool_cpp_compiler_uid': u.id,
+ 'release_tool_cpp_compiler_input_uid': u.id,
+
+ # Must be an object with an `id` property, which
+ # will be called repeatedly, to generate multiple UIDs.
+ 'u': u,
+ }
+
+ # TODO: it would be good to have jinja stop if one of the
+ # expected context values is not defined.
+ self.gen_file('gnuarmeclipse/.project.tmpl', ctx, '.project')
+ self.gen_file('gnuarmeclipse/.cproject.tmpl', ctx, '.cproject')
+
+ print 'Done.'
+
+ # override
+ @staticmethod
+ def build(project_name, log_name="build_log.txt", cleanup=True):
+ """
+ Build GNU ARM Eclipse project.
+ """
+
+ ret_code = 0
+
+ # TODO: add code to run the build in a headless configuration.
+
+ # Cleanup the exported and built files
+ if cleanup:
+ os.remove('.project')
+ os.remove('.cproject')
+ # TODO: remove Debug, Release
+
+ if ret_code != 0:
+ # Seems like something went wrong.
+ return -1
+ else:
+ return 0
+
+ # -------------------------------------------------------------------------
+ # Process source files/folders exclusions.
+
+ def compute_exclusions(self):
+ """
+ With the project root as the only source folder known to CDT,
+ based on the list of source files, compute the folders to not
+ be included in the build.
+
+ The steps are:
+ - get the list of source folders, as dirname(source_file)
+ - compute the top folders (subfolders of the project folder)
+ - iterate all subfolders and add them to a tree, with all
+ nodes markes as 'not used'
+ - iterate the source folders and mark them as 'used' in the
+ tree, including all intermediate nodes
+ - recurse the tree and collect all unused folders; descend
+ the hierarchy only for used nodes
+ """
+ source_folders = [self.filter_dot(s) for s in set(dirname(
+ src) for src in self.resources.c_sources + self.resources.cpp_sources + self.resources.s_sources)]
+ if '.' in source_folders:
+ source_folders.remove('.')
+
+ # print 'source folders'
+ # print source_folders
+
+ top_folders = [f for f in set(s.split(os.sep)[0]
+ for s in source_folders)]
+ # print 'top folders'
+ # print top_folders
+
+ self.source_tree = {}
+ for top_folder in top_folders:
+ for root, dirs, files in os.walk(top_folder):
+ if len(dirs) == 0:
+ self.add_source_folder_to_tree(root)
+
+ for folder in source_folders:
+ self.add_source_folder_to_tree(folder, True)
+
+ # print
+ # print self.source_tree
+ # self.dump_paths(self.source_tree)
+
+ # print 'excludings'
+ self.excluded_folders = ['BUILD']
+ self.recurse_excludings(self.source_tree)
+
+ print 'Source folders: {0}, with {1} exclusions'.format(len(source_folders), len(self.excluded_folders))
def add_source_folder_to_tree(self, path, is_used=False):
"""
@@ -155,67 +286,105 @@ class GNUARMEclipse(Exporter):
p = n[s]
n = n[s]['children']
- def compute_exclusions(self):
+ def recurse_excludings(self, node):
"""
- With the project root as the only source folder known to CDT,
- based on the list of source files, compute the folders to not
- be included in the build.
-
- The steps are:
- - get the list of source folders, as dirname(source_file)
- - compute the top folders (subfolders of the project folder)
- - iterate all subfolders and add them to a tree, with all
- nodes markes as 'not used'
- - iterate the source folders and mark them as 'used' in the
- tree, including all intermediate nodes
- - recurse the tree and collect all unused folders; descend
- the hierarchy only for used nodes
+ Recurse the tree and collect all unused folders; descend
+ the hierarchy only for used nodes.
"""
- source_folders = [self.filter_dot(s) for s in set(dirname(
- src) for src in self.resources.c_sources + self.resources.cpp_sources + self.resources.s_sources)]
- source_folders.remove('.')
- # print 'source folders'
- # print source_folders
+ for k in node.keys():
+ n = node[k]
+ if n['is_used'] == False:
+ x = []
+ ni = n
+ while True:
+ x.insert(0, ni['name'])
+ if 'parent' not in ni:
+ break
+ ni = ni['parent']
+ path = '/'.join(x)
+ # print path
+ self.excluded_folders.append(path)
+ else:
+ self.recurse_excludings(n['children'])
- top_folders = [f for f in set(s.split(os.sep)[0]
- for s in source_folders)]
- # print 'top folders'
- # print top_folders
+ # -------------------------------------------------------------------------
- self.source_tree = {}
- for top_folder in top_folders:
- for root, dirs, files in os.walk(top_folder):
- if len(dirs) == 0:
- self.add_source_folder_to_tree(root)
-
- for folder in source_folders:
- self.add_source_folder_to_tree(folder, True)
-
- # print
- # print self.source_tree
- # self.dump_paths(self.source_tree)
-
- # print 'excludings'
- self.excluded_folders = []
- self.recurse_excludings(self.source_tree)
-
- def generate(self):
+ @staticmethod
+ def filter_dot(s):
"""
- Override the parent method with code generation.
+ Remove the './' prefix, if present.
+ This function assumes that resources.win_to_unix()
+ replaced all windows backslashes with slashes.
"""
- if not self.resources.linker_script:
- raise NotSupportedException("No linker script found.")
+ if s == None:
+ return None
+ if s[:2] == './':
+ return s[2:]
+ return s
- self.resources.win_to_unix()
+ # -------------------------------------------------------------------------
- print 'libraries'
- print self.resources.libraries
+ def dump_tree(self, node, depth=0):
+ for k in node.keys():
+ n = node[k]
+ pn = n['parent']['name'] if 'parent' in n.keys() else ''
+ print ' ' * depth, n['name'], n['is_used'], pn
+ if len(n['children'].keys()) != 0:
+ self.dump_tree(n['children'], depth + 1)
- libraries = []
- print self.resources.libraries
- for lib in self.resources.libraries:
- l, _ = splitext(basename(lib))
- libraries.append(l[3:])
+ def dump_paths(self, node, depth=0):
+ for k in node.keys():
+ n = node[k]
+ x = []
+ ni = n
+ while True:
+ x.insert(0, ni['name'])
+ if 'parent' not in ni:
+ break
+ ni = ni['parent']
+ path = '/'.join(x)
+ print path, n['is_used']
+ self.dump_paths(n['children'], depth + 1)
+
+ # -------------------------------------------------------------------------
+
+ def process_options(self):
+ """
+ CDT managed projects store lots of build options in separate
+ variables, with separate IDs in the .cproject file.
+ When the CDT build is started, all these options are brought
+ together to compose the compiler and linker command lines.
+
+ Here the process is reversed, from the compiler and linker
+ command lines, the options are identified and various flags are
+ set to control the template generation process.
+
+ Once identified, the options are removed from the command lines.
+
+ The options that were not identified are options that do not
+ have CDT equivalents and will be passed in the 'Other options'
+ categories.
+
+ Althogh this process does not have a very complicated logic,
+ given the large number of explicit configuration options
+ used by GNU ARM Eclipse managed build plug-in, it is tedious...
+ """
+ flags = self.flags
+
+ if False:
+ print
+ print 'common_flags', flags['common_flags']
+ print 'asm_flags', flags['asm_flags']
+ print 'c_flags', flags['c_flags']
+ print 'cxx_flags', flags['cxx_flags']
+ print 'ld_flags', flags['ld_flags']
+
+ # Initialise the 'last resort' options where all unrecognised
+ # options will be collected.
+ self.options['as']['other'] = ''
+ self.options['c']['other'] = ''
+ self.options['cpp']['other'] = ''
+ self.options['ld']['other'] = ''
MCPUS = {
'Cortex-M0': {'mcpu': 'cortex-m0', 'fpu_unit': None},
@@ -229,119 +398,449 @@ class GNUARMEclipse(Exporter):
'Cortex-M7FD': {'mcpu': 'cortex-m7', 'fpu_unit': 'fpv5d16'},
}
+ # Remove options that are supplied by CDT
+ self.remove_option(flags['common_flags'], '-c')
+ self.remove_option(flags['common_flags'], '-MMD')
+
+ # As 'plan B', get the CPU from the target definition.
core = self.toolchain.target.core
- try:
- # cortex-m0, cortex-m0-small-multiply, cortex-m0plus,
- # cortex-m0plus-small-multiply, cortex-m1, cortex-m1-small-multiply,
- # cortex-m3, cortex-m4, cortex-m7.
- target_mcpu = MCPUS[core]['mcpu']
+ self.options['common']['arm.target.family'] = None
- # default, fpv4spd16, fpv5d16, fpv5spd16
- target_fpu_unit = MCPUS[core]['fpu_unit']
+ # cortex-m0, cortex-m0-small-multiply, cortex-m0plus,
+ # cortex-m0plus-small-multiply, cortex-m1, cortex-m1-small-multiply,
+ # cortex-m3, cortex-m4, cortex-m7.
+ str = self.find_options(flags['common_flags'], '-mcpu=')
+ if str != None:
+ self.options['common']['arm.target.family'] = str[len('-mcpu='):]
+ self.remove_option(flags['common_flags'], str)
+ self.remove_option(flags['ld_flags'], str)
+ else:
+ if core not in MCPUS:
+ raise NotSupportedException(
+ 'Target core {0} not supported.'.format(core))
+ self.options['common']['arm.target.family'] = MCPUS[core]['mcpu']
- # soft, softfp, hard.
- target_fpu_abi = 'soft'
+ self.options['common']['arm.target.arch'] = 'none'
+ str = self.find_options(flags['common_flags'], '-march=')
+ arch = str[len('-march='):]
+ archs = {'armv6-m': 'armv6-m', 'armv7-m': 'armv7-m'}
+ if arch in archs:
+ self.options['common']['arm.target.arch'] = archs[arh]
+ self.remove_option(flags['common_flags'], str)
- if target_fpu_unit != None:
- target_fpu_abi = 'hard'
+ self.options['common']['arm.target.instructionset'] = 'thumb'
+ if '-mthumb' in flags['common_flags']:
+ self.remove_option(flags['common_flags'], '-mthumb')
+ self.remove_option(flags['ld_flags'], '-mthumb')
+ elif '-marm' in flags['common_flags']:
+ self.options['common']['arm.target.instructionset'] = 'arm'
+ self.remove_option(flags['common_flags'], '-marm')
+ self.remove_option(flags['ld_flags'], '-marm')
- except AttributeError:
- # TODO filter out projects with toolchain core not supported,
- # instead of raising an exception.
- raise NotSupportedException(
- 'Target core {0} not supported.'.format(core))
+ self.options['common']['arm.target.thumbinterwork'] = False
+ if '-mthumb-interwork' in flags['common_flags']:
+ self.options['common']['arm.target.thumbinterwork'] = True
+ self.remove_option(flags['common_flags'], '-mthumb-interwork')
- # TODO: get the list from existing .cproject
- build_folders = ['Debug', 'Release']
+ self.options['common']['arm.target.endianness'] = None
+ if '-mlittle-endian' in flags['common_flags']:
+ self.options['common']['arm.target.endianness'] = 'little'
+ self.remove_option(flags['common_flags'], '-mlittle-endian')
+ elif '-mbig-endian' in flags['common_flags']:
+ self.options['common']['arm.target.endianness'] = 'big'
+ self.remove_option(flags['common_flags'], '-mbig-endian')
- objects = [self.filter_dot(s) for s in self.resources.objects]
- for bf in build_folders:
- objects = [o for o in objects if not o.startswith(bf + '/')]
- print 'objects'
- print objects
+ self.options['common']['arm.target.fpu.unit'] = None
+ # default, fpv4spd16, fpv5d16, fpv5spd16
+ str = self.find_options(flags['common_flags'], '-mfpu=')
+ if str != None:
+ fpu = str[len('-mfpu='):]
+ fpus = {
+ 'fpv4-sp-d16': 'fpv4spd16',
+ 'fpv5-d16': 'fpv5d16',
+ 'fpv5-sp-d16': 'fpv5spd16'
+ }
+ if fpu in fpus:
+ self.options['common']['arm.target.fpu.unit'] = fpus[fpu]
- f = self.flags
- print 'common_flags'
- print f['common_flags']
- print 'asm_flags'
- print f['asm_flags']
- print 'c_flags'
- print f['c_flags']
- print 'cxx_flags'
- print f['cxx_flags']
- print 'ld_flags'
- print f['ld_flags']
+ self.remove_option(flags['common_flags'], str)
+ self.remove_option(flags['ld_flags'], str)
+ if self.options['common']['arm.target.fpu.unit'] == None:
+ if core not in MCPUS:
+ raise NotSupportedException(
+ 'Target core {0} not supported.'.format(core))
+ if MCPUS[core]['fpu_unit']:
+ self.options['common'][
+ 'arm.target.fpu.unit'] = MCPUS[core]['fpu_unit']
- source_folders = [self.filter_dot(s) for s in set(dirname(
- src) for src in self.resources.c_sources + self.resources.cpp_sources + self.resources.s_sources)]
- source_folders.remove('.')
+ # soft, softfp, hard.
+ str = self.find_options(flags['common_flags'], '-mfloat-abi=')
+ if str != None:
+ self.options['common']['arm.target.fpu.abi'] = str[
+ len('-mfloat-abi='):]
+ self.remove_option(flags['common_flags'], str)
+ self.remove_option(flags['ld_flags'], str)
- self.compute_exclusions()
+ self.options['common']['arm.target.unalignedaccess'] = None
+ if '-munaligned-access' in flags['common_flags']:
+ self.options['common']['arm.target.unalignedaccess'] = 'enabled'
+ self.remove_option(flags['common_flags'], '-munaligned-access')
+ elif '-mno-unaligned-access' in flags['common_flags']:
+ self.options['common']['arm.target.unalignedaccess'] = 'disabled'
+ self.remove_option(flags['common_flags'], '-mno-unaligned-access')
- asm_defines = self.toolchain.get_symbols(True)
- c_defines = self.toolchain.get_symbols()
- cpp_defines = self.toolchain.get_symbols()
+ # Default optimisation level for Release.
+ self.options['common']['optimization.level'] = '-Os'
- include_paths = [self.filter_dot(s) for s in self.resources.inc_dirs]
+ # If the project defines an optimisation level, it is used
+ # only for the Release configuration, the Debug one used '-Og'.
+ str = self.find_options(flags['common_flags'], '-O')
+ if str != None:
+ levels = {
+ '-O0': 'none', '-O1': 'optimize', '-O2': 'more',
+ '-O3': 'most', '-Os': 'size', '-Og': 'debug'
+ }
+ if str in levels:
+ self.options['common']['optimization.level'] = levels[str]
+ self.remove_option(flags['common_flags'], str)
- library_paths = [self.filter_dot(s) for s in self.resources.lib_dirs]
+ include_files = []
+ for all_flags in [flags['common_flags'], flags['c_flags'], flags['cxx_flags']]:
+ while '-include' in all_flags:
+ ix = all_flags.index('-include')
+ str = all_flags[ix + 1]
+ if str not in include_files:
+ include_files.append(str)
+ self.remove_option(all_flags, '-include')
+ self.remove_option(all_flags, str)
- linker_script = self.filter_dot(self.resources.linker_script)
+ self.options['common']['include_files'] = include_files
- ctx = {
- 'name': self.project_name,
- 'excluded_folders': '|'.join(self.excluded_folders),
- 'include_paths': include_paths,
- 'library_paths': library_paths,
- 'object_files': objects,
- 'libraries': libraries,
- 'linker_script': linker_script,
- 'asm_defines': asm_defines,
- 'c_defines': c_defines,
- 'cpp_defines': cpp_defines,
- 'target_mcpu': target_mcpu,
- 'target_fpu_abi': target_fpu_abi,
- 'target_fpu_unit': target_fpu_unit,
+ if '-ansi' in flags['c_flags']:
+ self.options['c']['compiler.std'] = '-ansi'
+ self.remove_option(flags['c_flags'], str)
+ else:
+ str = self.find_options(flags['c_flags'], '-std')
+ std = str[len('-std='):]
+ c_std = {
+ 'c90': 'c90', 'c89': 'c90', 'gnu90': 'gnu90', 'gnu89': 'gnu90',
+ 'c99': 'c99', 'c9x': 'c99', 'gnu99': 'gnu99', 'gnu9x': 'gnu98',
+ 'c11': 'c11', 'c1x': 'c11', 'gnu11': 'gnu11', 'gnu1x': 'gnu11'
+ }
+ if std in c_std:
+ self.options['c']['compiler.std'] = c_std[std]
+ self.remove_option(flags['c_flags'], str)
- # Unique IDs used each in multiple places.
- # Add more if needed.
- 'debug_config_uid': u.id,
- 'debug_tool_c_compiler_uid': u.id,
- 'debug_tool_c_compiler_input_uid': u.id,
- 'debug_tool_cpp_compiler_uid': u.id,
- 'debug_tool_cpp_compiler_input_uid': u.id,
- 'release_config_uid': u.id,
- 'release_tool_c_compiler_uid': u.id,
- 'release_tool_c_compiler_input_uid': u.id,
- 'release_tool_cpp_compiler_uid': u.id,
- 'release_tool_cpp_compiler_input_uid': u.id,
+ if '-ansi' in flags['cxx_flags']:
+ self.options['cpp']['compiler.std'] = '-ansi'
+ self.remove_option(flags['cxx_flags'], str)
+ else:
+ str = self.find_options(flags['cxx_flags'], '-std')
+ std = str[len('-std='):]
+ cpp_std = {
+ 'c++98': 'cpp98', 'c++03': 'cpp98',
+ 'gnu++98': 'gnucpp98', 'gnu++03': 'gnucpp98',
+ 'c++0x': 'cpp0x', 'gnu++0x': 'gnucpp0x',
+ 'c++11': 'cpp11', 'gnu++11': 'gnucpp11',
+ 'c++1y': 'cpp1y', 'gnu++1y': 'gnucpp1y',
+ 'c++14': 'cpp14', 'gnu++14': 'gnucpp14',
+ 'c++1z': 'cpp1z', 'gnu++1z': 'gnucpp1z',
+ }
+ if std in cpp_std:
+ self.options['cpp']['compiler.std'] = cpp_std[std]
+ self.remove_option(flags['cxx_flags'], str)
- # Must be an object with an `id` property, which
- # will be called repeatedly, to generate multiple UIDs.
- 'u': u,
+ # Common optimisation options.
+ optimization_options = {
+ '-fmessage-length=0': 'optimization.messagelength',
+ '-fsigned-char': 'optimization.signedchar',
+ '-ffunction-sections': 'optimization.functionsections',
+ '-fdata-sections': 'optimization.datasections',
+ '-fno-common': 'optimization.nocommon',
+ '-fno-inline-functions': 'optimization.noinlinefunctions',
+ '-ffreestanding': 'optimization.freestanding',
+ '-fno-builtin': 'optimization.nobuiltin',
+ '-fsingle-precision-constant': 'optimization.spconstant',
+ '-fPIC': 'optimization.PIC',
+ '-fno-move-loop-invariants': 'optimization.nomoveloopinvariants',
}
- self.gen_file('gnuarmeclipse/.project.tmpl', ctx, '.project')
- self.gen_file('gnuarmeclipse/.cproject.tmpl', ctx, '.cproject')
+ for option in optimization_options:
+ self.options['common'][optimization_options[option]] = False
+ if option in flags['common_flags']:
+ self.options['common'][optimization_options[option]] = True
+ self.remove_option(flags['common_flags'], option)
+
+ # Common warning options.
+ warning_options = {
+ '-fsyntax-only': 'warnings.syntaxonly',
+ '-pedantic': 'warnings.pedantic',
+ '-pedantic-errors': 'warnings.pedanticerrors',
+ '-w': 'warnings.nowarn',
+ '-Wunused': 'warnings.unused',
+ '-Wuninitialized': 'warnings.uninitialized',
+ '-Wall': 'warnings.allwarn',
+ '-Wextra': 'warnings.extrawarn',
+ '-Wmissing-declarations': 'warnings.missingdeclaration',
+ '-Wconversion': 'warnings.conversion',
+ '-Wpointer-arith': 'warnings.pointerarith',
+ '-Wpadded': 'warnings.padded',
+ '-Wshadow': 'warnings.shadow',
+ '-Wlogical-op': 'warnings.logicalop',
+ '-Waggregate-return': 'warnings.agreggatereturn',
+ '-Wfloat-equal': 'warnings.floatequal',
+ '-Werror': 'warnings.toerrors',
+ }
+
+ for option in warning_options:
+ self.options['common'][warning_options[option]] = False
+ if option in flags['common_flags']:
+ self.options['common'][warning_options[option]] = True
+ self.remove_option(flags['common_flags'], option)
+
+ # Common debug options.
+ debug_levels = {
+ '-g': 'default',
+ '-g1': 'minimal',
+ '-g3': 'max',
+ }
+ self.options['common']['debugging.level'] = 'none'
+ for option in debug_levels:
+ if option in flags['common_flags']:
+ self.options['common'][
+ 'debugging.level'] = debug_levels[option]
+ self.remove_option(flags['common_flags'], option)
+
+ debug_formats = {
+ '-ggdb': 'gdb',
+ '-gstabs': 'stabs',
+ '-gstabs+': 'stabsplus',
+ '-gdwarf-2': 'dwarf2',
+ '-gdwarf-3': 'dwarf3',
+ '-gdwarf-4': 'dwarf4',
+ '-gdwarf-5': 'dwarf5',
+ }
+
+ self.options['common']['debugging.format'] = ''
+ for option in debug_levels:
+ if option in flags['common_flags']:
+ self.options['common'][
+ 'debugging.format'] = debug_formats[option]
+ self.remove_option(flags['common_flags'], option)
+
+ self.options['common']['debugging.prof'] = False
+ if '-p' in flags['common_flags']:
+ self.options['common']['debugging.prof'] = True
+ self.remove_option(flags['common_flags'], '-p')
+
+ self.options['common']['debugging.gprof'] = False
+ if '-pg' in flags['common_flags']:
+ self.options['common']['debugging.gprof'] = True
+ self.remove_option(flags['common_flags'], '-gp')
+
+ # Assembler options.
+ self.options['as']['usepreprocessor'] = False
+ while '-x' in flags['asm_flags']:
+ ix = flags['asm_flags'].index('-x')
+ str = flags['asm_flags'][ix + 1]
+
+ if str == 'assembler-with-cpp':
+ self.options['as']['usepreprocessor'] = True
+ else:
+ # Collect all other assembler options.
+ self.options['as']['other'] += ' -x ' + str
+
+ self.remove_option(flags['asm_flags'], '-x')
+ self.remove_option(flags['asm_flags'], 'assembler-with-cpp')
+
+ self.options['as']['nostdinc'] = False
+ if '-nostdinc' in flags['asm_flags']:
+ self.options['as']['nostdinc'] = True
+ self.remove_option(flags['asm_flags'], '-nostdinc')
+
+ self.options['as']['verbose'] = False
+ if '-v' in flags['asm_flags']:
+ self.options['as']['verbose'] = True
+ self.remove_option(flags['asm_flags'], '-v')
+
+ # C options.
+ self.options['c']['nostdinc'] = False
+ if '-nostdinc' in flags['c_flags']:
+ self.options['c']['nostdinc'] = True
+ self.remove_option(flags['c_flags'], '-nostdinc')
+
+ self.options['c']['verbose'] = False
+ if '-v' in flags['c_flags']:
+ self.options['c']['verbose'] = True
+ self.remove_option(flags['c_flags'], '-v')
+
+ warning_options = {
+ '-Wmissing-prototypes': 'warnings.missingprototypes',
+ '-Wstrict-prototypes': 'warnings.strictprototypes',
+ '-Wbad-function-cast': 'warnings.badfunctioncast',
+ }
+
+ for option in warning_options:
+ self.options['c'][warning_options[option]] = False
+ if option in flags['common_flags']:
+ self.options['c'][warning_options[option]] = True
+ self.remove_option(flags['common_flags'], option)
+
+ # C++ options.
+ self.options['cpp']['nostdinc'] = False
+ if '-nostdinc' in flags['cxx_flags']:
+ self.options['cpp']['nostdinc'] = True
+ self.remove_option(flags['cxx_flags'], '-nostdinc')
+
+ self.options['cpp']['nostdincpp'] = False
+ if '-nostdinc++' in flags['cxx_flags']:
+ self.options['cpp']['nostdincpp'] = True
+ self.remove_option(flags['cxx_flags'], '-nostdinc++')
+
+ optimization_options = {
+ '-fno-exceptions': 'optimization.noexceptions',
+ '-fno-rtti': 'optimization.nortti',
+ '-fno-use-cxa-atexit': 'optimization.nousecxaatexit',
+ '-fno-threadsafe-statics': 'optimization.nothreadsafestatics',
+ }
+
+ for option in optimization_options:
+ self.options['cpp'][optimization_options[option]] = False
+ if option in flags['cxx_flags']:
+ self.options['cpp'][optimization_options[option]] = True
+ self.remove_option(flags['cxx_flags'], option)
+ if option in flags['common_flags']:
+ self.options['cpp'][optimization_options[option]] = True
+ self.remove_option(flags['common_flags'], option)
+
+ warning_options = {
+ '-Wabi': 'warnabi',
+ '-Wctor-dtor-privacy': 'warnings.ctordtorprivacy',
+ '-Wnoexcept': 'warnings.noexcept',
+ '-Wnon-virtual-dtor': 'warnings.nonvirtualdtor',
+ '-Wstrict-null-sentinel': 'warnings.strictnullsentinel',
+ '-Wsign-promo': 'warnings.signpromo',
+ '-Weffc++': 'warneffc',
+ }
+
+ for option in warning_options:
+ self.options['cpp'][warning_options[option]] = False
+ if option in flags['cxx_flags']:
+ self.options['cpp'][warning_options[option]] = True
+ self.remove_option(flags['cxx_flags'], option)
+ if option in flags['common_flags']:
+ self.options['cpp'][warning_options[option]] = True
+ self.remove_option(flags['common_flags'], option)
+
+ self.options['cpp']['verbose'] = False
+ if '-v' in flags['cxx_flags']:
+ self.options['cpp']['verbose'] = True
+ self.remove_option(flags['cxx_flags'], '-v')
+
+ # Linker options.
+ linker_options = {
+ '-nostartfiles': 'nostart',
+ '-nodefaultlibs': 'nodeflibs',
+ '-nostdlib': 'nostdlibs',
+ }
+
+ for option in linker_options:
+ self.options['ld'][linker_options[option]] = False
+ if option in flags['ld_flags']:
+ self.options['ld'][linker_options[option]] = True
+ self.remove_option(flags['ld_flags'], option)
+
+ self.options['ld']['gcsections'] = False
+ if '-Wl,--gc-sections' in flags['ld_flags']:
+ self.options['ld']['gcsections'] = True
+ self.remove_option(flags['ld_flags'], '-Wl,--gc-sections')
+
+ self.options['ld']['flags'] = []
+ to_remove = []
+ for opt in flags['ld_flags']:
+ if opt.startswith('-Wl,--wrap,'):
+ self.options['ld']['flags'].append('--wrap='+opt[len('-Wl,--wrap,'):])
+ to_remove.append(opt)
+ for opt in to_remove:
+ self.remove_option(flags['ld_flags'], opt)
+
+ # Other tool remaining options are separated by category.
+ self.options['as']['otherwarnings'] = self.find_options(
+ flags['asm_flags'], '-W')
+
+ self.options['c']['otherwarnings'] = self.find_options(
+ flags['c_flags'], '-W')
+ self.options['c']['otheroptimizations'] = self.find_options(flags[
+ 'c_flags'], '-f')
+
+ self.options['cpp']['otherwarnings'] = self.find_options(
+ flags['cxx_flags'], '-W')
+ self.options['cpp']['otheroptimizations'] = self.find_options(
+ flags['cxx_flags'], '-f')
+
+ # Other common remaining options are separated by category.
+ self.options['common']['optimization.other'] = self.find_options(
+ flags['common_flags'], '-f')
+ self.options['common']['warnings.other'] = self.find_options(
+ flags['common_flags'], '-W')
+
+ # Remaining common flags are added to each tool.
+ self.options['as']['other'] += ' ' + \
+ ' '.join(flags['common_flags']) + ' ' + \
+ ' '.join(flags['asm_flags'])
+ self.options['c']['other'] += ' ' + \
+ ' '.join(flags['common_flags']) + ' ' + ' '.join(flags['c_flags'])
+ self.options['cpp']['other'] += ' ' + \
+ ' '.join(flags['common_flags']) + ' ' + \
+ ' '.join(flags['cxx_flags'])
+ self.options['ld']['other'] += ' ' + \
+ ' '.join(flags['common_flags']) + ' ' + ' '.join(flags['ld_flags'])
+
+ if len(self.system_libraries) > 0:
+ self.options['ld']['other'] += ' -Wl,--start-group '
+ self.options['ld'][
+ 'other'] += ' '.join('-l' + s for s in self.system_libraries)
+ self.options['ld']['other'] += ' -Wl,--end-group '
+
+ # Strip all 'other' flags, since they might have leading spaces.
+ self.options['as']['other'] = self.options['as']['other'].strip()
+ self.options['c']['other'] = self.options['c']['other'].strip()
+ self.options['cpp']['other'] = self.options['cpp']['other'].strip()
+ self.options['ld']['other'] = self.options['ld']['other'].strip()
+
+ if False:
+ print
+ print self.options
+
+ print
+ print 'common_flags', flags['common_flags']
+ print 'asm_flags', flags['asm_flags']
+ print 'c_flags', flags['c_flags']
+ print 'cxx_flags', flags['cxx_flags']
+ print 'ld_flags', flags['ld_flags']
@staticmethod
- def build(project_name, log_name="build_log.txt", cleanup=True):
- """
- Build GNU ARM Eclipse project.
- """
-
- ret_code = 0
-
- # TODO: add code to run the build in a headless configuration.
-
- # Cleanup the exported and built files
- if cleanup:
- os.remove('.project')
- os.remove('.cproject')
-
- if ret_code !=0:
- # Seems like something went wrong.
- return -1
+ def find_options(lst, option):
+ tmp = [str for str in lst if str.startswith(option)]
+ if len(tmp) > 0:
+ return tmp[0]
else:
- return 0
+ return None
+
+ @staticmethod
+ def find_options(lst, prefix):
+ other = ''
+ opts = [str for str in lst if str.startswith(prefix)]
+ if len(opts) > 0:
+ for opt in opts:
+ other += ' ' + opt
+ GNUARMEclipse.remove_option(lst, opt)
+ return other.strip()
+
+ @staticmethod
+ def remove_option(lst, option):
+ if option in lst:
+ lst.remove(option)
+
+# =============================================================================