Commit 65901c3d authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto

Merge pull request #679 from masuidrive/merge_to_cruby_building_script

Rebuild CRuby based building script without Makefile
parents a48fc0d7 7c469c0b
......@@ -20,6 +20,7 @@
cscope.out
/src/y.tab.c
/bin
/build
/mrblib/mrblib.c
/mrblib/*.*tmp
/mrblib/mrblib.mrb
......
# CMake build system for mruby
# License: released under the same license as mruby
# Author: jonforums@gmail.com
# Author: beoran@gmail.com
#
# Usage example:
# 1. Ensure CMake, Bison, and a build toolchain are on `PATH`
# 2. Change to a build directory outside source tree, eg - `build` subdir
# 3. Create build Makefiles or project files.
# `cmake ..` (UNIX-like system)
# `cmake -G "MSYS Makefiles" ..`
# `cmake -G "Visual Studio 10" ..`
# `cmake -G "NMake Makefiles" ..`
# ** to cross-compile: add -DCMAKE_TOOLCHAIN_FILE=/path/to/toolchain/file
# ** to set install dir: add -DCMAKE_INSTALL_PREFIX=/path/to/installdir
# 4a. Build: `make` (to make noisy, add `VERBOSE=1`)
# 4b. Build and test: `make all test`
# 4c. Build, test, and install: `make all test install`
# 4d. Build, test, and package: `make all test package`
cmake_minimum_required(VERSION 2.8.8 FATAL_ERROR)
# Default build mode is Release With Debug Info unless specified
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
"Choose build type: empty Debug Release RelWithDebInfo MinSizeRel"
FORCE)
message(STATUS "Build type not set, defaulting to 'RelWithDebInfo'")
endif()
project(mruby C)
# TODO stop polluting source tree with CMakeFiles/ and CMakeCache.txt
# on build location check failure
# Make sure we are not trying to generate in in-tree build unless building
# with an MSVC or Xcode IDE where it's OK.
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT (MSVC_IDE OR XCODE))
message(FATAL_ERROR
"\nIn-source builds are not allowed as CMake would overwrite the "
"Makefiles distributed with mruby. Delete any created 'CMakeFiles' "
"subdirectory and 'CMakeCache.txt' file from the current directory, "
"change to the 'build' subdirectory, and re-run CMake from there.")
endif()
if(COMMAND cmake_policy)
cmake_policy(SET CMP0003 NEW) # don't split absolute link paths
cmake_policy(SET CMP0012 NEW) # recognize number & boolean literals
cmake_policy(SET CMP0015 NEW) # convert relative link paths to absolute
endif(COMMAND cmake_policy)
# Match original Makefile's default in-tree install.
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR} CACHE PATH
"Install path prefix prepended to install directories."
FORCE
)
endif()
# TODO refactor to use an option when adding shared lib support
set(BUILD_SHARED_LIBS OFF)
# Version of mruby, useful for versoning .so and .dll files.
# TODO automate by parsing src/version.h -or- extract git info?
set(MRUBY_VERSION 1.0.0dev)
string(REGEX MATCH "^[0-9]+[.][0-9]+" MRUBY_SOVERSION ${MRUBY_VERSION})
string(REPLACE "." "" MRUBY_DLL_SHORTVER ${MRUBY_SOVERSION})
# Search in the `cmake` directory for custom CMake helper modules.
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules")
include(IntrospectSystem)
# Search for C header files in these directories.
include_directories("${CMAKE_SOURCE_DIR}/include" "${CMAKE_SOURCE_DIR}/src")
# TODO re-enable (and implement) if needed
# On some 64-bit platforms, libraries should be installed into `lib64'
# instead of `lib'. Set this to 64 to do that.
#set(LIB_SUFFIX "" CACHE STRING "Suffix for 'lib' directories, e.g. '64'")
# build the components
add_subdirectory(src)
add_subdirectory(mrblib)
add_subdirectory(tools)
add_subdirectory(test)
# install the header files
install(FILES include/mruby.h DESTINATION include)
install(FILES include/mrbconf.h DESTINATION include)
install(DIRECTORY include/mruby DESTINATION include FILES_MATCHING PATTERN "*.h")
# TODO refactor once proper versioning scheme implemented
# archive packaging
set(CPACK_GENERATOR "TGZ;ZIP")
string(TOLOWER ${CMAKE_SYSTEM_NAME} MRUBY_HOST)
if(CMAKE_C_COMPILER_VERSION)
string(REPLACE "." "" MRUBY_GCC_VERSION ${CMAKE_C_COMPILER_VERSION})
endif()
# TODO add build info suffix for non-Windows builds?
if(MINGW)
set(MRUBY_BUILD "-mingw${MRUBY_GCC_VERSION}")
elseif(MSVC)
set(MRUBY_BUILD "-msvc${MSVC_VERSION}")
endif()
set(CPACK_PACKAGE_FILE_NAME
"${CMAKE_PROJECT_NAME}-${MRUBY_VERSION}-${MRUBY_HOST}${MRUBY_BUILD}"
)
include(CPack)
# vim: ts=2 sts=2 sw=2 et
# encoding: utf-8
# Build description.
# basic build file for mruby
# compiler, linker (gcc), archiver, parser generator
CC = ENV['CC'] || 'gcc'
LL = ENV['LL'] || 'gcc'
AR = ENV['AR'] || 'ar'
YACC = ENV['YACC'] || 'bison'
MAKE = ENV['MAKE'] || 'make'
# mruby source root path
MRUBY_ROOT = ENV['MRUBY_ROOT'] || File.expand_path(File.dirname(__FILE__))
# by default GEMs are deactivated
ENABLE_GEMS = ENV['ENABLE_GEMS'] == 'true'
# the default file which contains the active GEMs
ACTIVE_GEMS = ENV['ACTIVE_GEMS'] || File.join(MRUBY_ROOT, '/mrbgems/GEMS.active')
# default compile option
COMPILE_MODE = ENV['COMPILE_MODE'] || :debug
load 'tasks/ruby_ext.rake'
load 'tasks/mruby_build.rake'
load 'tasks/mruby_gem_spec.rake'
##############################
# compile flags
load File.expand_path(ENV['CONFIG'] || './build_config.rb')
case COMPILE_MODE.to_s
when 'release'
CFLAGS = ['-O3']
when 'small'
CFLAGS = ['-Os']
else # including 'debug'
e = ENV['CFLAGS']
CFLAGS = if e then [e] else ['-g', '-O3'] end
end
LDFLAGS = [ENV['LDFLAGS']]
LIBS = [ENV['LIBS'] || '-lm']
if ENABLE_GEMS
require './mrbgems/build_tasks'
Rake::Task[:load_mrbgems_flags].invoke
else
CFLAGS << "-DDISABLE_GEMS"
end
CFLAGS << "-Wall" << "-Werror-implicit-function-declaration" << "-I#{MRUBY_ROOT}/include"
if ENV['OS'] == 'Windows_NT'
MAKE_FLAGS = "--no-print-directory CC=#{CC} LL=#{LL} AR=#{AR} YACC=#{YACC} CFLAGS=\"#{CFLAGS.join(' ')}\" LDFLAGS=\"#{LDFLAGS.join(' ')}\" LIBS=\"#{LIBS.join(' ')}\" ENABLE_GEMS=\"#{ENABLE_GEMS}\" MRUBY_ROOT=\"#{MRUBY_ROOT}\""
else
MAKE_FLAGS = "--no-print-directory CC='#{CC}' LL='#{LL}' AR='#{AR}' YACC='#{YACC}' CFLAGS='#{CFLAGS.join(' ')}' LDFLAGS='#{LDFLAGS.join(' ')}' LIBS='#{LIBS.join(' ')}' ENABLE_GEMS='#{ENABLE_GEMS}' MRUBY_ROOT='#{MRUBY_ROOT}'"
end
load 'tasks/rules.rake'
load 'src/mruby_core.rake'
load 'mrblib/mrblib.rake'
load 'tools/mrbc/mrbc.rake'
load 'tasks/mrbgems.rake'
load 'tasks/libmruby.rake'
load 'tools/mruby/mruby.rake'
load 'tools/mirb/mirb.rake'
load 'test/mrbtest.rake'
##############################
# internal variables
# generic build targets, rules
task :default => :all
CP = ENV['CP'] ||= 'cp'
RM_F = ENV['RM_F'] ||= 'rm -f'
CAT = ENV['CAT'] ||= 'cat'
binfiles = [exefile('bin/mruby'), exefile('bin/mirb'), exefile('bin/mrbc')]
desc "build all targets, install (locally) in-repo"
task :all => binfiles + MRuby.targets.map { |t| [exefile("#{t.build_dir}/bin/mruby"), exefile("#{t.build_dir}/bin/mirb"), exefile("#{t.build_dir}/bin/mrbc")] }.flatten
##############################
# generic build targets, rules
file exefile('bin/mruby') => exefile('build/host/bin/mruby') do |t|
FileUtils.cp t.prerequisites.first, t.name
end
task :default => :all
file exefile('bin/mirb') => exefile('build/host/bin/mirb') do |t|
FileUtils.cp t.prerequisites.first, t.name
end
desc "build all targets, install (locally) in-repo"
task :all do
sh "#{MAKE} -C src #{MAKE_FLAGS}"
sh "#{MAKE} -C mrblib #{MAKE_FLAGS}"
if ENABLE_GEMS
puts "-- MAKE mrbgems --"
Rake::Task['mrbgems_all'].invoke
end
sh "#{MAKE} -C tools/mruby #{MAKE_FLAGS}"
sh "#{MAKE} -C tools/mirb #{MAKE_FLAGS}"
file exefile('bin/mrbc') => exefile('build/host/bin/mrbc') do |t|
FileUtils.cp t.prerequisites.first, t.name
end
desc "sh all mruby tests"
task :test => [:all] do
sh "#{MAKE} -C test #{MAKE_FLAGS}"
desc "run all mruby tests"
task :test => MRuby.targets.map { |t| exefile("#{t.build_dir}/test/mrbtest") } do
sh "#{filename exefile('build/host/test/mrbtest')}"
if MRuby.targets.count > 1
puts "\nYou should run #{MRuby.targets.map{ |t| t.name == 'host' ? nil : "#{t.build_dir}/test/mrbtest" }.compact.join(', ')} on target device."
end
end
desc "clean all built and in-repo installed artifacts"
task :clean do
sh "#{MAKE} clean -C src #{MAKE_FLAGS}"
sh "#{MAKE} clean -C mrblib #{MAKE_FLAGS}"
if ENABLE_GEMS
puts "-- MAKE mrbgems --"
Rake::Task['mrbgems_clean'].invoke
MRuby.targets.each do |t|
FileUtils.rm_rf t.build_dir
end
sh "#{MAKE} clean -C tools/mruby #{MAKE_FLAGS}"
sh "#{MAKE} clean -C tools/mirb #{MAKE_FLAGS}"
sh "#{MAKE} clean -C test #{MAKE_FLAGS}"
end
desc "show build config summary"
task :showconfig do
puts " CC = #{CC}"
puts " LL = #{LL}"
puts " AR = #{AR}"
puts " YACC = #{YACC}"
puts " MAKE = #{MAKE}"
puts ""
puts " CFLAGS = #{CFLAGS.join(' ')}"
puts " LDFLAGS = #{LDFLAGS.join(' ')}"
puts " LIBS = #{LIBS.join(' ')}"
puts ""
puts " ENABLE_GEMS = #{ENABLE_GEMS}"
FileUtils.rm_f binfiles
end
MRuby::Build.new do |conf|
conf.cc = ENV['CC'] || 'gcc'
conf.ld = ENV['LD'] || 'gcc'
conf.ar = ENV['AR'] || 'ar'
# conf.cxx = conf.cc
# conf.objcc = conf.cc
# conf.asm = conf.cc
# conf.yacc = 'bison'
# conf.gperf = 'gperf'
# conf.cat = 'cat'
# conf.git = 'git'
conf.cflags << (ENV['CFLAGS'] || %w(-g -O3 -Wall -Werror-implicit-function-declaration))
conf.ldflags << (ENV['LDFLAGS'] || %w(-lm))
# conf.cxxflags = []
# conf.objccflags = []
# conf.asmflags = []
# conf.gem 'doc/mrbgems/ruby_extension_example'
# conf.gem 'doc/mrbgems/c_extension_example'
# conf.gem 'doc/mrbgems/c_and_ruby_extension_example'
# conf.gem :git => 'git@github.com:masuidrive/mrbgems-example.git', :branch => 'master'
end
=begin
MRuby::CrossBuild.new('i386') do |conf|
conf.cc = ENV['CC'] || 'gcc'
conf.ld = ENV['LD'] || 'gcc'
conf.ar = ENV['AR'] || 'ar'
# conf.cxx = 'gcc'
# conf.objcc = 'gcc'
# conf.asm = 'gcc'
# conf.yacc = 'bison'
# conf.gperf = 'gperf'
# conf.cat = 'cat'
# conf.git = 'git'
if ENV['OS'] == 'Windows_NT' # MinGW
conf.cflags = %w(-g -O3 -Wall -Werror-implicit-function-declaration -Di386_MARK)
conf.ldflags = %w(-s -static)
else
conf.cflags << %w(-g -O3 -Wall -Werror-implicit-function-declaration -arch i386)
conf.ldflags << %w(-arch i386)
end
# conf.cxxflags << []
# conf.objccflags << []
# conf.asmflags << []
# conf.gem 'doc/mrbgems/ruby_extension_example'
# conf.gem 'doc/mrbgems/c_extension_example'
# conf.gem 'doc/mrbgems/c_and_ruby_extension_example'
end
=end
\ No newline at end of file
# Sample toolchain file for building for Windows from an Arch Linux system.
#
# Typical usage:
# 1) install cross compiler: `sudo pacman -S mingw32-gcc`
# 2) cp cmake/Toolchain-Arch-mingw32.cmake.sample ~/Toolchain-Arch-mingw32.cmake
# 3) tweak toolchain values as needed
# 4) cd build
# 5) cmake -DCMAKE_TOOLCHAIN_FILE=~/Toolchain-Arch-mingw32.cmake ..
# name of the target OS on which the built artifacts will run
# and the toolchain prefix
set(CMAKE_SYSTEM_NAME Windows)
set(TOOLCHAIN_PREFIX i486-mingw32)
# cross compilers to use for C and C++
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)
# target environment on the build host system
# set 1st to dir with the cross compiler's C/C++ headers/libs
# set 2nd to dir containing personal cross development headers/libs
set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX} ~/crossdev/w32)
# modify default behavior of FIND_XXX() commands to
# search for headers/libs in the target environment and
# search for programs in the build host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
#
# Typical usage:
# 0) install cmake version 2.8-9 or higher.
# 1) install a PizzaFactory cross compiler
# a) darwin toolchain targeting sh-elf: http://sourceforge.jp/projects/pf3gnuchains/downloads/50061/sh-pizzafactory-elf.pkg/
# b) install pkg.
# c) export PATH=$PATH:/pizza/bin
# 2) cp cmake/Toolchain-OSX-GenericShElf.cmake.sample ~/Toolchain-OSX-GenericShElf.cmake
# 3) tweak toolchain values as needed
# 4) cd build
# 5) cmake -DCMAKE_TOOLCHAIN_FILE=~/Toolchain-OSX-GenericShElf.cmake ..
# 6) Run mirb on gdb
# a) sh-pizzafactory-elf-gdb tools/mirb/mirb
# b) target sim
# c) load
# d) run
# name of the target OS on which the built artifacts will run
# and the toolchain prefix
set(CMAKE_SYSTEM_NAME Generic)
set(TOOLCHAIN_PREFIX sh-pizzafactory-elf)
# cross compilers to use for C and C++
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
# target environment(s) on the build host system
# set 1st to dir with the cross compiler's C/C++ headers/libs
# set 2nd to dir containing personal cross development headers/libs
set(CMAKE_FIND_ROOT_PATH /pizza/${TOOLCHAIN_PREFIX})
# modify default behavior of FIND_XXX() commands to
# search for headers/libs in the target environment and
# search for programs in the build host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# Sample toolchain file for building for Windows from an OS X system.
#
# Typical usage:
# 1) install a mingw-w64 cross compiler
# a) darwin toolchain targeting win32: http://sourceforge.net/projects/mingw-w64/files/Toolchains targetting Win32/
# b) extract toolchain into ~/mingw/w32
# 2) cp cmake/Toolchain-OSX-mingw32.cmake.sample ~/Toolchain-OSX-mingw32.cmake
# 3) tweak toolchain values as needed
# 4) cd build
# 5) cmake -DCMAKE_TOOLCHAIN_FILE=~/Toolchain-OSX-mingw32.cmake ..
# name of the target OS on which the built artifacts will run
# and the toolchain prefix
set(CMAKE_SYSTEM_NAME Windows)
set(TOOLCHAIN_PREFIX i686-w64-mingw32)
# cross compilers to use for C and C++
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)
# target environment(s) on the build host system
# set 1st to dir with the cross compiler's C/C++ headers/libs
# set 2nd to dir containing personal cross development headers/libs
set(CMAKE_FIND_ROOT_PATH ~/mingw/w32/${TOOLCHAIN_PREFIX} ~/crossdev/w32)
# modify default behavior of FIND_XXX() commands to
# search for headers/libs in the target environment and
# search for programs in the build host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# Toolchain file for building with OpenWRT Toolchain for ANY OpenWRT Target.
# Following prequisition are necessary:
# - latest cmake version
# - mruby OpenWRT Package file (not yet in distribution)
# Switch to Cross Compile by setting the system name
SET(CMAKE_SYSTEM_NAME Linux)
# We show CMAKE the compiler, the rest will be guessed by the Toolchain
SET(CMAKE_C_COMPILER "$ENV{OPENWRT_TOOLCHAIN}/bin/$ENV{OPENWRT_TARGETCC}")
# We define an own release flag so that we can adapt the optimal C_FLAGS
SET(CMAKE_C_FLAGS_OPENWRT "$ENV{OPENWRT_TARGETFLAGS}")
# Sample toolchain file for building for ARM from an Ubuntu Linux system.
#
# Typical usage:
# 1) install cross compiler: `sudo apt-get install gcc-arm-linux-gnueabi`
# 2) cp cmake/Toolchain-Ubuntu-gnueabi.cmake.sample ~/Toolchain-Ubuntu-gnueabi.cmake
# 3) tweak toolchain values as needed
# 4) cd build
# 5) cmake -DCMAKE_TOOLCHAIN_FILE=~/Toolchain-Ubuntu-gnueabi.cmake ..
# name of the target OS on which the built artifacts will run and the
# toolchain prefix. if target is an embedded system without an OS, set
# CMAKE_SYSTEM_NAME to `Generic`
set(CMAKE_SYSTEM_NAME Linux)
set(TOOLCHAIN_PREFIX arm-linux-gnueabi)
# cross compilers to use for C
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
# target environment on the build host system
# set 1st to dir with the cross compiler's C/C++ headers/libs
# set 2nd to dir containing personal cross development headers/libs
set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX} ~/crossdev/eabi)
# modify default behavior of FIND_XXX() commands to
# search for headers/libs in the target environment and
# search for programs in the build host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# Sample toolchain file for building for ARM (w/hw float support) from an Ubuntu Linux system.
#
# Typical usage:
# 1) install cross compiler: `sudo apt-get install gcc-arm-linux-gnueabihf`
# 2) cp cmake/Toolchain-Ubuntu-gnueabihf.cmake.sample ~/Toolchain-Ubuntu-gnueabihf.cmake
# 3) tweak toolchain values as needed
# 4) cd build
# 5) cmake -DCMAKE_TOOLCHAIN_FILE=~/Toolchain-Ubuntu-gnueabihf.cmake ..
# name of the target OS on which the built artifacts will run and the
# toolchain prefix. if target is an embedded system without an OS, set
# CMAKE_SYSTEM_NAME to `Generic`
set(CMAKE_SYSTEM_NAME Linux)
set(TOOLCHAIN_PREFIX arm-linux-gnueabihf)
# cross compilers to use for C
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
# target environment on the build host system
# set 1st to dir with the cross compiler's C/C++ headers/libs
# set 2nd to dir containing personal cross development headers/libs
set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX} ~/crossdev/eabihf)
# modify default behavior of FIND_XXX() commands to
# search for headers/libs in the target environment and
# search for programs in the build host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# Sample toolchain file for building for Windows from an Ubuntu Linux system.
#
# Typical usage:
# 1) install cross compiler: `sudo apt-get install mingw-w64 g++-mingw-w64`
# 2) cp cmake/Toolchain-Ubuntu-mingw32.cmake.sample ~/Toolchain-Ubuntu-mingw32.cmake
# 3) tweak toolchain values as needed
# 4) cd build
# 5) cmake -DCMAKE_TOOLCHAIN_FILE=~/Toolchain-Ubuntu-mingw32.cmake ..
# name of the target OS on which the built artifacts will run
# and the toolchain prefix
set(CMAKE_SYSTEM_NAME Windows)
set(TOOLCHAIN_PREFIX i686-w64-mingw32)
# cross compilers to use for C and C++
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)
# target environment on the build host system
# set 1st to dir with the cross compiler's C/C++ headers/libs
# set 2nd to dir containing personal cross development headers/libs
set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX} ~/crossdev/w32)
# modify default behavior of FIND_XXX() commands to
# search for headers/libs in the target environment and
# search for programs in the build host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# system capabilities checking
# initial system defaults
if(CMAKE_COMPILER_IS_GNUCC)
set(MRUBY_DEFAULT_CFLAGS "-std=gnu99 -Wall -Werror-implicit-function-declaration -Wall -Wextra -Wno-unused-parameter -Wno-sign-compare -Wno-pointer-sign -Wno-missing-field-initializers -Wformat=2 -Wstrict-aliasing=2 -Wdisabled-optimization -Wpointer-arith -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align -Wredundant-decls")
set(CMAKE_C_FLAGS "${MRUBY_DEFAULT_CFLAGS}")
set(CMAKE_C_FLAGS_DEBUG "-O3 -ggdb")
set(CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 -g")
set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG")
set(MRUBY_LIBS m)
else()
if(MSVC)
# TODO default MSVC flags
add_definitions(
-D_CRT_SECURE_NO_WARNINGS
-wd4018 # suppress 'signed/unsigned mismatch'
)
endif()
endif()
add_definitions(-DDISABLE_GEMS)
if(MSVC)
add_definitions(
-DRUBY_EXPORT # required by oniguruma.h
)
endif()
# include helpers
include(CheckIncludeFile)
include(CheckSymbolExists)
# header checks
CHECK_INCLUDE_FILE(string.h HAVE_STRING_H)
if(HAVE_STRING_H)
add_definitions(-DHAVE_STRING_H)
endif()
CHECK_INCLUDE_FILE(float.h HAVE_FLOAT_H)
if(HAVE_FLOAT_H)
add_definitions(-DHAVE_FLOAT_H)
endif()
# symbol checks
CHECK_SYMBOL_EXISTS(gettimeofday sys/time.h HAVE_GETTIMEOFDAY)
if(NOT HAVE_GETTIMEOFDAY)
add_definitions(-DNO_GETTIMEOFDAY)
endif()
# vim: ts=2 sts=2 sw=2 et
# mrbgems
*.tmp
*.ctmp
*.rbtmp
gem_mixlib.c
gem_mrblib.c
gem_srclib.c
*.d
gem_init.c
gem_test.c
GEM := c_and_ruby_extension_example
include $(MAKEFILE_4_GEM)
GEM_C_FILES := $(wildcard $(SRC_DIR)/*.c)
GEM_OBJECTS := $(patsubst %.c, %.o, $(GEM_C_FILES))
GEM_RB_FILES := $(wildcard $(MRB_DIR)/*.rb)
MRUBY_CFLAGS :=
MRUBY_LDFLAGS :=
MRUBY_LIBS :=
gem-all : $(GEM_OBJECTS) gem-c-and-rb-files
gem-clean : gem-clean-c-and-rb-files
gem-test : gem-test-c-and-rb-files
MRuby::Gem::Specification.new('c_and_ruby_extension_example') do |spec|
spec.license = 'MIT'
spec.authors = 'mruby developers'
# spec.cflags = ''
# spec.mruby_cflags = ''
# spec.mruby_ldflags = ''
# spec.mruby_libs = ''
# spec.mruby_includes = ["#{spec.dir}/include"]
# spec.rbfiles = Dir.glob("#{dir}/mrblib/*.rb")
# spec.objs = Dir.glob("#{dir}/src/*.{c,cpp,m,asm,S}").map { |f| f.relative_path_from(dir).pathmap("#{build_dir}/%X.o") }
# spec.test_rbfiles = Dir.glob("#{dir}/test/*.rb")
# spec.test_objs = Dir.glob("#{dir}/test/*.{c,cpp,m,asm,S}").map { |f| f.relative_path_from(dir).pathmap("#{build_dir}/%X.o") }
# spec.test_preload = 'test/assert.rb'
end
class RubyExtension
module CRubyExtension
def CRubyExtension.ruby_method
puts "A Ruby Extension"
end
......
# mrbgems
*.tmp
*.ctmp
*.rbtmp
gem_mixlib.c
gem_mrblib.c
gem_srclib.c
*.d
gem_init.c
gem_test.c
GEM := c_extension_example
include $(MAKEFILE_4_GEM)
GEM_C_FILES := $(wildcard $(SRC_DIR)/*.c)
GEM_OBJECTS := $(patsubst %.c, %.o, $(GEM_C_FILES))
MRUBY_CFLAGS :=
MRUBY_LDFLAGS :=
MRUBY_LIBS :=
gem-all : $(GEM_OBJECTS) gem-c-files
gem-clean : gem-clean-c-files
gem-test : gem-test-c-files
MRuby::Gem::Specification.new('c_extension_example') do |spec|
spec.license = 'MIT'
spec.authors = 'mruby developers'
# spec.cflags = ''
# spec.mruby_cflags = ''
# spec.mruby_ldflags = ''
# spec.mruby_libs = ''
# spec.mruby_includes = ["#{spec.dir}/include"]
# spec.rbfiles = Dir.glob("#{dir}/mrblib/*.rb")
# spec.objs = Dir.glob("#{dir}/src/*.{c,cpp,m,asm,S}").map { |f| f.relative_path_from(dir).pathmap("#{build_dir}/%X.o") }
# spec.test_rbfiles = Dir.glob("#{dir}/test/*.rb")
# spec.test_objs = Dir.glob("#{dir}/test/*.{c,cpp,m,asm,S}").map { |f| f.relative_path_from(dir).pathmap("#{build_dir}/%X.o") }
# spec.test_preload = 'test/assert.rb'
end
/*
if *.c exists in test directory, auto generate this file
*/
#include <mruby.h>
void
mrb_c_extension_example_gem_test_init(mrb_state *mrb)
mrb_c_extension_example_gem_test(mrb_state *mrb)
{
/* test initializer in C */
}
# mrbgems
*.tmp
*.ctmp
*.rbtmp
gem_mixlib.c
gem_mrblib.c
gem_srclib.c
*.d
gem_init.c
gem_test.c
GEM := ruby_extension_example
include $(MAKEFILE_4_GEM)
GEM_RB_FILES := $(wildcard $(MRB_DIR)/*.rb)
MRUBY_CFLAGS :=
MRUBY_LDFLAGS :=
MRUBY_LIBS :=
gem-all : gem-rb-files
gem-clean : gem-clean-rb-files
gem-test : gem-test-rb-files
MRuby::Gem::Specification.new('ruby_extension_example') do |spec|
spec.license = 'MIT'
spec.authors = 'mruby developers'
# spec.cflags = ''
# spec.mruby_cflags = ''
# spec.mruby_ldflags = ''
# spec.mruby_libs = ''
# spec.mruby_includes = ["#{spec.dir}/include"]
# spec.rbfiles = Dir.glob("#{dir}/mrblib/*.rb")
# spec.objs = Dir.glob("#{dir}/src/*.{c,cpp,m,asm,S}").map { |f| f.relative_path_from(dir).pathmap("#{build_dir}/%X.o") }
# spec.test_rbfiles = Dir.glob("#{dir}/test/*.rb")
# spec.test_objs = Dir.glob("#{dir}/test/*.{c,cpp,m,asm,S}").map { |f| f.relative_path_from(dir).pathmap("#{build_dir}/%X.o") }
# spec.test_preload = 'test/assert.rb'
end
......@@ -5,6 +5,54 @@
# License: MIT-LICENSE
require 'getoptlong'
require 'fileutils'
class String
def ext(newext='')
return self.dup if ['.', '..'].include? self
if newext != ''
newext = (newext =~ /^\./) ? newext : ("." + newext)
end
self.chomp(File.extname(self)) << newext
end
def pathmap(spec=nil, &block)
return self if spec.nil?
result = ''
spec.scan(/%\{[^}]*\}-?\d*[sdpfnxX%]|%-?\d+d|%.|[^%]+/) do |frag|
case frag
when '%f'
result << File.basename(self)
when '%n'
result << File.basename(self).ext
when '%d'
result << File.dirname(self)
when '%x'
result << File.extname(self)
when '%X'
result << self.ext
when '%p'
result << self
when '%s'
result << (File::ALT_SEPARATOR || File::SEPARATOR)
when '%-'
# do nothing
when '%%'
result << "%"
when /%(-?\d+)d/
result << pathmap_partial($1.to_i)
when /^%\{([^}]*)\}(\d*[dpfnxX])/
patterns, operator = $1, $2
result << pathmap('%' + operator).pathmap_replace(patterns, &block)
when /^%/
fail ArgumentError, "Unknown pathmap specifier #{frag} in '#{spec}'"
else
result << frag
end
end
result
end
end
module MiniRake
class Task
......@@ -43,7 +91,8 @@ module MiniRake
puts "Invoke #{name} (already=[#{@already_invoked}], needed=[#{needed?}])" if $trace
return if @already_invoked
@already_invoked = true
@prerequisites.each { |n| Task[n].invoke }
prerequisites = @prerequisites.collect{ |n| n.is_a?(Proc) ? n.call(name) : n }.flatten
prerequisites.each { |n| Task[n].invoke }
execute if needed?
end
......@@ -64,7 +113,8 @@ module MiniRake
# Timestamp for this task. Basic tasks return the current time for
# their time stamp. Other tasks can be more sophisticated.
def timestamp
@prerequisites.collect { |p| Task[p].timestamp }.max || Time.now
prerequisites = @prerequisites.collect{ |n| n.is_a?(Proc) ? n.call(name) : n }.flatten
prerequisites.collect { |n| Task[n].timestamp }.max || Time.now
end
# Class Methods ----------------------------------------------------
......@@ -107,15 +157,12 @@ module MiniRake
# added to the existing task.
def define_task(args, &block)
task_name, deps = resolve_args(args)
deps = [deps] if (Symbol === deps) || (String === deps)
deps = deps.collect {|d| d.to_s }
lookup(task_name).enhance(deps, &block)
lookup(task_name).enhance([deps].flatten, &block)
end
# Define a rule for synthesizing tasks.
def create_rule(args, &block)
pattern, deps = resolve_args(args)
fail "Too many dependents specified in rule #{pattern}: #{deps.inspect}" if deps.size > 1
pattern = Regexp.new(Regexp.quote(pattern) + '$') if String === pattern
RULES << [pattern, deps, block]
end
......@@ -136,6 +183,7 @@ module MiniRake
RULES.each do |pattern, extensions, block|
if md = pattern.match(task_name)
ext = extensions.first
deps = extensions[1..-1]
case ext
when String
source = task_name.sub(/\.[^.]*$/, ext)
......@@ -145,7 +193,7 @@ module MiniRake
fail "Don't know how to handle rule dependent: #{ext.inspect}"
end
if File.exist?(source)
task = FileTask.define_task({task_name => [source]}, &block)
task = FileTask.define_task({task_name => [source]+deps}, &block)
task.source = source
return task
end
......@@ -181,7 +229,8 @@ module MiniRake
# stamp is out of date.
def needed?
return true unless File.exist?(name)
latest_prereq = @prerequisites.collect{|n| Task[n].timestamp}.max
prerequisites = @prerequisites.collect{ |n| n.is_a?(Proc) ? n.call(name) : n }.flatten
latest_prereq = prerequisites.collect{|n| Task[n].timestamp}.max
return false if latest_prereq.nil?
timestamp < latest_prereq
end
......@@ -191,27 +240,21 @@ module MiniRake
File.new(name.to_s).mtime
end
end
end
Rake = MiniRake
######################################################################
# Task Definition Functions ...
# Declare a basic task.
def task(args, &block)
module DSL
# Declare a basic task.
def task(args, &block)
MiniRake::Task.define_task(args, &block)
end
end
# Declare a file task.
def file(args, &block)
# Declare a file task.
def file(args, &block)
MiniRake::FileTask.define_task(args, &block)
end
end
# Declare a set of files tasks to create the given directories on
# demand.
def directory(dir)
# Declare a set of files tasks to create the given directories on
# demand.
def directory(dir)
path = []
Sys.split_all(dir).each do |p|
path << p
......@@ -219,28 +262,37 @@ def directory(dir)
Sys.makedirs(t.name)
end
end
end
end
# Declare a rule for auto-tasks.
def rule(args, &block)
# Declare a rule for auto-tasks.
def rule(args, &block)
MiniRake::Task.create_rule(args, &block)
end
end
# Write a message to standard out if $verbose is enabled.
def log(msg)
# Write a message to standard out if $verbose is enabled.
def log(msg)
print " " if $trace && $verbose
puts msg if $verbose
end
end
# Run the system command +cmd+.
def sh(cmd)
log cmd
# Run the system command +cmd+.
def sh(cmd)
puts cmd
system(cmd) or fail "Command Failed: [#{cmd}]"
end
end
def desc(text)
def desc(text)
end
end
end
Rake = MiniRake
include MiniRake::DSL
######################################################################
# Task Definition Functions ...
######################################################################
# Rake main application object. When invoking +rake+ from the command
# line, a RakeApp object is created and run.
......
# This is the default Makefile integrated
# by each Gem. It integrates important constants
# for usage inside of a Gem.
ifeq ($(strip $(MRUBY_ROOT)),)
# mruby src root
MRUBY_ROOT := $(realpath ../../..)
endif
# Tools
CC := gcc
RM := rm -f
AR := ar
# mruby compiler
ifeq ($(OS),Windows_NT)
MRBC = $(MRUBY_ROOT)/bin/mrbc.exe
else
MRBC = $(MRUBY_ROOT)/bin/mrbc
endif
SRC_DIR := src
MRB_DIR := mrblib
TEST_DIR := test
GEM_TEST_RB_FILES := $(wildcard $(TEST_DIR)/*.rb)
GEM_TEST_C_FILES := $(wildcard $(TEST_DIR)/*.c)
# LIBR can be manipulated with command line arguments
ifeq ($(strip $(LIBR)),)
# default mruby library
LIBR := $(MRUBY_ROOT)/lib/libmruby.a
endif
GEM_PACKAGE := mrb-$(GEM)-gem.a
ifeq ($(strip $(ACTIVE_GEMS)),)
# the default file which contains the active GEMs
ACTIVE_GEMS = GEMS.active
endif
MAKEFILE_GEM_LIST := $(MRUBY_ROOT)/mrbgems/g/MakefileGemList
-include $(MAKEFILE_GEM_LIST)
# Default rules which are calling the
# gem specific gem-all and gem-clean
# implementations of a gem
.PHONY : all
all : gem-info gem-all
gem-info:
@echo "Building Gem '$(GEM)'"
# Building target for C and Ruby files
gem-c-and-rb-files : gem_mixlib.o
$(AR) rs $(GEM_PACKAGE) $(GEM_OBJECTS) $^
gem_mixlib.c : gem_mrblib_header.ctmp gem_mrblib_irep.ctmp gem_mixlib_init.ctmp
cat $^ > $@
gem_mixlib_init.ctmp :
ruby $(MRUBY_ROOT)/mrbgems/generate_gem_mixlib.rb '$(GEM)' > $@
# Building target for C files
gem-c-files : gem_srclib.o
$(AR) rs $(GEM_PACKAGE) $(GEM_OBJECTS) $<
gem_srclib.c :
ruby $(MRUBY_ROOT)/mrbgems/generate_gem_srclib.rb '$(GEM)' > $@
# Building target for Ruby Files
gem-rb-files : gem_mrblib.o
$(AR) rs $(GEM_PACKAGE) $<
gem_mrblib.c : gem_mrblib_header.ctmp gem_mrblib_irep.ctmp gem_mrblib_init.ctmp
cat $^ > $@
gem_mrblib_header.ctmp :
ruby $(MRUBY_ROOT)/mrbgems/generate_gem_mrblib_header.rb '$(GEM)' > $@
gem_mrblib_init.ctmp :
ruby $(MRUBY_ROOT)/mrbgems/generate_gem_mrblib.rb '$(GEM)' > $@
gem_mrblib_irep.ctmp : gem_mrblib.rbtmp
$(MRBC) -Bgem_mrblib_irep_$(subst -,_,$(GEM)) -o$@ $<
gem_mrblib.rbtmp :
cat $(GEM_RB_FILES) > $@
gem_test.ctmp : gem_test.rbtmp $(GEM_TEST_C_FILES)
$(MRBC) -Bgem_mrblib_irep_$(subst -,_,$(GEM))_test -o$@ $<
ifeq ($(GEM_TEST_C_FILES),)
echo "void mrb_$(subst -,_,$(GEM))_gem_test_init(mrb_state* mrb) { }" >> $@
else
cat $(GEM_TEST_C_FILES) >> $@
endif
gem_test.rbtmp : $(GEM_TEST_RB_FILES)
ifeq ($(GEM_TEST_RB_FILES),)
echo > $@
else
cat $(GEM_TEST_RB_FILES) > $@
endif
gem-test-c-and-rb-files : gem_test.ctmp
gem-test-c-files : gem_test.ctmp
gem-test-rb-files : gem_test.ctmp
gem-clean-c-and-rb-files :
-$(RM) $(GEM_PACKAGE) gem_mixlib.o gem_mixlib.c gem_mrblib_header.ctmp gem_mrblib_irep.ctmp gem_mixlib_init.ctmp gem_mrblib.rbtmp
-$(RM) gem_srclib.c gem_srclib.o $(GEM_OBJECTS) gem_test.ctmp gem_test.rbtmp gem-cflags.tmp gem-ldflags.tmp gem-libs.tmp
gem-clean-c-files :
-$(RM) $(GEM_PACKAGE) gem_srclib.c gem_srclib.o $(GEM_OBJECTS) gem_test.ctmp gem_test.rbtmp gem-cflags.tmp gem-ldflags.tmp gem-libs.tmp
gem-clean-rb-files :
-$(RM) $(GEM_PACKAGE) gem_mrblib.o gem_mrblib.c gem_mrblib_header.ctmp gem_mrblib_init.ctmp gem_mrblib_irep.ctmp gem_mrblib.rbtmp
-$(RM) gem_test.ctmp gem_test.rbtmp gem-cflags.tmp gem-ldflags.tmp gem-libs.tmp
%.o : %.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) $(GEM_CFLAGS_LIST) $< -o $@
.PHONY : clean
clean : gem-clean
@echo "Gem '$(GEM)' is clean"
.PHONY : gem-flags
gem-flags :
@echo "$(MRUBY_CFLAGS) -I`pwd`/include" > gem-cflags.tmp
@echo "$(MRUBY_LDFLAGS)" > gem-ldflags.tmp
@echo "$(MRUBY_LIBS)" > gem-libs.tmp
MRBGEMS_PATH = File.dirname(__FILE__)
GEM_INIT = "#{MRBGEMS_PATH}/gem_init"
GEM_MAKEFILE = "#{MRBGEMS_PATH}/g/Makefile"
GEM_MAKEFILE_LIST = "#{MRBGEMS_PATH}/g/MakefileGemList"
MAKEFILE_4_GEM = "#{MRUBY_ROOT}/mrbgems/Makefile4gem"
def gem_make_flags
if ENV['OS'] == 'Windows_NT'
"#{MAKE_FLAGS rescue ''} MAKEFILE_4_GEM=\"#{MAKEFILE_4_GEM}\""
else
"#{MAKE_FLAGS rescue ''} MAKEFILE_4_GEM='#{MAKEFILE_4_GEM}'"
end
end
task :mrbgems_all => ["#{GEM_INIT}.a", :mrbgems_generate_gem_makefile_list] do
for_each_gem do |path, gemname|
sh "#{MAKE} -C #{path} #{gem_make_flags}"
end
end
task :load_mrbgems_flags do
for_each_gem do |path, gemname|
sh "#{MAKE} gem-flags -C #{path} #{gem_make_flags}"
CFLAGS << File.read("#{path}/gem-cflags.tmp").chomp
LDFLAGS << File.read("#{path}/gem-ldflags.tmp").chomp
LIBS << File.read("#{path}/gem-libs.tmp").chomp
end
end
task :mrbgems_clean do
if ENV['OS'] == 'Windows_NT'
sh "cd #{MRUBY_ROOT.gsub('/', '\\')}\\mrbgems && #{RM_F} *.c *.d *.a *.o"
sh "cd #{MRUBY_ROOT.gsub('/', '\\')}\\mrbgems\\g && #{RM_F} *.c *.d *.rbtmp *.ctmp *.o mrbtest"
else
sh "cd #{MRUBY_ROOT}/mrbgems && #{RM_F} *.c *.d *.a *.o"
sh "cd #{MRUBY_ROOT}/mrbgems/g && #{RM_F} *.c *.d *.rbtmp *.ctmp *.o mrbtest"
end
for_each_gem do |path, gemname|
sh "#{MAKE} gem-clean -C #{path} #{gem_make_flags}"
end
end
task :mrbgems_prepare_test do
for_each_gem do |path, gemname, escaped_gemname|
sh "#{MAKE} gem-test -C #{path} #{gem_make_flags}"
end
open("#{MRUBY_ROOT}/mrbgems/g/mrbgemtest.ctmp", 'w') do |f|
for_each_gem do |path, gemname, escaped_gemname|
f.puts "void mrb_#{escaped_gemname}_gem_test_init(mrb_state *mrb);"
f.puts "extern const char gem_mrblib_irep_#{escaped_gemname}_test[];"
end
f.puts "void mrbgemtest_init(mrb_state* mrb) {"
for_each_gem do |path, gemname, escaped_gemname|
f.puts "mrb_#{escaped_gemname}_gem_test_init(mrb);"
end
for_each_gem do |path, gemname, escaped_gemname|
f.puts "mrb_load_irep(mrb, gem_mrblib_irep_#{escaped_gemname}_test);"
end
f.puts "}"
end
sh "#{CAT} #{for_each_gem{|path, gemname| "#{path}/gem_test.ctmp "}} >> #{MRUBY_ROOT}/mrbgems/g/mrbgemtest.ctmp"
end
file "#{GEM_INIT}.a" => ["#{GEM_INIT}.c", "#{GEM_INIT}.o"] do |t|
sh "#{AR} rs #{t.name} #{GEM_INIT}.o"
end
rule ".o" => [".c"] do |t|
puts "Build the driver which initializes all gems"
sh "#{CC} #{CFLAGS.join(' ')} -I#{MRUBY_ROOT}/include -MMD -c #{t.source} -o #{t.name}"
end
file "#{GEM_INIT}.c" do |t|
puts "Generate Gem driver: #{t.name}"
open(t.name, 'w') do |f|
f.puts <<__EOF__
/*
* This file contains a list of all
* initializing methods which are
* necessary to bootstrap all gems.
*
* IMPORTANT:
* This file was generated!
* All manual changes will get lost.
*/
#include "mruby.h"
#{for_each_gem{|path, gemname, escaped_gemname| "void GENERATED_TMP_mrb_%s_gem_init(mrb_state*);" % [escaped_gemname]}}
void
mrb_init_mrbgems(mrb_state *mrb) {
#{for_each_gem{|path, gemname, escaped_gemname| " GENERATED_TMP_mrb_%s_gem_init(mrb);" % [escaped_gemname]}}
}
__EOF__
end
end
def for_each_gem(&block)
IO.readlines(ACTIVE_GEMS).map { |line|
path = line.chomp
if not File.exist?(path)
path2 = File.join MRUBY_ROOT, 'mrbgems', 'g', path
path = path2 if File.exist? path2
end
gemname = File.basename(path)
escaped_gemname = gemname.gsub(/-/, '_')
block.call(path, gemname, escaped_gemname)
}.join('')
end
task :mrbgems_generate_gem_makefile_list do
open(GEM_MAKEFILE_LIST, 'w') do |f|
f.puts <<__EOF__
GEM_LIST := #{for_each_gem{|path, gemname| "#{path}/mrb-#{gemname}-gem.a "}}
GEM_ARCHIVE_FILES := #{MRUBY_ROOT}/mrbgems/gem_init.a
GEM_ARCHIVE_FILES += $(GEM_LIST)
GEM_CFLAGS_LIST := #{for_each_gem{|path, gemname| "#{File.read("#{path}/gem-cflags.tmp").chomp} "}}
GEM_LDFLAGS_LIST := #{for_each_gem{|path, gemname| "#{File.read("#{path}/gem-ldflags.tmp").chomp} "}}
GEM_LIBS_LIST := #{for_each_gem{|path, gemname| "#{File.read("#{path}/gem-libs.tmp").chomp} "}}
__EOF__
end
end
#!/usr/bin/env ruby
gemname = ARGV.shift.gsub('-', '_')
puts <<__EOF__
void mrb_#{gemname}_gem_init(mrb_state*);
void
GENERATED_TMP_mrb_#{gemname}_gem_init(mrb_state *mrb)
{
mrb_#{gemname}_gem_init(mrb);
mrb_load_irep(mrb, gem_mrblib_irep_#{gemname});
if (mrb->exc) {
mrb_p(mrb, mrb_obj_value(mrb->exc));
exit(0);
}
}
__EOF__
#!/usr/bin/env ruby
gemname = ARGV.shift.gsub('-', '_')
puts <<__EOF__
void
GENERATED_TMP_mrb_#{gemname}_gem_init(mrb_state *mrb)
{
mrb_load_irep(mrb, gem_mrblib_irep_#{gemname});
if (mrb->exc) {
mrb_p(mrb, mrb_obj_value(mrb->exc));
exit(0);
}
}
__EOF__
#!/usr/bin/env ruby
puts <<__EOF__
/*
* This file is loading the irep
* Ruby GEM code.
*
* IMPORTANT:
* This file was generated!
* All manual changes will get lost.
*/
#include "mruby.h"
#include "mruby/irep.h"
#include "mruby/dump.h"
#include "mruby/string.h"
#include "mruby/proc.h"
__EOF__
\ No newline at end of file
#!/usr/bin/env ruby
gemname = ARGV.shift.gsub('-', '_')
puts <<__EOF__
/*
* This file is loading the irep
* Ruby GEM code.
*
* IMPORTANT:
* This file was generated!
* All manual changes will get lost.
*/
#include "mruby.h"
void mrb_#{gemname}_gem_init(mrb_state*);
void
GENERATED_TMP_mrb_#{gemname}_gem_init(mrb_state *mrb)
{
mrb_#{gemname}_gem_init(mrb);
}
__EOF__
\ No newline at end of file
# transform mruby's standard lib into a C library
file(GLOB MRBLIB_SRC_RB "*.rb")
if(CMAKE_CROSSCOMPILING)
# create native tools and `mrblib.ctmp` required to build `mrblib.c`
include(ExternalProject)
ExternalProject_Add(mruby-native
DOWNLOAD_COMMAND ""
SOURCE_DIR "${CMAKE_SOURCE_DIR}"
CONFIGURE_COMMAND "${CMAKE_COMMAND}" "${CMAKE_SOURCE_DIR}"
INSTALL_COMMAND ""
BINARY_DIR "${CMAKE_BINARY_DIR}/native"
)
# aggregate mruby's standard library as a single C file
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mrblib.c"
DEPENDS mruby-native init_mrblib.c "${CMAKE_BINARY_DIR}/native/mrblib/mrblib.ctmp"
COMMAND "${CMAKE_BINARY_DIR}/native/tools/xpcat/xpcat"
-o "${CMAKE_CURRENT_BINARY_DIR}/mrblib.c"
"${CMAKE_CURRENT_SOURCE_DIR}/init_mrblib.c"
"${CMAKE_BINARY_DIR}/native/mrblib/mrblib.ctmp"
)
else()
# generate a single rb file from all existing ones
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mrblib.rbtmp"
DEPENDS xpcat
COMMAND xpcat -o "${CMAKE_CURRENT_BINARY_DIR}/mrblib.rbtmp" ${MRBLIB_SRC_RB}
)
# mruby compile and generate C byte array representation
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mrblib.ctmp"
DEPENDS mrbc "${CMAKE_CURRENT_BINARY_DIR}/mrblib.rbtmp"
COMMAND mrbc -Bmrblib_irep -o"${CMAKE_CURRENT_BINARY_DIR}/mrblib.ctmp"
"${CMAKE_CURRENT_BINARY_DIR}/mrblib.rbtmp"
)
# aggregate mruby's standard library as a single C file
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mrblib.c"
DEPENDS xpcat init_mrblib.c "${CMAKE_CURRENT_BINARY_DIR}/mrblib.ctmp"
COMMAND xpcat -o "${CMAKE_CURRENT_BINARY_DIR}/mrblib.c"
"${CMAKE_CURRENT_SOURCE_DIR}/init_mrblib.c"
"${CMAKE_CURRENT_BINARY_DIR}/mrblib.ctmp"
)
endif()
# generate final static libmruby archive library
add_library(libmruby_static STATIC
mrblib.c
$<TARGET_OBJECTS:mruby_object>
)
set_target_properties(libmruby_static PROPERTIES OUTPUT_NAME mruby)
install(TARGETS libmruby_static
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
# vim: ts=2 sts=2 sw=2 et
# Makefile description.
# basic build file for mruby library (Ruby part)
# project-specific macros
# extension of the executable-file is modifiable(.exe .out ...)
BASEDIR = .
TARGET := mrblib
MLIB := $(TARGET).o
CLIB := $(TARGET).c
DLIB := $(TARGET).ctmp
RLIB := $(TARGET).rbtmp
DEPLIB := $(TARGET).d
MRB1 := $(BASEDIR)/*.rb
MRBS := $(MRB1)
LIBR0 := ../lib/libmruby_core.a
LIBR := ../lib/libmruby.a
# libraries, includes
INCLUDES = -I../src -I../include
ifeq ($(strip $(COMPILE_MODE)),)
# default compile option
COMPILE_MODE = debug
endif
ifeq ($(COMPILE_MODE),debug)
CFLAGS = -g -O3
else ifeq ($(COMPILE_MODE),release)
CFLAGS = -O3
else ifeq ($(COMPILE_MODE),small)
CFLAGS = -Os
endif
ALL_CFLAGS = -Wall -Werror-implicit-function-declaration $(CFLAGS)
ifeq ($(OS),Windows_NT)
MAKE_FLAGS = CC=$(CC) LL=$(LL) ALL_CFLAGS='$(ALL_CFLAGS)' LDFLAGS='$(LDFLAGS)'
else
MAKE_FLAGS = CC='$(CC)' LL='$(LL)' ALL_CFLAGS='$(ALL_CFLAGS)' LDFLAGS='$(LDFLAGS)'
endif
# mruby compiler
ifeq ($(OS),Windows_NT)
MRBC = ../bin/mrbc.exe
else
MRBC = ../bin/mrbc
endif
##############################
# generic build targets, rules
.PHONY : all
all : $(LIBR)
# update libmruby.a
$(LIBR) : $(MLIB) $(LIBR0)
$(CP) $(LIBR0) $(LIBR)
$(AR) r $(LIBR) $(MLIB)
# Compile mrblib source
$(MLIB) : $(CLIB)
$(CC) $(ALL_CFLAGS) -MMD $(INCLUDES) -c $(CLIB) -o $(MLIB)
# Compile C source from merged mruby source
$(CLIB) : $(RLIB) $(MRBC)
$(MRBC) -Bmrblib_irep -o$(DLIB) $(RLIB); $(CAT) init_$(TARGET).c $(DLIB) > $@
$(MRBC) : $(LIBR0)
$(MAKE) -C ../tools/mrbc $(MAKE_FLAGS)
# merge mruby sources
$(RLIB) : $(MRBS)
$(CAT) $(MRBS) > $@
# clean up
.PHONY : clean
clean :
@echo "make: removing targets, objects and depend files of `pwd`"
-$(RM_F) $(MRBC) $(MLIB) $(CLIB) $(RLIB) $(DLIB) $(DEPLIB) $(LIBR)
dir = File.dirname(__FILE__).sub(%r|^\./|, '')
MRuby.each_target do
self.libmruby << "#{build_dir}/#{dir}/mrblib.o"
file "#{build_dir}/#{dir}/mrblib.o" => "#{build_dir}/#{dir}/mrblib.c"
file "#{build_dir}/#{dir}/mrblib.c" => [mrbcfile] + Dir.glob("#{dir}/*.rb") do |t|
mrbc, *rbfiles = t.prerequisites
FileUtils.mkdir_p File.dirname(t.name)
open(t.name, 'w') do |f|
f.puts File.read("#{dir}/init_mrblib.c")
compile_mruby f, rbfiles, 'mrblib_irep'
end
end
end
# build the core mruby C files
find_package(BISON)
bison_target(mruby parse.y "${CMAKE_CURRENT_BINARY_DIR}/parse.c")
file(GLOB MRUBY_SRC_C "*.c")
list(APPEND MRUBY_SRC_C "${CMAKE_CURRENT_BINARY_DIR}/parse.c")
add_library(mruby_object OBJECT ${MRUBY_SRC_C} ${BISON_mruby_OUTPUTS})
# vim: ts=2 sts=2 sw=2 et
# Makefile description.
# basic build file for mruby library
# project-specific macros
# extension of the executable-file is modifiable(.exe .out ...)
BASEDIR = .
TARGET := ../lib/libmruby_core.a
YSRC := $(BASEDIR)/parse.y
YC := $(BASEDIR)/y.tab.c
KWD := $(BASEDIR)/keywords
LDEF := $(BASEDIR)/lex.def
EXCEPT1 := $(YC) $(BASEDIR)/minimain.c
OBJY := $(patsubst %.c,%.o,$(YC))
OBJ1 := $(patsubst %.c,%.o,$(filter-out $(EXCEPT1),$(wildcard $(BASEDIR)/*.c)))
#OBJ2 := $(patsubst %.c,%.o,$(wildcard $(BASEDIR)/ext/regex/*.c))
#OBJ3 := $(patsubst %.c,%.o,$(wildcard $(BASEDIR)/ext/enc/*.c))
OBJS := $(OBJ1) $(OBJ2) $(OBJ3)
# libraries, includes
INCLUDES = -I$(BASEDIR) -I$(BASEDIR)/../include
ifeq ($(strip $(COMPILE_MODE)),)
# default compile option
COMPILE_MODE = debug
endif
ifeq ($(COMPILE_MODE),debug)
CFLAGS = -g -O3
else ifeq ($(COMPILE_MODE),release)
CFLAGS = -O3
else ifeq ($(COMPILE_MODE),small)
CFLAGS = -Os
endif
ALL_CFLAGS = -Wall -Werror-implicit-function-declaration $(CFLAGS)
##############################
# generic build targets, rules
.PHONY : all
all : $(TARGET)
# executable constructed using linker from object files
$(TARGET) : $(OBJS) $(OBJY)
$(AR) r $@ $(OBJS) $(OBJY)
-include $(OBJS:.o=.d) $(OBJY:.o=.d)
# objects compiled from source
$(OBJS) : %.o : %.c
$(CC) $(ALL_CFLAGS) -MMD $(INCLUDES) -c $< -o $@
# parser compile
$(OBJY) : $(YC) $(LDEF)
$(CC) $(ALL_CFLAGS) -MMD $(INCLUDES) -c $(YC) -o $(OBJY)
# yacc compile
$(YC) : $(YSRC)
$(YACC) -o $(YC) $(YSRC)
$(LDEF) : $(KWD)
gperf -L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k'1,3,$$' $(KWD) > $(LDEF)
# clean up
.PHONY : clean #cleandep
clean :
@echo "make: removing targets, objects and depend files of `pwd`"
-$(RM_F) $(TARGET) $(OBJS) $(OBJY) $(YC)
-$(RM_F) $(OBJS:.o=.d) $(OBJY:.o=.d)
-$(RM_F) $(patsubst %.c,%.o,$(EXCEPT1)) $(patsubst %.c,%.d,$(EXCEPT1))
/* ANSI-C code produced by gperf version 3.0.3 */
/* Command-line: gperf -L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k'1,3,$' ./keywords */
/* ANSI-C code produced by gperf version 3.0.4 */
/* Command-line: gperf -L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k'1,3,$' src/keywords */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
......@@ -28,13 +28,13 @@
#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
#endif
#line 1 "./keywords"
#line 1 "src/keywords"
struct kwtable {const char *name; int id[2]; enum mrb_lex_state_enum state;};
const struct kwtable *mrb_reserved_word(const char *, unsigned int);
static const struct kwtable *reserved_word(const char *, unsigned int);
#define mrb_reserved_word(str, len) reserved_word(str, len)
#line 8 "./keywords"
#line 8 "src/keywords"
struct kwtable;
#define TOTAL_KEYWORDS 40
......@@ -44,12 +44,10 @@ struct kwtable;
#define MAX_HASH_VALUE 50
/* maximum key range = 43, duplicates = 0 */
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) || defined(__GNUC_STDC_INLINE__)
inline
#endif
#elif defined(__GNUC__)
__inline
#endif
static unsigned int
hash (register const char *str, register unsigned int len)
......@@ -100,7 +98,7 @@ hash (register const char *str, register unsigned int len)
#ifdef __GNUC__
__inline
#ifdef __GNUC_STDC_INLINE__
#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
__attribute__ ((__gnu_inline__))
#endif
#endif
......@@ -110,87 +108,87 @@ mrb_reserved_word (register const char *str, register unsigned int len)
static const struct kwtable wordlist[] =
{
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
#line 18 "./keywords"
#line 18 "src/keywords"
{"break", {keyword_break, keyword_break}, EXPR_MID},
#line 23 "./keywords"
#line 23 "src/keywords"
{"else", {keyword_else, keyword_else}, EXPR_BEG},
#line 33 "./keywords"
#line 33 "src/keywords"
{"nil", {keyword_nil, keyword_nil}, EXPR_END},
#line 26 "./keywords"
#line 26 "src/keywords"
{"ensure", {keyword_ensure, keyword_ensure}, EXPR_BEG},
#line 25 "./keywords"
#line 25 "src/keywords"
{"end", {keyword_end, keyword_end}, EXPR_END},
#line 42 "./keywords"
#line 42 "src/keywords"
{"then", {keyword_then, keyword_then}, EXPR_BEG},
#line 34 "./keywords"
#line 34 "src/keywords"
{"not", {keyword_not, keyword_not}, EXPR_ARG},
#line 27 "./keywords"
#line 27 "src/keywords"
{"false", {keyword_false, keyword_false}, EXPR_END},
#line 40 "./keywords"
#line 40 "src/keywords"
{"self", {keyword_self, keyword_self}, EXPR_END},
#line 24 "./keywords"
#line 24 "src/keywords"
{"elsif", {keyword_elsif, keyword_elsif}, EXPR_VALUE},
#line 37 "./keywords"
#line 37 "src/keywords"
{"rescue", {keyword_rescue, modifier_rescue}, EXPR_MID},
#line 43 "./keywords"
#line 43 "src/keywords"
{"true", {keyword_true, keyword_true}, EXPR_END},
#line 46 "./keywords"
#line 46 "src/keywords"
{"until", {keyword_until, modifier_until}, EXPR_VALUE},
#line 45 "./keywords"
#line 45 "src/keywords"
{"unless", {keyword_unless, modifier_unless}, EXPR_VALUE},
#line 39 "./keywords"
#line 39 "src/keywords"
{"return", {keyword_return, keyword_return}, EXPR_MID},
#line 21 "./keywords"
#line 21 "src/keywords"
{"def", {keyword_def, keyword_def}, EXPR_FNAME},
#line 16 "./keywords"
#line 16 "src/keywords"
{"and", {keyword_and, keyword_and}, EXPR_VALUE},
#line 22 "./keywords"
#line 22 "src/keywords"
{"do", {keyword_do, keyword_do}, EXPR_BEG},
#line 49 "./keywords"
#line 49 "src/keywords"
{"yield", {keyword_yield, keyword_yield}, EXPR_ARG},
#line 28 "./keywords"
#line 28 "src/keywords"
{"for", {keyword_for, keyword_for}, EXPR_VALUE},
#line 44 "./keywords"
#line 44 "src/keywords"
{"undef", {keyword_undef, keyword_undef}, EXPR_FNAME},
#line 35 "./keywords"
#line 35 "src/keywords"
{"or", {keyword_or, keyword_or}, EXPR_VALUE},
#line 30 "./keywords"
#line 30 "src/keywords"
{"in", {keyword_in, keyword_in}, EXPR_VALUE},
#line 47 "./keywords"
#line 47 "src/keywords"
{"when", {keyword_when, keyword_when}, EXPR_VALUE},
#line 38 "./keywords"
#line 38 "src/keywords"
{"retry", {keyword_retry, keyword_retry}, EXPR_END},
#line 29 "./keywords"
#line 29 "src/keywords"
{"if", {keyword_if, modifier_if}, EXPR_VALUE},
#line 19 "./keywords"
#line 19 "src/keywords"
{"case", {keyword_case, keyword_case}, EXPR_VALUE},
#line 36 "./keywords"
#line 36 "src/keywords"
{"redo", {keyword_redo, keyword_redo}, EXPR_END},
#line 32 "./keywords"
#line 32 "src/keywords"
{"next", {keyword_next, keyword_next}, EXPR_MID},
#line 41 "./keywords"
#line 41 "src/keywords"
{"super", {keyword_super, keyword_super}, EXPR_ARG},
#line 31 "./keywords"
#line 31 "src/keywords"
{"module", {keyword_module, keyword_module}, EXPR_VALUE},
#line 17 "./keywords"
#line 17 "src/keywords"
{"begin", {keyword_begin, keyword_begin}, EXPR_BEG},
#line 11 "./keywords"
#line 11 "src/keywords"
{"__LINE__", {keyword__LINE__, keyword__LINE__}, EXPR_END},
#line 12 "./keywords"
#line 12 "src/keywords"
{"__FILE__", {keyword__FILE__, keyword__FILE__}, EXPR_END},
#line 10 "./keywords"
#line 10 "src/keywords"
{"__ENCODING__", {keyword__ENCODING__, keyword__ENCODING__}, EXPR_END},
#line 14 "./keywords"
#line 14 "src/keywords"
{"END", {keyword_END, keyword_END}, EXPR_END},
#line 15 "./keywords"
#line 15 "src/keywords"
{"alias", {keyword_alias, keyword_alias}, EXPR_FNAME},
#line 13 "./keywords"
#line 13 "src/keywords"
{"BEGIN", {keyword_BEGIN, keyword_BEGIN}, EXPR_END},
{""},
#line 20 "./keywords"
#line 20 "src/keywords"
{"class", {keyword_class, keyword_class}, EXPR_CLASS},
{""}, {""},
#line 48 "./keywords"
#line 48 "src/keywords"
{"while", {keyword_while, modifier_while}, EXPR_VALUE}
};
......@@ -208,5 +206,5 @@ mrb_reserved_word (register const char *str, register unsigned int len)
}
return 0;
}
#line 50 "./keywords"
#line 50 "src/keywords"
dir = File.dirname(__FILE__).sub(%r|^\./|, '')
MRuby.each_target do
lex_def = "#{dir}/lex.def"
objs = Dir.glob("src/*.{c}").map { |f| f.pathmap("#{build_dir}/%X.o") } + ["#{build_dir}/#{dir}/y.tab.o"]
self.libmruby << objs
file "#{build_dir}/lib/libmruby_core.a" => objs do |t|
archive t.name, 'r', t.prerequisites
end
# Parser
file "#{build_dir}/#{dir}/y.tab.c" => ["#{dir}/parse.y"] do |t|
run_yacc t.name, t.prerequisites.first
end
file "#{build_dir}/#{dir}/y.tab.o" => ["#{build_dir}/#{dir}/y.tab.c", lex_def] do |t|
compile_c t.name, t.prerequisites.first, [], dir
end
# Lexical analyzer
file lex_def => "#{dir}/keywords" do |t|
run_gperf t.name, t.prerequisites.first
end
end
MRuby.each_target do
file "#{build_dir}/lib/libmruby.a" => libmruby.flatten do |t|
archive t.name, 'r', t.prerequisites
end
end
dir = File.dirname(__FILE__).sub(%r|^\./|, '')
MRuby.each_target do
if enable_gems?
self.libmruby << "#{build_dir}/mrbgems/gem_init.o"
file "#{build_dir}/mrbgems/gem_init.o" => "#{build_dir}/mrbgems/gem_init.c"
file "#{build_dir}/mrbgems/gem_init.c" do |t|
FileUtils.mkdir_p "#{build_dir}/mrbgems"
open(t.name, 'w') do |f|
f.puts <<__EOF__
/*
* This file contains a list of all
* initializing methods which are
* necessary to bootstrap all gems.
*
* IMPORTANT:
* This file was generated!
* All manual changes will get lost.
*/
#include "mruby.h"
#{gems.map{|gem| "void GENERATED_TMP_mrb_%s_gem_init(mrb_state* mrb);" % [gem.funcname]}.join("\n")}
void
mrb_init_mrbgems(mrb_state *mrb) {
#{gems.map{|gem| "GENERATED_TMP_mrb_%s_gem_init(mrb);" % [gem.funcname]}.join("\n")}
}
__EOF__
end
end
end
end
module MRuby
class << self
attr_accessor :build
def targets
@targets ||= []
end
def each_target(&block)
@targets.each do |target|
target.instance_eval(&block)
end
end
end
class Build
include Rake::DSL
attr_accessor :name
attr_accessor :cc, :cflags, :includes
attr_accessor :ld, :ldflags, :libs
attr_accessor :ar
attr_writer :cxx, :cxxflags
attr_writer :objcc, :objccflags
attr_writer :asm, :asmflags
attr_accessor :gperf, :yacc
attr_accessor :cat, :git
attr_reader :root, :gems
attr_reader :libmruby
def initialize(&block)
@name ||= 'host'
@root = File.expand_path("#{File.dirname(__FILE__)}/..")
@cc, @cflags, @includes = 'gcc', %W(-DDISABLE_GEMS -MMD), %W(#{@root}/include)
@ldflags, @libs = [], %w(-lm)
@ar = 'ar'
@cxxflags, @objccflags, @asmflags = [], [], []
@yacc, @gperf = 'bison', 'gperf'
@cat, @git = 'cat', 'git'
@gems, @libmruby = [], []
MRuby.targets << self
MRuby.build = self
instance_eval(&block)
end
def cxx; @cxx || cc; end
def cxxflags; @cxxflags.empty? ? cflags : @cxxflags; end
def objcc; @objcc || cc; end
def objccflags; @objccflags.empty? ? cflags : @objccflags; end
def asm; @asm || cc; end
def asmflags; @asmflags.empty? ? cflags : @asmflags; end
def ld; @ld || cc; end
def gem(gemdir)
gemdir = load_external_gem(gemdir) if gemdir.is_a?(Hash)
[@cflags, @cxxflags, @objcflags, @asmflags].each do |f|
f.delete '-DDISABLE_GEMS' if f
end
Gem::processing_path = gemdir
load File.join(gemdir, "mrbgem.rake")
end
def load_external_gem(params)
if params[:git]
url = params[:git]
gemdir = "build/mrbgems/#{url.match(/([-_\w]+)(\.[-_\w]+|)$/).to_a[1]}"
return gemdir if File.exists?(gemdir)
options = []
options << "--branch \"#{params[:branch]}\"" if params[:branch]
run_git_clone gemdir, url, options
gemdir
else
fail "unknown gem option #{params}"
end
end
def enable_gems?
!@gems.empty?
end
def gemlibs
enable_gems? ? ["#{build_dir}/mrbgems/gem_init.o"] + @gems.map{ |g| g.lib } : []
end
def build_dir
#@build_dir ||= "build/#{name}"
"build/#{self.name}"
end
def mrbcfile
@mrbcfile ||= exefile("build/host/bin/mrbc")
end
def compile_c(outfile, infile, flags=[], includes=[])
FileUtils.mkdir_p File.dirname(outfile)
flags = [cflags, gems.map { |g| g.mruby_cflags }, flags]
flags << [self.includes, gems.map { |g| g.mruby_includes }, includes].flatten.map { |f| "-I#{filename f}" }
sh "#{filename cc} #{flags.flatten.join(' ')} -o #{filename outfile} -c #{filename infile}"
end
def compile_cxx(outfile, infile, flags=[], includes=[])
FileUtils.mkdir_p File.dirname(outfile)
flags = [cxxflags, gems.map { |g| g.mruby_cflags }, flags]
flags << [self.includes, gems.map { |g| g.mruby_includes }, includes].flatten.map { |f| "-I#{filename f}" }
sh "#{filename cxx} #{flags.flatten.join(' ')} -o #{filename outfile} -c #{filename infile}"
end
def compile_objc(outfile, infile, flags=[], includes=[])
FileUtils.mkdir_p File.dirname(outfile)
flags = [objcflags, gems.map { |g| g.mruby_cflags }, flags]
flags << [self.includes, gems.map { |g| g.mruby_includes }, includes].flatten.map { |f| "-I#{filename f}" }
sh "#{filename objcc} #{flags.flatten.join(' ')} -o #{filename outfile} -c #{filename infile}"
end
def compile_asm(outfile, infile, flags=[], includes=[])
FileUtils.mkdir_p File.dirname(outfile)
flags = [asmflags, gems.map { |g| g.mruby_cflags }, flags]
flags << [self.includes, gems.map { |g| g.mruby_includes }, includes].flatten.map { |f| "-I#{filename f}" }
sh "#{filename asm} #{flags.flatten.join(' ')} -o #{filename outfile} -c #{filename infile}"
end
def compile_mruby(outfile, infiles, funcname)
cmd = "#{cat} #{filenames [infiles]} | #{filename mrbcfile} -B#{funcname}"
if outfile.is_a?(IO)
IO.popen("#{cmd} -o- -", 'r') do |f|
outfile.puts f.read
end
else
FileUtils.mkdir_p File.dirname(outfile)
sh "#{cmd} -o#{filename outfile} -"
end
end
def link(outfile, objfiles, flags=[], libs=[])
FileUtils.mkdir_p File.dirname(outfile)
flags = [ldflags, flags]
libs = [libs, self.libs]
sh "#{filename ld} -o #{filename outfile} #{flags.join(' ')} #{filenames objfiles} #{libs.flatten.join(' ')}"
end
def archive(outfile, options, objfiles)
FileUtils.mkdir_p File.dirname(outfile)
sh "#{filename ar} #{options} #{filename outfile} #{filenames objfiles}"
end
def run_yacc(outfile, infile)
FileUtils.mkdir_p File.dirname(outfile)
sh "#{filename yacc} -o #{filename outfile} #{filename infile}"
end
def run_gperf(outfile, infile)
FileUtils.mkdir_p File.dirname(outfile)
sh %Q[#{filename gperf} -L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" #{filename infile} > #{filename outfile}]
end
def run_git_clone(gemdir, giturl, options=[])
sh "#{filename git} clone #{options.join(' ')} #{filename giturl} #{filename gemdir}"
end
end # Build
class CrossBuild < Build
def initialize(name, &block)
@name ||= name
super(&block)
end
end # CrossBuild
end # MRuby
require 'pathname'
module MRuby
module Gem
class << self
attr_accessor :processing_path
end
class Specification
include Rake::DSL
attr_reader :build
attr_accessor :name, :dir
def self.attr_array(*vars)
attr_reader *vars
vars.each do |v|
class_eval "def #{v}=(val);@#{v}||=[];@#{v}+=[val].flatten;end"
end
end
attr_array :licenses, :authors
alias :license= :licenses=
alias :author= :authors=
attr_array :cflags
attr_array :mruby_cflags, :mruby_includes, :mruby_ldflags, :mruby_libs
attr_array :rbfiles, :objs
attr_array :test_objs, :test_rbfiles
attr_accessor :test_preload
def initialize(name, &block)
@name = name
@build = MRuby.build
@dir = Gem.processing_path
@cflags = []
@mruby_cflags, @mruby_ldflags, @mruby_libs = [], [], []
@mruby_includes = ["#{dir}/include"]
@rbfiles = Dir.glob("#{dir}/mrblib/*.rb")
@objs = Dir.glob("#{dir}/src/*.{c,cpp,m,asm,S}").map { |f| f.relative_path_from(@dir).to_s.pathmap("#{build_dir}/%X.o") }
@test_rbfiles = Dir.glob("#{dir}/test/*.rb")
@test_objs = Dir.glob("#{dir}/test/*.{c,cpp,m,asm,S}").map { |f| f.relative_path_from(dir).to_s.pathmap("#{build_dir}/%X.o") }
@test_preload = 'test/assert.rb'
instance_eval(&block)
@objs << "#{build_dir}/gem_init.o"
if !name || !licenses || !authors
fail "#{name || dir} required to set name, license(s) and author(s)"
end
build.gems << self
build.libmruby << @objs
define_default_rules
add_tasks
end
def testlib
"#{build_dir}/libmrb-#{name}-gem-test.a"
end
def funcname
@funcname ||= @name.gsub('-', '_')
end
def build_dir
return @build_dir if @build_dir
@build_dir = "#{build.build_dir}/mrbgems/#{name}"
FileUtils.mkdir_p @build_dir
@build_dir
end
def add_tasks
test_rbc = "#{build_dir}/gem_test.c"
test_rbobj = test_rbc.ext('o')
Rake::FileTask.define_task testlib => test_objs + [test_rbobj] do |t|
build.archive t.name, 'rs', t.prerequisites
end
Rake::FileTask.define_task test_rbobj => test_rbc
Rake::FileTask.define_task test_rbc => [build.mrbcfile] + test_rbfiles do |t|
open(t.name, 'w') do |f|
f.puts gem_init_header
build.compile_mruby f, test_rbfiles, "gem_test_irep_#{funcname}" unless test_rbfiles.empty?
end
open(t.name, 'a') do |f|
f.puts "void mrb_#{funcname}_gem_test(mrb_state *mrb);" unless test_objs.empty?
f.puts "void GENERATED_TMP_mrb_#{funcname}_gem_test(mrb_state *mrb) {"
f.puts " mrb_#{funcname}_gem_test(mrb);" unless test_objs.empty?
f.puts <<__EOF__ unless test_rbfiles.empty?
mrb_load_irep(mrb, gem_test_irep_#{funcname});
if (mrb->exc) {
mrb_p(mrb, mrb_obj_value(mrb->exc));
exit(0);
}
__EOF__
f.puts "}"
end
end
Rake::FileTask.define_task "#{build_dir}/gem_init.o" => "#{build_dir}/gem_init.c"
Rake::FileTask.define_task "#{build_dir}/gem_init.c" => [build.mrbcfile] + rbfiles do |t|
generate_gem_init(t.name)
end
end
def define_default_rules
obj_matcher = Regexp.new("^#{build_dir}/(.*)\\.o$")
{
'.c' => proc { |t| build.compile_c t.name, t.prerequisites.first, cflags },
'.cpp' => proc { |t| build.compile_cxx t.name, t.prerequisites.first, cflags },
'.m' => proc { |t| build.compile_objc t.name, t.prerequisites.first, cflags },
'.S' => proc { |t| build.compile_asm t.name, t.prerequisites.first, cflags }
}.each do |ext, compile|
rule obj_matcher => [
proc { |file|
file.sub(obj_matcher, "#{dir}/\\1#{ext}")
},
proc { |file|
get_dependencies(file)
}] do |t|
FileUtils.mkdir_p File.dirname(t.name)
compile.call t
end
rule obj_matcher => [
proc { |file|
file.sub(obj_matcher, "#{build_dir}/\\1#{ext}")
},
proc { |file|
get_dependencies(file)
}] do |t|
FileUtils.mkdir_p File.dirname(t.name)
compile.call t
end
end
end
def generate_gem_init(fname)
open(fname, 'w') do |f|
f.puts gem_init_header
build.compile_mruby f, rbfiles, "gem_mrblib_irep_#{funcname}" unless rbfiles.empty?
f.puts "void mrb_#{funcname}_gem_init(mrb_state *mrb);"
f.puts "void GENERATED_TMP_mrb_#{funcname}_gem_init(mrb_state *mrb) {"
f.puts " mrb_#{funcname}_gem_init(mrb);" unless objs.empty?
f.puts <<__EOF__ unless rbfiles.empty?
mrb_load_irep(mrb, gem_mrblib_irep_#{funcname});
if (mrb->exc) {
mrb_p(mrb, mrb_obj_value(mrb->exc));
exit(0);
}
__EOF__
f.puts "}"
end
end # generate_gem_init
def gem_init_header
<<__EOF__
/*
* This file is loading the irep
* Ruby GEM code.
*
* IMPORTANT:
* This file was generated!
* All manual changes will get lost.
*/
#include "mruby.h"
#include "mruby/irep.h"
#include "mruby/dump.h"
#include "mruby/string.h"
#include "mruby/proc.h"
__EOF__
end # gem_init_header
end # Specification
end # Gem
end # MRuby
\ No newline at end of file
def exefile(filename)
if ENV['OS'] == 'Windows_NT'
"#{filename}.exe"
else
filename
end
end
def filename(name)
if ENV['OS'] == 'Windows_NT'
'"'+name.gsub('/', '\\')+'"'
end
'"'+name+'"'
end
def filenames(names)
[names].flatten.map { |n| filename(n) }.join(' ')
end
class String
def relative_path_from(dir)
Pathname.new(self).relative_path_from(Pathname.new(dir)).to_s
end
end
def get_dependencies(file)
file = file.pathmap('%n.d') unless File.extname(file) == '.d'
if File.exists?(file)
File.read(file).gsub("\\\n ", "").scan(/^\S+:\s+(.+)$/).flatten.map {|s| s.split(' ') }.flatten
else
[]
end
end
MRuby.each_target do |t|
obj_matcher = Regexp.new("^#{build_dir}/(.*)\\.o$")
{
'.c' => proc { |t| compile_c t.name, t.prerequisites.first },
'.cpp' => proc { |t| compile_cxx t.name, t.prerequisites.first },
'.m' => proc { |t| compile_objc t.name, t.prerequisites.first },
'.S' => proc { |t| compile_asm t.name, t.prerequisites.first }
}.each do |ext, compile|
rule obj_matcher => [
proc { |file|
file.sub(obj_matcher, "\\1#{ext}")
},
proc { |file|
get_dependencies(file)
}] do |t|
FileUtils.mkdir_p File.dirname(t.name)
compile.call t
end
rule obj_matcher => [
proc { |file|
file.sub(obj_matcher, "#{build_dir}/\\1#{ext}")
},
proc { |file|
get_dependencies(file)
}] do |t|
FileUtils.mkdir_p File.dirname(t.name)
compile.call t
end
end
end
# build standalone mrbtest runner containing all *.rb tests
if(NOT CMAKE_CROSSCOMPILING)
file(GLOB MRBTEST_SRC_RB "assert.rb" "t/*.rb")
# generate a single rb file from all existing test *.rb
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mrbtest.rbtmp"
DEPENDS xpcat
COMMAND xpcat -o "${CMAKE_CURRENT_BINARY_DIR}/mrbtest.rbtmp" ${MRBTEST_SRC_RB}
)
# mruby compile and generate C byte array representation
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mrbtest.ctmp"
DEPENDS mrbc "${CMAKE_CURRENT_BINARY_DIR}/mrbtest.rbtmp"
COMMAND mrbc -Bmrbtest_irep -o"${CMAKE_CURRENT_BINARY_DIR}/mrbtest.ctmp"
"${CMAKE_CURRENT_BINARY_DIR}/mrbtest.rbtmp"
)
# aggregate mruby's *.rb test files as a single C file
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mrbtest.c"
DEPENDS xpcat init_mrbtest.c "${CMAKE_CURRENT_BINARY_DIR}/mrbtest.ctmp"
COMMAND xpcat -o "${CMAKE_CURRENT_BINARY_DIR}/mrbtest.c"
"${CMAKE_CURRENT_SOURCE_DIR}/init_mrbtest.c"
"${CMAKE_CURRENT_BINARY_DIR}/mrbtest.ctmp"
)
add_executable(mrbtest
EXCLUDE_FROM_ALL
"${CMAKE_CURRENT_SOURCE_DIR}/driver.c"
"${CMAKE_CURRENT_BINARY_DIR}/mrbtest.c"
)
target_link_libraries(mrbtest libmruby_static ${MRUBY_LIBS})
add_custom_target(test
DEPENDS mrbtest
COMMAND "${CMAKE_CURRENT_BINARY_DIR}/mrbtest"
)
endif()
# vim: ts=2 sts=2 sw=2 et
# Makefile description.
# basic build file for the mruby testing environment mrbtest
# project-specific macros
# extension of the executable-file is modifiable(.exe .out ...)
MRUBY_ROOT := ..
BASEDIR = .
TARGET := mrbtest
LIBR := ../lib/libmruby.a
ifeq ($(strip $(ENABLE_GEMS)),)
# by default GEMs are deactivated
ENABLE_GEMS = false
endif
ifeq ($(ENABLE_GEMS),false)
GEM_ARCHIVE_FILES =
else
GEMDIR := ../mrbgems
GEMDLIB := $(GEMDIR)/g/mrbgemtest.ctmp
MAKEFILE_GEM_LIST := $(MRUBY_ROOT)/mrbgems/g/MakefileGemList
ifeq ($(wildcard $(MAKEFILE_GEM_LIST)),)
GEM_ARCHIVE_FILES =
else
include $(MAKEFILE_GEM_LIST)
endif
endif
MLIB := $(TARGET).o
CLIB := $(TARGET).c
INIT := init_$(TARGET).c
DLIB := $(TARGET).ctmp
RLIB := $(TARGET).rbtmp
DEPLIB := $(TARGET).d driver.d
ASSLIB := $(BASEDIR)/assert.rb
MRBS := $(BASEDIR)/t/*.rb
OBJS := driver.o $(MLIB)
# for mruby/mrbc test
REPLIB := $(BASEDIR)/report.rb
TESTRB := mrubytest.rb
TESTMRB := mrubytest.mrb
TESTRB_REP := mrubytest.rb.report
TESTMRB_REP := mrubytest.mrb.report
# libraries, includes
LIBS = -lm
INCLUDES = -I$(BASEDIR)/../src -I$(BASEDIR)/../include
ifeq ($(strip $(COMPILE_MODE)),)
# default compile option
COMPILE_MODE = debug
endif
ALL_CFLAGS = -Wall -Werror-implicit-function-declaration $(CFLAGS)
ifeq ($(OS),Windows_NT)
MAKE_FLAGS = CC=$(CC) LL=$(LL) ALL_CFLAGS='$(ALL_CFLAGS)' LDFLAGS='$(LDFLAGS)'
else
MAKE_FLAGS = CC='$(CC)' LL='$(LL)' ALL_CFLAGS='$(ALL_CFLAGS)' LDFLAGS='$(LDFLAGS)'
endif
# mruby compiler and test driver
ifeq ($(OS),Windows_NT)
MRBC = ../bin/mrbc.exe
MRUBY= ../bin/mruby.exe
EXE := $(TARGET).exe
else
MRBC = ../bin/mrbc
MRUBY= ../bin/mruby
EXE := $(TARGET)
endif
RAKE = ../minirake
##############################
# generic build targets, rules
.PHONY : test
all : $(EXE) $(MRUBY) $(TESTRB) $(TESTMRB)
@echo "# exec mrbtest"
./$(EXE)
@echo
@echo "# exec mruby test with ruby script"
@($(MRUBY) $(TESTRB) > $(TESTRB_REP) && echo "mrubytest.rb success.") || $(CAT) $(TESTRB_REP)
@echo
@echo "# exec mruby test with mrb file"
@($(MRUBY) -b $(TESTMRB) > $(TESTMRB_REP) && echo "mrubytest.mrb success.") || $(CAT) $(TESTMRB_REP)
@echo
# executable constructed using linker from object files
$(EXE) : generate-mrbgems-test $(OBJS) $(LIBR) $(GEM_ARCHIVE_FILES)
$(LL) -o $@ $(LDFLAGS) $(OBJS) $(LIBR) $(GEM_ARCHIVE_FILES) $(LIBS)
generate-mrbgems-test :
ifeq ($(ENABLE_GEMS),true)
@$(RAKE) mrbgems_prepare_test
endif
-include $(OBJS:.o=.d)
# objects compiled from source
$(OBJS) : %.o : %.c
$(CC) $(ALL_CFLAGS) -MMD $(INCLUDES) -c $< -o $@
# Compile C source from merged mruby source
$(CLIB) : $(DLIB) $(INIT) $(GEMDLIB)
$(CAT) $(INIT) $(DLIB) $(GEMDLIB) > $@
$(DLIB) : $(RLIB) $(MRBC)
$(MRBC) -Bmrbtest_irep -o$@ $(RLIB)
# merge mruby sources
$(RLIB) : $(ASSLIB) $(MRBS)
$(CAT) $(ASSLIB) $(MRBS) > $@
# Compile mrb file from mruby source
$(TESTMRB) : $(MRBC) $(TESTRB)
$(MRBC) $(TESTRB)
$(TESTRB) : $(ASSLIB) $(MRBS) $(REPLIB)
$(CAT) $(ASSLIB) $(MRBS) $(REPLIB) > $@
# clean up
.PHONY : clean
clean :
@echo "make: removing targets, objects and depend files of `pwd`"
-$(RM_F) $(MLIB) $(CLIB) $(RLIB) $(DLIB) $(DEPLIB) $(OBJS) $(EXE)
-$(RM_F) $(TESTRB) $(TESTMRB) $(TESTRB_REP) $(TESTMRB_REP)
dir = File.dirname(__FILE__).sub(%r|^\./|, '')
MRuby.each_target do
exec = exefile("#{build_dir}/#{dir}/mrbtest")
clib = "#{build_dir}/#{dir}/mrbtest.c"
mlib = clib.ext('o')
mrbs = Dir.glob("#{dir}/t/*.rb")
init = "#{dir}/init_mrbtest.c"
asslib = "#{dir}/assert.rb"
objs = ["#{build_dir}/#{dir}/driver.o", mlib]
file exec => objs + gems.map{ |g| g.testlib } + ["#{build_dir}/lib/libmruby.a"] do |t|
link t.name, t.prerequisites, [], gems.map { |g| g.mruby_libs }
end
file mlib => [clib]
file clib => [exefile("#{build_dir}/bin/mrbc"), init, asslib] + mrbs do |t|
open(clib, 'w') do |f|
f.puts File.read(init)
compile_mruby f, [asslib] + mrbs, 'mrbtest_irep'
gems.each do |g|
f.puts "void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb);"
end
f.puts "void mrbgemtest_init(mrb_state* mrb) {"
gems.each do |g|
f.puts " GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb);"
end
f.puts "}"
end
end
end
\ No newline at end of file
# specify the internal and external tools to be built
add_subdirectory(xpcat)
add_subdirectory(mrbc)
add_subdirectory(mruby)
add_subdirectory(mirb)
# vim: ts=2 sts=2 sw=2 et
# build tools/mirb executable
file(GLOB MIRBBIN_SRC_C "*.c")
add_executable(mirb ${MIRBBIN_SRC_C})
target_link_libraries(mirb libmruby_static ${MRUBY_LIBS})
install(TARGETS mirb RUNTIME DESTINATION bin)
# vim: ts=2 sts=2 sw=2 et
# Makefile description.
# basic build file for mirb executable
# project-specific macros
# extension of the executable-file is modifiable(.exe .out ...)
MRUBY_ROOT := ../..
BASEDIR = ../../src
TARGET := ../../bin/mirb
LIBR := ../../lib/libmruby.a
ifeq ($(strip $(ENABLE_GEMS)),)
# by default GEMs are deactivated
ENABLE_GEMS = false
endif
ifeq ($(ENABLE_GEMS),false)
GEM_ARCHIVE_FILES =
else
MAKEFILE_GEM_LIST := $(MRUBY_ROOT)/mrbgems/g/MakefileGemList
ifeq ($(wildcard $(MAKEFILE_GEM_LIST)),)
GEM_ARCHIVE_FILES =
else
include $(MAKEFILE_GEM_LIST)
endif
endif
ifeq ($(OS),Windows_NT)
EXE := $(TARGET).exe
else
EXE := $(TARGET)
endif
OBJ0 := $(patsubst %.c,%.o,$(wildcard $(BASEDIR)/../tools/mirb/*.c))
OBJS := $(OBJ0)
# ext libraries
EXTS := $(EXT1)
# libraries, includes
LIBS = -lm
INCLUDES = -I$(BASEDIR) -I$(BASEDIR)/../include
ifeq ($(strip $(COMPILE_MODE)),)
# default compile option
COMPILE_MODE = debug
endif
ifeq ($(COMPILE_MODE),debug)
CFLAGS = -g -O3
else ifeq ($(COMPILE_MODE),release)
CFLAGS = -O3
else ifeq ($(COMPILE_MODE),small)
CFLAGS = -Os
endif
ALL_CFLAGS = -Wall -Werror-implicit-function-declaration $(CFLAGS)
ifeq ($(OS),Windows_NT)
MAKE_FLAGS = CC=$(CC) LL=$(LL) ALL_CFLAGS='$(ALL_CFLAGS)' LDFLAGS='$(LDFLAGS)'
else
MAKE_FLAGS = CC='$(CC)' LL='$(LL)' ALL_CFLAGS='$(ALL_CFLAGS)' LDFLAGS='$(LDFLAGS)'
endif
##############################
# generic build targets, rules
.PHONY : all
all : $(LIBR) $(EXE)
# executable constructed using linker from object files
$(EXE) : $(LIBR) $(OBJS) $(GEM_ARCHIVE_FILES) $(EXTS)
$(LL) -o $@ $(LDFLAGS) $(OBJS) $(LIBR) $(GEM_ARCHIVE_FILES) $(EXTS) $(LIBS)
-include $(OBJS:.o=.d)
# objects compiled from source
$(OBJS) : %.o : %.c
$(CC) $(ALL_CFLAGS) -MMD $(INCLUDES) -c $< -o $@
# C library compile
$(LIBR) :
@$(MAKE) -C $(BASEDIR) $(MAKE_FLAGS)
# mruby library compile
# extend libraries complile
$(EXTS) : %.o : %.c
$(CC) $(ALL_CFLAGS) -MMD $(INCLUDES) -c $< -o $@
# clean up
.PHONY : clean #cleandep
clean :
$(MAKE) clean -C ../../mrblib $(MAKE_FLAGS)
$(MAKE) clean -C ../mrbc $(MAKE_FLAGS)
@echo "make: removing targets, objects and depend files of `pwd`"
-$(RM_F) $(EXE) $(OBJS)
-$(RM_F) $(OBJS:.o=.d)
dir = File.dirname(__FILE__).sub(%r|^\./|, '')
MRuby.each_target do
exec = exefile("#{build_dir}/bin/mirb")
objs = Dir.glob("#{dir}/*.{c}").map { |f| f.pathmap("#{build_dir}/%X.o") }
file exec => objs + ["#{build_dir}/lib/libmruby.a"] do |t|
link t.name, t.prerequisites, [], gems.map { |g| g.mruby_libs }
end
end
\ No newline at end of file
# build tools/mrbc executable
file(GLOB MRBC_SRC_C "*.c")
add_executable(mrbc ${MRBC_SRC_C} $<TARGET_OBJECTS:mruby_object>)
target_link_libraries(mrbc ${MRUBY_LIBS})
install(TARGETS mrbc RUNTIME DESTINATION bin)
# vim: ts=2 sts=2 sw=2 et
# Makefile description.
# basic build file for mruby-compiler
# project-specific macros
# extension of the executable-file is modifiable(.exe .out ...)
BASEDIR := ../../src
TARGET := ../../bin/mrbc
LIBR := ../../lib/libmruby_core.a
ifeq ($(OS),Windows_NT)
EXE := $(TARGET).exe
else
EXE := $(TARGET)
endif
EXCEPT1 :=
OBJ0 := $(patsubst %.c,%.o,$(wildcard $(BASEDIR)/../tools/mrbc/*.c))
#OBJ1 := $(patsubst %.c,%.o,$(filter-out $(EXCEPT1),$(wildcard $(BASEDIR)/*.c)))
#OBJ2 := $(patsubst %.c,%.o,$(wildcard $(BASEDIR)/ext/regex/*.c))
#OBJ3 := $(patsubst %.c,%.o,$(wildcard $(BASEDIR)/ext/enc/*.c))
OBJS := $(OBJ0)
# libraries, includes
LIBS = -lm
INCLUDES = -I$(BASEDIR) -I$(BASEDIR)/../include
# compiler, linker (gcc)
ifeq ($(strip $(COMPILE_MODE)),)
# default compile option
COMPILE_MODE = debug
endif
ifeq ($(COMPILE_MODE),debug)
CFLAGS = -g -O3
else ifeq ($(COMPILE_MODE),release)
CFLAGS = -O3
else ifeq ($(COMPILE_MODE),small)
CFLAGS = -Os
endif
ALL_CFLAGS = -Wall -Werror-implicit-function-declaration $(CFLAGS)
ifeq ($(OS),Windows_NT)
MAKE_FLAGS = CC=$(CC) LL=$(LL) ALL_CFLAGS="$(ALL_CFLAGS)"
else
MAKE_FLAGS = CC='$(CC)' LL='$(LL)' ALL_CFLAGS='$(ALL_CFLAGS)'
endif
##############################
# generic build targets, rules
.PHONY : all
all : $(EXE)
# executable constructed using linker from object files
$(EXE) : $(OBJS) $(LIBR)
$(LL) -o $@ $(LDFLAGS) $(OBJS) $(LIBR) $(LIBS)
-include $(OBJS:.o=.d)
# objects compiled from source
$(OBJS) : %.o : %.c
$(CC) $(ALL_CFLAGS) -MMD $(INCLUDES) -c $< -o $@
# C library compile
$(LIBR) :
@$(MAKE) -C $(BASEDIR) $(MAKE_FLAGS)
# clean up
.PHONY : clean
clean :
@echo "make: removing targets, objects and depend files of `pwd`"
-$(RM_F) $(EXE) $(OBJS)
-$(RM_F) $(OBJS:.o=.d)
dir = File.dirname(__FILE__).sub(%r|^\./|, '')
MRuby.each_target do
exec = exefile("#{build_dir}/bin/mrbc")
objs = Dir.glob("#{dir}/*.{c}").map { |f| f.pathmap("#{build_dir}/%X.o") }
file exec => objs + ["#{build_dir}/lib/libmruby_core.a"] do |t|
link t.name, t.prerequisites, [], gems.map { |g| g.mruby_libs }
end
end
\ No newline at end of file
# build tools/mruby executable
file(GLOB MRUBYBIN_SRC_C "*.c")
add_executable(mruby ${MRUBYBIN_SRC_C})
target_link_libraries(mruby libmruby_static ${MRUBY_LIBS})
install(TARGETS mruby RUNTIME DESTINATION bin)
# vim: ts=2 sts=2 sw=2 et
# Makefile description.
# basic build file for mruby executable
# project-specific macros
# extension of the executable-file is modifiable(.exe .out ...)
MRUBY_ROOT := ../..
BASEDIR = $(MRUBY_ROOT)/src
TARGET := $(MRUBY_ROOT)/bin/mruby
LIBR := $(MRUBY_ROOT)/lib/libmruby.a
ifeq ($(strip $(ENABLE_GEMS)),)
# by default GEMs are deactivated
ENABLE_GEMS = false
endif
ifeq ($(ENABLE_GEMS),false)
GEM_ARCHIVE_FILES =
else
MAKEFILE_GEM_LIST := $(MRUBY_ROOT)/mrbgems/g/MakefileGemList
ifeq ($(wildcard $(MAKEFILE_GEM_LIST)),)
GEM_ARCHIVE_FILES =
else
include $(MAKEFILE_GEM_LIST)
endif
endif
ifeq ($(OS),Windows_NT)
EXE := $(TARGET).exe
else
EXE := $(TARGET)
endif
OBJ0 := $(patsubst %.c,%.o,$(wildcard $(BASEDIR)/../tools/mruby/*.c))
#OBJ1 := $(patsubst %.c,%.o,$(filter-out $(EXCEPT1),$(wildcard $(BASEDIR)/*.c)))
#OBJ2 := $(patsubst %.c,%.o,$(wildcard $(BASEDIR)/ext/regex/*.c))
#OBJ3 := $(patsubst %.c,%.o,$(wildcard $(BASEDIR)/ext/enc/*.c))
OBJS := $(OBJ0)
# ext libraries
#EXT1 := $(patsubst %.c,%.o,$(wildcard $(BASEDIR)/../ext/socket/*.c))
EXTS := $(EXT1)
# libraries, includes
LIBS = -lm
INCLUDES = -I$(BASEDIR) -I$(BASEDIR)/../include
# compiler, linker (gcc)
ifeq ($(strip $(COMPILE_MODE)),)
# default compile option
COMPILE_MODE = debug
endif
ifeq ($(COMPILE_MODE),debug)
CFLAGS = -g -O3
else ifeq ($(COMPILE_MODE),release)
CFLAGS = -O3
else ifeq ($(COMPILE_MODE),small)
CFLAGS = -Os
endif
ALL_CFLAGS = -Wall -Werror-implicit-function-declaration $(CFLAGS)
ifeq ($(OS),Windows_NT)
MAKE_FLAGS = CC=$(CC) LL=$(LL) ALL_CFLAGS='$(ALL_CFLAGS)' LDFLAGS='$(LDFLAGS)'
else
MAKE_FLAGS = CC='$(CC)' LL='$(LL)' ALL_CFLAGS='$(ALL_CFLAGS)' LDFLAGS='$(LDFLAGS)'
endif
##############################
# generic build targets, rules
.PHONY : all
all : $(LIBR) $(EXE)
# executable constructed using linker from object files
$(EXE) : $(LIBR) $(OBJS) $(GEM_ARCHIVE_FILES) $(EXTS)
$(LL) -o $@ $(LDFLAGS) $(OBJS) $(LIBR) $(GEM_ARCHIVE_FILES) $(EXTS) $(LIBS)
-include $(OBJS:.o=.d)
# objects compiled from source
$(OBJS) : %.o : %.c
$(CC) $(ALL_CFLAGS) -MMD $(INCLUDES) -c $< -o $@
# C library compile
$(LIBR) :
@$(MAKE) -C $(BASEDIR) $(MAKE_FLAGS)
# mruby library compile
# extend libraries complile
$(EXTS) : %.o : %.c
$(CC) $(ALL_CFLAGS) -MMD $(INCLUDES) -c $< -o $@
# clean up
.PHONY : clean #cleandep
clean :
$(MAKE) clean -C ../../mrblib $(MAKE_FLAGS)
$(MAKE) clean -C ../mrbc $(MAKE_FLAGS)
@echo "make: removing targets, objects and depend files of `pwd`"
-$(RM_F) $(EXE) $(OBJS)
-$(RM_F) $(OBJS:.o=.d)
dir = File.dirname(__FILE__).sub(%r|^\./|, '')
MRuby.each_target do
exec = exefile("#{build_dir}/bin/mruby")
objs = Dir.glob("#{dir}/*.{c}").map { |f| f.pathmap("#{build_dir}/%X.o") }
file exec => objs + ["#{build_dir}/lib/libmruby.a"] do |t|
link t.name, t.prerequisites, [], gems.map { |g| g.mruby_libs }
end
end
\ No newline at end of file
# build tools/xpcat internal executable
add_executable(xpcat xpcat.c)
# vim: ts=2 sts=2 sw=2 et
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void
usage(const char *program)
{
printf("Usage: %s -o outputfile FILE...\n", program);
}
int
main(int argc, char *argv[])
{
int i, ch;
const char *output = NULL;
FILE *infile = NULL;
FILE *outfile = NULL;
if (argc < 4) {
usage(argv[0]);
return EXIT_FAILURE;
}
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-o") == 0) {
i++;
if (i < argc)
output = argv[i];
else {
usage(argv[0]);
return EXIT_FAILURE;
}
}
}
if (output) {
outfile = fopen(output, "wb");
if (!outfile) {
fprintf(stderr, "[ERROR] unable to open output file: %s\n", output);
return EXIT_FAILURE;
}
setbuf(outfile, NULL);
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-o") == 0) {
i++;
continue;
}
infile = fopen(argv[i], "rb");
if (!infile) {
fprintf(stderr, "[ERROR] unable to open input file: %s\n", argv[i]);
return EXIT_FAILURE;
}
setbuf(infile, NULL);
while ((ch = getc(infile)) != EOF) {
if (putc(ch, outfile) == EOF) {
fprintf(stderr, "[ERROR] error writing output file: %s\n", output);
return EXIT_FAILURE;
}
}
fclose(infile);
}
}
fclose(outfile);
return EXIT_SUCCESS;
}
/* vim: set ts=2 sts=2 sw=2 et: */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment