Closed andrewkatson closed 5 months ago
I see this issue with other libraries too just FYI so it is not just this BUILD
file. Like one I have a glob
I only want to run on linux
and a normal list on mac
but instead the glob
runs.
This is that BUILD
file
package(default_visibility = ["//visibility:public"])
config_setting(
name = "windows",
constraint_values = [
"@platforms//os:windows",
],
visibility = ["//visibility:public"],
)
config_setting(
name = "mac",
constraint_values = [
"@platforms//os:macos",
],
visibility = ["//visibility:public"],
)
config_setting(
name = "linux",
constraint_values = [
"@platforms//os:linux",
],
visibility = ["//visibility:public"],
)
cc_library(
name = "libnorm",
srcs = select({
"windows": glob(["**/*.a"]),
"mac": ["build/libnorm.a"],
"linux": glob(["**/*.a"]),
}),
hdrs = select({
"windows": glob(["**/include/**/*.h"]),
"mac": [
"include/galois.h",
"include/normApi.h",
"include/normEncoder.h",
"include/normEncoderMDP.h",
"include/normEncoderRS16.h",
"include/normEncoderRS8.h",
"include/normFile.h",
"include/normMessage.h",
"include/normNode.h",
"include/normObject.h",
"include/normPostProcess.h",
"include/normSegment.h",
"include/normSession.h",
"include/normSimAgent.h",
"include/normVersion.h"
],
"linux": glob(["**/include/**/*.h"]),
}),
includes = select({
"windows": [],
"mac": ["include"],
"linux": [],
})
)
Also I read https://bazel.build/reference/be/functions#select and this should not be possible. But it definitely is.
Oh and even more odd when I specify linux_x86_64
with @platforms//cpu:x86_64
instead of just linux
I still get it being selected even though I am on the M2 macbook air which should be arm
.
Also only when I remove the windows
and linux
branches of the select statement do I only run the mac
code. I must be doing something wrong here but I can't figure it out.
I have also tried just using @platforms//os:specific_os
inside of the select statement.
I have tested this on Windows
and Ubuntu
and the select works as it would be expected to.
Okay I added a select using the same exact config_setting rules to the bazel codebase tests to see if I could reproduce this.
https://github.com/bazelbuild/bazel
And it worked exactly as expected. So I must be doing something wrong or bazel uses its own version of bazel separate from the one I am using.
Hmmm now I am more confused. I think what is happening is that during evaluation these things are being picked up but during compilation and runtime these extra bits are not picked up. Because when I add in files that won't compile as sources the build fails. If I remove them the build succeeds. In both cases the bazel query
shows the broken file as a dependency.
Every branch of the select is included in the output of query. If you'd like to see specifically what would happen on the current platform you can use aquery instead.
+1 to what keith said. query
gives all select branches, cquery
, along with whatever flags you use to set CPU or target OS, will give you only the used branch.
Also, it's sort of wasteful to wrap the platform constraints, as you did with
config_setting(
name = "mac",
constraint_values = ["@platforms//os:macos",],
)
You can use "@platforms//os:macos"
directly as select()
keys.
And, finally, to give you better control over what you get, you should consider using platforms to target the actual environments you are building for.
platform
s for each of linux, macos, and windows.That will put you in much better position to cross compile for another platform, lets say mac arm from mac x86, or even windows from linux using clang.
Oh I see I knew I was doing something odd. Okay so when I try to build something with the second BUILD
file as a dependency I get the following error. Where it seems like it is trying to execute the glob
. I guess it is trying to evaluate it or something but it doesn't strike me as intended behavior.
no such package '@libnorm//': error globbing [**/include/**/*.h] op=FILES: /private/var/tmp/_bazel_andrewkatson/68e86775b12d9adab2e45c6c1e0fc99b/external/libnorm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm/norp/norm (Too many levels of symbolic links) and referenced by '//src:general_import_tester'
ERROR: Analysis of target '//src:general_import_tester' failed; build aborted: Analysis failed
I tried doing os + cpu to stop this and it didn't work it still tries to evaluate all of the branches.
glob
is evaluated before select
, so you can't prevent globs from being executed by wrapping them in a select
.
Thank you!
So I have a
BUILD
file that looks like thisThis is meant to be an external repository that I am defining a rule for. But when I run
bazel query
on the path to the library I have that depends on this I get the following.As you can see it is running the
glob
that is picking up the.a
file even though that should only happen on mac. When I remove thelinux
part of the select it works and I don't pull in the.a
. What am I doing wrong here?