xmake-io / xmake

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

Bug with `on_test` #4922

Closed smac89 closed 5 months ago

smac89 commented 5 months ago

I created this package xmake file for hello-imgui:

package("hello-imgui")
    set_homepage("https://github.com/pthom/hello_imgui")
    set_description("Hello, Dear ImGui: unleash your creativity in app development and prototyping")
    set_license("MIT")
    set_policy("package.librarydeps.strict_compatibility", true)

    add_urls("https://github.com/pthom/hello_imgui/archive/refs/tags/$(version).tar.gz")
    add_versions("v1.4.2", "1de7df2400076e18bbb519759999ccc9e93381e1d25b382b5c503e41fce767eb")

    add_configs(
        "has_opengl3",
        {description = "Use OpenGL3 as a rendering backend. This is the recommended choice, especially for beginners", default = false, type = "boolean"}
    )
    add_configs("has_metal", {description = "Use Metal as a rendering backend. Apple only, advanced users only", default = false, type = "boolean"})
    add_configs("has_vulkan", {description = "Use Vulkan as a rendering backend. Advanced users only", default = false, type = "boolean"})
    add_configs("has_directx11", {description = "Use DirectX11 as a rendering backend. Windows only, still experimental", default = false, type = "boolean"})
    add_configs(
        "has_directx12",
        {description = "Use DirectX12 as a rendering backend. Windows only, advanced users only, still experimental", default = false, type = "boolean"}
    )
    add_configs("use_sdl2", {description = "Use Sdl2 as a platform backend", default = false, type = "boolean"})
    add_configs("use_glfw3", {description = "Use Glfw3 as a platform backend", default = false, type = "boolean"})
    add_configs("use_freetype", {description = "Use freetype for text rendering", default = true, type = "boolean"})

    add_configs("imgui_version", {description = "Use the specfied version of imgui", default = "*", type = "string"})

    add_deps("cmake")

    on_load(function (package)
        if package:config("has_opengl3") then
            package:add("deps", "glad")
        elseif package:config("has_vulkan") then
            package:add("deps", "vulkansdk")
        end
        if package:config("use_sdl2") then
            package:add("deps", "libsdl")
        elseif package:config("use_glfw3") then
            package:add("deps", "glfw")
        end
        if package:config("use_freetype") then
            package:add("deps", "freetype")
        end
        -- https://xmake.io/#/manual/global_interfaces?id=use-as-a-private-package
        package:add("deps", "imgui-src " .. package:config("imgui_version"), {private = true})
    end)

    on_install("windows", "macosx", "linux", function (package)
        local configs = {}
        local imgui_src_dep = package:dep("imgui-src")

        table.insert(configs, "-DHELLOIMGUI_IMGUI_SOURCE_DIR=" .. path.join(imgui_src_dep:cachedir(), "source", imgui_src_dep:name()))

        table.insert(configs, "-DCMAKE_BUILD_TYPE=" .. (package:is_debug() and "Debug" or "Release"))
        table.insert(configs, "-DBUILD_SHARED_LIBS=" .. (package:config("shared") and "ON" or "OFF"))
        for name, enabled in pairs(package:configs()) do
            table.insert(configs, "-DHELLOIMGUI_" .. name:upper() .. "=" .. (enabled and "ON" or "OFF"))
        end
        import("package.tools.cmake").install(package, configs)
    end)

    on_test(function (package)
        assert(package:check_cxxsnippets({test = [[
            #include <hello_imgui/hello_imgui.h>
            int main(int , char *[]) {
                HelloImGui::Run(
                    []{ ImGui::Text("Hello, world!"); }, // Gui code
                    "Hello!", true);                     // Window title + Window size auto
            }
        ]]}, {configs = {language = "cxx17"}}))
    end)

The package file for imgui-src is defined simply as:

package("imgui-src")
    set_base("imgui")
    on_install(function () end)
    on_test(function() end)

When I build the hello-imgui package, everything looks good, and I even see this towards the end:

{ 
  sysincludedirs = { 
    "/home/user/.local/share/xmake/packages/h/hello-imgui/v1.4.2/3867d18f39804217a9828d5ad141028e/include" 
  },
  license = "MIT",
  static = true,
  links = { 
    "stb_hello_imgui",
    "imgui",
    "hello_imgui",
    "lunasvg" 
  },
  version = "v1.4.2",
  linkdirs = { 
    "/home/user/.local/share/xmake/packages/h/hello-imgui/v1.4.2/3867d18f39804217a9828d5ad141028e/lib" 
  },
  libfiles = { 
    "/home/user/.local/share/xmake/packages/h/hello-imgui/v1.4.2/3867d18f39804217a9828d5ad141028e/lib/libstb_hello_imgui.a",
    "/home/user/.local/share/xmake/packages/h/hello-imgui/v1.4.2/3867d18f39804217a9828d5ad141028e/lib/libimgui.a",
    "/home/user/.local/share/xmake/packages/h/hello-imgui/v1.4.2/3867d18f39804217a9828d5ad141028e/lib/libhello_imgui.a",
    "/home/user/.local/share/xmake/packages/h/hello-imgui/v1.4.2/3867d18f39804217a9828d5ad141028e/lib/liblunasvg.a" 
  } 
}

However, at the end I get the following error:

patching /home/user/.local/share/xmake/packages/h/hello-imgui/v1.4.2/3867d18f39804217a9828d5ad141028e/lib/pkgconfig/hello-imgui.pc ..
checking for clang++ ... /usr/bin/clang++
checking for flags (-fPIC) ... ok
checking for flags (-pthread) ... ok
checking for flags (-fdiagnostics-color=always) ... ok
/usr/bin/ld: /home/user/.local/share/xmake/packages/h/hello-imgui/v1.4.2/3867d18f39804217a9828d5ad141028e/lib/libhello_imgui.a(runner_sdl2.cpp.o): in function `HelloImGui::RunnerSdl2::Impl_SetWindowIcon()':
/home/user/.cache/xmake/2404/h/hello-imgui/v1.4.2/source/src/hello_imgui/internal/backend_impls/runner_sdl2.cpp:213:(.text+0x623): undefined reference to `stbi_load_from_memory'
/usr/bin/ld: /home/user/.cache/xmake/2404/h/hello-imgui/v1.4.2/source/src/hello_imgui/internal/backend_impls/runner_sdl2.cpp:230:(.text+0x6ac): undefined reference to `stbi_image_free'
/usr/bin/ld: /home/user/.local/share/xmake/packages/h/hello-imgui/v1.4.2/3867d18f39804217a9828d5ad141028e/lib/libhello_imgui.a(image_from_asset.cpp.o): in function `HelloImGui::_GetCachedImage(char const*)':
/home/user/.cache/xmake/2404/h/hello-imgui/v1.4.2/source/src/hello_imgui/internal/image_from_asset.cpp:74:(.text+0x3a9): undefined reference to `stbi_load_from_memory'
/usr/bin/ld: /home/user/.local/share/xmake/packages/h/hello-imgui/v1.4.2/3867d18f39804217a9828d5ad141028e/lib/libhello_imgui.a(imgui_theme.cpp.o): in function `ImGuiTheme::ShowThemeTweakGui(ImGuiTheme::ImGuiTweakedTheme*)':
/home/user/.cache/xmake/2404/h/hello-imgui/v1.4.2/source/src/hello_imgui/impl/imgui_theme.cpp:1160:(.text+0x951b): undefined reference to `ImGui::ShowStyleEditor(ImGuiStyle*)'
collect2: error: ld returned 1 exit status
> checking for c++ links(stb_hello_imgui, imgui, hello_imgui, lunasvg, glad, SDL2, freetype, z, dl)
> checking for c++ snippet(test)
error: execv(/usr/bin/g++ -o /tmp/.xmake1000/240401/_5CF6085BEE504310807CF3BA13958E30.b /tmp/.xmake1000/240401/_5CF6085BEE504310807CF3BA13958E30.o -m64 -L/home/user/.local/share/xmake/packages/h/hello-imgui/v1.4.2/3867d18f39804217a9828d5ad141028e/lib -L/home/user/.local/share/xmake/packages/g/glad/v0.1.36/dd6f7de88060486a93ea896ea2b462ea/lib -L/usr/lib -lstb_hello_imgui -limgui -lhello_imgui -llunasvg -lglad -lSDL2 -lfreetype -lz -ldl) failed(1)
  => install hello-imgui v1.4.2 .. failed
error: install failed!

I investigated this issue for some time yesterday, and discovered that the package installdir (/home/user/.local/share/xmake/packages/h/hello-imgui/v1.4.2/3867d18f39804217a9828d5ad141028e) was actually never created or was deleted right after the installation. In any case, it doesn't exist, which could explain why the linker is having a hard time finding what it needs.

Any help would be appreciated

Originally posted by @smac89 in https://github.com/xmake-io/xmake/discussions/4919

smac89 commented 5 months ago

This is indeed a bug, and has to do with on_test and package:check_cxxsnippets.

  1. If the test fails, xmake deletes everything in the install folder.
  2. check_cxxsnippets does not produce the correct compile command. Given the above snippet, it tries to execute this command:
    /usr/bin/g++ -o /tmp/.xmake1000/240401/_82EDF1BAE8414A10880A19FFAB1D9D20.b /tmp/.xmake1000/240401/_82EDF1BAE8414A10880A19FFAB1D9D20.o -m64 -L/home/user/.local/share/xmake/packages/h/hello-imgui/v1.4.2/3867d18f39804217a9828d5ad141028e/lib -L/home/user/.local/share/xmake/packages/g/glad/v0.1.36/dd6f7de88060486a93ea896ea2b462ea/lib -L/usr/lib -lstb_hello_imgui -limgui -lhello_imgui -llunasvg -lglad -lSDL2 -lfreetype -lz -ldl

    Notice the lack of a .cpp file anywhere in the command? It doesn't include the source file. I was able to fix the issue with check_cxxsnippets, by specifying the linking order for the library. I had to add the following add_linkorders("hello_imgui", "stb_hello_imgui", "imgui") to the package file

For now, I've decided to ignore the snippet issue and settled for a simpler test:

assert(package:has_cxxincludes("hello_imgui/hello_imgui.h"))

Which works

Originally posted by @smac89 in https://github.com/xmake-io/xmake/discussions/4919#discussioncomment-8977528

waruqi commented 5 months ago

please add add_links("hello_imgui", "stb_hello_imgui", "imgui") in your package configuration.

If you don't configure any links, xmake will automatically walk the lib directory when the package is installed and get all the library files to set the links, but their linking order is undefined. If there is a dependency order between several sub-libraries of the package, configure them explicitly via add_links.

It has nothing to do with on_test and is not a bug.

libfiles = { "/home/user/.local/share/xmake/packages/h/hello-imgui/v1.4.2/3867d18f39804217a9828d5ad141028e/lib/libstb_hello_imgui.a", "/home/user/.local/share/xmake/packages/h/hello-imgui/v1.4.2/3867d18f39804217a9828d5ad141028e/lib/libimgui.a", "/home/user/.local/share/xmake/packages/h/hello-imgui/v1.4.2/3867d18f39804217a9828d5ad141028e/lib/libhello_imgui.a", "/home/user/.local/share/xmake/packages/h/hello-imgui/v1.4.2/3867d18f39804217a9828d5ad141028e/lib/liblunasvg.a" }

smac89 commented 5 months ago

please add add_links("hello_imgui", "stb_hello_imgui", "imgui") in your package configuration.

@waruqi would that still be necessary even after using add_linkorders("hello_imgui", "stb_hello_imgui", "imgui")?

Everything seems to be linking properly after adding that line. This also means the test is passing.


Also, the reason I say on_test has a bug is because the installed package is deleted if the on_test test fails. I don't see this documented anywhere, and I don't think this is something people will easily catch. In my case at least, I didn't, and it took me a while of debugging to figure out that the reason the apparently installed package no longer exists in the install directory is because the test failed, and xmake just deletes it.

If you don't see it as a bug or think it's intuitive enough, I would go ahead and close this issue.

waruqi commented 5 months ago

would that still be necessary even after using add_linkorders("hello_imgui", "stb_hello_imgui", "imgui")?

you need only add_links, please remove add_linkorders