Introduce diagnostic for calling `set_kind()` in `package()`
Xmake Version
3.0.2
Operating System Version and Architecture
AlmaLinux 9
Describe Bug
In my own xmake-repo, I introduced a simple package definition for a small static library. Because of copy-paste, I left set_kind("static") in it, like:
package("mylib")
set_kind("static")
 set_urls("<mylibURL>")
 on_install(function (pkg)
 import("package.tools.xmake").install(pkg, {})
 end)
The static library itself is very simple, nothing interesting to report.
add_rules("mode.debug", "mode.release")
set_languages("gnuxx20")
target("mylib")
set_kind("static")
add_files("source/*.cpp")
add_includedirs("include", {public = true})
add_headerfiles("include/*.hpp")
When building my project which add_requires("mylib", {configs={"local"}}) and for the target add_packages("mylib", ...<other libs>), the package installed fine and, with -v verbose output, I saw that the table for the installed library contains sysincludedirs. But the cache (.xmake/linux/x86_64/cache/package) did not have sysincludedirs for the mylib package, thus the build failed.
It took a while for me to notice the set_kind() "inside" package() and when I removed it, it worked fine.
Expected Behavior
Obviously the set_kind() "inside" package() wreaks havoc. Now, maybe some of this is intended behavior, but even if it is, it's strange. So, either:
- report an error when calling
set_kind()"inside"package() - report a warning about it having potentially unwanted effect, with some way of suppressing said warning for those who are fine with it
Project Configuration
add_rules("mode.debug", "mode.release")
add_requires("mylib main", {configs = {"local"}})
set_languages "gnuxx20"
target "myapp"
set_kind "binary"
add_files(<stuff>)
add_packages("mylib", ...<other packages>)
Additional Information and Error Logs
nothing to add
package:set_kind values is library/binary/toolchain Please reference https://github.com/xmake-io/xmake-repo/blob/43c6b0306ee6fe70f53b3749d85952fe1a69a46e/packages/y/yyjson/xmake.lua#L47
package:set_kind values is library/binary/toolchain Please reference https://github.com/xmake-io/xmake-repo/blob/43c6b0306ee6fe70f53b3749d85952fe1a69a46e/packages/y/yyjson/xmake.lua#L47
The target() of my library has set_kind(static), just like in the link you provided, and that's fine. The problem is that I had set_kind also in the package - in your link, it would be in the line just after package("yyjson").
The package kind is not equal to target kind, because package is not equal to target.
No static kind for package, package can support static/shared libraries at same time.
You need use add_requires("xxx", {configs = {shared = true/false}}) to switch static/shared package.
Expected Behavior
Obviously the set_kind() "inside" package() wreaks havoc. Now, maybe some of this is intended behavior, but even if it is, it's strange. So, either:
- report an error when calling set_kind() "inside" package()
- report a warning about it having potentially unwanted effect, with some way of suppressing said warning for those who are fine with it
I suppose it's a xmake language server that you are looking for. But I'm afraid you can only remember this syntax and api usage for the time being.
Also, set_kind() can be designed to check its current scope. Then xmake can limit its values according to its scope (in this situation, package and target). If set_kind() gets an unexpected value, xmake throws an error. But simply remember its usage I suggest : )
xmake has hundreds of interfaces, thousands of interface parameters, and tens of thousands of parameter values. I don't have time to fully test each interface.
Currently, some API parameter detection has been implemented. More detection may be added in the future, but it is not my main focus at the moment. I don’t have much time. You can try to submit a pull request to add more detection.
https://github.com/xmake-io/xmake/tree/dev/xmake/modules/private/check/checkers/api
I suppose it's a xmake language server that you are looking for. But I'm afraid you can only remember this syntax and api usage for the time being. Also,
set_kind()can be designed to check its current scope. Then xmake can limit its values according to its scope (in this situation,packageandtarget). Ifset_kind()gets an unexpected value, xmake throws an error. But simply remember its usage I suggest : )
A language server would help, but like you said, checking the context is best here. As @waruqi pointed out "no static kind for package".
I very much appreciate the time xmake developers put into it and understand that there are many concurrent and competing concerns. This issue is in no way a reflection on you guys.
My point was that I encountered this one after copy-paste, not intentionally, and it was very hard to debug and took several hours. Yet it seemed likely that someone with knowledge of xmake codebase might be able to add some if context=="package" and kind=="static" or kind=="shared" then error()" somewhere without much effort.
Case in point, I looked at https://github.com/xmake-io/xmake/blob/dev/xmake/modules/private/check/checkers/api/target/kind.lua and I can't figure out how to check the context. Maybe it's implied that target is the context here (because it's kind.lua in target directory), but there's no package directory and I don't have an idea how to introduce one correctly.
There is a language server in development which checks for this case already. But it is still in development and you will get alot of incorrect warnings. https://github.com/CppCXY/xmake_ls
There is a language server in development which checks for this case already. But it is still in development and you will get alot of incorrect warnings. https://github.com/CppCXY/xmake_ls
That's great! Still, there are situations when running a LS is not simple or easy. In this particular case, I was working, as I often do, over SSH on a "lightly" embedded Linux (SBC with a "trimmed down" standard distribution). Which is a great "power point" for xmake, because it is overkill to use Python for meson and CMake syntax is too weird to handle cross-compiling, building on target (for debugging), building (unit) tests on a "regular" host, and all that.
@waruqi If we introduce package api checking, how would we go about running the checker over package repos? Creating a dummy project for the repo or adding the ability to check repos to the checker itself?
you can check it here.
https://github.com/xmake-io/xmake/blob/7dabd19751248074ccfaf470e9b7eb5f1a57ca9b/xmake/modules/private/action/require/impl/package.lua#L1130
like this
https://github.com/xmake-io/xmake/blob/dev/xmake/actions/build/check.lua