Merge pull request #568 from tritao/rpaths
Use rpaths & soname/install_name to link sibling shared libraries on OS X and Linux
This commit is contained in:
commit
fd4b937449
@ -786,6 +786,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
api.register {
|
||||
name = "runpathdirs",
|
||||
scope = "config",
|
||||
kind = "list:path",
|
||||
tokens = true,
|
||||
}
|
||||
|
||||
api.register {
|
||||
name = "runtime",
|
||||
scope = "config",
|
||||
|
@ -178,9 +178,21 @@
|
||||
-- Format a list of values to be safely written as part of a variable assignment.
|
||||
--
|
||||
|
||||
function make.list(value)
|
||||
function make.list(value, quoted)
|
||||
quoted = false
|
||||
if #value > 0 then
|
||||
return " " .. table.concat(value, " ")
|
||||
if quoted then
|
||||
local result = ""
|
||||
for _, v in ipairs (value) do
|
||||
if #result then
|
||||
result = result .. " "
|
||||
end
|
||||
result = result .. premake.quoted(v)
|
||||
end
|
||||
return result
|
||||
else
|
||||
return " " .. table.concat(value, " ")
|
||||
end
|
||||
else
|
||||
return ""
|
||||
end
|
||||
|
@ -429,14 +429,14 @@
|
||||
|
||||
|
||||
function make.ldFlags(cfg, toolset)
|
||||
local flags = table.join(toolset.getLibraryDirectories(cfg), toolset.getldflags(cfg), cfg.linkoptions)
|
||||
local flags = table.join(toolset.getLibraryDirectories(cfg), toolset.getrunpathdirs(cfg, cfg.runpathdirs), toolset.getldflags(cfg), cfg.linkoptions)
|
||||
_p(' ALL_LDFLAGS += $(LDFLAGS)%s', make.list(flags))
|
||||
end
|
||||
|
||||
|
||||
function make.libs(cfg, toolset)
|
||||
local flags = toolset.getlinks(cfg)
|
||||
_p(' LIBS +=%s', make.list(flags))
|
||||
_p(' LIBS +=%s', make.list(flags, true))
|
||||
end
|
||||
|
||||
|
||||
|
@ -165,6 +165,7 @@
|
||||
|
||||
end
|
||||
|
||||
clang.getrunpathdirs = gcc.getrunpathdirs
|
||||
|
||||
--
|
||||
-- Build a list of linker flags corresponding to the settings in
|
||||
@ -189,6 +190,10 @@
|
||||
local r = { iif(cfg.system == premake.MACOSX, "-dynamiclib", "-shared") }
|
||||
if cfg.system == "windows" and not cfg.flags.NoImportLib then
|
||||
table.insert(r, '-Wl,--out-implib="' .. cfg.linktarget.relpath .. '"')
|
||||
elseif cfg.system == premake.LINUX then
|
||||
table.insert(r, '-Wl,-soname=' .. premake.quoted(cfg.linktarget.name))
|
||||
elseif cfg.system == premake.MACOSX then
|
||||
table.insert(r, '-Wl,-install_name,' .. premake.quoted('@rpath/' .. cfg.linktarget.name))
|
||||
end
|
||||
return r
|
||||
end,
|
||||
|
@ -191,6 +191,52 @@
|
||||
return result
|
||||
end
|
||||
|
||||
--
|
||||
-- Return a list of decorated rpaths
|
||||
--
|
||||
|
||||
function gcc.getrunpathdirs(cfg, dirs)
|
||||
local result = {}
|
||||
|
||||
if not ((cfg.system == premake.MACOSX)
|
||||
or (cfg.system == premake.LINUX)) then
|
||||
return result
|
||||
end
|
||||
|
||||
local rpaths = {}
|
||||
|
||||
-- User defined runpath search paths
|
||||
for _, fullpath in ipairs(cfg.runpathdirs) do
|
||||
local rpath = path.getrelative(cfg.buildtarget.directory, fullpath)
|
||||
if not (table.contains(rpaths, rpath)) then
|
||||
table.insert(rpaths, rpath)
|
||||
end
|
||||
end
|
||||
|
||||
-- Automatically add linked shared libraries path relative to target directory
|
||||
for _, sibling in ipairs(config.getlinks(cfg, "siblings", "object")) do
|
||||
if (sibling.kind == premake.SHAREDLIB) then
|
||||
local fullpath = sibling.linktarget.directory
|
||||
local rpath = path.getrelative(cfg.buildtarget.directory, fullpath)
|
||||
if not (table.contains(rpaths, rpath)) then
|
||||
table.insert(rpaths, rpath)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for _, rpath in ipairs(rpaths) do
|
||||
if (cfg.system == premake.MACOSX) then
|
||||
rpath = "@loader_path/" .. rpath
|
||||
elseif (cfg.system == premake.LINUX) then
|
||||
rpath = iif(rpath == ".", "", "/" .. rpath)
|
||||
rpath = "$$ORIGIN" .. rpath
|
||||
end
|
||||
|
||||
table.insert(result, "-Wl,-rpath,'" .. rpath .. "'")
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
--
|
||||
-- Return a list of LDFLAGS for a specific configuration.
|
||||
@ -212,8 +258,12 @@
|
||||
kind = {
|
||||
SharedLib = function(cfg)
|
||||
local r = { iif(cfg.system == premake.MACOSX, "-dynamiclib", "-shared") }
|
||||
if cfg.system == "windows" and not cfg.flags.NoImportLib then
|
||||
if cfg.system == premake.WINDOWS and not cfg.flags.NoImportLib then
|
||||
table.insert(r, '-Wl,--out-implib="' .. cfg.linktarget.relpath .. '"')
|
||||
elseif cfg.system == premake.LINUX then
|
||||
table.insert(r, '-Wl,-soname=' .. premake.quoted(cfg.linktarget.name))
|
||||
elseif cfg.system == premake.MACOSX then
|
||||
table.insert(r, '-Wl,-install_name,' .. premake.quoted('@rpath/' .. cfg.linktarget.name))
|
||||
end
|
||||
return r
|
||||
end,
|
||||
@ -313,7 +363,8 @@
|
||||
local links = config.getlinks(cfg, "system", "fullpath")
|
||||
for _, link in ipairs(links) do
|
||||
if path.isframework(link) then
|
||||
table.insert(result, "-framework " .. path.getbasename(link))
|
||||
table.insert(result, "-framework")
|
||||
table.insert(result, path.getbasename(link))
|
||||
elseif path.isobjectfile(link) then
|
||||
table.insert(result, link)
|
||||
else
|
||||
|
@ -187,7 +187,9 @@
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
function msc.getrunpathdirs()
|
||||
return {}
|
||||
end
|
||||
|
||||
--
|
||||
-- Decorate include file search paths for the MSVC command line.
|
||||
|
@ -102,6 +102,7 @@
|
||||
snc.getcppflags = gcc.getcppflags
|
||||
snc.getdefines = gcc.getdefines
|
||||
snc.getincludedirs = gcc.getincludedirs
|
||||
snc.getrunpathdirs = gcc.getrunpathdirs
|
||||
snc.getLibraryDirectories = gcc.getLibraryDirectories
|
||||
snc.getlinks = gcc.getlinks
|
||||
|
||||
|
@ -35,11 +35,20 @@
|
||||
kind "SharedLib"
|
||||
prepare { "ldFlags", "linkCmd" }
|
||||
test.capture [[
|
||||
ALL_LDFLAGS += $(LDFLAGS) -shared -s
|
||||
ALL_LDFLAGS += $(LDFLAGS) -shared -Wl,-soname=libMyProject.so -s
|
||||
LINKCMD = $(CXX) -o "$@" $(OBJECTS) $(RESOURCES) $(ALL_LDFLAGS) $(LIBS)
|
||||
]]
|
||||
end
|
||||
|
||||
function suite.links_onMacOSXCppSharedLib()
|
||||
_OS = "macosx"
|
||||
kind "SharedLib"
|
||||
prepare { "ldFlags", "linkCmd" }
|
||||
test.capture [[
|
||||
ALL_LDFLAGS += $(LDFLAGS) -dynamiclib -Wl,-install_name,@rpath/libMyProject.dylib -Wl,-x
|
||||
LINKCMD = $(CXX) -o "$@" $(OBJECTS) $(RESOURCES) $(ALL_LDFLAGS) $(LIBS)
|
||||
]]
|
||||
end
|
||||
|
||||
--
|
||||
-- Check link command for a shared C library.
|
||||
@ -50,7 +59,7 @@
|
||||
kind "SharedLib"
|
||||
prepare { "ldFlags", "linkCmd" }
|
||||
test.capture [[
|
||||
ALL_LDFLAGS += $(LDFLAGS) -shared -s
|
||||
ALL_LDFLAGS += $(LDFLAGS) -shared -Wl,-soname=libMyProject.so -s
|
||||
LINKCMD = $(CC) -o "$@" $(OBJECTS) $(RESOURCES) $(ALL_LDFLAGS) $(LIBS)
|
||||
]]
|
||||
end
|
||||
@ -153,12 +162,29 @@
|
||||
|
||||
prepare { "ldFlags", "libs", "ldDeps" }
|
||||
test.capture [[
|
||||
ALL_LDFLAGS += $(LDFLAGS) -Lbuild/bin/Debug -s
|
||||
ALL_LDFLAGS += $(LDFLAGS) -Lbuild/bin/Debug -Wl,-rpath,'$$ORIGIN/../../build/bin/Debug' -s
|
||||
LIBS += -lMyProject2
|
||||
LDDEPS += build/bin/Debug/libMyProject2.so
|
||||
]]
|
||||
end
|
||||
|
||||
function suite.links_onMacOSXSiblingSharedLib()
|
||||
_OS = "macosx"
|
||||
links "MyProject2"
|
||||
flags { "RelativeLinks" }
|
||||
|
||||
test.createproject(wks)
|
||||
kind "SharedLib"
|
||||
location "build"
|
||||
|
||||
prepare { "ldFlags", "libs", "ldDeps" }
|
||||
test.capture [[
|
||||
ALL_LDFLAGS += $(LDFLAGS) -Lbuild/bin/Debug -Wl,-rpath,'@loader_path/../../build/bin/Debug' -Wl,-x
|
||||
LIBS += -lMyProject2
|
||||
LDDEPS += build/bin/Debug/libMyProject2.dylib
|
||||
]]
|
||||
end
|
||||
|
||||
--
|
||||
-- Check a linking multiple siblings.
|
||||
--
|
||||
|
@ -347,7 +347,7 @@
|
||||
function suite.links_onFramework()
|
||||
links { "Cocoa.framework" }
|
||||
prepare()
|
||||
test.contains({ "-framework Cocoa" }, gcc.getlinks(cfg))
|
||||
test.contains({ "-framework Cocoa" }, {table.implode (gcc.getlinks(cfg), '', '', ' ')})
|
||||
end
|
||||
|
||||
function suite.links_onSystemLibs_onWindows()
|
||||
|
Loading…
Reference in New Issue
Block a user