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

xmake添加多个deps时,deps内部有相互依赖的情况下编译无法通过 #5342

Open
poemdistance opened this issue Jul 13, 2024 · 24 comments
Labels

Comments

@poemdistance
Copy link

Xmake 版本

v2.9.3+20240624

操作系统版本和架构

Linux 6.9.8-arch1-1 #1 SMP PREEMPT_DYNAMIC Fri, 05 Jul 2024 22:11:24 +0000 x86_64 GNU/Linux

描述问题

样例放在了这里:https://github.com/poemdistance/xmakeIssueExample

克隆下来执行xmake就可以复现。

lib2 和 baseLib 作为独立项目
lib2依赖baseLib,baseLib内部添加一个包含main函数的测试文件(test.c)用来测试baseLib.
baseLib xmake.lua:

target("baseLib")
    set_kind("static")
    add_files("add.c")

target("test")
    set_kind("binary")
    add_files("test.c")
    add_deps("baseLib")

lib2 xmake.lua:

includes("baseLib")

target("lib2")
    set_kind("static")
    add_files("mul.c")
    add_deps("baseLib")

此时在lib2和baseLib同级目录下新建源文件both.c,并写好对应的xmake.lua


includes("baseLib")
includes("lib2")

target("both")
    set_kind("binary")
    add_files("both.c")
    add_deps("baseLib", "lib2")

编译后报错

期待的结果

正常编译通过,生成both二进制文件

工程配置

见以上详细描述

附加信息和错误日志

/usr/bin/g++ -o build/linux/x86_64/release/test build/.objs/test/linux/x86_64/release/baseLib/test.c.o build/.objs/test/linux/x86_64/release/lib2/baseLib/test.c.o -m64 -Lbuild/linux/x86_64/release -s -lbaseLib
/usr/bin/ld: build/.objs/test/linux/x86_64/release/lib2/baseLib/test.c.o: in function `main':
test.c:(.text.startup+0x0): multiple definition of `main'; build/.objs/test/linux/x86_64/release/baseLib/test.c.o:test.c:(.text.startup+0x0): first defined here
collect2: error: ld returned 1 exit status
error: @programdir/core/main.lua:329: @programdir/actions/build/main.lua:148: @programdir/modules/async/runjobs.lua:325: @programdir/actions/build/kinds/binary.lua:53: @programdir/core/sandbox/modules/os.lua:378: execv(/usr/bin/g++ -o build/linux/x86_64/release/test build/.objs/test/linux/x86_64/release/baseLib/test.c.o build/.objs/test/linux/x86_64/release/lib2/baseLib/test.c.o -m64 -Lbuild/linux/x86_64/release -s -lbaseLib) failed(1)
stack traceback:
    [C]: in function 'error'
    [@programdir/core/base/os.lua:973]:
    [@programdir/core/sandbox/modules/os.lua:378]: in function 'execv'
    [@programdir/modules/core/tools/gcc.lua:580]:
    [C]: in function 'xpcall'
    [@programdir/core/base/utils.lua:275]:
    [@programdir/core/tool/linker.lua:221]: in function 'link'
    [@programdir/actions/build/kinds/binary.lua:53]: in function 'callback'
    [@programdir/modules/core/project/depend.lua:217]: in function 'on_changed'
    [@programdir/actions/build/kinds/binary.lua:41]: in function '_do_link_target'
    [@programdir/actions/build/kinds/binary.lua:83]:
    [@programdir/actions/build/kinds/binary.lua:110]: in function '_link_target'
    [@programdir/actions/build/kinds/binary.lua:138]: in function 'jobfunc'
    [@programdir/modules/async/runjobs.lua:241]:
    [C]: in function 'xpcall'
    [@programdir/core/base/utils.lua:275]: in function 'trycall'
    [@programdir/core/sandbox/modules/try.lua:117]: in function 'try'
    [@programdir/modules/async/runjobs.lua:223]: in function 'cotask'
    [@programdir/core/base/scheduler.lua:406]:

stack traceback:
	[C]: in function 'error'
	@programdir/core/base/os.lua:973: in function 'base/os.raiselevel'
	(...tail calls...)
	@programdir/core/main.lua:329: in upvalue 'cotask'
	@programdir/core/base/scheduler.lua:406: in function <@programdir/core/base/scheduler.lua:399>
@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


Title: When xmake adds multiple deps, the compilation fails if there are interdependencies within the deps.

@star-hengxing
Copy link
Contributor

lib2 都已经包含了,那么就不需要 includes("baseLib")

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


lib2 is already included, so there is no need for includes("baseLib")

@star-hengxing
Copy link
Contributor

你声明了两次 test target,配置会追加进去,所以 add_files 了两个不同位置的 main,最后链接报错。
你这里问题是,baseLib 和 test 应该重新命名,分开四个 target。
或者打平依赖,把根目录或者 lib2 目录下的 baseLib 删了

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


You declared the test target twice, and the configuration will be appended, so add_files main in two different locations, and finally the link reports an error.
Your problem here is that baseLib and test should be renamed to separate the four targets.
Or flatten the dependencies and delete baseLib in the root directory or lib2 directory

@poemdistance
Copy link
Author

lib2 都已经包含了,那么就不需要 includes("baseLib") 了

实际项目中lib2是通过git submodule的方式引入的baseLib,它的版本跟both.c引入baseLib的版本可能不一致,只includes(lib2)不行。我是把lib2当成独立模块看待,baseLib也当成独立模块看待,只是恰好lib2依赖了baseLib

你声明了两次 test target,配置会追加进去,所以 add_files 了两个不同位置的 main,最后链接报错。
你这里问题是,baseLib 和 test 应该重新命名,分开四个 target。
或者打平依赖,把根目录或者 lib2 目录下的 baseLib 删了

还是上面提到的,lib2本身依赖baseLib(通过git submodule直接拉取了完整baseLib项目),所以lib2中的baseLib不能删除,同样both.c可能需要的baseLib版本跟lib2中的baseLib不一定同步,也不能删,又因为lib2中的test target和baseLib中的test target本身就是同一个,重命名解决不了。test target其实只在baseLib声明了一次,只是lib2通过submodule复制过来了,导致了includes("lib2")时被追加了一遍。

这种情况xmake有没有办法可以做到识别出来并正常编译。或者还有没有其它办法解决(复制.a/.so库过来虽然也能规避问题,但不是很想这么做)

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


lib2 is already included, so there is no need for includes("baseLib")

In the actual project, lib2 is introduced as baseLib through git submodule. Its version may be inconsistent with the version of baseLib introduced in both.c. Just includes(lib2) will not work. I treat lib2 as an independent module, and baseLib as an independent module. It just happens that lib2 depends on baseLib.

You declared the test target twice, and the configuration will be appended, so add_files main in two different locations, and finally the link reports an error.
Your problem here is that baseLib and test should be renamed to separate the four targets.
Or flatten the dependencies and delete baseLib in the root directory or lib2 directory

As mentioned above, lib2 itself relies on baseLib (the complete baseLib project is directly pulled through git submodule), so baseLib in lib2 cannot be deleted. Similarly, the baseLib version that both.c may require is not necessarily synchronized with the baseLib in lib2, and It cannot be deleted, and because the test target in lib2 and the test target in baseLib are the same, renaming cannot solve the problem. The test target is actually only declared once in baseLib, but lib2 is copied through submodule, causing it to be appended once in includes("lib2").

Is there any way for xmake to identify this situation and compile it normally? Or is there any other way to solve it (copying the .a/.so library can also avoid the problem, but I don’t really want to do it)

@waruqi
Copy link
Member

waruqi commented Jul 13, 2024

你这么搞,both 和 lib2 到底是打算用外面那个 baseLib 还是 lib2/baseLib 呢?我人工都识别不出来,xmake 怎么能识别。

既然 baseLib 本地有两个不同的版本存在,完全可以做成 package ,按版本维护,针对不同 target 引入不同的 baseLib package 即使同名也不会冲突,而不是一个项目下存在两份。。

如果非要这么搞,首先得弄清楚,到底哪个 target 用的哪份 baseLib ,两个 baseLib 是否需要同时参与编译,还是仅仅只用其中一份,什么时候用哪一个。。

目前给的信息,我只能知道 both, lib2 同时会依赖 baseLib ,按目录结构我只能猜测,both 用的外面那个 baseLib ,lib2 用的 lib2/baseLib ,但这样,即使 target 名不同,也是有依赖冲突的, both 同时 link 了两份不同版本的 baseLib

如果 both/lib2 都是用的外面那份 baselib,那么 lib2/baseLib 又是要来干嘛的。。反正我是识别不出来。

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


If you do this, do both and lib2 intend to use the external baseLib or lib2/baseLib? I can't recognize it manually, how can xmake recognize it?

Since there are two different versions of baseLib locally, it can be made into a package, maintained by version, and different baseLib packages introduced for different targets will not conflict even if they have the same name, instead of having two copies under one project. .

If you must do this, you must first figure out which baseLib is used by which target, whether both baseLibs need to be compiled at the same time, or only one of them is used, and when to use which one. .

From the information given so far, I can only know that both and lib2 will depend on baseLib at the same time. Regarding the directory structure, I can only guess that both uses the external baseLib and lib2 uses lib2/baseLib. But in this way, even if the target names are different, there will still be dependencies. Conflicting, both linked two different versions of baseLib at the same time.

If both/lib2 uses the external baselib, then what is lib2/baseLib doing? . Anyway, I can't recognize it.

@poemdistance
Copy link
Author

使用了推荐的package,编译报错:
lib2/build/packages/b/baselib/xmake.lua: package(baseLib) not found!

编译失败的地方 lib2/xmake.lua:

add_rules("mode.debug", "mode.release")

add_repositories("local-repo build")
add_requires("baseLib")

target("lib2")
    set_kind("static")
    add_files("mul.c")
    add_packages("baseLib")

lib2目录结构:

.
├── baseLib
│   ├── add.c
│   ├── add.h
│   ├── test.c
│   └── xmake.lua
├── build
│   └── packages
│       ├── b
│       │   └── baselib
│       │       ├── linux
│       │       │   └── x86_64
│       │       │       └── release
│       │       │           └── lib
│       │       │               └── libbaseLib.a
│       │       └── xmake.lua
│       └── t
│           └── test
│               ├── linux
│               │   └── x86_64
│               │       └── release
│               │           └── bin
│               │               └── test
│               └── xmake.lua
├── mul.c
├── mul.h
└── xmake.lua

lib2/baseLib/ 下执行xmake package -o ../build生成package。
然后在lib2下执行xmake后报错。

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


Using the recommended package, the compiler reported an error:
lib2/build/packages/b/baselib/xmake.lua: package(baseLib) not found!

Where compilation fails lib2/xmake.lua:

add_rules("mode.debug", "mode.release")

add_repositories("local-repo build")
add_requires("baseLib")

target("lib2")
    set_kind("static")
    add_files("mul.c")
    add_packages("baseLib")

lib2 directory structure:

.
├── baseLib
│ ├── add.c
│ ├── add.h
│ ├── test.c
│ └── xmake.lua
├── build
│ └── packages
│ ├── b
│ │ └── baselib
│ │ ├── linux
│ │ │ └── x86_64
│ │ │ └── release
│ │ │ └── lib
│ │ │ └── libbaseLib.a
│ │ └── xmake.lua
│ └── t
│ └── test
│ ├── linux
│ │ └── x86_64
│ │ └── release
│ │ └── bin
│ │ └── test
│ └── xmake.lua
├──mul.c
├── mul.h
└── xmake.lua

Execute xmake package -o ../build under lib2/baseLib/ to generate the package.
Then an error is reported after executing xmake under lib2.

@waruqi
Copy link
Member

waruqi commented Jul 14, 2024

xmake package 

默认打的是本地二进制包。。我的意思的是做成源码包,不要用 xmake package,不走 submodules,进行版本控制。。

走 xmake package 你每次还得先进去 build baselib 不嫌麻烦么,而且没法版本控制。。

另外,包名要小写。。add_requires 里也小写。。

我的意思是搞成远程源码包,通过 git url 作为源,add_versions + git commit 管理版本,进行版本控制。

比如这样

https://github.com/xmake-io/xmake-repo/blob/f428da7ca3b040ce188c0ce11cc18d499a2ab456/packages/x/x264/xmake.lua#L7-L9

或者直接找几个 xmake-repo 仓库的包看下。。https://github.com/xmake-io/xmake-repo/blob/dev/packages/z/zlib/xmake.lua

当然,如果你非要用 二进制的本地包,也可以,提供完整可复现工程过来,我看下

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


xmake package

The default version is the local binary package. . What I mean is to create a source code package, do not use xmake package, do not use submodules, and perform version control. .

Isn’t it troublesome to use xmake package and you have to build baselib first every time? .

In addition, the package name should be lowercase. . Add_requires is also lowercase. .

Reference https://xmake.io/#/zh-cn/package/local_3rd_source_library?id=%e9%9b%86%e6%88%90-cmake-%e4%bb%a3%e7%a0%81%e5 %ba%93

For this, just change cmake.install to xmake.install.

Of course, if you insist on using the binary local package, you can also provide a complete reproducible project and let me take a look.

@poemdistance
Copy link
Author

好的,感谢~
我去学下你说的远程源码包的方案。

当然,如果你非要用 二进制的本地包,也可以,提供完整可复现工程过来,我看下

工程在这里:https://github.com/poemdistance/xmakeIssueExample

git clone下来后,到仓库根目录:

cd lib2/baseLib
xmake package -o ../build -P .
xmake -P .

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


OK, thanks~
I'm going to learn the remote source code package solution you mentioned.

Of course, if you insist on using binary local packages, you can also provide a complete reproducible project and let me take a look.

The project is here: https://github.com/poemdistance/xmakeIssueExample

After git clone is downloaded, go to the root directory of the warehouse:

cd lib2/baseLib
xmake package -o ../build -P .
xmake -P .

@poemdistance
Copy link
Author

应该就是大小写问题,修改成小写后可以成功编译了:)

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


It should be a case problem. After changing it to lowercase, it can be compiled successfully :)

@poemdistance
Copy link
Author

应该就是大小写问题,修改成小写后可以成功编译了:)

不过这里强制要求小写的原因是什么,windows不区分大小写可能导致冲突?

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


It should be a case problem. After changing it to lower case, it can be compiled successfully :)

But what is the reason for forcing lowercase here? Windows is not case-sensitive, which may cause conflicts?

@waruqi
Copy link
Member

waruqi commented Jul 15, 2024

应该就是大小写问题,修改成小写后可以成功编译了:)

不过这里强制要求小写的原因是什么,windows不区分大小写可能导致冲突?

要跨平台,很多系统是大小写不敏感的,但还有些系统是大小写敏感的。。如果同时存在两个 同名,但是大小写不同的包,再不同系统上会存在各种冲突问题。。强制小写可以规避这种问题。

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


It should be a case problem. After changing it to lower case, it can be compiled successfully:)

But what is the reason for forcing lowercase here? Windows is not case-sensitive, which may cause conflicts?

To be cross-platform, many systems are case-insensitive, but some systems are case-sensitive. . If there are two packages with the same name but different capitalization, there will be various conflict problems on different systems. . Forcing lowercase can circumvent this problem.

@poemdistance
Copy link
Author

问题: 生成package时,头文件没有复制到包下面的inlude文件夹

package("season")
    set_urls("git@github.com:poemdistance/season.git")

    on_install("macosx", "linux", function (package)
        os.cd("src")
        -- os.cp("*.h", package:installdir("include"))
        import("package.tools.xmake").install(package)
    end)
package_end()

import("package.tools.xmake").install(package) 这个语句在我的项目中只复制了.a文件到xxx/lib/下,头文件是需要自己调用 os.cp("*.h", package:installdir("include"))吗?

或者我在哪里遗漏了什么设置导致头文件没有复制过去?

@waruqi
Copy link
Member

waruqi commented Jul 15, 2024

自己项目里 add_headerfiles配置安装头文件

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


Add_headerfiles configures the installation header files in your own project

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants