xmake-io / xmake

🔥 A cross-platform build utility based on Lua
https://xmake.io
Apache License 2.0
9.61k stars 763 forks source link

find_package fails to find binutils on system #5267

Closed enzalito closed 1 week ago

enzalito commented 1 month ago

Xmake Version

v2.9.1+20240422

Operating System Version and Architecture

Ubuntu 24.04

Describe Bug

When I build a target that requires binutils, xmake tries to download it from its repos event though it is installed on my system.

Expected Behavior

Use binutils from my system.

Project Configuration

add_requires("binutils")

target("example")
    set_kind("binary")
    add_cxxflags("-std=c++20", "-fPIC", {force = true})
    add_files("main.cpp")
    add_packages("binutils")

Additional Information and Error Logs

I think that the problem comes from the fact that binutils in a binary dependency but the package doesn't provide any executable named binutils, so lib.detect.find_program fails to find it.

If that is the case, could the issue be solved by implementing find_binutils in xmake/modules/detect/tools ?

waruqi commented 1 month ago

you can open a pr to add on_fetch, it will find system binutils. https://github.com/xmake-io/xmake-repo/blob/dev/packages/b/binutils/xmake.lua

like this.

https://github.com/xmake-io/xmake-repo/blob/84f6cefdff3501dbe4953b732d04813e351ee809/packages/c/cuda-samples/xmake.lua#L14

enzalito commented 4 weeks ago

Ok thanks, I will do that.
I have one question though. Sometimes binutils is not not packaged with all the static / dynamic libraries and header files (binutils on Ubuntu, binutils-dev has everything). So should I check if both the binaries and the lib / header files exist in on_fetch ?

waruqi commented 4 weeks ago

use package:is_binary() and package:is_library()

enzalito commented 2 weeks ago

@waruqi I'm not certain that I'm on the right path but I came up with that :

    on_fetch("@linux", "@macosx", "@msys", function (package, opt)
        if opt.system then
            if package:is_binary() then
                -- TODO
                return {}

            elseif package:is_library() then
                local libs = {"bfd", "ctf", "opcodes"}
                result = {links = {}}
                for _, lib in ipairs(libs) do
                    local libinfo = package:find_package("system::" .. lib)                    
                    if libinfo then
                        table.insert(result.links, libinfo.links)
                    end
                end
                return result
            end
        end
    end)

It works for me when I use package:add("deps", "binutils", {kind = "library", system = true}) at least.

For the binary part, I'm not sure about how I should proceed. I tried using package:find_package here too but none of binutils' binaries were found. package:find_tool("system::" .. name) only finds a fraction of the libraries : ld, objcopy and ranlib.
I'm also unsure about how I could merge the results of multiple package:find_tool calls.

waruqi commented 2 weeks ago

see https://github.com/xmake-io/xmake-repo/blob/41fe34936a4d2a81355528dcfba3d809de3b1905/packages/l/llvm/fetch.lua#L22

only return non-nil value.