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 link mechanism and order #1452
Comments
Just a draftAdjust the order of each configuration type-- -la -ld -lb -lc -le -ls1 -ls2
add_syslinks("s1", "s2")
add_links("a")
add_links("b", "c", {order = 2})
add_links("d", {order = 1})
add_links("e") -- -la -ld -lb -lc -le
add_ldflags("-la")
add_ldflags("-lb", "-lc", {order = 2})
add_ldflags("-ld", {order = 1})
add_ldflags("-le") and add_includedirs, add_xxx etc, it supports all configurations Adjust the link order between packages, deps, and options-- -la -le -lf -lb -lc -ld -lg -ls1 -ls2
add_syslinks("s1", "s2")
add_links("a")
add_links("b", "c", {order = 4})
add_links("d", {order = 5})
add_links("package::e", {order = 1)
add_links("option::f", {order = 2)
add_links("dep::g")
add_packages("e")
add_options("f")
add_deps("g") We can use namespaces such as link group-- -Wl,--start-group -la -lb -lc -Wl,--end-group -Wl,--start-group -lx -ly -lz -Wl,--end-group
add_links("a", "b", "c", {group = true})
add_syslinks("x", "y", "z", {group = true}) link group with deps, options and packages-- -Wl,--start-group -la -lb -lc -ld -Wl,--end-group
add_links("a", "package::b", "dep::c", "option::d", {group = true}))
add_packages("b")
add_options("d")
add_deps("c") link whole archive-- -Wl,--whole-archive -la -lb -lc -Wl,--no-whole-archive
add_links("a", "b", "c", {whole = true}) link whole archive with deps, options and packages-- -Wl,--whole-archive -la -lb -lc -ld -Wl,--no-whole-archive
add_links("a", "package::b", "dep::c", "option::d", {whole = true}))
add_packages("b")
add_options("d")
add_deps("c") Explicitly specify the linked file namelibfoo.a libfoo.so in same directory add_links("libfoo.a")
add_links("libfoo.so")
add_links("foo.lib") |
Instead of repeating package, option, dependency using the "package::name" and setting the link order will it be better introduce "link_order" option for packages, options and dependencies? Before,
After,
Instead of using a separate group flag, wouldn't it be better to use the "order" flag with two elements to denote the group? e.g.
This will end up with the command line,
|
I still want to consider other configurations in package, such as
This is a bit too complicated, or we can use same order to put it in a group without using two elements. add_links("a", "b", {order = 5})
add_links("c", {order = 5}) |
It's a bad idea using numbers to specify link orders. What matters is only the link order of some specific links and obviously a tree structure is more precise and robust. |
The main reason is that the order of links between add_packages/add_options/add_links cannot be controlled. Are there any other better ideas? |
@xq114 How to define the tree structure? should it be a single command like,
|
This does not conflict with tree inheritance, I only want to modify the link order between options/packages/links in the current target, and support link grouping. target("test")
-- need not `dep::xxx`, we only adjust the link order between options/packages/links in the current target
add_linkorders("a", "b", "package::c", "option::d")
add_linkorders("a", "b", "package::c", "option::d", {group = true}) how about this? |
about whole link target("test")
add_deps("a", {wholelink = true}) -- only for dep("xxx"), -lxxx
add_links("a", "b", "c", {wholelink = true})
add_options("a", "b", "c", {wholelink = true})
add_packages("a", "b", "c", {wholelink = true}) |
You're right, I mean, we can use a couple of add_linkorders("a", "package::b", "c", "option::d")
add_linkorders("c", "package::e")
add_linkorders("b", "package::f) If I want to modify the structure by adding g->a, just a modification to the first line would work, without rearranging the numbers denoting the position of linking. Furthermore, it's better if a graph structure is supported, i.e. a->b->d a->c->d. The actual link order could be either a->b->c->d or a->c->b->d depending on implementation. |
Does it respect package add_deps() by default?
Will the link order will be?
|
right |
Another solution comes from cmake and some other build systems: links can be treated as targets with dependency hierarchy. So the order of links can be derived from that.
Since dependency is specified, a simple topological sort can be applied to find the actual link order (and find circular dependencies). The implementation is similar to calculating the build order of targets. For group links, another mechanism must be applied. General solution is
a link group can be simplified as a node and topological sort still applies. A more tricky mechanism is to treat circular dependencies as link group (which means they require symbols from each other), e.g.
This is the solution of most build systems; if this kind of mechanism is chosen, a Tarjan's algorithm can be used to find the strong components for links. A simpler implementation is just to link these libraries multiple times: create a copy of the link every time it's required, and take all copies into account when calculating the link order, which reduced the usage of group link. As for whole archive, it has nothing to do with link orders (in my opinion). We can just add whole archive flags for every links specified with {whole=true}, and remove all |
I would also love the ability to link a single library statically -- this can be achieved on clang/GCC using Maybe a syntax like |
I will consider it |
Now I have improved it. #4250 $ xmake update -s github:xmake-io/xmake#links link group-- -Wl,--start-group -la -lb -Wl,--end-group
add_linkgroups("a", "b", {group = true}) link group (whole archive)-- -Wl,--whole-archive -la -lb -Wl,--no-whole-archive
add_linkgroups("a", "b", {whole = true}) link group (static search)-- -Wl,-Bstatic -la -lb -Wl,-Bdynamic
add_linkgroups("a", "b", {static = true}) modify links ordersIt will create graph and use topological sort to sort links. and it will check link cycle in add_links("a", "b", "c", "d", "e")
-- e -> b -> a
add_linkorders("e", "b", "a")
-- e -> d
add_linkorders("e", "d") sort links and linkgroupsadd_links("a", "b", "c", "d", "e")
add_linkgroups("c", "d", {name = "foo", group = true})
add_linkorders("e", "linkgroup::foo") sort links and frameworksadd_links("a", "b", "c", "d", "e")
add_frameworks("Foundation", "CoreFoundation")
add_linkorders("e", "framework::CoreFoundation") examplesadd_rules("mode.debug", "mode.release")
add_requires("libpng")
target("bar")
set_kind("shared")
add_files("src/foo.cpp")
add_linkgroups("m", "pthread", {whole = true})
target("foo")
set_kind("static")
add_files("src/foo.cpp")
add_packages("libpng", {public = true})
target("demo")
set_kind("binary")
add_deps("foo")
add_files("src/main.cpp")
if is_plat("linux", "macosx") then
add_syslinks("pthread", "m", "dl")
end
if is_plat("macosx") then
add_frameworks("Foundation", "CoreFoundation")
end
add_linkorders("framework::Foundation", "png16", "foo")
add_linkorders("dl", "linkgroup::syslib")
add_linkgroups("m", "pthread", {name = "syslib", group = true}) |
add_linkgroups("a", "b", {whole = true})如果同时需要-Wl,--start-group ,就有点歧义的感觉了,add_links("a", "b", {whole = true,group = true})或者 增加add_linkwhole("a", "b")? |
I improved it. add_linkgroups("a", "b", {group = true})
add_linkgroups("a", "b", {whole = true})
add_linkgroups("a", "b", {group = true, whole = true}) and add_links("a", "b", "e")
add_linkorders("b", "linkgroup::foo")
add_linkgroups("c", "d", {name = "foo"})
|
we can use |
xmake update -s dev |
在 package 中,报这个错误:
|
暂不支持 package ,仅用于 target 下调整 |
好的,请问这个有计划支持吗?期待一下。 |
I have supported it. #4314 we can also use add_linkorders to sort package links and add linkgroups/wholearchives. package("libpng")
add_linkorders("png16", "png", "linkgroup::foo")
add_linkgroups("dl", {name = "foo", group = true}) |
Roadmap
-Wl,--start-group
-Wl,--whole-archive
Related issues
The text was updated successfully, but these errors were encountered: