更新
Native Client in Ada
NACLでNativeなコード書くならAdaだろうということで試してみた。
NACLのバイナリは特殊なのでコードのコンパイルは用意されている特殊なGCCを使う(SDKですね)。これはいやな予感。ものは試しに叩いてみる。
yudai@mac% ./nacl-gcc ~/temp/example.adb nacl-gcc: /Users/yudai/temp/example.adb: Ada compiler not installed on this system
はいはい、--enable-languages、--enable-languages。
しょうがないので、ソースをとってきてSDK自体をコンパイルする。Makefileを見る限り、GCC4.2.2になにやらパッチを当てているらしい。configureしてるところの--enable-languagesにadaを足して、ついでにgcc-ada-4.2.2.tar.bz2を拾ってきてnacl/googleclient/third_party/gccに入れておく。Makefileにtar xfする行も足しておこう。GCCのコンパイルは時間がかかるので、Linuxサーバ上で作業する。
とりあえず、Makeしてみるとエラーが出た。
cio.c: In function ‘put_int’: cio.c:83: error: ‘stdout’ undeclared (first use in this function) cio.c:83: error: (Each undeclared identifier is reported only once cio.c:83: error: for each function it appears in.) cio.c: In function ‘put_int_stderr’: cio.c:89: error: ‘stderr’ undeclared (first use in this function) cio.c: In function ‘put_char_stderr’: cio.c:101: error: ‘stderr’ undeclared (first use in this function) make[6]: *** [cio.o] Error 101make[6]: Leaving directory `/home/yudai/temp/nacl/googleclient/native_client/tools/BUILD/build-gcc-nacl/gcc/ada/rts' make[5]: *** [gnatlib] Error 2make[5]: Leaving directory `/home/yudai/temp/nacl/googleclient/native_client/tools/BUILD/build-gcc-nacl/gcc/ada' make[4]: *** [gnatlib-plain] Error 2makemake[4]: Leaving directory `/home/yudai/temp/nacl/googleclient/native_client/tools/BUILD/build-gcc-nacl/nacl/libada' make[3]: *** [all-target-libada] Error 2makemakemake[3]: Leaving directory `/home/yudai/temp/nacl/googleclient/native_client/tools/BUILD/build-gcc-nacl' make[2]: *** [all] Error 2make[2]: Leaving directory `/home/yudai/temp/nacl/googleclient/native_client/tools/BUILD/build-gcc-nacl' make[1]: *** [gcc] Error 2make[1]: Leaving directory `/home/yudai/temp/nacl/googleclient/native_client/tools' make: *** [build] Error 2
cio.cを見てみると、
/* Don't use macros on GNU/Linux since they cause incompatible changes between
glibc 2.0 and 2.1#ifdef Linux#undef putchar */
#undef getchar
#undef fputc
#undef stderr
#undef stdout
#endif
あ、あんでふしてる……。とりあえず、コメントアウトしてる。
再度Makeするとまた似たようなたエラーが。直してみる。しかしエラー。何度か適当に直してみるとこんな感じのパッチのパッチが出来た。
ゴミが入っていたので修正。
*** gcc-4.2.2.patch.orig 2008-12-08 12:53:23.000000000 +0900
--- gcc-4.2.2.patch 2008-12-11 17:28:06.000000000 +0900
***************
*** 1890,1892 ****
--- 1890,2144 ----
+++ gcc-4.2.2/stage_last 2008-11-29 16:18:47.320180000 -0800
@@ -0,0 +1 @@
+stage1
+ diff -Naru ../PRISTINE/gcc-4.2.2/gcc/ada/cio.c gcc-4.2.2/gcc/ada/cio.c
+ --- ../PRISTINE/gcc-4.2.2/gcc/ada/cio.c 2005-11-15 23:06:45.000000000 +0900
+ +++ gcc-4.2.2/gcc/ada/cio.c 2008-12-11 15:26:54.000000000 +0900
+ @@ -42,7 +42,7 @@
+ #include "adaint.h"
+
+ /* Don't use macros on GNU/Linux since they cause incompatible changes between
+ - glibc 2.0 and 2.1 */
+ + glibc 2.0 and 2.1
+ #ifdef linux
+ #undef putchar
+ #undef getchar
+ @@ -50,6 +50,7 @@
+ #undef stderr
+ #undef stdout
+ #endif
+ +*/
+
+ #ifdef VTHREADS
+ #undef putchar
+ !@@@@@@@@@@@@@@@@@
+ diff -Naru ../PRISTINE/gcc/ada/adaint.c gcc-4.2.2/gcc/ada/adaint.c
+ --- ../PRISTINE/gcc/ada/adaint.c 2006-02-15 18:30:39.000000000 +0900
+ +++ gcc-4.2.2/gcc/ada/adaint.c 2008-12-11 16:15:26.000000000 +0900
+ @@ -794,7 +794,7 @@
+
+ strcpy (path, "GNAT-XXXXXX");
+
+ -#if (defined (__FreeBSD__) || defined (linux)) && !defined (__vxworks)
+ +#if (defined (__FreeBSD__) || defined (linux) || defined (nacl)) && !defined (__vxworks)
+ return mkstemp (path);
+ #elif defined (__Lynx__)
+ mktemp (path);
+ @@ -884,7 +884,7 @@
+ free (pname);
+ }
+
+ -#elif defined (linux) || defined (__FreeBSD__)
+ +#elif defined (linux) || defined (__FreeBSD__) || defined (nacl)
+ #define MAX_SAFE_PATH 1000
+ char *tmpdir = getenv ("TMPDIR");
+
+ @@ -2574,8 +2574,8 @@
+ #if defined (CROSS_COMPILE) \
+ || (! ((defined (sparc) || defined (i386)) && defined (sun) \
+ && defined (__SVR4)) \
+ - && ! (defined (linux) && (defined (i386) || defined (__x86_64__))) \
+ - && ! (defined (linux) && defined (__ia64__)) \
+ + && ! ((defined (linux) || defined (nacl)) && (defined (i386) || defined (__x86_64__))) \
+ + && ! ((defined (linux) || defined (nacl)) && defined (__ia64__)) \
+ && ! defined (__FreeBSD__) \
+ && ! defined (__hpux__) \
+ && ! defined (__APPLE__) \
+ diff -Naru ../PRISTINE/gcc-4.2.2/gcc/ada/cstreams.c gcc-4.2.2/gcc/ada/cstreams.c
+ --- ../PRISTINE/gcc-4.2.2/gcc/ada/cstreams.c 2005-07-01 10:29:17.000000000 +0900
+ +++ gcc-4.2.2/gcc/ada/cstreams.c 2008-12-11 16:43:13.000000000 +0900
+ @@ -53,7 +53,7 @@
+
+ #ifdef linux
+ /* Don't use macros on GNU/Linux since they cause incompatible changes between
+ - glibc 2.0 and 2.1 */
+ + glibc 2.0 and 2.1
+
+ #ifdef stderr
+ # undef stderr
+ @@ -64,8 +64,8 @@
+ #ifdef stdout
+ # undef stdout
+ #endif
+ -
+ +*/
+ #endif
+
+ /* The _IONBF value in MINGW32 stdio.h is wrong. */
+ diff -Naru ../PRISTINE/gcc/ada/init.c gcc-4.2.2/gcc/ada/init.c
+ --- ../PRISTINE/gcc/ada/init.c 2006-05-29 03:03:28.000000000 +0900
+ +++ gcc-4.2.2/gcc/ada/init.c 2008-12-11 16:17:34.000000000 +0900
+ @@ -632,7 +632,7 @@
+ /* GNU/Linux Section */
+ /*********************/
+
+ -#elif defined (linux) && (defined (i386) || defined (__x86_64__) \
+ +#elif (defined (linux) || defined (nacl)) && (defined (i386) || defined (__x86_64__) \
+ || defined (__ia64__))
+
+ #include <signal.h>
+ diff -Naru ../PRISTINE/gcc/ada/link.c gcc-4.2.2/gcc/ada/link.c
+ --- ../PRISTINE/gcc/ada/link.c 2005-07-01 10:29:17.000000000 +0900
+ +++ gcc-4.2.2/gcc/ada/link.c 2008-12-11 16:18:04.000000000 +0900
+ @@ -162,7 +162,7 @@
+ unsigned char __gnat_using_gnu_linker = 1;
+ char *__gnat_object_library_extension = ".a";
+
+ -#elif defined (linux)
+ +#elif (defined (linux) || defined (nacl))
+ const char *__gnat_object_file_option = "";
+ const char *__gnat_run_path_option = "-Wl,-rpath,";
+ char __gnat_shared_libgnat_default = STATIC;
+ diff -Naru ../PRISTINE/gcc/ada/sysdep.c gcc-4.2.2/gcc/ada/sysdep.c
+ --- ../PRISTINE/gcc/ada/sysdep.c 2006-05-29 03:03:28.000000000 +0900
+ +++ gcc-4.2.2/gcc/ada/sysdep.c 2008-12-11 16:18:57.000000000 +0900
+ @@ -314,7 +314,7 @@
+ }
+ #endif
+
+ -#if defined (linux) || defined (sun) || defined (sgi) || defined (__EMX__) \
+ +#if (defined (linux) || defined (nacl)) || defined (sun) || defined (sgi) || defined (__EMX__) \
+ || (defined (__osf__) && ! defined (__alpha_vxworks)) || defined (WINNT) \
+ || defined (__MACHTEN__) || defined (__hpux__) || defined (_AIX) \
+ || (defined (__svr4__) && defined (i386)) || defined (__Lynx__) \
+ @@ -371,7 +371,7 @@
+ int *avail,
+ int waiting)
+ {
+ -#if defined (linux) || defined (sun) || defined (sgi) || defined (__EMX__) \
+ +#if (defined (linux) || defined (nacl)) || defined (sun) || defined (sgi) || defined (__EMX__) \
+ || (defined (__osf__) && ! defined (__alpha_vxworks)) \
+ || defined (__CYGWIN32__) || defined (__MACHTEN__) || defined (__hpux__) \
+ || defined (_AIX) || (defined (__svr4__) && defined (i386)) \
+ @@ -391,7 +391,7 @@
+ /* Set RAW mode, with no echo */
+ termios_rec.c_lflag = termios_rec.c_lflag & ~ICANON & ~ECHO;
+
+ -#if defined(linux) || defined (sun) || defined (sgi) || defined (__EMX__) \
+ +#if (defined(linux) || defined (nacl)) || defined (sun) || defined (sgi) || defined (__EMX__) \
+ || defined (__osf__) || defined (__MACHTEN__) || defined (__hpux__) \
+ || defined (_AIX) || (defined (__svr4__) && defined (i386)) \
+ || defined (__Lynx__) || defined (__FreeBSD__)
+ diff -Naru ../PRISTINE/gcc/ada/tracebak.c gcc-4.2.2/gcc/ada/tracebak.c
+ --- ../PRISTINE/gcc/ada/tracebak.c 2006-05-29 03:03:28.000000000 +0900
+ +++ gcc-4.2.2/gcc/ada/tracebak.c 2008-12-11 16:19:21.000000000 +0900
+ @@ -354,7 +354,7 @@
+
+ /*----------------------------- ia64 ---------------------------------*/
+
+ -#elif defined (__ia64__) && (defined (linux) || defined (__hpux__))
+ +#elif defined (__ia64__) && ((defined (linux) || defined (nacl)) || defined (__hpux__))
+
+ #define USE_GCC_UNWINDER
+ /* Use _Unwind_Backtrace driven exceptions on ia64 HP-UX and ia64
+ diff -Naru ../PRISTINE/gcc-4.2.2/gcc/ada/ctrl_c.c gcc-4.2.2/gcc/ada/ctrl_c.c
+ --- ../PRISTINE/gcc-4.2.2/gcc/ada/ctrl_c.c 2005-07-01 10:29:17.000000000 +0900
+ +++ gcc-4.2.2/gcc/ada/ctrl_c.c 2008-12-11 17:16:15.000000000 +0900
+ @@ -48,101 +48,9 @@
+ /* __gnat_uninstall_int_handler will reinstall the original handler */
+ void __gnat_uninstall_int_handler (void);
+
+ -/* POSIX implementation */
+ -
+ -#if (defined (_AIX) || defined (unix)) && !defined (__vxworks)
+ -
+ -#include <signal.h>
+ -
+ -void (*sigint_intercepted) (void) = 0;
+ -
+ -struct sigaction original_act;
+ -
+ -static void
+ -__gnat_int_handler (int sig __attribute__ ((unused)))
+ -{
+ - if (sigint_intercepted != 0)
+ - sigint_intercepted ();
+ -}
+ -
+ -/* Install handler and save original handler. */
+ -
+ -void
+ -__gnat_install_int_handler (void (*proc) (void))
+ -{
+ - struct sigaction act;
+ -
+ - if (sigint_intercepted == 0)
+ - {
+ - act.sa_handler = __gnat_int_handler;
+ - act.sa_flags = SA_RESTART;
+ - sigemptyset (&act.sa_mask);
+ - sigaction (SIGINT, &act, &original_act);
+ - }
+ -
+ - sigint_intercepted = proc;
+ -}
+ -
+ -/* Restore original handler */
+ -
+ -void
+ -__gnat_uninstall_int_handler (void)
+ -{
+ - if (sigint_intercepted != 0)
+ - {
+ - sigaction (SIGINT, &original_act, 0);
+ - sigint_intercepted = 0;
+ - }
+ -}
+ -
+ -/* Windows implementation */
+ -
+ -#elif defined (__MINGW32__)
+ -
+ -#include "mingw32.h"
+ -#include <windows.h>
+ -
+ -void (*sigint_intercepted) (void) = NULL;
+ -
+ -static BOOL WINAPI
+ -__gnat_int_handler (DWORD dwCtrlType)
+ -{
+ - switch (dwCtrlType)
+ - {
+ - case CTRL_C_EVENT:
+ - case CTRL_BREAK_EVENT:
+ - if (sigint_intercepted != 0)
+ - sigint_intercepted ();
+ - break;
+ -
+ - case CTRL_CLOSE_EVENT:
+ - case CTRL_LOGOFF_EVENT:
+ - case CTRL_SHUTDOWN_EVENT:
+ - break;
+ - }
+ -}
+ -
+ -void
+ -__gnat_install_int_handler (void (*proc) (void))
+ -{
+ - if (sigint_intercepted == NULL)
+ - SetConsoleCtrlHandler (__gnat_int_handler, TRUE);
+ -
+ - sigint_intercepted = proc;
+ -}
+ -
+ -void
+ -__gnat_uninstall_int_handler (void)
+ -{
+ - if (sigint_intercepted != NULL)
+ - SetConsoleCtrlHandler (__gnat_int_handler, FALSE);
+ -
+ - sigint_intercepted = NULL;
+ -}
+ -
+ /* Default implementation: do nothing */
+
+ -#else
+ +
+
+ void
+ __gnat_install_int_handler (void (*proc) (void) __attribute__ ((unused)))
+ @@ -153,4 +61,4 @@
+ __gnat_uninstall_int_handler (void)
+ {
+ }
+ -#endif
+ +
なんかすごく適当です。ctrl_c.cとかひどい。
でもこれでも動かないんだなー。まだエラーがでる。
とりあえず今回はここまで。GCCに詳しい人に何とかしてもらいたいなぁ(チラッ。