Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve linker for package #5542 #5543

Merged
merged 5 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion tests/projects/c++/snippet_runtimes/xmake.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ add_requires("bar")
target("foo")
set_kind("binary")
add_files("src/*.cpp")

add_packages("bar")

on_config(function(target)
Expand Down
41 changes: 30 additions & 11 deletions xmake/core/package/package.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1281,9 +1281,9 @@ function _instance:toolconfig(name)
end
end

-- get the target compiler
-- get the package compiler
function _instance:compiler(sourcekind)
local compilerinst = self:_memcache():get("compiler")
local compilerinst = self:_memcache():get2("compiler", sourcekind)
if not compilerinst then
if not sourcekind then
os.raise("please pass sourcekind to the first argument of package:compiler(), e.g. cc, cxx, as")
Expand All @@ -1293,11 +1293,28 @@ function _instance:compiler(sourcekind)
os.raise(errors)
end
compilerinst = instance
self:_memcache():set("compiler", compilerinst)
self:_memcache():set2("compiler", sourcekind, compilerinst)
end
return compilerinst
end

-- get the package linker
function _instance:linker(targetkind, sourcekinds)
local linkerinst = self:_memcache():get3("linker", targetkind, sourcekinds)
if not linkerinst then
if not sourcekinds then
os.raise("please pass sourcekinds to the second argument of package:linker(), e.g. cc, cxx, as")
end
local instance, errors = linker.load(targetkind, sourcekinds, self)
if not instance then
os.raise(errors)
end
linkerinst = instance
self:_memcache():set3("linker", targetkind, sourcekinds, linkerinst)
end
return linkerinst
end

-- has the given tool for the current package?
--
-- e.g.
Expand Down Expand Up @@ -2357,22 +2374,24 @@ function _instance:_generate_build_configs(configs, opt)
end
end
if runtimes then
-- @note we need to patch package:sourcekinds(), because it wiil be called nf_runtime for gcc/clang
local sourcekind = opt.sourcekind or "cxx"
local tool, name = self:tool("ld")
local linker, errors = linker.load("binary", sourcekind, {target = package})
if not linker then
os.raise(errors)
self.sourcekinds = function (self)
return sourcekind
end
local fake_target = {is_shared = function(_) return false end,
sourcekinds = function(_) return sourcekind end}
local compiler = self:compiler(sourcekind)
local cxflags = compiler:map_flags("runtime", runtimes, {target = fake_target})
local cxflags = compiler:map_flags("runtime", runtimes, {target = self})
configs.cxflags = table.wrap(configs.cxflags)
table.join2(configs.cxflags, cxflags)

local ldflags = linker:map_flags("runtime", runtimes, {target = fake_target})
local ldflags = self:linker("binary", sourcekind):map_flags("runtime", runtimes, {target = self})
configs.ldflags = table.wrap(configs.ldflags)
table.join2(configs.ldflags, ldflags)

local shflags = self:linker("shared", sourcekind):map_flags("runtime", runtimes, {target = self})
configs.shflags = table.wrap(configs.shflags)
table.join2(configs.shflags, shflags)
self.sourcekinds = nil
end
if self:config("lto") then
local configs_lto = self:_generate_lto_configs(opt.sourcekind or "cxx")
Expand Down
2 changes: 1 addition & 1 deletion xmake/modules/core/tools/clang.lua
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ function nf_runtime(self, runtime, opt)
if triple_libdir then
maps["c++_shared"] = table.join(maps["c++_shared"], nf_rpathdir(self, triple_libdir))
end
if target:is_shared() and self:is_plat("macosx", "iphoneos", "watchos") then
if target:is_shared() and target.filename and self:is_plat("macosx", "iphoneos", "watchos") then
maps["c++_shared"] = table.join(maps["c++_shared"], "-install_name")
maps["c++_shared"] = table.join(maps["c++_shared"], "@rpath/" .. target:filename())
end
Expand Down
67 changes: 26 additions & 41 deletions xmake/modules/package/tools/autoconf.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@
-- imports
import("core.base.option")
import("core.project.config")
import("core.tool.linker")
import("core.tool.compiler")
import("core.tool.toolchain")
import("core.cache.memcache")
import("lib.detect.find_tool")
import("private.utils.toolchain", {alias = "toolchain_utils"})

-- translate paths
function _translate_paths(paths)
Expand Down Expand Up @@ -78,16 +77,6 @@ function _get_msvc_runenvs(package)
return os.joinenvs(_get_msvc(package):runenvs())
end

-- map compiler flags
function _map_compflags(package, langkind, name, values)
return compiler.map_flags(langkind, name, values, {target = package})
end

-- map linker flags
function _map_linkflags(package, targetkind, sourcekinds, name, values)
return linker.map_flags(targetkind, sourcekinds, name, values, {target = package})
end

-- is cross compilation?
function _is_cross_compilation(package)
if not package:is_plat(os.subhost()) then
Expand Down Expand Up @@ -199,13 +188,13 @@ function _get_cflags_from_packagedeps(package, opt)
local result = {}
if values then
if values.defines then
table.join2(result, _map_compflags(package, "cxx", "define", values.defines))
table.join2(result, toolchain_utils.map_compflags_for_package(package, "cxx", "define", values.defines))
end
if values.includedirs then
table.join2(result, _translate_paths(_map_compflags(package, "cxx", "includedir", values.includedirs)))
table.join2(result, _translate_paths(toolchain_utils.map_compflags_for_package(package, "cxx", "includedir", values.includedirs)))
end
if values.sysincludedirs then
table.join2(result, _translate_paths(_map_compflags(package, "cxx", "sysincludedir", values.sysincludedirs)))
table.join2(result, _translate_paths(toolchain_utils.map_compflags_for_package(package, "cxx", "sysincludedir", values.sysincludedirs)))
end
end
return result
Expand All @@ -230,16 +219,16 @@ function _get_ldflags_from_packagedeps(package, opt)
local result = {}
if values then
if values.linkdirs then
table.join2(result, _translate_paths(_map_linkflags(package, "binary", {"cxx"}, "linkdir", values.linkdirs)))
table.join2(result, _translate_paths(toolchain_utils.map_linkflags_for_package(package, "binary", {"cxx"}, "linkdir", values.linkdirs)))
end
if values.links then
table.join2(result, _map_linkflags(package, "binary", {"cxx"}, "link", values.links))
table.join2(result, toolchain_utils.map_linkflags_for_package(package, "binary", {"cxx"}, "link", values.links))
end
if values.syslinks then
table.join2(result, _translate_paths(_map_linkflags(package, "binary", {"cxx"}, "syslink", values.syslinks)))
table.join2(result, _translate_paths(toolchain_utils.map_linkflags_for_package(package, "binary", {"cxx"}, "syslink", values.syslinks)))
end
if values.frameworks then
table.join2(result, _map_linkflags(package, "binary", {"cxx"}, "framework", values.frameworks))
table.join2(result, toolchain_utils.map_linkflags_for_package(package, "binary", {"cxx"}, "framework", values.frameworks))
end
end
return result
Expand Down Expand Up @@ -306,21 +295,21 @@ function buildenvs(package, opt)
table.join2(cxxflags, _get_cflags_from_packagedeps(package, opt))
table.join2(cppflags, _get_cflags_from_packagedeps(package, opt))
table.join2(ldflags, _get_ldflags_from_packagedeps(package, opt))
table.join2(cflags, _map_compflags(package, "c", "define", defines))
table.join2(cflags, _map_compflags(package, "c", "includedir", includedirs))
table.join2(cflags, _map_compflags(package, "c", "sysincludedir", sysincludedirs))
table.join2(asflags, _map_compflags(package, "as", "define", defines))
table.join2(asflags, _map_compflags(package, "as", "includedir", includedirs))
table.join2(asflags, _map_compflags(package, "as", "sysincludedir", sysincludedirs))
table.join2(cxxflags, _map_compflags(package, "cxx", "define", defines))
table.join2(cxxflags, _map_compflags(package, "cxx", "includedir", includedirs))
table.join2(cxxflags, _map_compflags(package, "cxx", "sysincludedir", sysincludedirs))
table.join2(ldflags, _map_linkflags(package, "binary", {"cxx"}, "link", links))
table.join2(ldflags, _map_linkflags(package, "binary", {"cxx"}, "syslink", syslinks))
table.join2(ldflags, _map_linkflags(package, "binary", {"cxx"}, "linkdir", linkdirs))
table.join2(shflags, _map_linkflags(package, "shared", {"cxx"}, "link", links))
table.join2(shflags, _map_linkflags(package, "shared", {"cxx"}, "syslink", syslinks))
table.join2(shflags, _map_linkflags(package, "shared", {"cxx"}, "linkdir", linkdirs))
table.join2(cflags, toolchain_utils.map_compflags_for_package(package, "c", "define", defines))
table.join2(cflags, toolchain_utils.map_compflags_for_package(package, "c", "includedir", includedirs))
table.join2(cflags, toolchain_utils.map_compflags_for_package(package, "c", "sysincludedir", sysincludedirs))
table.join2(asflags, toolchain_utils.map_compflags_for_package(package, "as", "define", defines))
table.join2(asflags, toolchain_utils.map_compflags_for_package(package, "as", "includedir", includedirs))
table.join2(asflags, toolchain_utils.map_compflags_for_package(package, "as", "sysincludedir", sysincludedirs))
table.join2(cxxflags, toolchain_utils.map_compflags_for_package(package, "cxx", "define", defines))
table.join2(cxxflags, toolchain_utils.map_compflags_for_package(package, "cxx", "includedir", includedirs))
table.join2(cxxflags, toolchain_utils.map_compflags_for_package(package, "cxx", "sysincludedir", sysincludedirs))
table.join2(ldflags, toolchain_utils.map_linkflags_for_package(package, "binary", {"cxx"}, "link", links))
table.join2(ldflags, toolchain_utils.map_linkflags_for_package(package, "binary", {"cxx"}, "syslink", syslinks))
table.join2(ldflags, toolchain_utils.map_linkflags_for_package(package, "binary", {"cxx"}, "linkdir", linkdirs))
table.join2(shflags, toolchain_utils.map_linkflags_for_package(package, "shared", {"cxx"}, "link", links))
table.join2(shflags, toolchain_utils.map_linkflags_for_package(package, "shared", {"cxx"}, "syslink", syslinks))
table.join2(shflags, toolchain_utils.map_linkflags_for_package(package, "shared", {"cxx"}, "linkdir", linkdirs))
envs.CC = package:build_getenv("cc")
envs.AS = package:build_getenv("as")
envs.AR = package:build_getenv("ar")
Expand All @@ -341,13 +330,9 @@ function buildenvs(package, opt)
end
local runtimes = package:runtimes()
if runtimes then
local fake_target = {is_shared = function(_) return false end,
sourcekinds = function(_) return "cxx" end}
table.join2(cxxflags, _map_compflags(fake_target, "cxx", "runtime", runtimes))
table.join2(ldflags, _map_linkflags(fake_target, "binary", {"cxx"}, "runtime", runtimes))
fake_target = {is_shared = function(_) return true end,
sourcekinds = function(_) return "cxx" end}
table.join2(shflags, _map_linkflags(fake_target, "shared", {"cxx"}, "runtime", runtimes))
table.join2(cxxflags, toolchain_utils.map_compflags_for_package(package, "cxx", "runtime", runtimes))
table.join2(ldflags, toolchain_utils.map_linkflags_for_package(package, "binary", {"cxx"}, "runtime", runtimes))
table.join2(shflags, toolchain_utils.map_linkflags_for_package(package, "shared", {"cxx"}, "runtime", runtimes))
end
if package:config("asan") then
table.join2(cflags, package:_generate_sanitizer_configs("address", "cc").cflags)
Expand Down
Loading
Loading