Skip to content

Instantly share code, notes, and snippets.

@kjunichi
Last active November 4, 2022 11:55
Show Gist options
  • Save kjunichi/27f2de2ee24f280ab497 to your computer and use it in GitHub Desktop.
Save kjunichi/27f2de2ee24f280ab497 to your computer and use it in GitHub Desktop.
クロスコンパイル入門

背景

もともとは、DLLをオープンしてシンボル参照して、必要な関数を呼ぶ形式にすれば、簡単にmruby-webcam (OpenCVの力を借りてWebCamの画像を表示する)のマルチプラットフォーム対応のバイナリが作成出来ると考えていた。

しかし、OpenCVは32ビット環境では最新版ではWebCamが扱えない状態C++ APIを使う必要がある

さらに悪いことc++はdlopenやLoadLibraryではマングリング問題やnewやdeleteのラッパーが必要で簡単には使えない。 JulialangでC++の関数の呼び出しがサポートされていることを知るも、これも、完全なものではなく、せいぜい マングリングを解決する程度のものであった。

結局、各プラットフォームに依存したCのソースを書く必要が出てくることが分かった。

そんわけで、クロスコンパイルを習得して、mruby-cliにゆくゆくは載せられるような形に出来ないかと始めた次第。

目標

dockerでrunすると、Windows用のバイナリファイルがローカルに出来る

もう少し具体的な例

ImageMagickやopencvを使ったmrbgemsを含むWindows向けのmrubyをdocker上でビルドしたい

現時点で知っていること

  • mruby-cliで外部ライブラリに依存しないmrbgemsを含むmrubyならビルド可能
  • mingwをLinux上で動かすことは出来る模様

課題

  • windows向けのライブラリのdocker上での保持
  • ターゲットとしているライブラリの依存関係の把握

必要そうなこと

LinuxでのMingw

32bit

--host=i686-w64-mingw32

64bit

--host=x86_64-w64-mingw32

作業メモ

apt-get install -y mingw-w64-tools
apt-get update
apt-get install -y mingw-w64
apt-get install -y git
apt-get install mingw-w64-tools
apt-get install cmake 
apt-get install cmake-curses-gui
apt-get install -y vim
apt-get install gettext
set(CMAKE_SYSTEM_NAME Windows)
 
# specify the cross compiler
set(CMAKE_C_COMPILER   /usr/bin/i686-w64-mingw32-gcc)
set(CMAKE_CXX_COMPILER /usr/bin/i686-w64-mingw32-g++)
 
# set PKG_CONFIG_PATH for MinGW Cross Compile Environment
set(ENV{PKG_CONFIG_PATH} /usr/i686-w64-mingw32/lib/pkgconfig)
 
# where is the target environment 
set(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32/)
cmake -DCMAKE_TOOLCHAIN_FILE=../build.old/my.cmake -DWITH_IPP=OFF  ..
i686-w64-mingw32-g++ webcam.cpp -o webcam -I ./install/include/ -L ./install/lib  ./install/lib/libopencv_core300.dll.a -lopencv_highgui300 -lopencv_video300 -lopencv_videoio300 -lopencv_imgcodecs300

static化

OpenCV本体をstatic化する

cmake -DCMAKE_TOOLCHAIN_FILE=../mytool.cmake -DWITH_IPP=OFF -DBUILD_SHARED_LIBS=OFF  ..
i686-w64-mingw32-g++ webcam.cpp -o webcam.exe -I ./install/include/ \
 install/lib/libopencv_highgui300.a \
 install/lib/libopencv_videoio300.a \
 install/lib/libopencv_imgcodecs300.a \
 install/lib/libopencv_imgproc300.a \
 install/lib/libopencv_core300.a \
 install/lib/libopencv_hal300.a \
 3rdparty/lib/libIlmImf.a \
 3rdparty/lib/libzlib.a \
 3rdparty/lib/liblibjasper.a \
 3rdparty/lib/liblibjpeg.a \
 3rdparty/lib/liblibtiff.a \
 3rdparty/lib/liblibwebp.a \
 3rdparty/lib/liblibpng.a \
 -lvfw32 -lole32 -loleaut32 -lgdi32 -lcomdlg32 -luuid 

ImageMagicke編

--- a/magick/distribute-cache.c
+++ b/magick/distribute-cache.c
@@ -87,6 +87,8 @@
 #define LENGTH_TYPE size_t
 #define MAGICKCORE_HAVE_DISTRIBUTE_CACHE
 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
+#include <winsock.h>
+#include <ws2tcpip.h>
 #define CHAR_TYPE_CAST (char *)
 #define CLOSE_SOCKET(socket) (void) closesocket(socket)
 #define HANDLER_RETURN_TYPE DWORD WINAPI
--- a/magick/nt-base.c
+++ b/magick/nt-base.c
@@ -62,6 +62,7 @@
 #include <ntsecapi.h>
 #include <wincrypt.h>
 #endif
+#include <winsock.h>
 ^L
 /*
   Define declarations.
--- a/magick/random.c
+++ b/magick/random.c
@@ -449,6 +449,7 @@ static StringInfo *GenerateEntropicChaos(RandomInfo *random_info)
   SetStringInfoLength(chaos,sizeof(nanoseconds));
   SetStringInfoDatum(chaos,(unsigned char *) &nanoseconds);
   ConcatenateStringInfo(entropy,chaos);
+#undef MAGICKCORE_HAVE_MKSTEMP
 #if defined(MAGICKCORE_HAVE_MKSTEMP)
   {
     char
--- a/magick/resource.c
+++ b/magick/resource.c
@@ -522,6 +522,7 @@ MagickExport int AcquireUniqueFileResource(char *path)
       *p++=portable_filename[c];
     }
     key=DestroyStringInfo(key);
+#undef MAGICKCORE_HAVE_MKSTEMP
 #if defined(MAGICKCORE_HAVE_MKSTEMP)
     file=mkstemp(path);
     if (file != -1)
LIBS="/usr/i686-w64-mingw32/lib/libws2_32.a /usr/i686-w64-mingw32/lib/libmsvcr110.a" ./configure --enable-static=yes --enable-shared=no --host=i686-w64-mingw32 --prefix=/usr/i686-w64-mingw32 --without-perl

BAD

i686-w64-mingw32-g++ webcam.cpp -o webcam -I ./install/include/ \
 install/lib/libopencv_core300.a \
 install/lib/libopencv_calib3d300.a \
 install/lib/libopencv_imgcodecs300.a \
 install/lib/libopencv_stitching300.a \
 install/lib/libopencv_imgproc300.a \
 install/lib/libopencv_superres300.a \
 install/lib/libopencv_features2d300.a \
 install/lib/libopencv_ml300.a \
 install/lib/libopencv_ts300.a \
 install/lib/libopencv_flann300.a \
 install/lib/libopencv_objdetect300.a \
 install/lib/libopencv_video300.a \
 install/lib/libopencv_hal300.a \
 install/lib/libopencv_photo300.a \
 install/lib/libopencv_videoio300.a \
 install/lib/libopencv_highgui300.a \
 install/lib/libopencv_shape300.a \
 install/lib/libopencv_videostab300.a \
 -lvfw32 -lole32 -loleaut32 -lgdi32 -lcomdlg32 -luuid \
 3rdparty/lib/libIlmImf.a \
 3rdparty/lib/libzlib.a \
 3rdparty/lib/liblibjasper.a \
 3rdparty/lib/liblibjpeg.a \
 3rdparty/lib/liblibtiff.a \
 3rdparty/lib/liblibwebp.a \
 3rdparty/lib/liblibpng.a

まとめ

クロスコンパイル自体は、案ずるより産むがやすしだった。 が、Dockerで汎用化を考えると難しい。docker run -it hoge /bin/bashで都度 必要なソースを持ってきてコンパイルが現実的かも知れない。

参考資料

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment