Building Lua |
|
For detailed instructions, see also [Chapter 1] of "Beginning Lua Programming".
BuildingModules explains how to build C extension modules for Lua.
Please note that Lua is a clean subset of ANSI C, and can be compiled as C or C++. Lua headers do not come with {#ifdef __cplusplus extern "C" {#endif ... Lua header ...#ifdef __cplusplus}#endif } in them so that lua can be compiled as C or C++ simply by changing the name of the files, without having to make any changes to the file contents.
If lua was compiled as a C library, which is typical with pre-packaged binaries, in order to embed Lua in a C++ application (i.e. link C to C++) you will have to place extern "C"
around the inclusion of the Lua headers in your C++ application, e.g.,
extern "C" { #include "lua.h" }
If you do not do this you may get link errors because of C++ name mangling.
Please do not complain about this on the mailing list. :-) Take the time to search the mailing list as this has been covered many times before.
It could be argued that if you are distributing a pre-packaged binaries of the libraries, then you have compiled the lua core as either C (most likely) or as C++, and if you compiled lua as C, you should modify the lua headers to indicate this. However, using prebuilt libraries for lua isn't recommended by the authors, they recommend directly incorporating the lua source into your application. See BuildingModules for a discussion (the end of the page).
By default if lua 5.1 or later is compiled as C++, it will use C++ exceptions to unwind the stack rather than longjmp/setjmp, though this is configurable (at compile time). See luaconf.h near LUAI_THROW/LUAI_TRY for a discussion of this.
For 5.0, you may have to contact Alexey to find a patch that to use C++ exceptions rather than setjmp/longjmp, find his email on the page:' AlexeyVolynskov
Be aware that as of lua 5.1.1, when building with LUA_USE_MACOSX defined, lua avoids the use of dlopen() and the other dlfcn APIs on OS X because dlopen() didn't used to be supported without using a 3rd party (open source) dlcompat library. However, as of OS X 10.3, dlopen() is provided, and as of OS X 10.4 dlopen() is the recommended way to dynamically load libraries (for non-objective-c code, at least). That means that the OS X specific module loading code is completely unnecessary if you don't want to target pre-10.3 versions of OS X. If you define LUA_USE_DLOPEN it will take precedence over the LUA_USE_DL_DYLD.
See http://developer.apple.com/releasenotes/DeveloperTools/RN-dyld/index.html for more information.
Lua Build [1] contains files to build lua, luac and libraries. It works on the following platforms. It contains all of the necessary source code and build files.
vc6/Lua.dsw
and do Build
).
tar xvzf luabuild-x.x.tgz ; cd LuaX/unix; make all
)
Please contact NickTrout if you would like to add another platform. Currently only statically linked versions of Lua are built.
Take everything in src and src/lua and do : -
bcc *.c -olua.exe
All projects must be created within the Lua src directory ''1 Core.lib and standard lib'' create a static library(for .dll)(.lib) for Win32 Console or GUI have no importance for the lib. Add the required files mentionned in the Install file. Add to the project include directory the lua include directory. Setup the compiler to Pentium code and Word data alignment: you will then be able to define USE_FASTROUND in luser_number.h. Compile.
Alternative :create a dynamic library(.dll) for Win32 Console or GUI have no importance for the lib. Add the required files mentionned in the Install file. Modify the lua.h and lualib.h files by defining: LUA_API as __declspec(dllexport) and LUALIB_API as __declspec(dllexport). Add to the project include directory the lua include directory. Setup the compiler to Pentium code and Word data alignment: you will then be able to define USE_FASTROUND in luser_number.h. Compile.
Notes : the compiler will complain and create warnings regarding inexistant structures (e.g. lua_State). You can safely ignore them. If you want to USE_POPEN, you need to convert popen and pclose to _popen and _pclose. You can define USE_TMPNAME to 1. 2 Lua interpreter and compiler create an executable (.exe) for Win32 and Console. Include the Core and Standard libraries and the required files mentionned in the Install file. Add to the project include directory the lua include directory. Setup the compiler to Pentium code and Word data alignment. Compile. You are ready to go !
Note : If you use Lua DLLs instead of LIBs, don't forget to define in lua.h and lualib.h LUA_API as __declspec(dllimport) and LUALIB_API as __declspec(dllimport).
Briefly this includes a Visual Studio Solution and 3 projects. A project to build Lua 5.x as a static lib, a project to test that the lib is working, and a project to build luac. Here are the details of what this is [Read Me] here are the files [Visual Studio .Net 2003 ( version 7.1 ) Solution and Project files]
Note: Download files at [Philippe Lhoste (PhiLho) French Web site], I have to update the Lua page for direct downloads.
They can be used with little changes for Lua 4.0.1 (specific project for this version is available too).
Basically, I have set a .dsw file (workspace) at the root of the Lua tree, and several .dsp (projects) scattered on the hierarchy, to produce either library files, DLLs or executables.
To compile, you should do the libraries first (dependencies should take care of this).
To do the DLLs, I had to create .def files, but for Lua 4.0.1, I just used the make_def.lua script (supposing I already have a Lua binary, of course :-) ).
You don't have to create .def files to make DLL's, just add LUA_API=__declspec(dllexport)
or LUALIB_API=__declspec(dllexport)
to your C compiler defines, worked perfectly for me.
-- JaenSaul
Yes, but at Lua 4.0 time, this facility wasn't available, and I derivated the 5.0 projects from the 4.0 ones. Beside, I like .def files, it allows to see all the API functions at a glance... -- PhilippeLhoste
Seems someone made a provision for this (at least as of 5.1) with the LUA_BUILD_AS_DLL define. -- BobClown?
I also created some resource files, to give nice icons and some version information.
Simply:
make mingw
But the lua executable that you will obtain will not support the dynamic
loading of modules. If you want to enable this feature you should modify
the target mingw
to:
mingw: $(MAKE) "LUA_A=lua51.dll" "LUA_T=lua.exe" \ "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ "MYCFLAGS='-DLUA_DL_DLL -DLUA_BUILD_AS_DLL'" "MYLIBS=" "MYLDFLAGS=-s" \ lua.exe $(MAKE) "LUAC_T=luac.exe" luac.exe
For those willing to live dangerously (in the sense that extra symbols
are exported from the DLL that are not official Lua APIs) you can build
both lua.exe and luac.exe by changing the mingw
target to:
mingw: $(MAKE) "LUA_A=lua51.dll" "LUA_T=lua.exe" "LUAC_T=luac.exe" \ "AR=$(CC) -shared -Wl,--export-all-symbols -o" "RANLIB=strip --strip-unneeded" \ "MYCFLAGS=-DLUA_BUILD_AS_DLL" "MYLIBS=" "MYLDFLAGS=-s" all
Note that the official Lua distribution creates and uses lua51.dll
whereas
LuaBinaries distributes lua5.1.dll
. Both use the name lua.exe
but that
application is linked with one or the other DLL
-- this can be the source of subtle bugs when both are installed (see below 'Creating a forward dll').
To install Lua properly, open the top-level Makefile and change:
TO_BIN= lua luac
to TO_BIN= lua.exe luac.exe lua51.dll
cd src && $(INSTALL_DATA) $(TO_LIB) $(INSTALL_LIB)
to #cd src && $(INSTALL_DATA) $(TO_LIB) $(INSTALL_LIB)
Now for some older versions...
Here are config [13] and Makefile [14] samples used successfully to build Lua 5.0.2. No changes are necessary to the Makefiles in Lua's subdirectories. Use the target dll (i.e., "make dll") to build everything with lua.exe and luac.exe using lua.dll and lualib.dll. Copy everything in the lua-5.0.2/bin to MSYS/local/bin and copy liblualib.a and liblua.a to MSYS/local/lib. Now you can compile dynamically loadable libraries by linking them with liblualib.a and liblua.a (-L /usr/local/lib -llua -llualib).
Here are Makefile and luaconf.h examples [15] for building lua-5.1-work5 as a pair of DLLs and a pair of applications. "make install" puts these files into the Mingw /usr/local subdirectories.
Warning: the following applies to the older (1.5) version of Cygwin. Cygwin 1.7 no longer uses "-mno-cygwin" (someone: please update this section).
Unfortunately, the Lua 5.1.1 Makefile does not have an option for cleanly building from the version of MinGW included in Cygwin.
To easily build Lua for Windows using Cygwin without modifying the Makefiles:
make "CC=gcc -mno-cygwin" mingw
If you also want luac.exe:
make "CC=gcc -mno-cygwin" -C src LUAC_T=luac.exe luac.exe
These commands build lua.exe dynamically linked to lua51.dll and builds luac.exe statically linked to lua. The reason we don't dynamically link luac.exe to lua51.dll is that luac.exe uses certain internal functions not exported by lua51.dll . A possibly better approach would be to export those additional symbols from lua51.dll [2], and preferably only adding those symbols.
Instead of the above two commands, it is also fairly straight-forward to modify the Lua Makefile. Add the following to src/Makefile:
mingw-cygwin: $(MAKE) "LUA_A=lua51.dll" "LUA_T=lua.exe" \ "CC=gcc -mno-cygwin" \ "AR=gcc -mno-cygwin -shared -o" "RANLIB=strip --strip-unneeded" \ "MYCFLAGS=-DLUA_BUILD_AS_DLL" "MYLIBS=" "MYLDFLAGS=-s" lua.exe && \ $(MAKE) "LUAC_T=luac.exe" "CC=gcc -mno-cygwin" luac.exe
then build with make mingw-cygwin
.
To install, add "TO_LIB=lua51.dll" to the make command. For example,
make TO_LIB=lua51.dll local
The following describes building a Cygwin build of Lua (i.e. linked against cygwin1.dll [*3]). For MinGW builds under Cygwin, see above instead. See also the Cygwin Lua package [3][4][5].
"make posix" will build a Cygwin Lua without shared library support or readline support.
"make linux" will build a Cygwin Lua without shared library support and with readline support.[*1]
"make mingw" will build a Cygwin Lua with shared library support, but it doesn't use "-DLUA_USE_LINUX" so it won't be ideal.
To build a Cygwin Lua with shared library support and readline support, you can use these build rules[*2]:
cygwin: $(MAKE) "LUA_A=cyglua-5.1.dll" "LUA_T=lua.exe" \ "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ "MYCFLAGS=-DLUA_USE_LINUX -DLUA_BUILD_AS_DLL" \ "MYLIBS=-lreadline -lhistory" "MYLDFLAGS=-s" lua.exe
The above also works for Lua 5.2, just change the name of the DLL:
cygwin: $(MAKE) "LUA_A=cyglua-5.2.dll" "LUA_T=lua.exe" \ "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ "MYCFLAGS=-DLUA_USE_LINUX -DLUA_BUILD_AS_DLL" \ "MYLIBS=-lreadline -lhistory" "MYLDFLAGS=-s" lua.exe
Note: Cygwin usually prefixes shared libraries by "cyg". The Lua package in Cygwin uses "cyglua-5.1.dll", though you may still use the conventional Windows "lua51.dll" or "lua52.dll".
Unlike Linux, Cygwin doesn't require "-lncurses", although it doesn't hurt.
LUA_USE_ULONGJMP
, which is part of LUA_POSIX
and in turn LUA_USE_LINUX
, used to cause a harmless warning in Cygwin 1.5 [16]. In Cygwin 1.7, this appears to no longer occur because Cygwin 1.7 defines _setjmp
. Therefore, LUA_POSIX
or LUA_USE_LINUX
can now be used without warning in Cygwin.
The "MYLDFLAGS=-s" is optional: It strips symbols from the executables, which aren't needed, thereby reducing file size. "RANLIB=strip --strip-unneeded" is optional too: this reduces the number of unnecessary symbols in the DLL. The Lua Cygwin package uses "RANLIB=:" (i.e. do nothing), which can also be written "RANLIB=@:" (i.e. no output). The Lua default "RANLIB=ranlib" is invalid to execute on a Windows DLL.
The Lua Cygwin package uses "AR=$(CC) -shared -Wl,--enable-auto-image-base -Wl,--enable-auto-import -Wl,--out-implib,liblua.dll.a -o". The "-Wl,--out-implib,liblua.dll.a" generates an import library if you want one (actually optional in Windows-based gcc). The "-Wl,--enable-auto-import" should be standard on Cygwin [6]. The "-Wl,--enable-auto-image-base [7][8][9][10] is an optional improvement but apparently enabled by default now [11][12]. Therefore, it looks like "-Wl,--enable-auto-image-base -Wl,--enable-auto-import" is no longer needed.
You may, like the Lua Cygwin package, wish to set LUA_CPATH_DEFAULT to use .dll rather than .so for the extension of Lua C modules, but this is optional.
For info on using LuaRocks under Cygwin, see [*4]
For a quick and clean (not dirty! :-)) Lua build with Dev-C++, use this .bat file:[17]. You may have to alter your path before running this .bat with that (SET PATH=C:\Dev-Cpp\Bin;C:\Dev-Cpp\lib\gcc-lib\mingw32\3.2;%PATH% please reflect with the directory of you Dev C++). It builds lua.exe, luac.exe, lua5.dll and lualib5.dll. Copy it to lua-5.0 directory and run. I hate to say this, but this .bat has no warranty (it worked for _me_ on Windows XP and 2000), i just hope it'll be useful (additionally, it's much easier to read than makefiles). For building all with devCpp, use this .bat/.cmd [18]. You'll have to edit it if DevCPP is not in C:\Dev-Cpp\. Copy the file to lua-5.0 directory and run it, it'll build liblua.a, liblualib.a, lua5.dll, lualib5.dll, lua.exe and luac.exe. I've tested with dev-cpp 5 beta.
Lua 5.0.2 (and most probably higher versions) can be built in Windows using these devcpp configurations. 1. Download the lua tar.gz and extract it to a folder of your choice. 2. Download and extract this file [19] into the lua-5.0.2 folder so that you have a subfolder called devcpp 3. open the devcpp folder and double click on corelibs.dev etc.
NOTE: Change -DLUA_API=__declspec(dllexport) to -DLUA_API='__declspec(dllexport)'
Just hit the compile button and everything should be fine Remark that there MUST NOT be any lua.dll's in you system path. Otherwise the standard libs and lua.exe may have problems linking to the correct dll. I don't know how to set this from the devcpp files directly.
The default name for the Lua 5.1 DLL as specified in Lua makefile is lua51.dll. However there are several precompiled binaries out there using another convention. The real problems appear when you use an interpreter using one convention (for example lua51.dll) and try to load a module using another convention (lua5.1.dll). If both dll exist, both will be loaded resulting in code duplication, and potential bugs related to static variable duplication (for example freeing a block of memory in one dll while it was allocated in the other can lead to unpredictable results).
The solution is to make sure that the interpreter and all modules use the same dll. If they were linked with different dll names, you can create a kind of fake dll (called a proxy dll or forwarding dll), that forward all API calls to the good one. In the example above you could create a proxy dll called lua5.1.dll that forwards all calls to lua51.dll. That way both the interpreter and the modules will use the same copy of the dll (lua51.dll), avoiding problems mentionned above.
You can find scripts generating such a DLL there: LuaProxyDllThree and there: LuaProxyDllTwo.
This is a minimal CMakeLists file
PROJECT ( lua ) IF( NOT WIN32 ) message( FATAL_ERROR "Written for window only" ) ENDIF() CMAKE_MINIMUM_REQUIRED(VERSION 2.8) # remove warnings ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS ) SET (HDR_LIBLUA src/lapi.h src/lauxlib.h src/lcode.h src/lctype.h src/ldebug.h src/ldo.h src/lfunc.h src/lgc.h src/llex.h src/llimits.h src/lmem.h src/lobject.h src/lopcodes.h src/lparser.h src/lstate.h src/lstring.h src/ltable.h src/ltm.h src/lua.h src/luaconf.h src/lualib.h src/lundump.h src/lvm.h src/lzio.h ) #SET_SOURCE_FILES_PROPERTIES(${HDR_LIBLUA} PROPERTIES HEADER_FILE_ONLY TRUE) #include_directories(src) # Build Libraries SET (SRC_LIBLUA src/lapi.c src/lauxlib.c src/lbaselib.c src/lbitlib.c src/lcode.c src/lcorolib.c src/lctype.c src/ldblib.c src/ldebug.c src/ldo.c src/ldump.c src/lfunc.c src/lgc.c src/linit.c src/liolib.c src/llex.c src/lmathlib.c src/lmem.c src/loadlib.c src/lobject.c src/lopcodes.c src/loslib.c src/lparser.c src/lstate.c src/lstring.c src/lstrlib.c src/ltable.c src/ltablib.c src/ltm.c src/lundump.c src/lvm.c src/lzio.c ) SET ( SRC_LUA src/lua.c ) SET ( SRC_LUAC src/luac.c ) # compile with C++ compiler set_source_files_properties(${SRC_LIBLUA} ${SRC_LUA} ${SRC_LUAC} PROPERTIES LANGUAGE CXX) # append headers to sources to make them show up in MSVC GUI LIST(APPEND SRC_LIBLUA ${HDR_LIBLUA}) #Library ADD_LIBRARY ( lualib ${SRC_LIBLUA} ) #DLL ADD_LIBRARY ( lua5.2 SHARED ${SRC_LIBLUA} ) SET_TARGET_PROPERTIES (lua5.2 PROPERTIES DEFINE_SYMBOL "LUA_BUILD_AS_DLL" ) #exe ADD_EXECUTABLE ( lua ${SRC_LUA} ) ADD_EXECUTABLE ( luac ${SRC_LUAC} ) #lua uses a DLL; luac uses a library TARGET_LINK_LIBRARIES ( lua lua5.2 ) TARGET_LINK_LIBRARIES ( luac lualib )
copy and paste this into a CMakeLists.txt file in the root of 5.2.2
use a command like:
cmake -G "Visual Studio 10"
depending in your version of dev studio. Use the lua.sln file to compile.