HTTP/2に最適化されたhttpdのh2oは64bit環境前提に作られている(Raspbianは32bit)が、とりあえずやってみた
前提
- h2oはcmakeに対応しているので、cmakeを利用してcross compileを行う
- cross compile環境はdocker上に作ったCentOS7環境
cross compilerをインストールしておく
/opt/rpi/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64
環境変数CROSS_COMPILEをセットしておく
export CROSS_COMPILE=arm-linux-gnueabihf-
zlib
ZLIB_VERSION=1.2.11
if [ ! -d zlib-${ZLIB_VERSION} ]; then
curl -L http://prdownloads.sourceforge.net/libpng/zlib-${ZLIB_VERSION}.tar.gz?download | tar zx
fi
cd zlib-${ZLIB_VERSION}
CC=${CROSS_COMPILE}gcc ./configure --prefix=${SYSROOT} && make && make install
cd ..
libressl
libresslは--hostの指定と、CCなどを設定して対応した
$(DEST)/lib/libssl.a: $(ARCHIVE)
if [ ! -e "libressl-$(VERSION)" ] ; then tar xzf "$(ARCHIVE)" ; fi
- if [ ! -e "libressl-$(VERSION)/Makefile" ] ; then (P=`pwd`/$(DEST); cd libressl-$(VERSION) && ./configure --prefix="$$P" --libdir="$$P/lib" --disable-shared `test "$(UNAME)" = "Darwin" && echo '--disable-asm'`) ; fi
+ if [ ! -e "libressl-$(VERSION)/Makefile" ] ; then (P=`pwd`/$(DEST); cd libressl-$(VERSION) && CC=${CROSS_COMPILE}gcc LD=${CROSS_COMPILE}ld CCLD=$LD AR=${CROSS_COMPILE}ar CXX=${CROSS_COMPILE}g++ CPP=${CROSS_COMPILE}cpp RANLIB=${CROSS_COMPILE}ranlib ./configure --host=arm-linux-gnueabi --prefix="$$P" --libdir="$$P/lib" --disable-shared `test "$(UNAME)" = "Darwin" && echo '--disable-asm'`) ; fi
(cd libressl-$(VERSION) && make && make install)
mruby
mrubyのbuildにcrubyを使う。
mruby自体にcross compileの対応がしてあるため、rubyの設定ファイルを書く
mrubyルートディレクトリにあるbuild_conf.rbを参考にしながらMRuby::CrossBuild.new
を使う
MRuby::CrossBuild.new('arm-linux-gnueabi') do |conf|
toolchain :gcc
conf.cc.command = ENV['CROSS_COMPILE'] + 'gcc'
conf.cxx.command = ENV['CROSS_COMPILE'] + 'g++'
conf.linker.command = ENV['CROSS_COMPILE'] + 'gcc'
conf.archiver.command = ENV['CROSS_COMPILE'] + 'ar'
# conf.cc.flags << "-m32"
# conf.linker.flags << "-m32"
# use mrbgems
Dir.glob("../mruby-*/mrbgem.rake") do |x|
g = File.basename File.dirname x
if g == 'mruby-onig-regexp'
conf.gem "../deps/#{g}" do |c|
c.bundle_onigmo
end
else
conf.gem "../deps/#{g}"
end
end
# include all the core GEMs
conf.gembox 'full-core'
conf.build_mrbtest_lib_only
#conf.gem 'examples/mrbgems/c_and_ruby_extension_example'
conf.test_runner.command = 'env'
end
mruby-file-statのクロスコンパイルに失敗するため、以下のパッチを適用する
diff --git a/deps/mruby-file-stat/mrbgem.rake b/deps/mruby-file-stat/mrbgem.rake
index ff7d076b..133aee1f 100644
--- a/deps/mruby-file-stat/mrbgem.rake
+++ b/deps/mruby-file-stat/mrbgem.rake
@@ -14,12 +14,16 @@ MRuby::Gem::Specification.new('mruby-file-stat') do |spec|
file config do
FileUtils.mkdir_p build_dir, :verbose => true
Dir.chdir build_dir do
+ if build.kind_of? MRuby::CrossBuild
+ host = "--host=#{build.name}"
+ end
+
if ENV['OS'] == 'Windows_NT'
_pp 'on Windows', dir
FileUtils.touch "#{build_dir}/config.h", :verbose => true
else
_pp './configure', dir
- system env, "#{dir}/configure"
+ system env, "#{dir}/configure #{host}"
end
end
end
h2o
cmakeを利用したcross compile。
CMAKE_TOOLCHAIN_FILEを指定し、raspberry pi用のcmakeファイルを作る
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_SYSROOT /opt/rpi/rootfs)
set(CMAKE_STAGING_PREFIX /home/data/target)
set(tools /opt/rpi/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64)
set(CMAKE_C_COMPILER ${tools}/bin/arm-linux-gnueabihf-gcc)
# set(CMAKE_CXX_COMPILER ${tools}/bin/arm-linux-gnueabihf-g++)
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT} ${CMAKE_STAGING_PREFIX})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
今まで諸々やってきたことをCMakeLists.txtへのpatchとして作る
アーカイブのパスがhostに依存しているため、cross compile時に切り替えられるようにしておく
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0e95190b..0dbf8384 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -75,7 +75,12 @@ OPTION(WITH_PICOTLS "whether or not to build with picotls" "ON")
IF (WITH_BUNDLED_SSL)
SET(BUNDLED_SSL_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/libressl-build/include")
SET(BUNDLED_SSL_LIBRARIES "${CMAKE_CURRENT_BINARY_DIR}/libressl-build/lib/libssl.a" "${CMAKE_CURRENT_BINARY_DIR}/libressl-build/lib/libcrypto.a")
- ADD_CUSTOM_TARGET(bundled-ssl make -f ${CMAKE_CURRENT_SOURCE_DIR}/misc/libressl.mk SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}/misc
+ IF (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm")
+ SET(BUNDLED_SSL_CONFIG "libressl_linux-arm.mk")
+ ELSE ()
+ SET(BUNDLED_SSL_CONFIG "libressl.mk")
+ ENDIF ()
+ ADD_CUSTOM_TARGET(bundled-ssl make -f ${CMAKE_CURRENT_SOURCE_DIR}/misc/${BUNDLED_SSL_CONFIG} SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}/misc
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
ELSE (WITH_BUNDLED_SSL)
IF (NOT OPENSSL_FOUND)
@@ -445,7 +450,12 @@ IF (WITH_MRUBY)
ELSE ()
SET(MRUBY_TOOLCHAIN "gcc")
ENDIF ()
- ADD_CUSTOM_TARGET(mruby MRUBY_TOOLCHAIN=${MRUBY_TOOLCHAIN} MRUBY_CONFIG=${CMAKE_CURRENT_SOURCE_DIR}/misc/mruby_config.rb MRUBY_BUILD_DIR=${CMAKE_CURRENT_BINARY_DIR}/mruby ruby minirake
+ IF (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm")
+ SET(CMAKE_MRUBY_CONFIG "mruby_config_linux-arm.rb")
+ ELSE ()
+ SET(CMAKE_MRUBY_CONFIG "mruby_config.rb")
+ ENDIF ()
+ ADD_CUSTOM_TARGET(mruby MRUBY_TOOLCHAIN=${MRUBY_TOOLCHAIN} MRUBY_CONFIG=${CMAKE_CURRENT_SOURCE_DIR}/misc/${CMAKE_MRUBY_CONFIG} MRUBY_BUILD_DIR=${CMAKE_CURRENT_BINARY_DIR}/mruby ruby minirake
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/deps/mruby)
LIST(APPEND STANDALONE_SOURCE_FILES
lib/handler/mruby.c
@@ -473,10 +483,16 @@ ELSE (WITH_BUNDLED_SSL)
ENDIF (WITH_BUNDLED_SSL)
IF (WITH_MRUBY)
TARGET_INCLUDE_DIRECTORIES(h2o BEFORE PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/deps/mruby/include ${CMAKE_CURRENT_SOURCE_DIR}/deps/mruby-input-stream/src)
+ IF (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm")
+ SET(CMAKE_MRUBY_AR_DIR "arm-linux-gnueabi")
+ ELSE ()
+ SET(CMAKE_MRUBY_AR_DIR "host")
+ ENDIF ()
+
# note: the paths need to be determined before libmruby.flags.mak is generated
TARGET_LINK_LIBRARIES(h2o
- "${CMAKE_CURRENT_BINARY_DIR}/mruby/host/lib/libmruby.a"
- "${CMAKE_CURRENT_BINARY_DIR}/mruby/host/mrbgems/mruby-onig-regexp/onigmo-6.1.1/.libs/libonigmo.a"
+ "${CMAKE_CURRENT_BINARY_DIR}/mruby/${CMAKE_MRUBY_AR_DIR}/lib/libmruby.a"
+ "${CMAKE_CURRENT_BINARY_DIR}/mruby/${CMAKE_MRUBY_AR_DIR}/mrbgems/mruby-onig-regexp/onigmo-6.1.1/.libs/libonigmo.a"
"m")
ADD_DEPENDENCIES(h2o mruby)
ENDIF (WITH_MRUBY)
ビルドスクリプトは以下の通り
if [ ! -d h2o ]; then
git clone https://github.com/h2o/h2o.git
fi
cd h2o
cp ../libressl_linux-arm.mk misc
cp ../mruby_config_linux-arm.rb misc
patch --forward -p1 < ../mruby-file-stat_cross.patch
patch --forward -p1 < ../cross.patch
cmake -DWITH_MRUBY=on -DCMAKE_INSTALL_PREFIX=$SYSROOT -DCMAKE_TOOLCHAIN_FILE=`pwd`/../linux-arm.cmake .
make
今まで書いてきたことは下記のリポジトリにある
h2o cross compile build script
cloneしてmakeする
perlが必要ならyoctoのレシピを参考にすると