いけむランド

はてダからやってきました

road to e17 (5)

Ecore が終われば、もう e17 の準備は整ったようなものである。


e17 のビルドするには、まだ以下のライブラリを用意する必要があるが、今までのノウハウがあれば、ビルドに困ることは何らない。

Embryo
Small と呼ばれる仕様の小さなプログラミング言語コンパイラおよびインタプリタ *1
Edje
グラフィックとレイアウトのライブラリ。Evas のうわもの?
Efreet
Freedesktop.org 標準に合わせるためのライブラリ

これらの準備ができたら、いよいよ本丸である e17 に攻めることになるわけだが、数々の難関が待ち受けている。

ハードコーディング

今までに %s.so を %s.dll へ書き換えるくらいなら我慢したが、これはひどい。(差分は今回対応するために自分が足したもの。)

diff -urN origsrc/enlightenment-0.16.999.042/src/bin/e_start_main.c src/enlightenment-0.16.999.042/src/bin/e_start_main.c
--- origsrc/enlightenment-0.16.999.042/src/bin/e_start_main.c   2007-09-24 10:14:26.000000000 +0900
+++ src/enlightenment-0.16.999.042/src/bin/e_start_main.c       2008-02-11 21:55:12.859375000 +0900
@@ -365,23 +365,39 @@
        
        do_precache = 0;
        /* sanity checks - if precache might fail - check here first */
+#ifdef __CYGWIN__
+       lib = dlopen("cygevas-0.dll", RTLD_GLOBAL | RTLD_LAZY);
+#else // __CYGWIN__
        lib = dlopen("libevas.so", RTLD_GLOBAL | RTLD_LAZY);
        if (!lib) dlopen("libevas.so.1", RTLD_GLOBAL | RTLD_LAZY);
+#endif // __CYGWIN__
        if (!lib) goto done;
        func = dlsym(lib, "evas_init");
        if (!func) goto done;
+#ifdef __CYGWIN__
+       lib = dlopen("cygecore_file-0.dll", RTLD_GLOBAL | RTLD_LAZY);
+#else // __CYGWIN__
        lib = dlopen("libecore_file.so", RTLD_GLOBAL | RTLD_LAZY);
        if (!lib) dlopen("libecore_file.so.1", RTLD_GLOBAL | RTLD_LAZY);
+#endif // __CYGWIN__
        if (!lib) goto done;
        func = dlsym(lib, "ecore_file_init");
        if (!func) goto done;
+#ifdef __CYGWIN__
+       lib = dlopen("cygeet-0.dll", RTLD_GLOBAL | RTLD_LAZY);
+#else // __CYGWIN__
        lib = dlopen("libeet.so", RTLD_GLOBAL | RTLD_LAZY);
        if (!lib) dlopen("libeet.so.0", RTLD_GLOBAL | RTLD_LAZY);
+#endif // __CYGWIN__
        if (!lib) goto done;
        func = dlsym(lib, "eet_init");
        if (!func) goto done;
        /* precache SHOULD work */
+#ifdef __CYGWIN__
+       snprintf(buf, sizeof(buf), "%s/lib/enlightenment/preload/e_precache.dll", _prefix_path);
+#else // __CYGWIN__
        snprintf(buf, sizeof(buf), "%s/lib/enlightenment/preload/e_precache.so", _prefix_path);
+#endif // __CYGWIN__
        env_set("LD_PRELOAD", buf);
        printf("E - PRECACHE GOING NOW...\n");
        fflush(stdout);

undefined reference

e17 が動的に使用するモジュールのビルドで undefined reference が大量発生する。どうやら enlightenment*.exe を構成する *.o に含まれるシンボルであるが、当然ながらモジュールをビルドする際にはそれらを解決することが出来ない。だけど、これでも Linux ではビルドできるらしい。

-no-undefined
このオプションを指定すると、libtoolはすべてのシンボルが*.loファイルまたは-lで指定されるライブラリで定義されているとして振舞う。
ELFの*.so(shared object)ではこのような制約はないが、 Win32のPE-COFFのDLLは実行ファイルと同様に、リンク時にすべてのシンボルが解決される必要がある。

仕方ないので、enlightenment*.exe を構成するすべての *.o から DLL をつくるよう Makefile.am を変えてみる。

diff -urN origsrc/enlightenment-0.16.999.042/src/bin/Makefile.am src/enlightenment-0.16.999.042/src/bin/Makefile.am
--- origsrc/enlightenment-0.16.999.042/src/bin/Makefile.am      2007-12-30 11:53:56.000000000 +0900
+++ src/enlightenment-0.16.999.042/src/bin/Makefile.am  2008-02-12 20:23:36.734375000 +0900
@@ -7,6 +7,7 @@
           @cf_cflags@ \
           @VALGRIND_CFLAGS@ \
           @EDJE_DEF@ \
+          @E_DBUS_CFLAGS@ @E_HAL_CFLAGS@ \
           -DPACKAGE_BIN_DIR=\"@PACKAGE_BIN_DIR@\" \
           -DPACKAGE_LIB_DIR=\"@PACKAGE_LIB_DIR@\" \
           -DPACKAGE_DATA_DIR=\"@PACKAGE_DATA_DIR@\" \
@@ -294,46 +295,40 @@
 e_powersave.c \
 $(ENLIGHTENMENTHEADERS)
 
-enlightenment_SOURCES = \
-e_main.c \
-$(enlightenment_src)
 
-enlightenment_LDFLAGS = -export-dynamic @e_libs@ @x_libs@ @dlopen_libs@ @cf_libs@ @VALGRIND_LIBS@ @E_DBUS_LIBS@
-
-enlightenment_remote_SOURCES = \
-e.h \
-e_ipc_codec.c \
-e_remote_main.c
-
-enlightenment_remote_LDFLAGS = @e_libs@
-
-enlightenment_imc_SOURCES = \
-e.h \
-e_intl_data.c \
-e_config_data.c \
-e_imc_main.c
-# $(enlightenment_src)
-
-enlightenment_imc_LDFLAGS = @e_libs@ @dlopen_libs@
-
-enlightenment_start_SOURCES = \
-e_start_main.c
+# workaround
+lib_LTLIBRARIES = libenlightenment.la
+libenlightenment_la_SOURCES = $(enlightenment_src) \
+e_main.c e_remote_main.c e_imc_main.c e_thumb_main.c e_fm_main.c
+ 
+libenlightenment_la_LIBADD = @e_libs@ @x_libs@ @dlopen_libs@ @cf_libs@ \
+@VALGRIND_LIBS@ @E_DBUS_LIBS@ @E_HAL_LIBS@
+
+libenlightenment_la_DEPENDENCIES = $(top_builddir)/config.h
+libenlightenment_la_LDFLAGS = -version-info 0:0:0 -no-undefined
+
+enlightenment_SOURCES = e_main_cygwin.c
+enlightenment_LDADD = $(top_builddir)/src/bin/libenlightenment.la
+enlightenment_DEPENDENCIES = $(top_builddir)/src/bin/libenlightenment.la
+
+enlightenment_remote_SOURCES = e_remote_main_cygwin.c
+enlightenment_remote_LDADD = $(top_builddir)/src/bin/libenlightenment.la
+enlightenment_remote_DEPENDENCIES = $(top_builddir)/src/bin/libenlightenment.la+
+enlightenment_imc_SOURCES = e_imc_main_cygwin.c
+enlightenment_imc_LDADD = $(top_builddir)/src/bin/libenlightenment.la
+enlightenment_imc_DEPENDENCIES = $(top_builddir)/src/bin/libenlightenment.la
 
+enlightenment_start_SOURCES = e_start_main.c
 enlightenment_start_LDFLAGS = @dlopen_libs@
 
-enlightenment_thumb_SOURCES = \
-e_thumb_main.c \
-e_user.c \
-e_sha1.c
-
-enlightenment_thumb_LDFLAGS = @e_libs@
-
-enlightenment_fm_SOURCES = \
-e_fm_main.c \
-e_user.c \
-e_sha1.c
-
-enlightenment_fm_LDFLAGS = @e_libs@ @dlopen_libs@ @E_DBUS_LIBS@ @E_HAL_LIBS@
+enlightenment_thumb_SOURCES = e_thumb_main_cygwin.c
+enlightenment_thumb_LDADD = $(top_builddir)/src/bin/libenlightenment.la
+enlightenment_thumb_DEPENDENCIES = $(top_builddir)/src/bin/libenlightenment.la
+
+enlightenment_fm_SOURCES = e_fm_main_cygwin.c
+enlightenment_fm_LDADD = $(top_builddir)/src/bin/libenlightenment.la
+enlightenment_fm_DEPENDENCIES = $(top_builddir)/src/bin/libenlightenment.la
 enlightenment_fm_CFLAGS = $(INCLUDES) @E_HAL_CFLAGS@
 
 enlightenment_sys_SOURCES = \
@@ -341,11 +336,9 @@
 
 enlightenment_sys_LDFLAGS = @e_libs@
 
-enlightenment_init_SOURCES = \
-e_init_main.c \
-e_xinerama.c
-
-enlightenment_init_LDFLAGS = @e_libs@
+enlightenment_init_SOURCES = e_init_main.c
+enlightenment_init_LDADD = $(top_builddir)/src/bin/libenlightenment.la
+enlightenment_init_DEPENDENCIES = $(top_builddir)/src/bin/libenlightenment.la
 
 setuid_root_mode = a=rx,u+xs
 install-exec-hook:

すると enlightenment*.exe 間の main が衝突することになるため、それらを適当にリネームし、別の main からそれらを呼び出すように修正してみる。けっこうな荒療治である。

diff -urN origsrc/enlightenment-0.16.999.042/src/bin/e_main.c src/enlightenment-0.16.999.042/src/bin/e_main.c
--- origsrc/enlightenment-0.16.999.042/src/bin/e_main.c 2008-01-08 10:54:49.000000000 +0900
+++ src/enlightenment-0.16.999.042/src/bin/e_main.c     2008-02-11 17:21:59.859375000 +0900
@@ -60,7 +60,11 @@
    
 /* externally accessible functions */
 int
+#ifndef __CYGWIN__
 main(int argc, char **argv)
+#else // ! __CYGWIN__
+e_main_cygwin(int argc, char** argv)
+#endif // ! __CYGWIN__
 {
    int i;
    int nostartup = 0;
diff -urN origsrc/enlightenment-0.16.999.042/src/bin/e_main_cygwin.c src/enlightenment-0.16.999.042/src/bin/e_main_cygwin.c
--- origsrc/enlightenment-0.16.999.042/src/bin/e_main_cygwin.c  1970-01-01 09:00:00.000000000 +0900
+++ src/enlightenment-0.16.999.042/src/bin/e_main_cygwin.c      2008-02-11 17:21:59.890625000 +0900
@@ -0,0 +1,7 @@
+/* dummy e_main for cygwin */
+extern int e_main_cygwin(int argc, char** argv);
+
+int main(int argc, char** argv)
+{
+  return e_main_cygwin(argc, argv);
+}

この対応をしても、モジュールの一部でやはり undefined reference の問題でビルドできないものがある。これは他のモジュールに含まれてるシンボルを参照しているためで、これらは必須ではないと判断し、ビルドしないように修正する。


[追記] Windows がモジュールの undefined reference を許さないからライブラリ化して、小さな main だけの .exe をエントリとして用意するようにしろって、作者が 3 年も前に言ってるわ。orz

> Heh, I wish i had "figured it all out"; ewl/e does not work because it
> cannot seem to get at the images or fonts in the .edj theme, and no
> matter what run-time modules are not going to work because of
> limitations of Windows' run-time linker (unresolved symbols are not
> allowed at link time for shared objects like they are on unix). I guess
> it might be possible to build a statitically "linked" enlightenment.exe
> which contained all the modules you wanted to use, but i'm not sure.
> good luck. ;-)

you couldn't do that without big changes in code as it literally wants to OPEN
the modules - not expect them within the compiled wm. they rely on files and
dirs to work properly. the best you could do is wrap e in a tiny binary
executable and move the rest of e into a shared object - ie build the wm as a
enlightenment.so (or .dll) then make modules link to it. the enlightenment.so
will have a e_main_entry() that is actually just the current main() and then
you build an executabel that links to the enlightenment lib and blindly calls
its e_main_entry() with argc and arcg passed in. this woudl solve the problem
but its a very obtuse thnig to do and will mean a fair changes in build and
code setup - but then you can link the modules to the symbols they need... :)
(well also ass the code to load .dll not .so files) :) - if you can solve the %
a problem. i am suspecting that is your actual problem - that cybwin doesnt
support writing AND reading %a format floats. (man 3 printf on your linux box
to find out what it is) :)

*1:いつの間にか 簡単な紹介の頁 ができていたので、後で記事にするかも。