Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

306 lines (258 sloc) 9.783 kb
--[[
Supporting code for the UNIX makefile of the Lua/APR binding.
Author: Peter Odding <peter@peterodding.com>
Last Change: December 4, 2011
Homepage: http://peterodding.com/code/lua/apr/
License: MIT
This Lua script enhances the UNIX makefile of the Lua/APR binding in two ways,
both aiming to make the build process more portable:
- The external programs pkg-config, apr-1-config, apu-1-config and
apreq2-config are used to find the compiler and linker flags
for the Lua 5.1, APR 1, APR-util 1 and libapreq2 libraries.
- It knows about needed system packages on Debian, Ubuntu,
Arch Linux, Red Hat, Fedora Core, Suse Linux and CentOS.
The makefile always invokes this script to find compiler and linker flags, but
only when the build fails will the script be called to perform a "sanity
check" of the external dependencies / system packages.
]]
local DEBUG = os.getenv 'LUA_APR_DEBUG'
-- Miscellaneous functions. {{{1
-- trim() -- Trim leading/trailing whitespace from string. {{{2
local function trim(s)
return s:match '^%s*(.-)%s*$'
end
-- dedent() -- remove common leading whitespace from string. {{{2
local function dedent(text)
local pattern = '\n' .. text:match '^[ \t]*'
return trim(('\n' .. text):gsub(pattern, '\n'))
end
-- message() -- Print formatted message to standard error. {{{2
local function message(text, ...)
io.stderr:write(dedent(text:format(...)), '\n')
io.stderr:flush()
end
-- words() -- Iterate over whitespace separated words. {{{2
local function words(text)
return text:gmatch '%S+'
end
-- readfile() -- Read the contents of a file into a string. {{{2
local function readfile(path)
local handle = io.open(path)
local content = handle and handle:read '*a' or ''
if handle then handle:close() end
return content
end
-- executable() -- Check whether a given program is executable. {{{2
local function executable(program)
return os.execute('which ' .. program .. ' >/dev/null 2>&1') == 0
end
-- readcmd() -- Get the results of a shell command (status, stdout, stderr). {{{2
local function readcmd(command)
local stdout = os.tmpname()
local stderr = os.tmpname()
local status = os.execute(command
.. ' 1>"' .. stdout .. '"'
.. ' 2>"' .. stderr .. '"')
local output = readfile(stdout)
local errors = readfile(stderr)
os.remove(stdout)
os.remove(stderr)
return status, output, errors
end
-- readstdout() -- Get the standard output of a shell command. {{{2
local function readstdout(command)
local status, stdout, stderr = readcmd(command)
return status == 0 and stdout or ''
end
-- sudo() -- Prepend `sudo' to a command when `sudo' is installed. {{{2
local function sudo(command, args)
if executable 'sudo' and (os.getenv 'SUDO_USER'
or readstdout 'id -un' ~= 'root') then
command = 'sudo ' .. command
end
if #args > 0 then
command = command .. ' ' .. table.concat(args, ' ')
end
return command
end
-- mergeflags() -- Merge command line flags reported by pkg-config. {{{2
local function mergeflags(flags, command)
local status, stdout, stderr = readcmd(command)
if status == 0 then
for flag in words(stdout) do
if not flags[flag] then
local position = #flags + 1
flags[flag] = position
flags[position] = flag
end
end
end
end
-- getcflags() -- Get the compiler flags needed to build the Lua/APR binding. {{{1
local function getcflags()
local flags, count = {}, 0
-- Compiler flags for Lua 5.1.
mergeflags(flags, 'pkg-config --cflags lua5.1') -- Debian/Ubuntu
mergeflags(flags, 'pkg-config --cflags lua-5.1') -- FreeBSD
mergeflags(flags, 'pkg-config --cflags lua') -- Arch Linux
if DEBUG and #flags == 0 then
message "Warning: Failed to determine Lua 5.1 compiler flags."
end
count = #flags
-- Compiler flags for APR 1.
mergeflags(flags, 'apr-1-config --cflags --cppflags --includes') -- sometimes this is available
mergeflags(flags, 'pkg-config --cflags apr-1') -- otherwise we fall back to pkg-config
if DEBUG and #flags == count then
message "Warning: Failed to determine APR 1 compiler flags."
end
count = #flags
-- Compiler flags for APR-util 1.
mergeflags(flags, 'apu-1-config --includes') -- sometimes this is available
mergeflags(flags, 'pkg-config --cflags apr-util-1') -- otherwise we fall back to pkg-config
if DEBUG and #flags == count then
message "Warning: Failed to determine APR-util 1 compiler flags."
end
count = #flags
-- Compiler flags for libapreq2.
mergeflags(flags, 'apreq2-config --includes')
local have_apreq = (#flags > count)
if DEBUG and not have_apreq then
message "Warning: Failed to determine libapreq2 compiler flags."
end
-- Let the C source code know whether libapreq2 is available.
flags[#flags + 1] = '-DLUA_APR_HAVE_APREQ=' .. (have_apreq and 1 or 0)
return table.concat(flags, ' ')
end
-- getlflags() -- Get the linker flags needed to build the Lua/APR binding. {{{1
local function getlflags()
local flags = {}
-- Linker flags for APR 1.
mergeflags(flags, 'apr-1-config --link-ld --libs')
mergeflags(flags, 'pkg-config --libs apr-1')
if DEBUG and #flags == 0 then
message "Warning: Failed to determine APR 1 linker flags."
end
count = #flags
-- Linker flags for APR-util 1.
mergeflags(flags, 'apu-1-config --link-ld --libs --ldap-libs')
mergeflags(flags, 'pkg-config --libs apr-util-1')
if DEBUG and #flags == count then
message "Warning: Failed to determine APR-util 1 linker flags."
end
count = #flags
-- Linker flags for libapreq2.
mergeflags(flags, 'apreq2-config --link-ld')
if DEBUG and #flags == 0 then
message "Warning: Failed to determine apreq2 linker flags."
end
return table.concat(flags, ' ')
end
-- checkpackages() -- Check if required system packages are installed. {{{1
local function delimiter()
message(string.rep('-', 79))
end
local function checkpackages()
-- Let the user know what's going on.
delimiter()
message [[
It looks like your Lua/APR build failed. This could be because you're
missing some external dependencies. I will now check if you have the
required system packages installed (this should work on Debian, Ubuntu,
Arch Linux, Red Hat, Fedora Core, Suse Linux and CentOS).
]]
delimiter()
-- Perform platform detection.
local command, requiredpackages, installedpackagescmd
if executable 'dpkg' and executable 'apt-get' then
-- Debian & Ubuntu.
-- Tested on Ubuntu Linux 10.04 (Lucid Lynx).
command = 'apt-get install'
installedpackagescmd = [[ dpkg --list | awk '/^i/ {print $2}' ]]
requiredpackages = [[
lua5.1 liblua5.1-0 liblua5.1-0-dev
libapr1 libapr1-dev
libaprutil1 libaprutil1-dev libaprutil1-dbd-sqlite3
libapreq2 libapreq2-dev
]]
-- Newer versions of Ubuntu install "recommended packages" by default, but
-- unfortunately the libapreq2 package recommends libapache2-mod-apreq2 which
-- pulls in the whole Apache server :-|. I think this is stupid and work
-- around it by passing the --no-install-recommends command line option
-- when it seems to be supported (unfortunately "apt-get --help" doesn't list
-- the supported command line options so we have to grep the binary :-P).
if os.execute 'strings /usr/bin/apt-get | grep -q install-recommends 1>/dev/null 2>&1' == 0 then
command = command .. ' --no-install-recommends'
end
elseif executable 'rpm' and executable 'yum' then
-- Red Hat, Fedora Core, Suse Linux & CentOS.
-- Tested on Fedora Core 15.
command = 'yum install'
installedpackagescmd = [[ rpm -qa --qf '%{NAME}\n' ]]
requiredpackages = [[
lua lua-devel
apr apr-devel
apr-util apr-util-devel
libapreq2 libapreq2-devel
]]
elseif executable 'pacman' then
-- Arch Linux.
-- Tested on Arch Linux 2011.08.19.
command = 'pacman -S'
installedpackagescmd = [[ bash -c "comm -23 <(pacman -Qeq) <(pacman -Qmq)" ]]
requiredpackages = [[ lua apr apr-util perl-libapreq2 ]]
else
message [[
Unknown platform: You'll have to install the required system
packages manually (lua, apr, apr-util and libapreq2).
]]
delimiter()
os.exit(1)
end
-- Find the installed packages.
local installedpackages = {}
local handle = io.popen(installedpackagescmd)
for name in handle:lines() do
installedpackages[name] = true
end
-- Determine missing packages.
local missingpackages = {}
for name in words(requiredpackages) do
if installedpackages[name] then
message(" - Package `%s' is already installed.", name)
else
message(" - Missing package `%s'!", name)
table.insert(missingpackages, name)
end
end
-- If we found any missing system packages, suggest to the user how the
-- missing packages can be installed.
delimiter()
if #missingpackages == 0 then
message [[
It looks like you have all required external dependencies installed,
something else must have gone wrong...
]]
else
message([[
The Lua/APR binding has several external dependencies and it looks like
some are missing on your system. You should be able to install the
dependencies with the following command:
%s
]], sudo(command, missingpackages))
end
delimiter()
-- Because this script is executed from the makefile in || expressions we
-- always exit with a non-zero exit code, so that the build still fails.
os.exit(1)
end
-- }}}1
if arg[1] == '--cflags' then
print(getcflags())
elseif arg[1] == '--lflags' then
print(getlflags())
elseif arg[1] == '--check' then
checkpackages()
else
message("Invalid option!")
os.exit(1)
end
Jump to Line
Something went wrong with that request. Please try again.