diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8771f1b8397546eeb6a6f3490ac1ee92e31c4e7a..8510e3fcf33c5d1b6b34c55fb66ec421f7816880 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
@@ -180,6 +179,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")
@@ -283,7 +285,7 @@ message (STATUS "ENABLE_GCOV: ${ENABLE_GCOV}")
 message (STATUS "ENABLE_TRACE: ${ENABLE_TRACE}")
 message (STATUS "ENABLE_BACKTRACE: ${ENABLE_BACKTRACE} (symbol resolve: ${HAVE_BFD})")
 message (STATUS "ENABLE_CLIENT: ${ENABLE_CLIENT}")
+message (STATUS "ENABLE_BUNDLED_LUAJIT: ${ENABLE_BUNDLED_LUAJIT}")
 message (STATUS "")
 message (STATUS "To view or modify configuration results, check out CMakeCache.txt.")
 message (STATUS "")
-
diff --git a/cmake/luajit.cmake b/cmake/luajit.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..9f8ed4244f569c16f4f824d11f35ac61f84cdb4c
--- /dev/null
+++ b/cmake/luajit.cmake
@@ -0,0 +1,129 @@
+
+#
+# LuaJIT configuration file.
+#
+# A copy of LuaJIT is maintained within Tarantool
+# source. It's located in third_party/luajit.
+#
+# Instead of this copy, Tarantool can be compiled
+# with a system-wide LuaJIT, or LuaJIT at a given
+# prefix. This is used when compiling Tarantool
+# as part of a distribution, e.g. Debian.
+#
+# To explicitly request use of the bundled LuaJIT,
+# add -DENABLE_BUNDLED_LUAJIT=True to CMake
+# configuration flags.
+# To explicitly request use of LuaJIT at a given
+# prefix, use -DLUAJIT_PREFIX=/path/to/LuaJIT.
+#
+# These two options are incompatible with each other.
+#
+# If neither of the two options is given, this script
+# first attempts to use the system-installed LuaJIT
+# and, in case it is not present or can not be used,
+# falls back to the bundled one.
+#
+# Adds CMake options: ENABLED_BUNDLED_LUAJIT, LUAJIT_PREFIX
+# Exports CMake defines: LUAJIT_PREFIX, LUAJIT_INCLUDE, LUAJIT_LIB
+# Modifies CMAKE_CFLAGS with -I${LUAJIT_INCLUDE}
+#
+
+#
+# Bundled LuaJIT paths.
+#
+set (LUAJIT_BUNDLED_PREFIX "${PROJECT_BINARY_DIR}/third_party/luajit/src")
+set (LUAJIT_BUNDLED_LIB "${LUAJIT_BUNDLED_PREFIX}/libluajit.a")
+
+macro (luajit_use_bundled)
+    set (LUAJIT_PREFIX "${LUAJIT_BUNDLED_PREFIX}")
+    set (LUAJIT_INCLUDE "${LUAJIT_BUNDLED_PREFIX}")
+    set (LUAJIT_LIB "${LUAJIT_BUNDLED_LIB}")
+    set (ENABLE_BUNDLED_LUAJIT True)
+endmacro()
+
+#
+# LuaJIT testing routine
+# (see cmake/luatest.cpp for a 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()
+    set (CMAKE_REQUIRED_INCLUDES "${LUAJIT_INCLUDE}")
+    CHECK_CXX_SOURCE_RUNS ("${LUAJIT_TEST}" LUAJIT_RUNS)
+    unset (LUAJIT_TEST)
+    unset (CMAKE_REQUIRED_LIBRARIES)
+    unset (CMAKE_REQUIRED_INCLUDES)
+endmacro()
+
+#
+# Check if there is a system LuaJIT availaible and
+# usable with the server (determined by a compiled test).
+#
+macro (luajit_try_system)
+    find_path (LUAJIT_INCLUDE lua.h PATH_SUFFIXES luajit-2.0 luajit)
+    find_library (LUAJIT_LIB NAMES luajit luajit-5.1 PATH_SUFFIXES x86_64-linux-gnu)
+    message (STATUS "include: ${LUAJIT_INCLUDE}, lib: ${LUAJIT_LIB}")
+    if (LUAJIT_INCLUDE AND LUAJIT_LIB)
+        message (STATUS "Found a system-wide LuaJIT.")
+        luajit_test()
+        if ("${LUAJIT_RUNS}" STREQUAL "1")
+            message (STATUS "System-wide LuaJIT at ${LUAJIT_LIB} is suitable for use.")
+        else()
+            message (WARNING "System-wide LuaJIT at ${LUAJIT_LIB} is NOT suitable for use, using the bundled one.")
+	        luajit_use_bundled()
+        endif()
+    else()
+        message (STATUS "Not found a system LuaJIT, using the bundled one.")
+        luajit_use_bundled()
+    endif()
+endmacro()
+
+#
+# Check if there is a usable LuaJIT at the given prefix path.
+#
+macro (luajit_try_prefix)
+    find_path (LUAJIT_INCLUDE "lua.h" ${LUAJIT_PREFIX} NO_DEFAULT_PATH)
+    find_library (LUAJIT_LIB "luajit" ${LUAJIT_PREFIX} NO_DEFAULT_PATH)
+    if (LUAJIT_INCLUDE AND LUAJIT_LIB)
+        include_directories("${LUAJIT_INCLUDE}")
+        luajit_test()
+        if (LUAJIT_RUNS)
+            message (STATUS "LuaJIT at ${LUAJIT_PREFIX} is suitable for use.")
+        else()
+            message (FATAL_ERROR "LuaJIT at ${LUAJIT_PREFIX} is NOT suitable for use.")
+        endif()
+    else()
+        message (FATAL_ERROR "Couldn't find LuaJIT in '${LUAJIT_PREFIX}'")
+    endif()
+endmacro()
+
+#
+# LuaJIT options.
+#
+option(ENABLE_BUNDLED_LUAJIT "Enable building of the bundled LuaJIT" OFF)
+option(LUAJIT_PREFIX "Build with LuaJIT at the given path" "")
+
+if (LUAJIT_PREFIX AND ENABLE_BUNDLED_LUAJIT)
+    message (FATAL_ERROR "Options LUAJIT_PREFIX and ENABLE_BUNDLED_LUAJIT "
+                         "are not compatible with each other.")
+endif()
+
+if (LUAJIT_PREFIX)
+    # trying to build with specified LuaJIT.
+    luajit_try_prefix()
+elseif (NOT ENABLE_BUNDLED_LUAJIT)
+    # trying to build with system LuaJIT, macro can turn on
+    # building of LuaJIT bundled with the server source.
+    luajit_try_system()
+else()
+    luajit_set_default()
+endif()
+
+unset (LUAJIT_RUNS)
+set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${LUAJIT_INCLUDE}")
+
+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 0000000000000000000000000000000000000000..9b749423dcc5b7b58bc01ad1c438ef6954b34ec0
--- /dev/null
+++ b/cmake/luatest.cpp
@@ -0,0 +1,78 @@
+/*
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ *    copyright notice, this list of conditions and the
+ *    following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Find out LuaJIT behavior on the current platform.
+ *
+ * LuaJIT uses different stack unwinding mechanisms on 32-bit x86
+ * and 64-bit x86-64 hardware: on a  32-bit system it can use
+ * its own * longjmp-style "internal stack unwinding".
+ * Among other things, this mechanism doesn't support exception
+ * propagation from Lua panic function (lua_atpanic()), and
+ * this is exactly what Tarantool does: throws an exception
+ * in lua_atpanic().
+ *
+ * Which mechanism to use is determined at library
+ * compile time, by a set of flags
+ * (-fexceptions -funwind-tables -DLUAJIT_UNWIND_EXTERNAL),
+ * hence, when configuring, we can't just check the library file
+ * to find out whether or not it will work.
+ * Instead, we compile and run this test.
+ *
+ * http://lua-users.org/lists/lua-l/2010-04/msg00470.html
+ */
+
+#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're lucky, we should get here. */
+	}
+	lua_close(L);
+	return 0;
+}
diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt
index 08a90869b7155dbed43f7377a8f43e2ce44785a3..331d9e9f600f32b41cfecf0a4c5fb348236f356b 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 04c948a1dd78088c765bcb7b65292d20d9334e0a..4067c2ee64e3605a48f3bf3524d948d08037528f 100644
--- a/core/admin.m
+++ b/core/admin.m
@@ -42,9 +42,10 @@
 #include <tbuf.h>
 #include <util.h>
 #include <errinj.h>
-#include "third_party/luajit/src/lua.h"
-#include "third_party/luajit/src/lauxlib.h"
-#include "third_party/luajit/src/lualib.h"
+
+#include "lua.h"
+#include "lauxlib.h"
+#include "lualib.h"
 
 static const char *help =
 	"available commands:" CRLF
@@ -66,7 +67,7 @@ static const char *help =
 static const char *unknown_command = "unknown command. try typing help." CRLF;
 
 
-#line 70 "core/admin.m"
+#line 71 "core/admin.m"
 static const int admin_start = 1;
 static const int admin_first_final = 135;
 static const int admin_error = 0;
@@ -74,7 +75,7 @@ static const int admin_error = 0;
 static const int admin_en_main = 1;
 
 
-#line 69 "core/admin.rl"
+#line 70 "core/admin.rl"
 
 
 
@@ -136,12 +137,12 @@ admin_dispatch(lua_State *L)
 	p = fiber->rbuf->data;
 
 	
-#line 140 "core/admin.m"
+#line 141 "core/admin.m"
 	{
 	cs = admin_start;
 	}
 
-#line 145 "core/admin.m"
+#line 146 "core/admin.m"
 	{
 	if ( p == pe )
 		goto _test_eof;
@@ -204,15 +205,15 @@ case 6:
 	}
 	goto st0;
 tr13:
-#line 239 "core/admin.rl"
+#line 240 "core/admin.rl"
 	{slab_validate(); ok(out);}
 	goto st135;
 tr20:
-#line 227 "core/admin.rl"
+#line 228 "core/admin.rl"
 	{return 0;}
 	goto st135;
 tr25:
-#line 154 "core/admin.rl"
+#line 155 "core/admin.rl"
 	{
 			start(out);
 			tbuf_append(out, help, strlen(help));
@@ -220,9 +221,9 @@ tr25:
 		}
 	goto st135;
 tr36:
-#line 213 "core/admin.rl"
+#line 214 "core/admin.rl"
 	{strend = p;}
-#line 160 "core/admin.rl"
+#line 161 "core/admin.rl"
 	{
 			strstart[strend-strstart]='\0';
 			start(out);
@@ -231,7 +232,7 @@ tr36:
 		}
 	goto st135;
 tr43:
-#line 167 "core/admin.rl"
+#line 168 "core/admin.rl"
 	{
 			if (reload_cfg(err))
 				fail(out, err);
@@ -240,11 +241,11 @@ tr43:
 		}
 	goto st135;
 tr67:
-#line 237 "core/admin.rl"
+#line 238 "core/admin.rl"
 	{coredump(60); ok(out);}
 	goto st135;
 tr76:
-#line 174 "core/admin.rl"
+#line 175 "core/admin.rl"
 	{
 			int ret = snapshot(NULL, 0);
 
@@ -259,9 +260,9 @@ tr76:
 		}
 	goto st135;
 tr98:
-#line 223 "core/admin.rl"
+#line 224 "core/admin.rl"
 	{ state = false; }
-#line 187 "core/admin.rl"
+#line 188 "core/admin.rl"
 	{
 			strstart[strend-strstart] = '\0';
 			if (errinj_set_byname(strstart, state)) {
@@ -273,9 +274,9 @@ tr98:
 		}
 	goto st135;
 tr101:
-#line 222 "core/admin.rl"
+#line 223 "core/admin.rl"
 	{ state = true; }
-#line 187 "core/admin.rl"
+#line 188 "core/admin.rl"
 	{
 			strstart[strend-strstart] = '\0';
 			if (errinj_set_byname(strstart, state)) {
@@ -287,7 +288,7 @@ tr101:
 		}
 	goto st135;
 tr117:
-#line 130 "core/admin.rl"
+#line 131 "core/admin.rl"
 	{
 			tarantool_cfg_iterator_t *i;
 			char *key, *value;
@@ -307,15 +308,15 @@ tr117:
 		}
 	goto st135;
 tr131:
-#line 230 "core/admin.rl"
+#line 231 "core/admin.rl"
 	{start(out); fiber_info(out); end(out);}
 	goto st135;
 tr137:
-#line 229 "core/admin.rl"
+#line 230 "core/admin.rl"
 	{start(out); tarantool_info(out); end(out);}
 	goto st135;
 tr146:
-#line 148 "core/admin.rl"
+#line 149 "core/admin.rl"
 	{
 			start(out);
 			errinj_info(out);
@@ -323,33 +324,33 @@ tr146:
 		}
 	goto st135;
 tr152:
-#line 233 "core/admin.rl"
+#line 234 "core/admin.rl"
 	{start(out); palloc_stat(out); end(out);}
 	goto st135;
 tr160:
-#line 232 "core/admin.rl"
+#line 233 "core/admin.rl"
 	{start(out); slab_stat(out); end(out);}
 	goto st135;
 tr164:
-#line 234 "core/admin.rl"
+#line 235 "core/admin.rl"
 	{start(out); stat_print(out);end(out);}
 	goto st135;
 st135:
 	if ( ++p == pe )
 		goto _test_eof135;
 case 135:
-#line 342 "core/admin.m"
+#line 343 "core/admin.m"
 	goto st0;
 tr14:
-#line 239 "core/admin.rl"
+#line 240 "core/admin.rl"
 	{slab_validate(); ok(out);}
 	goto st7;
 tr21:
-#line 227 "core/admin.rl"
+#line 228 "core/admin.rl"
 	{return 0;}
 	goto st7;
 tr26:
-#line 154 "core/admin.rl"
+#line 155 "core/admin.rl"
 	{
 			start(out);
 			tbuf_append(out, help, strlen(help));
@@ -357,9 +358,9 @@ tr26:
 		}
 	goto st7;
 tr37:
-#line 213 "core/admin.rl"
+#line 214 "core/admin.rl"
 	{strend = p;}
-#line 160 "core/admin.rl"
+#line 161 "core/admin.rl"
 	{
 			strstart[strend-strstart]='\0';
 			start(out);
@@ -368,7 +369,7 @@ tr37:
 		}
 	goto st7;
 tr44:
-#line 167 "core/admin.rl"
+#line 168 "core/admin.rl"
 	{
 			if (reload_cfg(err))
 				fail(out, err);
@@ -377,11 +378,11 @@ tr44:
 		}
 	goto st7;
 tr68:
-#line 237 "core/admin.rl"
+#line 238 "core/admin.rl"
 	{coredump(60); ok(out);}
 	goto st7;
 tr77:
-#line 174 "core/admin.rl"
+#line 175 "core/admin.rl"
 	{
 			int ret = snapshot(NULL, 0);
 
@@ -396,9 +397,9 @@ tr77:
 		}
 	goto st7;
 tr99:
-#line 223 "core/admin.rl"
+#line 224 "core/admin.rl"
 	{ state = false; }
-#line 187 "core/admin.rl"
+#line 188 "core/admin.rl"
 	{
 			strstart[strend-strstart] = '\0';
 			if (errinj_set_byname(strstart, state)) {
@@ -410,9 +411,9 @@ tr99:
 		}
 	goto st7;
 tr102:
-#line 222 "core/admin.rl"
+#line 223 "core/admin.rl"
 	{ state = true; }
-#line 187 "core/admin.rl"
+#line 188 "core/admin.rl"
 	{
 			strstart[strend-strstart] = '\0';
 			if (errinj_set_byname(strstart, state)) {
@@ -424,7 +425,7 @@ tr102:
 		}
 	goto st7;
 tr118:
-#line 130 "core/admin.rl"
+#line 131 "core/admin.rl"
 	{
 			tarantool_cfg_iterator_t *i;
 			char *key, *value;
@@ -444,15 +445,15 @@ tr118:
 		}
 	goto st7;
 tr132:
-#line 230 "core/admin.rl"
+#line 231 "core/admin.rl"
 	{start(out); fiber_info(out); end(out);}
 	goto st7;
 tr138:
-#line 229 "core/admin.rl"
+#line 230 "core/admin.rl"
 	{start(out); tarantool_info(out); end(out);}
 	goto st7;
 tr147:
-#line 148 "core/admin.rl"
+#line 149 "core/admin.rl"
 	{
 			start(out);
 			errinj_info(out);
@@ -460,22 +461,22 @@ tr147:
 		}
 	goto st7;
 tr153:
-#line 233 "core/admin.rl"
+#line 234 "core/admin.rl"
 	{start(out); palloc_stat(out); end(out);}
 	goto st7;
 tr161:
-#line 232 "core/admin.rl"
+#line 233 "core/admin.rl"
 	{start(out); slab_stat(out); end(out);}
 	goto st7;
 tr165:
-#line 234 "core/admin.rl"
+#line 235 "core/admin.rl"
 	{start(out); stat_print(out);end(out);}
 	goto st7;
 st7:
 	if ( ++p == pe )
 		goto _test_eof7;
 case 7:
-#line 479 "core/admin.m"
+#line 480 "core/admin.m"
 	if ( (*p) == 10 )
 		goto st135;
 	goto st0;
@@ -628,28 +629,28 @@ case 23:
 	}
 	goto tr33;
 tr33:
-#line 213 "core/admin.rl"
+#line 214 "core/admin.rl"
 	{strstart = p;}
 	goto st24;
 st24:
 	if ( ++p == pe )
 		goto _test_eof24;
 case 24:
-#line 639 "core/admin.m"
+#line 640 "core/admin.m"
 	switch( (*p) ) {
 		case 10: goto tr36;
 		case 13: goto tr37;
 	}
 	goto st24;
 tr34:
-#line 213 "core/admin.rl"
+#line 214 "core/admin.rl"
 	{strstart = p;}
 	goto st25;
 st25:
 	if ( ++p == pe )
 		goto _test_eof25;
 case 25:
-#line 653 "core/admin.m"
+#line 654 "core/admin.m"
 	switch( (*p) ) {
 		case 10: goto tr36;
 		case 13: goto tr37;
@@ -1099,28 +1100,28 @@ case 73:
 		goto tr91;
 	goto st0;
 tr91:
-#line 221 "core/admin.rl"
+#line 222 "core/admin.rl"
 	{ strstart = p; }
 	goto st74;
 st74:
 	if ( ++p == pe )
 		goto _test_eof74;
 case 74:
-#line 1110 "core/admin.m"
+#line 1111 "core/admin.m"
 	if ( (*p) == 32 )
 		goto tr92;
 	if ( 33 <= (*p) && (*p) <= 126 )
 		goto st74;
 	goto st0;
 tr92:
-#line 221 "core/admin.rl"
+#line 222 "core/admin.rl"
 	{ strend = p; }
 	goto st75;
 st75:
 	if ( ++p == pe )
 		goto _test_eof75;
 case 75:
-#line 1124 "core/admin.m"
+#line 1125 "core/admin.m"
 	switch( (*p) ) {
 		case 32: goto st75;
 		case 111: goto st76;
@@ -1812,7 +1813,7 @@ case 134:
 	_out: {}
 	}
 
-#line 245 "core/admin.rl"
+#line 246 "core/admin.rl"
 
 
 	tbuf_ltrim(fiber->rbuf, (void *)pe - (void *)fiber->rbuf->data);
diff --git a/core/admin.rl b/core/admin.rl
index 25b15e999c73273ee9a168daae2139c69e99b0f3..59d9573b93c72d80e3ce4b36abb5183010f5c26d 100644
--- a/core/admin.rl
+++ b/core/admin.rl
@@ -40,9 +40,10 @@
 #include <tbuf.h>
 #include <util.h>
 #include <errinj.h>
-#include "third_party/luajit/src/lua.h"
-#include "third_party/luajit/src/lauxlib.h"
-#include "third_party/luajit/src/lualib.h"
+
+#include "lua.h"
+#include "lauxlib.h"
+#include "lualib.h"
 
 static const char *help =
 	"available commands:" CRLF
diff --git a/core/tarantool_lua.m b/core/tarantool_lua.m
index 919437c0ab8d65f8197915dc913a81b72064964e..9f02772362b3c340d9df65814fb3e9ac50646d63 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 "lua.h"
+#include "lauxlib.h"
+#include "lualib.h"
 
 #include "pickle.h"
 #include "fiber.h"
diff --git a/include/config.h.cmake b/include/config.h.cmake
index 16a3d21ce915b4884fa41ccd31423c04a1376dd7..b09c4a209ad95a4dda06b4287f6e08f43d4c7b99 100644
--- a/include/config.h.cmake
+++ b/include/config.h.cmake
@@ -50,7 +50,9 @@
  * 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@"
 #define INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@"
 #define BUILD_TYPE "@CMAKE_BUILD_TYPE@"
diff --git a/mod/box/box_lua.m b/mod/box/box_lua.m
index b4af76ca5f2036b62e38948c478b89c449e403b4..9507d173e9ccce6e47d3cb49c6c4fa271aebf321 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 "lua.h"
+#include "lauxlib.h"
+#include "lualib.h"
 
 #include "pickle.h"
 #include "tuple.h"
diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt
index a6715612cca44a3def3a6f2914f2f2a5dbb830a5..4fb0eefc05aeb6ad912fc7a6a02043ede64ba9d1 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_BUNDLED_LUAJIT)
+    luajit_build()
 endif()
-add_custom_target(libluajit
-    DEPENDS ${PROJECT_BINARY_DIR}/third_party/luajit/src/libluajit.a
-)