-
-
Notifications
You must be signed in to change notification settings - Fork 888
Open
Labels
Milestone
Description
你在什么场景下需要该功能?
参考以下的项目示例:(基于xmake 3.0.4,linux x86_64)
xmake.lua
target("a::util")
set_kind("static")
add_files("a-util.cpp")
add_headerfiles("a-util.hpp")
target("b::util")
set_kind("static")
add_files("b-util.cpp")
add_headerfiles("b-util.hpp")
target("main")
set_kind("binary")
add_files("main.cpp")
add_deps("a::util", "b::util")main.cpp
#include <iostream>
#include "a-util.hpp"
#include "b-util.hpp"
int main()
{
std::cout << a::util::func() << b::util::func() << '\n';
return 0;
}a-util.hpp
namespace a::util
{
int func();
}
b-util.hpp相似,不再重复
a-util.cpp
#include "a-util.hpp"
int a::util::func()
{
return 1;
}
b-util.cpp相似,不再重复
冲突情形
项目在编译时,静态库a::util和b::util的默认生成名称(basename)均为util,生成的库名称均为libutil.a。链接时,xmake在参数中生成了-lutil,但链接器的搜索路径下同时存在两个libutil.a,因此只链接了其中一个库。尽管这种情况可以通过设置set_basename("a-util")来解决,但是出现类似这种错误时,通常只会产生链接错误,用户没法第一时间想到生成名称的问题。
如果设置了set_policy("build.intermediate_directory", false),两个冲突的库会彼此覆盖,导致了相同问题。
链接参数:
/usr/local/bin/g++ -o build/linux/x86_64/release/main build/.objs/main/linux/x86_64/release/main.cpp.o -m64 -Lbuild/linux/x86_64/release/a -Lbuild/linux/x86_64/release/b -lutil出现错误的提示:
❯ xmake build main [ 87%]: linking.release main error: /usr/bin/ld: build/.objs/main/linux/x86_64/release/main.cpp.o: in function `main': main.cpp:(.text+0x1e): undefined reference to `b::util::func()' collect2: error: ld returned 1 exit status
描述可能的解决方案
潜在解决方案:
- 添加检查,出现冲突时自动停止编译
- 更改默认命名规则,将命名空间纳入
且这两种方案可以并行存在,见“候选方案”一节
描述你认为的候选方案
方案1
xmake自动检查目标文件名冲突情况,如果存在冲突则停止编译并发出告警。
示例:
> xmake build
error: conflicting basename for target a::util and b::util! Use set_basename to resolve the conflict, see documentation for usage
方案2
更改默认命名规则(例如,a::util的basename从util变更为a-util,b::util变更为b-util,分别生成liba-util.a和libb-util.a)。这种方案可避免绝大部分情况下的冲突。
这种方案也可以和方案1并行,例如当存在a::util和a-util时,两者的目标文件名同样发生了冲突,方案1同样可以发出告警,通知用户通过set_basename更改名称
其他信息
前文提到的项目示例:example.tar.gz