Skip to content

feature-request:解决或提示静态库生成名称冲突 #7000

@Stehsaer

Description

@Stehsaer

你在什么场景下需要该功能?

参考以下的项目示例:(基于xmake 3.0.4linux 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::utilb::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. 添加检查,出现冲突时自动停止编译
  2. 更改默认命名规则,将命名空间纳入

且这两种方案可以并行存在,见“候选方案”一节

描述你认为的候选方案

方案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-utilb::util变更为b-util,分别生成liba-util.alibb-util.a)。这种方案可避免绝大部分情况下的冲突。

这种方案也可以和方案1并行,例如当存在a::utila-util时,两者的目标文件名同样发生了冲突,方案1同样可以发出告警,通知用户通过set_basename更改名称

其他信息

前文提到的项目示例:example.tar.gz

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions