1# Added LUA_ADD_EXECUTABLE Ryan Phillips <ryan at trolocsis.com>
2# This CMakeLists.txt has been first taken from LuaDist
3# Copyright (C) 2007-2011 LuaDist.
4# Created by Peter Drahoš
5# Redistribution and use of this file is allowed according to the terms of the MIT license.
6# Debugged and (now seriously) modified by Ronan Collobert, for Torch7
7
8#project(LuaJIT C ASM)
9
10SET(LUAJIT_DIR ${CMAKE_CURRENT_LIST_DIR}/luajit)
11
12SET(CMAKE_REQUIRED_INCLUDES
13  ${LUAJIT_DIR}
14  ${LUAJIT_DIR}/src
15  ${CMAKE_CURRENT_BINARY_DIR}
16)
17
18OPTION(WITH_AMALG "Build eveything in one shot (needs memory)" ON)
19
20# Ugly warnings
21IF(MSVC)
22  ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
23ENDIF()
24
25# Various includes
26INCLUDE(CheckLibraryExists)
27INCLUDE(CheckFunctionExists)
28INCLUDE(CheckCSourceCompiles)
29INCLUDE(CheckTypeSize)
30
31# LuaJIT specific
32option(LUAJIT_DISABLE_FFI "Disable FFI." OFF)
33option(LUAJIT_ENABLE_LUA52COMPAT "Enable Lua 5.2 compatibility." ON)
34option(LUAJIT_DISABLE_JIT "Disable JIT." OFF)
35option(LUAJIT_CPU_SSE2 "Use SSE2 instead of x87 instructions." ON)
36option(LUAJIT_CPU_NOCMOV "Disable NOCMOV." OFF)
37option(LUAJIT_DISABLE_GC64 "Disable GC64" OFF)
38MARK_AS_ADVANCED(LUAJIT_DISABLE_FFI LUAJIT_ENABLE_LUA52COMPAT
39  LUAJIT_DISABLE_GC64
40  LUAJIT_DISABLE_JIT LUAJIT_CPU_SSE2 LUAJIT_CPU_NOCMOV)
41
42IF(LUAJIT_DISABLE_FFI)
43  ADD_DEFINITIONS(-DLUAJIT_DISABLE_FFI)
44ENDIF()
45
46IF(LUAJIT_ENABLE_LUA52COMPAT)
47  ADD_DEFINITIONS(-DLUAJIT_ENABLE_LUA52COMPAT)
48ENDIF()
49
50IF(LUAJIT_DISABLE_GC64)
51  ADD_DEFINITIONS(-DLUAJIT_DISABLE_GC64)
52ENDIF()
53
54IF(LUAJIT_DISABLE_JIT)
55  ADD_DEFINITIONS(-DLUAJIT_DISABLE_JIT)
56ENDIF()
57
58IF(LUAJIT_CPU_SSE2)
59  ADD_DEFINITIONS(-DLUAJIT_CPU_SSE2)
60ENDIF()
61
62IF(LUAJIT_CPU_NOCMOV)
63  ADD_DEFINITIONS(-DLUAJIT_CPU_NOCMOV)
64ENDIF()
65######
66
67
68CHECK_TYPE_SIZE("void*" SIZEOF_VOID_P)
69IF(SIZEOF_VOID_P EQUAL 8)
70  ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE)
71ENDIF()
72
73if ( WIN32 AND NOT CYGWIN )
74  set ( LJVM_MODE peobj )
75elseif ( APPLE )
76  set ( CMAKE_EXE_LINKER_FLAGS "-pagezero_size 10000 -image_base 100000000 ${CMAKE_EXE_LINKER_FLAGS}" )
77  set ( LJVM_MODE machasm )
78else ()
79  set ( LJVM_MODE elfasm )
80endif ()
81
82IF(NOT WIN32)
83  FIND_LIBRARY(DL_LIBRARY "dl")
84  IF(DL_LIBRARY)
85    SET(CMAKE_REQUIRED_LIBRARIES ${DL_LIBRARY})
86    LIST(APPEND LIBS ${DL_LIBRARY})
87  ENDIF(DL_LIBRARY)
88  CHECK_FUNCTION_EXISTS(dlopen LUA_USE_DLOPEN)
89  IF(NOT LUA_USE_DLOPEN)
90    MESSAGE(FATAL_ERROR "Cannot compile a useful lua.
91Function dlopen() seems not to be supported on your platform.
92Apparently you are not on a Windows platform as well.
93So lua has no way to deal with shared libraries!")
94  ENDIF(NOT LUA_USE_DLOPEN)
95ENDIF(NOT WIN32)
96
97check_library_exists(m sin "" LUA_USE_LIBM)
98if ( LUA_USE_LIBM )
99  list ( APPEND LIBS m )
100endif ()
101
102if ( CMAKE_SYSTEM_NAME MATCHES "OpenBSD")
103  list ( APPEND LIBS pthread c++abi )
104endif ()
105
106## SOURCES
107MACRO(LJ_TEST_ARCH stuff)
108  CHECK_C_SOURCE_COMPILES("
109#undef ${stuff}
110#include \"lj_arch.h\"
111#if ${stuff}
112int main() { return 0; }
113#else
114#error \"not defined\"
115#endif
116" ${stuff})
117ENDMACRO()
118
119MACRO(LJ_TEST_ARCH_VALUE stuff value)
120  CHECK_C_SOURCE_COMPILES("
121#undef ${stuff}
122#include \"lj_arch.h\"
123#if ${stuff} == ${value}
124int main() { return 0; }
125#else
126#error \"not defined\"
127#endif
128" ${stuff}_${value})
129ENDMACRO()
130
131
132FOREACH(arch X64 X86 ARM ARM64 PPC PPCSPE MIPS)
133  LJ_TEST_ARCH(LJ_TARGET_${arch})
134  if(LJ_TARGET_${arch})
135    STRING(TOLOWER ${arch} TARGET_LJARCH)
136    MESSAGE(STATUS "LuaJIT Target: ${TARGET_LJARCH}")
137    BREAK()
138  ENDIF()
139ENDFOREACH()
140
141IF(NOT TARGET_LJARCH)
142  MESSAGE(FATAL_ERROR "architecture not supported")
143ELSE()
144  MESSAGE(STATUS "LuaJIT target ${TARGET_LJARCH}")
145ENDIF()
146
147FILE(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/jit)
148FILE(GLOB jit_files ${LUAJIT_DIR}/src/jit/*.lua)
149FILE(COPY ${jit_files} DESTINATION ${CMAKE_BINARY_DIR}/jit)
150
151SET(DASM_ARCH ${TARGET_LJARCH})
152SET(DASM_FLAGS)
153SET(TARGET_ARCH)
154LIST(APPEND TARGET_ARCH "LUAJIT_TARGET=LUAJIT_ARCH_${TARGET_LJARCH}")
155LJ_TEST_ARCH_VALUE(LJ_ARCH_BITS 64)
156IF(LJ_ARCH_BITS_64)
157  SET(DASM_FLAGS ${DASM_FLAGS} -D P64)
158ENDIF()
159LJ_TEST_ARCH_VALUE(LJ_HASJIT 1)
160IF(LJ_HASJIT_1)
161  SET(DASM_FLAGS ${DASM_FLAGS} -D JIT)
162ENDIF()
163LJ_TEST_ARCH_VALUE(LJ_HASFFI 1)
164IF(LJ_HASFFI_1)
165  SET(DASM_FLAGS ${DASM_FLAGS} -D FFI)
166ENDIF()
167LJ_TEST_ARCH_VALUE(LJ_DUALNUM 1)
168IF(LJ_DUALNUM_1)
169  SET(DASM_FLAGS ${DASM_FLAGS} -D DUALNUM)
170ENDIF()
171LJ_TEST_ARCH_VALUE(LJ_ARCH_HASFPU 1)
172IF(LJ_ARCH_HASFPU_1)
173  SET(DASM_FLAGS ${DASM_FLAGS} -D FPU)
174  LIST(APPEND TARGET_ARCH "LJ_ARCH_HASFPU=1")
175ELSE()
176  LIST(APPEND TARGET_ARCH "LJ_ARCH_HASFPU=0")
177ENDIF()
178LJ_TEST_ARCH_VALUE(LJ_ABI_SOFTFP 1)
179IF(NOT LJ_ABI_SOFTFP_1)
180  SET(DASM_FLAGS ${DASM_FLAGS} -D HFABI)
181  LIST(APPEND TARGET_ARCH "LJ_ABI_SOFTFP=0")
182ELSE()
183  LIST(APPEND TARGET_ARCH "LJ_ABI_SOFTFP=1")
184ENDIF()
185IF(WIN32)
186  SET(DASM_FLAGS ${DASM_FLAGS} -LN -D WIN)
187ENDIF()
188IF(TARGET_LJARCH STREQUAL "x86")
189  LJ_TEST_ARCH_VALUE(__SSE2__ 1)
190  IF(__SSE2__1)
191    SET(DASM_FLAGS ${DASM_FLAGS} -D SSE)
192  ENDIF()
193ENDIF()
194IF(TARGET_LJARCH STREQUAL "ppc")
195  LJ_TEST_ARCH_VALUE(LJ_ARCH_SQRT 1)
196  IF(NOT LJ_ARCH_SQRT_1)
197    SET(DASM_FLAGS ${DASM_FLAGS} -D SQRT)
198  ENDIF()
199  LJ_TEST_ARCH_VALUE(LJ_ARCH_PPC64 1)
200  IF(NOT LJ_ARCH_PPC64_1)
201    SET(DASM_FLAGS ${DASM_FLAGS} -D GPR64)
202  ENDIF()
203ENDIF()
204
205add_executable(minilua ${LUAJIT_DIR}/src/host/minilua.c)
206SET_TARGET_PROPERTIES(minilua PROPERTIES COMPILE_DEFINITIONS "${TARGET_ARCH}")
207CHECK_LIBRARY_EXISTS(m sin "" MINILUA_USE_LIBM)
208if(MINILUA_USE_LIBM)
209  TARGET_LINK_LIBRARIES(minilua m)
210endif()
211
212add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/buildvm_arch.h
213  COMMAND minilua ${LUAJIT_DIR}/dynasm/dynasm.lua ${DASM_FLAGS} -o ${CMAKE_CURRENT_BINARY_DIR}/buildvm_arch.h ${LUAJIT_DIR}/src/vm_${DASM_ARCH}.dasc
214  DEPENDS ${LUAJIT_DIR}/dynasm/dynasm.lua minilua
215)
216
217## Source Lists
218SET(SRC_LJLIB
219  ${LUAJIT_DIR}/src/lib_base.c
220  ${LUAJIT_DIR}/src/lib_math.c
221  ${LUAJIT_DIR}/src/lib_bit.c
222  ${LUAJIT_DIR}/src/lib_string.c
223  ${LUAJIT_DIR}/src/lib_table.c
224  ${LUAJIT_DIR}/src/lib_io.c
225  ${LUAJIT_DIR}/src/lib_os.c
226  ${LUAJIT_DIR}/src/lib_package.c
227  ${LUAJIT_DIR}/src/lib_debug.c
228  ${LUAJIT_DIR}/src/lib_jit.c
229  ${LUAJIT_DIR}/src/lib_ffi.c
230)
231
232SET(SRC_LIBAUX
233  ${LUAJIT_DIR}/src/lib_aux.c
234  ${LUAJIT_DIR}/src/lib_init.c
235)
236file (GLOB_RECURSE SRC_LJCORE   "${LUAJIT_DIR}/src/lj_*.c")
237list (APPEND SRC_LJCORE ${SRC_LJLIB} ${SRC_LIBAUX})
238file (GLOB_RECURSE SRC_BUILDVM  "${LUAJIT_DIR}/src/host/buildvm*.c")
239list (APPEND SRC_BUILDVM ${CMAKE_CURRENT_BINARY_DIR}/buildvm_arch.h)
240
241## GENERATE
242ADD_EXECUTABLE(buildvm ${SRC_BUILDVM})
243SET_TARGET_PROPERTIES(buildvm PROPERTIES COMPILE_DEFINITIONS "${TARGET_ARCH}")
244
245macro(add_buildvm_target _target _mode)
246  add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_target}
247    COMMAND buildvm ARGS -m ${_mode} -o ${CMAKE_CURRENT_BINARY_DIR}/${_target} ${ARGN}
248    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
249    DEPENDS buildvm ${ARGN}
250  )
251endmacro(add_buildvm_target)
252
253if (WIN32)
254  add_buildvm_target ( lj_vm.obj peobj )
255  set (LJ_VM_SRC ${CMAKE_CURRENT_BINARY_DIR}/lj_vm.obj)
256else ()
257  add_buildvm_target ( lj_vm.S ${LJVM_MODE} )
258  set (LJ_VM_SRC ${CMAKE_CURRENT_BINARY_DIR}/lj_vm.S)
259endif ()
260add_buildvm_target ( lj_ffdef.h   ffdef   ${SRC_LJLIB} )
261add_buildvm_target ( lj_bcdef.h  bcdef  ${SRC_LJLIB} )
262add_buildvm_target ( lj_folddef.h folddef ${LUAJIT_DIR}/src/lj_opt_fold.c )
263add_buildvm_target ( lj_recdef.h  recdef  ${SRC_LJLIB} )
264add_buildvm_target ( lj_libdef.h  libdef  ${SRC_LJLIB} )
265add_buildvm_target ( vmdef.lua  vmdef  ${SRC_LJLIB} )
266
267SET(DEPS
268  ${LJ_VM_SRC}
269  ${CMAKE_CURRENT_BINARY_DIR}/lj_ffdef.h
270  ${CMAKE_CURRENT_BINARY_DIR}/lj_bcdef.h
271  ${CMAKE_CURRENT_BINARY_DIR}/lj_libdef.h
272  ${CMAKE_CURRENT_BINARY_DIR}/lj_recdef.h
273  ${CMAKE_CURRENT_BINARY_DIR}/lj_folddef.h
274  ${CMAKE_CURRENT_BINARY_DIR}/vmdef.lua
275  )
276
277## COMPILE
278include_directories(
279  ${LUAJIT_DIR}/dynasm
280  ${LUAJIT_DIR}/src
281  ${CMAKE_CURRENT_BINARY_DIR}
282)
283
284IF(WITH_SHARED_LUA)
285    IF(WITH_AMALG)
286	add_library(luajit-5.1 SHARED ${LUAJIT_DIR}/src/ljamalg.c ${DEPS} )
287    ELSE()
288	add_library(luajit-5.1 SHARED ${SRC_LJCORE} ${DEPS} )
289    ENDIF()
290    SET_TARGET_PROPERTIES(luajit-5.1 PROPERTIES OUTPUT_NAME "lua51")
291ELSE()
292    IF(WITH_AMALG)
293	add_library(luajit-5.1 STATIC ${LUAJIT_DIR}/src/ljamalg.c ${DEPS} )
294    ELSE()
295	add_library(luajit-5.1 STATIC ${SRC_LJCORE} ${DEPS} )
296    ENDIF()
297    SET_TARGET_PROPERTIES(luajit-5.1 PROPERTIES
298	PREFIX "lib" IMPORT_PREFIX "lib" OUTPUT_NAME "luajit")
299ENDIF()
300
301target_link_libraries (luajit-5.1 ${LIBS} )
302
303IF(WIN32)
304  add_executable(luajit ${LUAJIT_DIR}/src/luajit.c)
305  target_link_libraries(luajit luajit-5.1)
306ELSE()
307  IF(WITH_AMALG)
308    add_executable(luajit ${LUAJIT_DIR}/src/luajit.c ${LUAJIT_DIR}/src/ljamalg.c ${DEPS})
309    # When using WITH_AMALG during a parallel build, its possible to run into
310    # false-positive "error: 'fold_hash' undeclared" compile errors due to a weird interaction
311    # when building two ljamalg.c at the same time.
312    #
313    # This adds a fake dependency from one to the other, forcing the build process to
314    # compile them sequentially rather than parallel.
315    #
316    # See https://github.com/torch/luajit-rocks/issues/39
317    add_dependencies(luajit luajit-5.1)
318  ELSE()
319    add_executable(luajit ${LUAJIT_DIR}/src/luajit.c ${SRC_LJCORE} ${DEPS})
320  ENDIF()
321  target_link_libraries(luajit ${LIBS})
322  SET_TARGET_PROPERTIES(luajit PROPERTIES ENABLE_EXPORTS ON)
323ENDIF()
324
325MACRO(LUAJIT_add_custom_commands luajit_target)
326  SET(target_srcs "")
327  FOREACH(file ${ARGN})
328    IF(${file} MATCHES ".*\\.lua$")
329      if(NOT IS_ABSOLUTE ${file})
330        set(file "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
331      endif()
332      set(source_file ${file})
333      string(LENGTH ${CMAKE_SOURCE_DIR} _luajit_source_dir_length)
334      string(LENGTH ${file} _luajit_file_length)
335      math(EXPR _begin "${_luajit_source_dir_length} + 1")
336      math(EXPR _stripped_file_length "${_luajit_file_length} - ${_luajit_source_dir_length} - 1")
337      string(SUBSTRING ${file} ${_begin} ${_stripped_file_length} stripped_file)
338
339      set(generated_file "${CMAKE_BINARY_DIR}/jitted_tmp/${stripped_file}_${luajit_target}_generated${CMAKE_C_OUTPUT_EXTENSION}")
340
341      add_custom_command(
342        OUTPUT ${generated_file}
343        MAIN_DEPENDENCY ${source_file}
344        DEPENDS luajit
345        COMMAND luajit
346        ARGS -bg
347          ${source_file}
348          ${generated_file}
349        COMMENT "Building Luajitted ${source_file}: ${generated_file}"
350      )
351
352      get_filename_component(basedir ${generated_file} PATH)
353      file(MAKE_DIRECTORY ${basedir})
354
355      set(target_srcs ${target_srcs} ${generated_file})
356      set_source_files_properties(
357        ${generated_file}
358        properties
359        external_object true # this is an object file
360        generated true        # to say that "it is OK that the obj-files do not exist before build time"
361      )
362    ELSE()
363      set(target_srcs ${target_srcs} ${file})
364    ENDIF(${file} MATCHES ".*\\.lua$")
365  ENDFOREACH(file)
366ENDMACRO()
367
368MACRO(LUA_ADD_EXECUTABLE luajit_target)
369  LUAJIT_add_custom_commands(${luajit_target} ${ARGN})
370  add_executable(${luajit_target} ${target_srcs})
371ENDMACRO(LUA_ADD_EXECUTABLE luajit_target)
372