From d2181f41ad8d570f330498485a7cf3b0a043a7a4 Mon Sep 17 00:00:00 2001 From: Dmitry Simonenko <pmwkaa@gmail.com> Date: Fri, 27 Jan 2012 14:44:51 +0400 Subject: [PATCH] Blueprint implementation: Add cmake option to support compilation with external luajit (https://blueprints.launchpad.net/tarantool/+spec/compile-with-external-luajit) --- CMakeLists.txt | 10 ++-- cmake/luajit.cmake | 115 +++++++++++++++++++++++++++++++++++++ cmake/luatest.cpp | 41 +++++++++++++ core/CMakeLists.txt | 4 +- core/admin.m | 8 +-- core/admin.rl | 8 +-- core/tarantool_lua.m | 8 +-- include/config.h.cmake | 10 +++- mod/box/box_lua.m | 8 +-- third_party/CMakeLists.txt | 73 +++++++++++++---------- 10 files changed, 232 insertions(+), 53 deletions(-) create mode 100644 cmake/luajit.cmake create mode 100644 cmake/luatest.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 6904f17f5f..a769f04dcd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,7 @@ include(CheckLibraryExists) include(CheckIncludeFile) include(CheckCCompilerFlag) include(CheckSymbolExists) +include(CheckCXXSourceRuns) include(TestBigEndian) find_program(ECHO echo) @@ -17,10 +18,8 @@ find_program(RAGEL ragel) find_program(CONFETTI confetti) find_program(LD ld) -set(luadir ${PROJECT_BINARY_DIR}/third_party/luajit/src) -link_directories(${luadir}) - include(cmake/check_objective_c_compiler.cmake) +include(cmake/luajit.cmake) # # This instructs the rest of the build system what product @@ -30,7 +29,6 @@ set (TARANTOOL_PRODUCT "box") set (TARANTOOL_MODULES "box") set (TARANTOOL_CLIENTS "") - # # Set default build type to Debug. This is to ease a developer's # life. Release binaries are built by BuildBot automatically anyway. @@ -184,6 +182,9 @@ endif() # # Now handle all configuration options. # + +# luajit options are defined in cmake/luajit.cmake + option(ENABLE_CLIENT "Enable building of console client" Off) if (ENABLE_CLIENT) set (TARANTOOL_CLIENTS ${TARANTOOL_CLIENTS} "tarantool") @@ -280,6 +281,7 @@ message (STATUS "${TARANTOOL_MODULES}.") message (STATUS "Please check out CMakeCache.txt to view or modify configuration results.") message (STATUS "") message (STATUS "*** The following options are on in this configuration: ***") +message (STATUS "ENABLE_LUAJIT: ${ENABLE_LUAJIT}") message (STATUS "ENABLE_CLIENT: ${ENABLE_CLIENT}") message (STATUS "ENABLE_GCOV: ${ENABLE_GCOV}") message (STATUS "ENABLE_TRACE: ${ENABLE_TRACE}") diff --git a/cmake/luajit.cmake b/cmake/luajit.cmake new file mode 100644 index 0000000000..d34baefbb7 --- /dev/null +++ b/cmake/luajit.cmake @@ -0,0 +1,115 @@ + +# +# luajit configuration file. +# + +# +# luajit defaults. +# +set (LUAJIT_DEFAULT_PREFIX "${PROJECT_BINARY_DIR}/third_party/luajit/src") +set (LUAJIT_DEFAULT_LIB "${LUAJIT_DEFAULT_PREFIX}/libluajit.a") +set (LUAJIT_TESTED 0) + +macro (luajit_set_default) + set (LUAJIT_PREFIX "${LUAJIT_DEFAULT_PREFIX}") + set (LUAJIT_INCLUDE "${LUAJIT_DEFAULT_PREFIX}") + set (LUAJIT_LIB "${LUAJIT_DEFAULT_LIB}") + set (ENABLE_LUAJIT ON) +endmacro() + +# +# luajit search macro. +# +macro (luajit_find isdefault) + if (${isdefault} STREQUAL "True") + find_path (LUAJIT_INCLUDE "lua.h") + find_library (LUAJIT_LIB "luajit") + else() + find_path (LUAJIT_INCLUDE "lua.h" ${LUAJIT_PREFIX} NO_DEFAULT_PATH) + find_library (LUAJIT_LIB "luajit" ${LUAJIT_PREFIX} NO_DEFAULT_PATH) + endif() +endmacro() + +# +# luajit testing routine +# (see cmake/luatest.cpp for description). +# +macro (luajit_test) + file (READ "${CMAKE_SOURCE_DIR}/cmake/luatest.cpp" LUAJIT_TEST) + set (CMAKE_REQUIRED_LIBRARIES "${LUAJIT_LIB}") + if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + set (CMAKE_REQUIRED_LIBRARIES "-ldl ${CMAKE_REQUIRED_LIBRARIES}") + endif() + CHECK_CXX_SOURCE_RUNS ("${LUAJIT_TEST}" LUAJIT_RUNS) + set (LUAJIT_TESTED "${LUAJIT_RUNS}") + unset (LUAJIT_RUNS) + unset (CMAKE_REQUIRED_LIBRARIES) +endmacro() + +# +# Check if there is system luajit availaible and +# it can be used with server exception's (determined by test). +# +macro (luajit_try_system) + luajit_find(True) + if (LUAJIT_INCLUDE AND LUAJIT_LIB) + message (STATUS "Found system luajit.") + luajit_test() + if (LUAJIT_TESTED) + message (STATUS "System luajit is suitable for use.") + else() + message (WARNING "System luajit is NOT suitable for use, using default.") + # in case of system inability to use + # system luajit, setting prefix. + luajit_set_default() + endif() + else() + message (STATUS "Not found system luajit, using default.") + luajit_set_default() + endif() +endmacro() + +# +# Check if there is usable luajit in specified prefix +# path. +# +macro (luajit_try_prefix) + luajit_find(False) + if (LUAJIT_INCLUDE AND LUAJIT_LIB) + include_directories("${LUAJIT_INCLUDE}") + link_directories("${LUAJIT_PREFIX}") + luajit_test() + if (LUAJIT_TESTED) + message (STATUS "Supplied luajit is suitable for use.") + else() + message (FATAL_ERROR "Supplied luajit is NOT suitable for use.") + endif() + else() + message (FATAL_ERROR "Couldn't find luajit in '${LUAJIT_PREFIX}'") + endif() +endmacro() + +# +# luajit options. +# +option(ENABLE_LUAJIT "Enable building of shipped luajit" OFF) +option(LUAJIT_PREFIX "luajit path" "") + +if (LUAJIT_PREFIX AND ENABLE_LUAJIT) + message (FATAL_ERROR "Only one of LUAJIT_PREFIX or ENABLE_LUAJIT " + "options can be specified.") +endif() + +if (LUAJIT_PREFIX) + # trying to build with specified luajit. + luajit_try_prefix() +elseif (NOT ENABLE_LUAJIT) + # trying to build with system luajit, macro can turn on + # building of luajit shipped with server. + luajit_try_system() +else() + luajit_set_default() +endif() + +message (STATUS "Luajit include: ${LUAJIT_INCLUDE}") +message (STATUS "Luajit lib: ${LUAJIT_LIB}") diff --git a/cmake/luatest.cpp b/cmake/luatest.cpp new file mode 100644 index 0000000000..453d6e1f89 --- /dev/null +++ b/cmake/luatest.cpp @@ -0,0 +1,41 @@ + +/* + * Test for determining luajit behavior on current platform. + * + * Luajit uses different stack unwinding mechanisms on x86/PPC + * and x64 and a compilation flags. + * + * Using default mechanism under x86 (32-bit) can cause troubles + * with raising and propogation exceptions from error handlers - + * it starts recursively call panic error handler. + * +*/ + +#include <cstdlib> +#include <lua.hpp> + +static int panic = 0; + +static int lua_panic_cb(lua_State *L) { + if (!panic++) + throw 0; + abort(); + return 0; +} + +int +main(int argc, char * argv[]) +{ + lua_State *L = luaL_newstate(); + if (L == NULL) + return 1; + lua_atpanic(L, lua_panic_cb); + try { + lua_pushstring(L, "uncallable"); + lua_call(L, 0, LUA_MULTRET); + } catch (...) { + /* if we luck, we should get here. */ + } + lua_close(L); + return 0; +} diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 861e9e11b5..aabc833186 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -72,7 +72,9 @@ add_library(core STATIC ${common_sources}) add_dependencies(core generate_headers luajit) set_target_properties(core PROPERTIES COMPILE_FLAGS "${core_cflags}") -set (common_libraries cfg core ev coro gopt misc objc luajit) +set (common_libraries cfg core ev coro gopt misc objc) +set (common_libraries ${common_libraries} ${LUAJIT_LIB}) + if (TARGET_OS_LINUX) set (common_libraries ${common_libraries} dl) endif() diff --git a/core/admin.m b/core/admin.m index b403e23074..215ed19ef8 100644 --- a/core/admin.m +++ b/core/admin.m @@ -41,9 +41,10 @@ #include TARANTOOL_CONFIG #include <tbuf.h> #include <util.h> -#include "third_party/luajit/src/lua.h" -#include "third_party/luajit/src/lauxlib.h" -#include "third_party/luajit/src/lualib.h" + +#include LUAJIT_LUA_H +#include LUAJIT_LAUXLIB_H +#include LUAJIT_LUALIB_H static const char *help = "available commands:" CRLF @@ -60,7 +61,6 @@ static const char *help = " - lua command" CRLF " - reload configuration" CRLF; - static const char *unknown_command = "unknown command. try typing help." CRLF; diff --git a/core/admin.rl b/core/admin.rl index 10d119709c..a11b770985 100644 --- a/core/admin.rl +++ b/core/admin.rl @@ -39,9 +39,10 @@ #include TARANTOOL_CONFIG #include <tbuf.h> #include <util.h> -#include "third_party/luajit/src/lua.h" -#include "third_party/luajit/src/lauxlib.h" -#include "third_party/luajit/src/lualib.h" + +#include LUAJIT_LUA_H +#include LUAJIT_LAUXLIB_H +#include LUAJIT_LUALIB_H static const char *help = "available commands:" CRLF @@ -58,7 +59,6 @@ static const char *help = " - lua command" CRLF " - reload configuration" CRLF; - static const char *unknown_command = "unknown command. try typing help." CRLF; %%{ diff --git a/core/tarantool_lua.m b/core/tarantool_lua.m index 04f6dcb3de..af752ee42f 100644 --- a/core/tarantool_lua.m +++ b/core/tarantool_lua.m @@ -29,10 +29,10 @@ * SUCH DAMAGE. */ #include "tarantool.h" -/* use a full path to avoid clashes with system lua */ -#include "third_party/luajit/src/lua.h" -#include "third_party/luajit/src/lauxlib.h" -#include "third_party/luajit/src/lualib.h" + +#include LUAJIT_LUA_H +#include LUAJIT_LAUXLIB_H +#include LUAJIT_LUALIB_H #include "pickle.h" #include "fiber.h" diff --git a/include/config.h.cmake b/include/config.h.cmake index 80ae5a6c5d..8c0f8cd31d 100644 --- a/include/config.h.cmake +++ b/include/config.h.cmake @@ -50,8 +50,16 @@ * Defined if this is a big-endian system. */ #cmakedefine HAVE_BYTE_ORDER_BIG_ENDIAN 1 - +/* + * predefined /etc directory prefix. + */ #define SYSCONF_DIR "@CMAKE_SYSCONF_DIR@" +/* + * path to luajit headers. + */ +#define LUAJIT_LUA_H "@LUAJIT_INCLUDE@/lua.h" +#define LUAJIT_LUALIB_H "@LUAJIT_INCLUDE@/lualib.h" +#define LUAJIT_LAUXLIB_H "@LUAJIT_INCLUDE@/lauxlib.h" /* * vim: syntax=c */ diff --git a/mod/box/box_lua.m b/mod/box/box_lua.m index 0a5087d16e..4a957c57f7 100644 --- a/mod/box/box_lua.m +++ b/mod/box/box_lua.m @@ -31,10 +31,10 @@ #include "box_lua.h" #include "tarantool.h" #include "box.h" -/* use a full path to avoid clashes with system Lua */ -#include "third_party/luajit/src/lua.h" -#include "third_party/luajit/src/lauxlib.h" -#include "third_party/luajit/src/lualib.h" + +#include LUAJIT_LUA_H +#include LUAJIT_LAUXLIB_H +#include LUAJIT_LUALIB_H #include "pickle.h" #include "tuple.h" diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt index a6715612cc..9834c3c549 100644 --- a/third_party/CMakeLists.txt +++ b/third_party/CMakeLists.txt @@ -8,36 +8,47 @@ endif() add_subdirectory(coro) add_subdirectory(gopt) -set (luajit_buildoptions BUILDMODE=static) -if (${CMAKE_BUILD_TYPE} STREQUAL "Debug") - set (luajit_buildoptions ${luajit_buildoptions} CCOPT=-O0) - set (luajit_buildoptions ${luajit_buildoptions} CCDEBUG=-ggdb) - set (luajit_buildoptions ${luajit_buildoptions} XCFLAGS='-DLUA_USE_APICHECK -DLUA_USE_ASSERT') -endif() -set (luajit_buildoptions ${luajit_buildoptions} Q='') -if (${PROJECT_BINARY_DIR} STREQUAL ${PROJECT_SOURCE_DIR}) - add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/third_party/luajit/src/libluajit.a - WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/third_party/luajit - COMMAND make clean - COMMAND make -C src -t buildvm_x86.h buildvm_arm.h - buildvm_x64.h buildvm_x64win.h - COMMAND make -C src ${luajit_buildoptions} - DEPENDS ${CMAKE_SOURCE_DIR}/CMakeCache.txt - ) -else() - add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/third_party/luajit - COMMAND mkdir ${PROJECT_BINARY_DIR}/third_party/luajit - ) - add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/third_party/luajit/src/libluajit.a - WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/third_party/luajit - COMMAND cp -r ${PROJECT_SOURCE_DIR}/third_party/luajit/* . - COMMAND make clean - COMMAND make -C src -t buildvm_x86.h buildvm_arm.h - buildvm_x64.h buildvm_x64win.h - COMMAND make -C src ${luajit_buildoptions} - DEPENDS ${PROJECT_BINARY_DIR}/CMakeCache.txt ${PROJECT_BINARY_DIR}/third_party/luajit +macro (luajit_build) + set (luajit_buildoptions BUILDMODE=static) + if (${CMAKE_BUILD_TYPE} STREQUAL "Debug") + set (luajit_buildoptions ${luajit_buildoptions} CCOPT=-O0) + set (luajit_buildoptions ${luajit_buildoptions} CCDEBUG=-ggdb) + set (luajit_buildoptions ${luajit_buildoptions} XCFLAGS='-DLUA_USE_APICHECK -DLUA_USE_ASSERT') + endif() + set (luajit_buildoptions ${luajit_buildoptions} Q='') + if (${PROJECT_BINARY_DIR} STREQUAL ${PROJECT_SOURCE_DIR}) + add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/third_party/luajit/src/libluajit.a + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/third_party/luajit + COMMAND make clean + COMMAND make -C src -t buildvm_x86.h buildvm_arm.h + buildvm_x64.h buildvm_x64win.h + COMMAND make -C src ${luajit_buildoptions} + DEPENDS ${CMAKE_SOURCE_DIR}/CMakeCache.txt + ) + else() + add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/third_party/luajit + COMMAND mkdir ${PROJECT_BINARY_DIR}/third_party/luajit + ) + add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/third_party/luajit/src/libluajit.a + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/third_party/luajit + COMMAND cp -r ${PROJECT_SOURCE_DIR}/third_party/luajit/* . + COMMAND make clean + COMMAND make -C src -t buildvm_x86.h buildvm_arm.h + buildvm_x64.h buildvm_x64win.h + COMMAND make -C src ${luajit_buildoptions} + DEPENDS ${PROJECT_BINARY_DIR}/CMakeCache.txt ${PROJECT_BINARY_DIR}/third_party/luajit + ) + endif() + add_custom_target(libluajit + DEPENDS ${PROJECT_BINARY_DIR}/third_party/luajit/src/libluajit.a ) + unset (luajit_buildoptions) +endmacro() + +# +# building shipped luajit only if there is no +# usable system one (see cmake/luajit.cmake) or by demand. +# +if (ENABLE_LUAJIT) + luajit_build() endif() -add_custom_target(libluajit - DEPENDS ${PROJECT_BINARY_DIR}/third_party/luajit/src/libluajit.a -) -- GitLab