-
问题描述:我这边尝试在 windows 下用 xmake+vs 编译别人用 cmake 管理的库时遇到一个问题,编译模式只能是 debug/release 。 我需要编译出 releasedbg 和 minsizerel 模式的库,但是好像传入的只要不是 debug ,都会生成 release的库,我想单步追踪一下哪里出了问题,但是不知道怎么在 vscode 上启动调试。 我的输入的命令是xmake f --arch=x64 --trybuild=cmake --kind=shared --mode=releasedbg --vs_runtime=MD --tryconfigs="-DBUILD_SHARED_LIBS=ON" xmake 输出的 dll 文件和 cmake 生成的 release 版 dll 大小一致,要明显小于 cmake 的 RelWithDebInfo 生成的 dll,因此猜测 xmake 应该实际走的是 release 模式 尝试的步骤根据文档,我在 vscode 中下载了 xmake 的源码,然后通过 问题我现在比较困惑的是,我要怎么结合我输入的命令,来进行跟踪调试?(打断点和单步) |
Beta Was this translation helpful? Give feedback.
Replies: 8 comments 6 replies
-
https://xmake.io/#/zh-cn/guide/faq?id=%e6%96%ad%e7%82%b9%e8%b0%83%e8%af%95 |
Beta Was this translation helpful? Give feedback.
-
谢谢,经过调试我发现应该是 xmake 里面的 mode 判断用的是 is_debug() and "Debug" or "Release" 所以没有对 releasedbg 做响应。 我现在有多个基础库是基于 cmake 已有的,本身的业务代码需要依赖这些基础库,一个简化的目录结构为 project 因为每个库里面 CMakeLists.txt 有通用的设置, 比如 -DCMAKE_BUILD_TYPE, 和 -DUSE_MSVC_RUNTIME_LIBRARY_DLL, 的 option 需要设置,也有每个 lib 专用的 option 需要设置,并且根据 project根节点的 mode/vs_runtime/kind 来组合设置 以前的做法是使用 cmake 手工编译每个库,手动设置 option ,待生成 static/dynamic lib 后再编译 project 的源码, 很容易出错而且非常麻烦,想请问能否通过每个lib维护一个 xmake.lua 打通这个手工编译的流程? 我目前想尽可能复用 cmakelists.txt 里面的 option, 想请问一下最佳实践是什么,我目前的想法是
目前遇到的问题:目前对子项目的 target 是这么写的 target("lib1")
set_kind("static") -- 固定类型为 static 或 shared 这里不知道怎么写成变化的
add_imports("core.project.config") -- 修改 trybuild
before_build(
function (pkg)
print("$(mode)")
print("$(kind)")
-- 设置4种构建类型
local trybuild = "-DCMAKE_BUILD_TYPE=Debug "
-- 设置 msvc dll 版本
trybuild = trybuild .. "-DUSE_MSVC_RUNTIME_LIBRARY_DLL=" .. (is_plat("windows") and "ON" or "OFF") .. " "
-- 设置 lib1 专用的 option
trybuild = trybuild .. "-DLIB1_USEUSE_OSMESA=" .. (is_kind("shared") and "ON" or "OFF") .. " "
config.set("trybuild", trybuild)
end
)
target_end()
|
Beta Was this translation helpful? Give feedback.
-
不是有包么,干么不用,参考 xmake-repo 里面的包配置 |
Beta Was this translation helpful? Give feedback.
-
去看了一下 package,好像没有 is_releasedbg 这样的 api, 所以是不是可以用 子工程下的 xmake.lua 改写成这样了 package("lib1")
add_deps("cmake")
set_sourcedir(os.scriptdir())
-- 制定 cmake 安装逻辑
on_install(
function (pkg)
local cfgs = {}
mode = "Debug"
if pkg:config("releasedbg") then -- 这里的写法是OK的吗?
mode = "RelWithDebInfo"
elseif pkg:config("release") then
mode = "Release"
elseif pkg:config("minsizerel") then -- 这里的写法是OK的吗?
mode = "MinSizeRel"
end
table.insert(cfgs, "-DCMAKE_BUILD_TYPE=" .. mode)
table.insert(cfgs, "-DBUILD_SHARED_LIBS=" .. (pkg:config("shared") and "ON" or "OFF"))
table.insert(cfgs, "-DUSE_MSVC_RUNTIME_LIBRARY_DLL=" .. (pkg:is_plat("windows") and "ON" or "OFF"))
import("package.tools.cmake").install(pkg, cfgs)
end
)
package_end() |
Beta Was this translation helpful? Give feedback.
-
我自己调了一下,感觉是 xmake 的内部代码只区分了 debug/release 导致对于 releasedbg 不响应,具体可以看下 由于没有进一步区分编译模式,所以这些地方都写死了 VS 的 类似还有 private/action/trybuild/msbuild.lua 的 52行 和 39行 我下周看能不能改一下试试,可能会牵扯到 mode() 函数返回的结果,目前我看底层调用的是 is_debug() ,如果要进一步区分编译模式,可能得直接返回字符串 |
Beta Was this translation helpful? Give feedback.
-
目前的确是用 add_configs 来定义的,但是还是对不上,似乎没有这么简单 我目前是把 但是生成的 vs 项目里面编译参数和 cmake 生成的 vs 项目对不上,编译后生成的文件大小也对不上,对比了一下编译命令,有2个宏在 xmake 生成的 VS 项目的编译命令里没有,分别是 import("package.tools.cmake").install 函数里面会通过 table.insert 添加一些给定的默认 cmake 命令行参数,有什么办法可以禁用 xmake 对 cmake 添加默认参数吗?目前猜想是添加的默认参数改变了 cmake 的行为,想调试一下 目前的 package 改成了这样 package("lib1")
-- 编译 cmake 项目需要 cmake 作为依赖
add_deps("cmake")
-- 本地源码目录
set_sourcedir(os.scriptdir())
-- 安装目录
set_installdir(path.join(os.projectdir(), "lib1"))
-- 总是保持安装
set_policy("package.install_always", true)
-- 添加参数
add_configs("mode", {description = "Library compile mode.", default = "debug", values = {"debug", "releasedbg", "release", "minsizerel"}})
add_configs("shared", {description = "If enable shared library.", default = false, type = "boolean"})
add_configs("vs_runtime_dll", {description = "If use MSVC runtime library dll.", default = true, type = "boolean"})
-- 生成 cmake 安装参数
on_install(
function (pkg)
local cfgs = {}
-- 将 xmake 的 mode 转换为 cmake 的编译模式
mode = pkg:config("mode")
if mode == "debug" then
cmake_mode = "Debug"
elseif mode == "releasedbg" then
cmake_mode = "RelWithDebInfo"
elseif mode == "release" then
cmake_mode = "Release"
elseif mode == "minsizerel" then
cmake_mode = "MinSizeRel"
else
raise("Unknown compile mode: " .. mode)
end
-- 设置 xmake 内部参数
pkg:set("kind", pkg:config("shared") and "shared" or "static")
-- 生成 cmake 配置参数
table.insert(cfgs, "-DCMAKE_BUILD_TYPE=" .. cmake_mode)
table.insert(cfgs, "-DBUILD_SHARED_LIBS=" .. (pkg:config("shared") and "ON" or "OFF"))
table.insert(cfgs, "-DUSE_MSVC_RUNTIME_LIBRARY_DLL=" .. ((pkg:is_plat("windows") and pkg:config("vs_runtime_dll")) and "ON" or "OFF"))
import("package.tools.cmake").install(pkg, cfgs) -- 这里会有什么办法可以禁止 xmake 在这里对 cmake 添加默认参数吗?
end
)
package_end() |
Beta Was this translation helpful? Give feedback.
-
问题找到了,的确是 xmake 添加的默认 flag 和 cmakelist.txt 中的设置发生冲突产生的 bug,目前修改之后程序编译后的大小是正常的,程序行为也正常了 具体做法是先注释掉 cmake.lua #365-373后,再注释掉 cmake.lua #377,整个 package 的编译就正常了 所以我觉得,是不是可以考虑一下增加类似上面的 vs_configuration=RelWIthDebInfo,以及 auto_flags=false,来控制 xmake 是否默认添加 flag,替代这里的注释代码的行为,同时设置 vs 的 configuration来和 cmake 对齐输出路径,这样能方便检查,从而避免这种隐式 bug。这样做可以给用户更大的自由度,已有的 cmake 代码库就完全不需要改动了。 而且,这个文件下面的 _get_configs_for_android、_get_configs_for_appleos、_get_configs_for_wasm 等函数里面都有类似的写法,很可能也会有这种隐式 bug,不仔细调试其实很难发现,程序不一定会崩,只是可能行为很奇怪。 感觉可以另开一个 issue 来修一下这个问题,您觉得呢? |
Beta Was this translation helpful? Give feedback.
-
这是特殊 api 设置不会考虑的。而且 cmake 也不只 vs 一个 generator,用户切到 ninja 就没法适用了。。 你想要最大自由度,就自己 os.exec 执行 cmake 命令,完全自主可控。。或者切到 ninja generator 去编译 |
Beta Was this translation helpful? Give feedback.
这是特殊 api 设置不会考虑的。而且 cmake 也不只 vs 一个 generator,用户切到 ninja 就没法适用了。。
你想要最大自由度,就自己 os.exec 执行 cmake 命令,完全自主可控。。或者切到 ninja generator 去编译