Movatterモバイル変換


[0]ホーム

URL:


leafo.net

My projects

View more →

Recent guides

View all →

Recent posts

Using LuaRocks to install packages in the current directory

How to configure where LuaRocks installs modules

PostedJanuary 28, 2016 by leafo (@moonscript) · Tags: lua
Tweet

LuaRocks is the package manager for Lua. When youdecide to install a package (or module1) there are afew places it can be installed.

The directory that LuaRocks installs to is called atree. It’s a speciallystructured directory that contains all the installed module files, along withmetadata about those modules.

A common request I've heard is“I wish LuaRocks worked likenpm and let meinstall modules in the current directory.” I'm glad to report it already can!I've written this guide to clear up any confusion about how and where LuaRocksinstalls modules.

There are three ways of choosing where packages get installed:

  • Global — the default, system level (eg./usr/share/lua/5.1)
  • Local — your home directory, with--local
  • Custom — any directory you specify with--tree some/directory

For general purpose modules, ones that will be available for any Lua script youexecute, thelocal tree should be used. This tree is located in your homedirectory (~/.luarocks). A global install is not recommended because itrequires root access.

If you're building a project in Lua you'll probably want to more closelycontrol the dependencies and their versions. For this scenario I recommendusing a tree that is located in the project’s directory. This is the approachused by other package mangers such asnpm.

How Lua finds packages

This section is not specific to LuaRocks, but LuaRocks utilizes this systemto provide Lua a way to load the modules it installs.

When executingrequire("hello.world") Lua must figure out where the file forthis module is in order to load it. A module can resolve to either Lua sourcecode, a.lua file, or a native code library, a.so on Linux or.dll onWindows.

Similar to your operating system’sPATH environment variable for findingexecutables, Lua has apath to find modules. As mentioned above, there aretwo types of modules, so Lua has two paths.

You can view (and edit) the paths usingpackage.path andpackage.cpathwithin a Lua script:

print(package.path)-- where .lua files are searched forprint(package.cpath)-- where native modules are searched for-- add a new directory to the pathpackage.path=package.path..";/opt/custom/?.lua"require("hello.zone")-- might load /opt/custom/hello/zone.lua

The initial value ofpackage.path andpackage.cpath comes from the defaultscompiled into your Lua executable, and the special environment variablesLUA_PATH andLUA_CPATH.

Setting the path with LuaRocks

LuaRocks has a built in command for setting the Lua path environment variables.It’s calledluarocks path

Running it the command might produce:

$ luarocks pathexport LUA_PATH='/home/leafo/.luarocks/share/lua/5.1/?.lua;/home/leafo/.luarocks/share/lua/5.1/?/init.lua;/usr/share/lua/5.1/?.lua;/usr/share/lua/5.1/?/init.lua;;./?.lua;/usr/lib/lua/5.1/?.lua;/usr/lib/lua/5.1/?/init.lua'export LUA_CPATH='/home/leafo/.luarocks/lib/lua/5.1/?.so;/usr/lib/lua/5.1/?.so;;./?.so;/usr/lib/lua/5.1/loadall.so'

The special syntax;; can be used in the environment variable’s value torepresent the default value provided by the Lua runtime.

This is a shell script that will set the Lua path environment variables tocorrectly load modules from the global and local install locations of LuaRocks.

You might want to append this to your.bashrc like this:

$ luarocks path >> ~/.bashrc

Now you canrequire() any modules that you've installed locally or globallywithout any additional steps. (After restarting your shell or sourcing the rcfile)

Modules installed globally will work without adjusting the Lua path sincethey are installed in the default Lua system path.

The install locations

Using a custom directory

Don’t care about the explanation, go to thequick guide.

Installing packages to the current directory is as simple as

luarocks install --tree lua_modules lpeg

This will install the packagelpeg (and any dependencies if necessary) to thedirectorylua_modules in the current directory.

Loading those modules is a bit more complicated.

The structure of thetree, atlua_modules/, after installinglpeg lookslike this:

lua_modules/├── lib│   ├── lua│   │   └── 5.1│   │       └── lpeg.so│   └── luarocks│       └── rocks-5.1│           ├── lpeg│           │   └── 1.0.0-1│           │       ├── lpeg-1.0.0-1.rockspec│           │       └── rock_manifest│           └── manifest└── share    └── lua        └── 5.1            └── re.lua

I happen to be using a version of LuaRocks compiled for Lua 5.1 in thisexample, but this technique will work for any version. Just make sure thepaths you create have the correct version

For this example I choselpegbecause it contains both a.lua module:re, and a native.so module:lpeg. From this we can already see how we might structure our Luapath andcpath.

  • Thepath would be:lua_modules/share/lua/5.1/?.lua
  • Thecpath would be:lua_modules/lib/lua/5.1/?.so

There’s one more entry we'd like to add to the path. A common idiom is to useaninit.lua file as the entry point for a package, located in the directoryof that package. We'll amend the path:

  • Thepath would be:lua_modules/share/lua/5.1/?.lua;lua_modules/share/lua/5.1/?/init.lua
  • Thecpath would belua_modules/lib/lua/5.1/?.so

; is used to provide two places to look in the path

As discussed above there are a few ways to enable these paths. From commandline you could prepend the environment variables in front of your command:

LUA_PATH='lua_modules/share/lua/5.1/?.lua;lua_modules/share/lua/5.1/?/init.lua;;' LUA_CPATH='lua_modules/lib/lua/5.1/?.so' lua my_script.lua

That’s a mouthful though, so lets use an alternate approach. Thelua commandline executable can take an-l flag to specify a module to load beforeexecuting the script.

Lets create a new file in the current directory,set_paths.lua:

-- set_paths.lualocalversion=_VERSION:match("%d+%.%d+")package.path='lua_modules/share/lua/'..version..'/?.lua;lua_modules/share/lua/'..version..'/?/init.lua;'..package.pathpackage.cpath='lua_modules/lib/lua/'..version..'/?.so;'..package.cpath

Now to run a script with the modules installed in that directory:

lua -l set_paths my_script.lua

This requires that the script be run from the same directory thatset_paths.lua andlua_modules/ is located

You might be tempted to putrequire("set_paths") in your code’s entry pointto avoid the additional argument, butit’s a bad idea.

A module should run on any machine it is installed to regardless of the packagepath configuration. Theset_paths script is only to facilitate developmentand execution in the current directory.

By configuring paths on script execution, you avoid embedding any assumptionsabout the package path in your code. If this additional step is too much totype, consider aMakefile that includes some of your common commands.

Quick guide

Want the full explanation? Scroll up.

Installing a package
luarocks install --tree lua_modules lpeg
Running scripts with packages

Create fileset_paths.lua:

-- set_paths.lualocalversion=_VERSION:match("%d+%.%d+")package.path='lua_modules/share/lua/'..version..'/?.lua;lua_modules/share/lua/'..version..'/?/init.lua;'..package.pathpackage.cpath='lua_modules/lib/lua/'..version..'/?.so;'..package.cpath

Execute scripts:

lua -l set_paths my_script.lua

Running tests withbusted:

busted --helper=set_paths

Do not includerequire("set_paths") in your code, scroll up to see why.

Local install

Installing packages to thelocal tree, or the home directory, requires the--local flag to be passed to theluarocks install install command. This isthe recommended way to install packages that are generally available because itdoes not require root access to perform the installation.

$ luarocks install --local moonscript

TheLUA_PATH andLUA_CPATH should be configured. This can be done with theluarocks path command as discussed above.

print(require("moonscript"))

Global install

Installing packages in the system tree requires root access. Prefixing theluarocks command withsudo is a common way to install global packages:

$ sudo luarocks install moonscript

Installing globally is not recommended since it requires root access. Use thelocal tree to install packages andmake them available for all your scripts.


1: The distinction isn’t always clear, but a package is synonymouswith a library, and a module is an individual thing (.lua file, shredlibrary) you can include from that package. I tend to use them interchangeably.

Here are some more guides tagged 'lua'
PostedApril 26, 2020
PostedJune 09, 2016
PostedJanuary 24, 2016
PostedAugust 08, 2015
PostedJuly 08, 2015
PostedJuly 08, 2015
PostedJuly 05, 2015
PostedJuly 04, 2015
PostedJuly 04, 2015

Related projects

LuaRocks.org

A community LuaRocks hosting repository

leafo.net · Generated Sun Oct 8 13:02:35 2023 bySitegenmastodon.social/@leafo


[8]ページ先頭

©2009-2025 Movatter.jp