diff --git a/examples/third_party/mesa/BUILD.mesa.bazel b/examples/third_party/mesa/BUILD.mesa.bazel index 074f6669..0e4ef2a3 100644 --- a/examples/third_party/mesa/BUILD.mesa.bazel +++ b/examples/third_party/mesa/BUILD.mesa.bazel @@ -39,6 +39,12 @@ meson_with_requirements( }, }), lib_source = ":all_srcs", + linkopts = select({ + "@openssl//:msvc_compiler": [ + "ws2_32.lib", + ], + "//conditions:default": [], + }), options = select({ "@platforms//os:linux": { # Disable LLVM support, as building LLVM in rules_foreign_cc CI would drastically increase the build time diff --git a/foreign_cc/meson.bzl b/foreign_cc/meson.bzl index 7b26f75b..33f38a35 100644 --- a/foreign_cc/meson.bzl +++ b/foreign_cc/meson.bzl @@ -2,6 +2,12 @@ load("//foreign_cc:utils.bzl", "full_label") load("//foreign_cc/built_tools:meson_build.bzl", "meson_tool") +load( + "//foreign_cc/private:cc_toolchain_util.bzl", + "absolutize_path_in_str", + "get_flags_info", + "get_tools_info", +) load( "//foreign_cc/private:detect_root.bzl", "detect_root", @@ -61,8 +67,34 @@ def _create_meson_script(configureParameters): attrs = configureParameters.attrs inputs = configureParameters.inputs + tools = get_tools_info(ctx) script = pkgconfig_script(inputs.ext_build_dirs) + # CFLAGS and CXXFLAGS are also set in foreign_cc/private/cmake_script.bzl, so that meson + # can use the intended tools. + # However, they are split by meson on whitespace. For Windows it's common to have spaces in path + # https://github.com/mesonbuild/meson/issues/3565 + # Skip setting them in this case. + if " " not in tools.cc: + script.append("##export_var## CC {}".format(_absolutize(ctx.workspace_name, tools.cc))) + if " " not in tools.cxx: + script.append("##export_var## CXX {}".format(_absolutize(ctx.workspace_name, tools.cxx))) + + # set flags same as foreign_cc/private/cc_toolchain_util.bzl + # cannot use get_flags_info() because bazel adds additional flags that + # aren't compatible with compiler or linker above + copts = (ctx.fragments.cpp.copts + ctx.fragments.cpp.conlyopts + getattr(ctx.attr, "copts", [])) or [] + cxxopts = (ctx.fragments.cpp.copts + ctx.fragments.cpp.cxxopts + getattr(ctx.attr, "copts", [])) or [] + + if copts: + script.append("##export_var## CFLAGS \"{}\"".format(" ".join(copts).replace("\"", "'"))) + if cxxopts: + script.append("##export_var## CXXFLAGS \"{}\"".format(" ".join(cxxopts).replace("\"", "'"))) + + flags = get_flags_info(ctx) + if flags.cxx_linker_executable: + script.append("##export_var## LDFLAGS \"{}\"".format(" ".join(flags.cxx_linker_executable).replace("\"", "'"))) + script.append("##export_var## CMAKE {}".format(attrs.cmake_path)) script.append("##export_var## NINJA {}".format(attrs.ninja_path)) script.append("##export_var## PKG_CONFIG {}".format(attrs.pkg_config_path)) @@ -201,3 +233,9 @@ def meson_with_requirements(name, requirements, **kwargs): toolchain = full_label("built_meson_toolchain_for_{}".format(name)), **kwargs ) + +def _absolutize(workspace_name, text, force = False): + if text.strip(" ").startswith("C:") or text.strip(" ").startswith("c:"): + return "\"{}\"".format(text) + + return absolutize_path_in_str(workspace_name, "$EXT_BUILD_ROOT/", text, force) diff --git a/foreign_cc/private/framework/helpers.bzl b/foreign_cc/private/framework/helpers.bzl index 47968133..b4de856a 100644 --- a/foreign_cc/private/framework/helpers.bzl +++ b/foreign_cc/private/framework/helpers.bzl @@ -191,6 +191,7 @@ def do_function_call(text, shell_context): return replace_exports(after, shell_context) arguments = split_arguments(after.strip(" ")) if after else [] + return call_shell(shell_context, funname, *arguments) # buildifier: disable=function-docstring @@ -199,22 +200,28 @@ def split_arguments(text): current = text.strip(" ") for _ in range(1, 2147483647): + current = current.strip(" ") if not current: break # we are ignoring escaped quotes - (before, separator, after) = current.partition("\"") - if not separator: - parts += current.split(" ") + s_quote = current.find("\"") + if s_quote < 0: + for e in current.split(" "): + if len(e) > 0: + parts.append(e) break - (quoted, separator2, after2) = after.partition("\"") - if not separator2: + + e_quote = current.find("\"", s_quote + 1) + if e_quote < 0: fail("Incorrect quoting in fragment: {}".format(current)) - before = before.strip(" ") - if before: + # backtrack to first space, from here to e_quote is a token + e_before = current.rfind(" ", 0, s_quote) + if e_before >= 0: + before = current[0:e_before].strip(" ") parts += before.split(" ") - parts.append("\"" + quoted + "\"") - current = after2 + parts.append(current[e_before + 1:e_quote + 1]) + current = current[e_quote + 1:] return parts diff --git a/test/convert_shell_script_test.bzl b/test/convert_shell_script_test.bzl index 88ff647f..1fe14ed8 100644 --- a/test/convert_shell_script_test.bzl +++ b/test/convert_shell_script_test.bzl @@ -84,6 +84,7 @@ def _split_arguments_test(ctx): " 1 2 3": ["1", "2", "3"], " usual \"quoted argument\"": ["usual", "\"quoted argument\""], "1 2": ["1", "2"], + "var -flag1=\"redacted\" -flag2=\"redacted\"": ["var", "-flag1=\"redacted\"", "-flag2=\"redacted\""], } for case in cases: result = split_arguments(case)