summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-06-21 09:32:57 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-06-21 09:32:57 -0600
commitaaaacf612dc228a31282c0c1c015f116eb309cd8 (patch)
tree43b7b643f99ef133d1315e7affd193cfaeff2fae /apps
parent650a85488872f2a2ca28969d9545b05fe99880db (diff)
downloadnuttx-aaaacf612dc228a31282c0c1c015f116eb309cd8.tar.gz
nuttx-aaaacf612dc228a31282c0c1c015f116eb309cd8.tar.bz2
nuttx-aaaacf612dc228a31282c0c1c015f116eb309cd8.zip
Straighten out issues about who calls C++ initializers with CXXTEST or HELLOXX are built as NSH applications; Add an ofstream test to CXXTEST suggested by Michael; Update many defconfig fiels to that they set configurations to handle C++ constructors just as before these configuration changes
Diffstat (limited to 'apps')
-rw-r--r--apps/ChangeLog.txt12
-rw-r--r--apps/examples/README.txt52
-rw-r--r--apps/examples/cxxtest/Kconfig11
-rw-r--r--apps/examples/cxxtest/cxxtest_main.cxx79
-rw-r--r--apps/examples/helloxx/Kconfig11
-rw-r--r--apps/examples/helloxx/helloxx_main.cxx9
-rw-r--r--apps/examples/nsh/Kconfig12
-rw-r--r--apps/examples/nsh/nsh_main.c16
8 files changed, 167 insertions, 35 deletions
diff --git a/apps/ChangeLog.txt b/apps/ChangeLog.txt
index 814d58b96..96208f250 100644
--- a/apps/ChangeLog.txt
+++ b/apps/ChangeLog.txt
@@ -579,3 +579,15 @@
(2013-6-12).
6.29 2013-xx-xx Gregory Nutt <gnutt@nuttx.org>
+
+ * apps/examples/nsh, cxxtest, and helloxx: C++ initializers should be
+ set once and, preferably, in the context of the task that uses any C++
+ statically initialized classes. These only becomes an issue is cxxtest
+ or helloxx are built as NSH builtin applications. Then you want the
+ initialization done in cxxtext or helloxx and not in NSH (and certainly
+ not twice). Added configuration options to control who does the C++
+ initialization. NSH now does not do C++ initialization be default and
+ must be configured to do otherwise. Converserly, cxxtest and helloxx
+ will do C++ initialization unless configured do otherwise (2013-6-21).
+ * apps/examples/cxxtext: Add ostream test as provided by Michael
+ (2013-6-21).
diff --git a/apps/examples/README.txt b/apps/examples/README.txt
index 8ef6b4a10..c6f31b034 100644
--- a/apps/examples/README.txt
+++ b/apps/examples/README.txt
@@ -256,14 +256,6 @@ examples/cxxtest
is not included in the NuttX source tree by default, but must be installed
(see misc/uClibc++/README.txt for installation).
- The NuttX setting that are required include:
-
- CONFIG_HAVE_CXX=y
- CONFIG_HAVE_CXXINITIALIZE=y
- CONFIG_UCLIBCXX=y
-
- Additional uClibc++ settings may be required in your build environment.
-
The uClibc++ test includes simple test of:
- iostreams,
@@ -271,6 +263,25 @@ examples/cxxtest
- RTTI, and
- Exceptions
+ Example Configuration Options
+ -----------------------------
+ CONFIG_EXAMPLES_CXXTEST=y - Eanbles the example
+ CONFIG_EXAMPLES_CXXTEST_CXXINITIALIZE=y - By default, if CONFIG_HAVE_CXX
+ and CONFIG_HAVE_CXXINITIALIZE are defined, then this example
+ will call the NuttX function to initialize static C++ constructors.
+ This option may be disabled, however, if that static initialization
+ was performed elsewhere.
+
+ Other Required Configuration Settings
+ -------------------------------------
+ Other NuttX setting that are required include:
+
+ CONFIG_HAVE_CXX=y
+ CONFIG_HAVE_CXXINITIALIZE=y
+ CONFIG_UCLIBCXX=y
+
+ Additional uClibc++ settings may be required in your build environment.
+
examples/dhcpd
^^^^^^^^^^^^^^
@@ -539,6 +550,11 @@ examples/helloxx
"built-in" that can be executed from the NSH command line.
CONFIG_EXAMPLES_HELLOXX_NOSTACKCONST - Set if the system does not
support construction of objects on the stack.
+ CONFIG_EXAMPLES_HELLOXX_CXXINITIALIZE - By default, if CONFIG_HAVE_CXX
+ and CONFIG_HAVE_CXXINITIALIZE are defined, then this example
+ will call the NuttX function to initialize static C++ constructors.
+ This option may be disabled, however, if that static initialization
+ was performed elsewhere.
Also needed:
@@ -742,17 +758,23 @@ examples/nrf24l01_term
examples/nsh
^^^^^^^^^^^^
+ Basic Configuration
+ -------------------
This directory provides an example of how to configure and use
the NuttShell (NSH) application. NSH is a simple shell
application. NSH is described in its own README located at
- apps/nshlib/README.txt
+ apps/nshlib/README.txt. This function is enabled with:
+
+ CONFIG_EXAMPLES_NSH=y
Applications using this example will need to provide an defconfig
file in the configuration directory with instruction to build
- applicationslike:
+ the NSH library like:
CONFIG_NSH_LIBRARY=y
+ Other Configuration Requirements
+ --------------------------------
NOTE: If the NSH serial console is used, then following is also
required to build the readline() library:
@@ -779,6 +801,16 @@ examples/nsh
CONFIG_STDIO_BUFFER_SIZE - Some value >= 64
CONFIG_STDIO_LINEBUFFER=y
+ C++ Support
+ -----------
+ If CONFIG_HAVE_CXX=y and CONFIG_HAVE_CXXINITIALIZE=y, then this NSH
+ example can be configured to initialize C++ constructors when it
+ is started. NSH does not use C++ and, by default, assumes that
+ constructors are initialized elsewhere. However, you can force
+ NSH to initialize constructors by setting:
+
+ CONFIG_EXAMPLES_NSH_CXXINITIALIZE=y
+
examples/nx
^^^^^^^^^^^
diff --git a/apps/examples/cxxtest/Kconfig b/apps/examples/cxxtest/Kconfig
index e8aa3d8f1..c5d73d531 100644
--- a/apps/examples/cxxtest/Kconfig
+++ b/apps/examples/cxxtest/Kconfig
@@ -11,4 +11,15 @@ config EXAMPLES_CXXTEST
Enable the C++ test program
if EXAMPLES_CXXTEST
+
+config EXAMPLES_CXXTEST_CXXINITIALIZE
+ bool "C++ Initialization"
+ default y
+ depends on HAVE_CXX && HAVE_CXXINITIALIZE
+ ---help---
+ By default, if CONFIG_HAVE_CXX and CONFIG_HAVE_CXXINITIALIZE are
+ defined, then this example will call the NuttX function to
+ initialize static C++ constructors. This option may be disabled,
+ however, if that static initialization was preformed elsewhere.
+
endif
diff --git a/apps/examples/cxxtest/cxxtest_main.cxx b/apps/examples/cxxtest/cxxtest_main.cxx
index 9c2974826..5feeaf5c8 100644
--- a/apps/examples/cxxtest/cxxtest_main.cxx
+++ b/apps/examples/cxxtest/cxxtest_main.cxx
@@ -41,6 +41,8 @@
#include <nuttx/init.h>
#include <nuttx/arch.h>
+#include <cstdio>
+#include <fstream>
#include <iostream>
#include <vector>
#include <map>
@@ -52,6 +54,13 @@ using namespace std;
//***************************************************************************
// Definitions
//***************************************************************************
+// Configuration ************************************************************
+// C++ initialization requires CXX initializer support
+
+#if !defined(CONFIG_HAVE_CXX) || !defined(CONFIG_HAVE_CXXINITIALIZE)
+# warning Support for static initializers is NOT enabled
+# undef CONFIG_EXAMPLES_CXXTEST_CXXINITIALIZE
+#endif
//***************************************************************************
// Private Classes
@@ -68,7 +77,7 @@ class Extend : public Base
public:
void printExtend(void)
{
- cout << "extend" << endl;
+ std::cout << "extend" << std::endl;
}
};
@@ -81,26 +90,55 @@ public:
//***************************************************************************
//***************************************************************************
+// Name: test_ostream
+//***************************************************************************/
+
+static void test_ofstream(void)
+{
+ std::ofstream ttyOut;
+
+ std::cout << "test ofstream===========================" << std::endl;
+ std::printf("printf: Starting test_ostream\n");
+ ttyOut.open ("/dev/console");
+ if (!ttyOut.good())
+ {
+ std::printf("printf: Failed opening /dev/console\n");
+ std::cout << "cout: Failed opening /dev/console" << std::endl;
+ std::cout << " good()=" << ttyOut.good();
+ std::cout << " eof()=" << ttyOut.eof();
+ std::cout << " fail()=" << ttyOut.fail();
+ std::cout << " bad()=" << ttyOut.bad() << std::endl;
+ }
+ else
+ {
+ std::printf("printf: Successfully opened /dev/console\n");
+ std::cout << "cout: Successfully opened /dev/console" << std::endl;
+ ttyOut << "Writing this to /dev/console\n";
+ ttyOut.close();
+ }
+}
+
+//***************************************************************************
// Name: test_iostream
//***************************************************************************/
static void test_iostream(void)
{
- cout << "test iostream===========================" << endl;
- cout << "Hello, this is only a test" << endl;
- cout << "Print an int: " << 190 << endl;
- cout << "Print a char: " << 'd' << endl;
+ std::cout << "test iostream===========================" << std::endl;
+ std::cout << "Hello, this is only a test" << std::endl;
+ std::cout << "Print an int: " << 190 << std::endl;
+ std::cout << "Print a char: " << 'd' << std::endl;
#if 0
int a;
string s;
- cout << "Please type in an int:" << endl;
- cin >> a;
- cout << "You type in: " << a << endl;
- cout << "Please type in a string:" << endl;
- cin >> s;
- cout << "You type in: " << s << endl;
+ std::cout << "Please type in an int:" << std::endl;
+ std::cin >> a;
+ std::cout << "You type in: " << a << std::endl;
+ std::cout << "Please type in a string:" << std::endl;
+ std::cin >> s;
+ std::cout << "You type in: " << s << std::endl;
#endif
}
@@ -110,7 +148,7 @@ static void test_iostream(void)
static void test_stl(void)
{
- cout << "test vector=============================" << endl;
+ std::cout << "test vector=============================" << std::endl;
vector<int> v1;
assert(v1.empty());
@@ -126,7 +164,7 @@ static void test_stl(void)
v1.pop_back();
assert(v1.size() == 3);
- cout << "v1=" << v1[0] << ' ' << v1[1] << ' ' << v1[2] << endl;
+ std::cout << "v1=" << v1[0] << ' ' << v1[1] << ' ' << v1[2] << std::endl;
assert(v1[2] == 3);
vector<int> v2 = v1;
@@ -137,13 +175,13 @@ static void test_stl(void)
vector<string>::iterator it;
for (it = v3.begin(); it != v3.end(); it++)
{
- cout << *it << ' ';
+ std::cout << *it << ' ';
}
- cout << endl;
+ std::cout << std::endl;
assert(v3[1] == "World");
- cout << "test map================================" << endl;
+ std::cout << "test map================================" << std::endl;
map<int,string> m1;
m1[12] = "Hello";
@@ -158,7 +196,7 @@ static void test_stl(void)
static void test_rtti(void)
{
- cout << "test rtti===============================" << endl;
+ std::cout << "test rtti===============================" << std::endl;
Base *a = new Base();
Base *b = new Extend();
assert(a);
@@ -182,7 +220,7 @@ static void test_rtti(void)
#ifdef CONFIG_UCLIBCXX_EXCEPTION
static void test_exception(void)
{
- cout << "test exception==========================" << endl;
+ std::cout << "test exception==========================" << std::endl;
try
{
throw runtime_error("runtime error");
@@ -190,7 +228,7 @@ static void test_exception(void)
catch (runtime_error &e)
{
- cout << "Catch exception: " << e.what() << endl;
+ std::cout << "Catch exception: " << e.what() << std::endl;
}
}
#endif
@@ -210,10 +248,11 @@ extern "C"
// If C++ initialization for static constructors is supported, then do
// that first
-#ifdef CONFIG_HAVE_CXXINITIALIZE
+#ifdef CONFIG_EXAMPLES_CXXTEST_CXXINITIALIZE
up_cxxinitialize();
#endif
+ test_ofstream();
test_iostream();
test_stl();
test_rtti();
diff --git a/apps/examples/helloxx/Kconfig b/apps/examples/helloxx/Kconfig
index 336389d24..d7c22cdc9 100644
--- a/apps/examples/helloxx/Kconfig
+++ b/apps/examples/helloxx/Kconfig
@@ -10,4 +10,15 @@ config EXAMPLES_HELLOXX
Enable the \"Hello, World!\" C++ example
if EXAMPLES_HELLOXX
+
+config EXAMPLES_HELLOXX_CXXINITIALIZE
+ bool "C++ Initialization"
+ default y
+ depends on HAVE_CXX && HAVE_CXXINITIALIZE
+ ---help---
+ By default, if CONFIG_HAVE_CXX and CONFIG_HAVE_CXXINITIALIZE are
+ defined, then this example will call the NuttX function to
+ initialize static C++ constructors. This option may be disabled,
+ however, if that static initialization was preformed elsewhere.
+
endif
diff --git a/apps/examples/helloxx/helloxx_main.cxx b/apps/examples/helloxx/helloxx_main.cxx
index eeca52263..27a4e2695 100644
--- a/apps/examples/helloxx/helloxx_main.cxx
+++ b/apps/examples/helloxx/helloxx_main.cxx
@@ -48,6 +48,13 @@
//***************************************************************************
// Definitions
//***************************************************************************
+// Configuration ************************************************************
+// C++ initialization requires CXX initializer support
+
+#if !defined(CONFIG_HAVE_CXX) || !defined(CONFIG_HAVE_CXXINITIALIZE)
+# undef CONFIG_EXAMPLES_HELLOXX_CXXINITIALIZE
+#endif
+
// Debug ********************************************************************
// Non-standard debug that may be enabled just for testing the constructors
@@ -135,7 +142,7 @@ extern "C"
// If C++ initialization for static constructors is supported, then do
// that first
-#ifdef CONFIG_HAVE_CXXINITIALIZE
+#ifdef CONFIG_EXAMPLES_HELLOXX_CXXINITIALIZE
up_cxxinitialize();
#endif
diff --git a/apps/examples/nsh/Kconfig b/apps/examples/nsh/Kconfig
index 309aa925e..bbb5ece01 100644
--- a/apps/examples/nsh/Kconfig
+++ b/apps/examples/nsh/Kconfig
@@ -12,4 +12,16 @@ config EXAMPLES_NSH
Enable the NuttShell (NSH) example
if EXAMPLES_NSH
+
+config EXAMPLES_NSH_CXXINITIALIZE
+ bool "C++ Initialization"
+ default n
+ depends on HAVE_CXX && HAVE_CXXINITIALIZE
+ ---help---
+ If HAVE_CXX and HAVE_CXXINITIALIZE are slected, then this NSH
+ example can be configured to initialize C++ constructors when it
+ is started. NSH does not use C++ and, by default, assumes that
+ constructors are initialized elsewhere. However, you can force
+ NSH to initialize constructors by setting this option.
+
endif
diff --git a/apps/examples/nsh/nsh_main.c b/apps/examples/nsh/nsh_main.c
index d9bfc2018..92aa58696 100644
--- a/apps/examples/nsh/nsh_main.c
+++ b/apps/examples/nsh/nsh_main.c
@@ -46,11 +46,13 @@
#include <errno.h>
#include <nuttx/arch.h>
+
#if defined(CONFIG_FS_BINFS) && (CONFIG_BUILTIN)
-#include <nuttx/binfmt/builtin.h>
+# include <nuttx/binfmt/builtin.h>
#endif
+
#if defined(CONFIG_LIBC_EXECFUNCS) && defined(CONFIG_EXECFUNCS_SYMTAB)
-#include <nuttx/binfmt/symtab.h>
+# include <nuttx/binfmt/symtab.h>
#endif
#include <apps/nsh.h>
@@ -59,6 +61,12 @@
* Pre-processor Definitions
****************************************************************************/
+/* C++ initialization requires CXX initializer support */
+
+#if !defined(CONFIG_HAVE_CXX) || !defined(CONFIG_HAVE_CXXINITIALIZE)
+# undef CONFIG_EXAMPLES_NSH_CXXINITIALIZE
+#endif
+
/* The NSH telnet console requires networking support (and TCP/IP) */
#ifndef CONFIG_NET
@@ -115,11 +123,11 @@ int nsh_main(int argc, char *argv[])
/* Call all C++ static constructors */
-#if defined(CONFIG_HAVE_CXX) && defined(CONFIG_HAVE_CXXINITIALIZE)
+#if defined(CONFIG_EXAMPLES_NSH_CXXINITIALIZE)
up_cxxinitialize();
#endif
- /* Make sure that we are using our symbol take */
+ /* Make sure that we are using our symbol table */
#if defined(CONFIG_LIBC_EXECFUNCS) && defined(CONFIG_EXECFUNCS_SYMTAB)
exec_setsymtab(CONFIG_EXECFUNCS_SYMTAB, 0);