Commit 9f89da6e authored by Jon's avatar Jon

Add native and cross compiling CMake build support

parent b5dcb712
...@@ -19,6 +19,7 @@ cscope.out ...@@ -19,6 +19,7 @@ cscope.out
/bin /bin
/mrblib/mrblib.c /mrblib/mrblib.c
/mrblib/*.*tmp /mrblib/*.*tmp
/build
/test/mrbtest /test/mrbtest
/test/mrbtest.c /test/mrbtest.c
/test/*.*tmp /test/*.*tmp
...@@ -4,3 +4,4 @@ Original Authors "mruby developers" are: ...@@ -4,3 +4,4 @@ Original Authors "mruby developers" are:
Kyushu Institute of Technology Kyushu Institute of Technology
Network Applied Communication Laboratory, Inc. Network Applied Communication Laboratory, Inc.
Daniel Bovensiepen Daniel Bovensiepen
Jon Maken
# # CMake build system for mruby
# Cmake build system for muby by beoran@rubyforhe.org, 2012. # License: released under the same license as mruby
# Released under the same license as mruby. # Author: jonforums@gmail.com
# # Author: beoran@gmail.com
# NOTE: the original Makefile build system had a few hacks in them,
# whch I didn't duplicate. In stead the build logic is like this:
# 1) First libritevm_object is built
# 2) From this libritevm_static.a is built.
# 2) Then mrbc is built and linked with libritevm_static.a .
# 4) Then libmrblib_object is builtfrom are built from the rb files in
# the mrblib subdirectory
# 5) Then libmrblib_object & libritevm_object are linked together into
# a single library libmrubylib_static.a
# 6) Finally, mruby is built and linked with libmrubylib_static.a
#
# As a result, applications that embed mruby will have to link against
# libmrubylib_static.a only..
#
# TODO: make this work on windows too, support build options to generate
# mrbconf.h, etc...
# #
# 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`
# Setup
# Need at least cmake version 2.8.8
cmake_minimum_required(VERSION 2.8.8 FATAL_ERROR) 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 a MSVC IDE where it's OK.
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT MSVC_IDE)
message(FATAL_ERROR
"\nIn-source builds are not allowed as CMake would overwrite the "
"Makefiles distributed with mruby. Please change to the 'build' "
"subdirectory and run CMake from there.")
endif()
if(COMMAND cmake_policy) if(COMMAND cmake_policy)
cmake_policy(SET CMP0003 NEW) cmake_policy(SET CMP0003 NEW) # don't split absolute link paths
cmake_policy(SET CMP0015 NEW) cmake_policy(SET CMP0012 NEW) # recognize number & boolean literals
cmake_policy(SET CMP0015 NEW) # convert relative link paths to absolute
endif(COMMAND cmake_policy) endif(COMMAND cmake_policy)
# Set the project name, we use only plain C. # Match original Makefile's default in-tree install.
project(MRUBY C) if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR} CACHE PATH
# C compiler flags. "Install path prefix prepended to install directories."
set(CMAKE_C_FLAGS "-Wall -g") FORCE
# should use -O3 if it's a release build.bin/mrb )
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. # Version of mruby, useful for versoning .so and .dll files.
set(MRUBY_VERSION 1.0.0) # 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(REGEX MATCH "^[0-9]+[.][0-9]+" MRUBY_SOVERSION ${MRUBY_VERSION})
string(REPLACE "." "" MRUBY_DLL_SHORTVER ${MRUBY_SOVERSION}) string(REPLACE "." "" MRUBY_DLL_SHORTVER ${MRUBY_SOVERSION})
# Search in the `cmake' directory for additional CMake modules if needed. # Search in the `cmake` directory for custom CMake helper modules.
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules")
include(IntrospectSystem)
# Search for C header files in these directories. # Search for C header files in these directories.
include_directories(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/src) include_directories("${CMAKE_SOURCE_DIR}/include" "${CMAKE_SOURCE_DIR}/src")
# Search for libaries too link tools with here:
link_directories("lib")
link_directories("mrblib")
# put binaries that get built in bin
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
# Put libraries that get built into `lib'.
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)
if(NOT IPHONE)
option(SHARED "Build shared libraries" on)
set(BUILD_SHARED_LIBS ${SHARED}) # actual CMake variable
endif(NOT IPHONE)
# TODO re-enable (and implement) if needed
# On some 64-bit platforms, libraries should be installed into `lib64' # On some 64-bit platforms, libraries should be installed into `lib64'
# instead of `lib'. Set this to 64 to do that. # instead of `lib'. Set this to 64 to do that.
set(LIB_SUFFIX "" CACHE STRING "Suffix for 'lib' directories, e.g. '64'") #set(LIB_SUFFIX "" CACHE STRING "Suffix for 'lib' directories, e.g. '64'")
set(FRAMEWORK_INSTALL_PREFIX "/Library/Frameworks" CACHE STRING # build the components
"Directory in which to install Mac OS X frameworks") add_subdirectory(src)
add_subdirectory(mrblib)
# Options (none yet). add_subdirectory(tools)
add_subdirectory(test)
# Set up compilers.
# install the header files
include(CheckCSourceCompiles) install(FILES include/mruby.h DESTINATION include)
install(FILES include/mrbconf.h DESTINATION include)
# Begin tests install(DIRECTORY include/mruby DESTINATION include FILES_MATCHING PATTERN "*.h")
include(CheckFunctionExists) # TODO refactor once proper versioning scheme implemented
include(CheckIncludeFiles) # archive packaging
include(CheckLibraryExists) set(CPACK_GENERATOR "TGZ;ZIP")
include(CheckSymbolExists) string(TOLOWER ${CMAKE_SYSTEM_NAME} MRUBY_HOST)
include(CheckTypeSize) if(CMAKE_C_COMPILER_VERSION)
include(FindPkgConfig) string(REPLACE "." "" MRUBY_GCC_VERSION ${CMAKE_C_COMPILER_VERSION})
include(TestBigEndian) endif()
# TODO add build info suffix for non-Windows builds?
# lib Libraries that mruby uses itself (just libm) if(MINGW)
set(MRUBY_LIBS m) set(MRUBY_BUILD "-mingw${MRUBY_GCC_VERSION}")
elseif(MSVC)
# Compile the sources to make libritevm set(MRUBY_BUILD "-msvc${MSVC_VERSION}")
add_subdirectory("src") endif()
set(CPACK_PACKAGE_FILE_NAME
# compile the compiler tool "${CMAKE_PROJECT_NAME}-${MRUBY_VERSION}-${MRUBY_HOST}${MRUBY_BUILD}"
add_subdirectory("tools/mrbc") )
include(CPack)
# compile libmrblib
add_subdirectory("mrblib") # vim: ts=2 sts=2 sw=2 et
# generate final library
add_library(mrubylib_static STATIC
$<TARGET_OBJECTS:ritevm_object> $<TARGET_OBJECTS:mrblib_object>)
add_library(mrubylib SHARED
$<TARGET_OBJECTS:ritevm_object> $<TARGET_OBJECTS:mrblib_object>)
install(TARGETS mrubylib mrubylib_static
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
# compile the interpreter tool
add_subdirectory("tools/mruby")
# for make install, install the header files
install(FILES include/mruby.h DESTINATION include)
install(FILES include/mrbconf.h DESTINATION include)
install(DIRECTORY include/mruby DESTINATION include)
# For now, also install header files in src dir to ${PREFIX}include/mruby
file(GLOB SRC_HEADERS src/*.h)
install (FILES ${SRC_HEADERS} DESTINATION include/mruby)
* Prerequisites * Prerequisites
1. Make sure you have bison (http://www.gnu.org/software/bison/) installed in your system. 1. Make sure you have bison (http://www.gnu.org/software/bison/) installed in your system.
2 Make sure you have cmake (http://www.cmake.org version 2.8.8 or
later installed).
* Compilation and Installation * Compilation and Installation
1. Run cmake . ; make ; make install in the top directory. 1. Run make in the top directory.
This command will create the following directories and This command will create the following directories and
store libraries and binaries files into them. store libraries and binaries files into them.
* /usr/local/bin * bin
* /usr/local/lib * lib
* /usr/local/include * include
If an error occurs when compiling mruby, it will be helpful for others if you If an error occurs when compiling mruby, it will be helpful for others if you
send a detailed report to the developers that includes the error log, machine, send a detailed report to the developers that includes the error log, machine,
......
# 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)
# 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)
# 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 "-Wall -Werror-implicit-function-declaration")
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()
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
# build mrblib # transform mruby's standard lib into a C library
# need custom commands
# Compile C source from merged mruby source
file(GLOB MRBLIB_SRC_RB "*.rb") file(GLOB MRBLIB_SRC_RB "*.rb")
# generate the a single rubu file from all the existing ones. if(CMAKE_CROSSCOMPILING)
add_custom_command(OUTPUT mrblib.rbtmp # create native tools and `mrblib.ctmp` required to build `mrblib.c`
COMMAND cat ${MRBLIB_SRC_RB} > mrblib.rbtmp include(ExternalProject)
DEPENDS ${MRBLIB_SRC_RB} ExternalProject_Add(mruby-native
) DOWNLOAD_COMMAND ""
SOURCE_DIR "${CMAKE_SOURCE_DIR}"
# generate the intermediate representation in C CONFIGURE_COMMAND "${CMAKE_COMMAND}" "${CMAKE_SOURCE_DIR}"
add_custom_command(OUTPUT mrblib_irep.c INSTALL_COMMAND ""
COMMAND echo -B mrblib_irep -o mrblib_irep.c mrblib.rbtmp BINARY_DIR "${CMAKE_BINARY_DIR}/native"
COMMAND mrbc -Bmrblib_irep -omrblib_irep.c mrblib.rbtmp )
DEPENDS mrblib.rbtmp
)
# finally generate the library's c file
add_custom_command(OUTPUT mrblib.c
COMMAND cat init_mrblib.c mrblib_irep.c > mrblib.c
DEPENDS init_mrblib.c mrblib_irep.c
)
# only use this C file to generate mrblib.
set(MRBLIB_SRC_C mrblib.c)
# add_library(mrblib_static STATIC ${MRBLIB_SRC_C})
add_library(mrblib_object OBJECT ${MRBLIB_SRC_C})
# target_link_libraries(mrblib ritevm ${MRUBY_LIBS})
# target_link_libraries(mrblib_static ritevm_static ${MRUBY_LIBS})
# install(TARGETS mrblib mrblib_static
# LIBRARY DESTINATION lib
# ARCHIVE DESTINATION lib)
# 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()
add_library(mrblib_object OBJECT mrblib.c)
# generate final static libmruby archive library
add_library(libmruby_static STATIC
$<TARGET_OBJECTS:mruby_object>
$<TARGET_OBJECTS:mrblib_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
# Build the C files in the mruby src directory # build the core mruby C files
cmake_minimum_required(VERSION 2.6)
if(CMAKE_VERSION VERSION_GREATER "2.8.0")
cmake_policy(SET CMP0012 OLD)
endif()
find_package(BISON) find_package(BISON)
BISON_TARGET(mruby parse.y ${CMAKE_CURRENT_BINARY_DIR}/parse.c) bison_target(mruby parse.y "${CMAKE_CURRENT_BINARY_DIR}/parse.c")
# configure_file("config.in.h" "config.h")
file(GLOB MRUBY_SRC_C "*.c") file(GLOB MRUBY_SRC_C "*.c")
add_library(ritevm_object OBJECT ${MRUBY_SRC_C}) list(APPEND MRUBY_SRC_C "${CMAKE_CURRENT_BINARY_DIR}/parse.c")
add_library(ritevm_static STATIC $<TARGET_OBJECTS:ritevm_object>)
add_library(ritevm SHARED $<TARGET_OBJECTS:ritevm_object>)
# target_link_libraries(ritevm ${MRUBY_LIBS}) add_library(mruby_object OBJECT ${MRUBY_SRC_C} ${BISON_mruby_OUTPUTS})
# target_link_libraries(ritevm_static ${MRUBY_LIBS}) add_library(mruby_static STATIC EXCLUDE_FROM_ALL $<TARGET_OBJECTS:mruby_object>)
# install(TARGETS ritevm ritevm_static
# LIBRARY DESTINATION lib
# ARCHIVE DESTINATION lib)
# vim: ts=2 sts=2 sw=2 et
# 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
# 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
# builds tools/mrbc # build tools/mrbc executable
file(GLOB MRBC_SRC_C "*.c") file(GLOB MRBC_SRC_C "*.c")
add_executable(mrbc ${MRBC_SRC_C}) add_executable(mrbc ${MRBC_SRC_C})
target_link_libraries(mrbc ritevm_static ${MRUBY_LIBS}) target_link_libraries(mrbc mruby_static ${MRUBY_LIBS})
install(TARGETS mrbc RUNTIME DESTINATION bin)
install(TARGETS mrbc RUNTIME DESTINATION bin)
# vim: ts=2 sts=2 sw=2 et
# builds tools/mrbc # build tools/mruby executable
file(GLOB MRUBYBIN_SRC_C "*.c") file(GLOB MRUBYBIN_SRC_C "*.c")
add_executable(mruby ${MRUBYBIN_SRC_C}) add_executable(mruby ${MRUBYBIN_SRC_C})
target_link_libraries(mruby mrubylib_static ${MRUBY_LIBS}) target_link_libraries(mruby libmruby_static ${MRUBY_LIBS})
install(TARGETS mruby RUNTIME DESTINATION bin)
install(TARGETS mruby RUNTIME DESTINATION bin)
# vim: ts=2 sts=2 sw=2 et
# 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
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);
}
}
done:
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