0

When I use bazel to generate c++ header source code and winmd file from midl file, I found MyType.winmd file is in output folder, while MyType.h locates at same directory as source code MyType.idl. What I want is that my generated header file locates at the same folder as MyType.winmd file.

MyType.idl:

namespace NS
{
    [default_interface]
    runtimeclass MyType
    {
    }
}

BUILD:

load(":cmd.bzl", "midl")
sh_binary(
    name = "midlCmd.bat",
    srcs = ["midl.bat"],
)
midl(
    name = "midlcc.bat",
    idl = "MyType.idl",
    winmd = "MyType.winmd",
)

cmd.bzl:

def _impl(ctx):
    winmd = ctx.outputs.winmd
    idl = ctx.file.idl
    ctx.actions.run(
        inputs = [idl],
        outputs = [winmd],
        arguments = [winmd.path, idl.path],
        progress_message = "Generate winmd from idl file: %s" % idl,
        executable = ctx.executable.code_gen_tool,
    )
midl = rule(
    implementation = _impl,
    output_to_genfiles = True,
    attrs = {
        "idl": attr.label(allow_single_file = True, mandatory = True),
        "winmd": attr.output(mandatory = True),
        "code_gen_tool": attr.label(
            executable = True,
            cfg = "exec",
            allow_files = True,
            default = Label("//cmd:midlCmd.bat"),
        ),
    },
)

midl.bat:

"C:\Program Files (x86)\Windows Kits\10\bin\10.0.20206.0\x64\midl.exe" ^
/metadata_dir "%WindowsSdkDir%References\%WindowsSDKVersion%Windows.Foundation.FoundationContract\4.0.0.0" ^
/reference "%WindowsSdkDir%References\%WindowsSDKVersion%Windows.Foundation.FoundationContract\4.0.0.0\Windows.Foundation.FoundationContract.winmd" ^
/cpp_cmd "C:\PROGRA~2\MICROS~1\2019\Community\VC\Tools\MSVC\14.28.29333\bin\Hostx64\x64\cl.exe" ^
/notlb ^
/winrt ^
/nomidl ^
/nologo ^
/enum_class ^
/ns_prefix ^
/client none ^
/server none ^
/winmd %1 %2

run command:

bazel build //cmd:all

Generated MyType.h here:

C:\Users\songy\source\repos\tuware\cmd>dir
Directory of C:\Users\songy\source\repos\tuware\cmd
2020-12-02  10:41 PM    <DIR>          .
2020-12-02  10:40 PM    <DIR>          ..
2020-12-02  10:41 PM               188 BUILD
2020-12-02  10:33 PM               746 cmd.bzl
2020-12-02  10:30 PM            10,975 midl.bat
2020-12-02  10:41 PM             6,987 MyType.h
2020-11-02  08:41 PM                82 MyType.idl

Generated MyType.winmd is here:

C:\Users\songy\source\repos\tuware\bazel-bin\cmd>dir
2020-12-02  10:30 PM            10,975 midlCmd.bat
2020-12-02  10:40 PM    <DIR>          midlCmd.bat.runfiles
2020-12-02  10:40 PM               247 midlCmd.bat.runfiles_manifest
2020-12-02  10:41 PM             1,536 MyType.winmd
2020-12-02  10:40 PM    <DIR>          setupCppDesktopDevEnvironment.bat.runfiles
2020-12-02  10:40 PM               293 setupCppDesktopDevEnvironment.bat.runfiles_manifest

Anything I'm missing?

Vertexwahn
  • 7,709
  • 6
  • 64
  • 90
Sammi Song
  • 36
  • 7
  • I'm afraid I don't understand. Can you repeat the full path of what you get, and what you expected? – rds Dec 16 '20 at 20:11
  • I'm expecting the cpp header file MyType.h and cppWinrt MyType.winmd are located in the same path: C:\Users\songy\source\repos\tuware\bazel-bin\cmd; But the results are: MyType.h is in the same folder with MyType.idl, while MyType.winmd is in C:\Users\songy\source\repos\tuware\bazel-bin\cmd; – Sammi Song Dec 18 '20 at 08:01
  • Bazel is sandboxed. It's impossible that the header file is generated in the source directory. – rds Dec 18 '20 at 17:46
  • But MyType.winmd are generated file as well, it is in the bazel sandbox path, not sure why generated file MyType.h can not locate there. – Sammi Song Dec 18 '20 at 18:56
  • It did generated MyType.h in the the source folder, not sure why. ```2020-12-02 10:41 PM 6,987 MyType.h``` – Sammi Song Dec 18 '20 at 19:10

2 Answers2

0

I don't see how the file can be outputted in the source directory with the sandboxing that bazel does.

The only thing I can think of is that the midlCmd.bat has hardcoded the absolute path.

The generator should be based on relative paths. If it needs a directory structure, the rule can provide ctx.configuration.genfiles_dir.path to the command line of the generator.

rds
  • 26,253
  • 19
  • 107
  • 134
  • Thanks for the hint. In my midl.bat, I did not use /out option, but using hardcode path for MyType.winmd file, that's why the header file is being generated in current folder, while the MyType.winmd is generated in the generated file(abosolute path). After adding /out option, and point it to ```ctx.configuration.genfiles_dir.path```, the file are generated in the same path as expected. – Sammi Song Dec 26 '20 at 23:18
0

Thanks @rds Here is the my own answer.

  1. Add ctx.configuration.genfiles_dir.path as /out option value in midl.bat
  2. use ctx.declare_file for winmd and .h generated file name.
def _impl(ctx):
    
    idl = ctx.file.idl

    midl_out_dir = ctx.configuration.genfiles_dir.path

    winmd = ctx.actions.declare_file(ctx.label.name + ".winmd")
    header = ctx.actions.declare_file(ctx.label.name + ".h")

    ctx.actions.run(
        executable = ctx.executable.code_gen_tool,
        arguments = [midl_out_dir, idl.path],
        inputs = [idl],
        outputs = [winmd, header],
        progress_message = "Generate winmd from idl file: %s" % idl.path,
    )

    return [DefaultInfo(files=depset([winmd, header]))]

midl = rule(
    implementation = _impl,
    output_to_genfiles = True,
    attrs = {
        "idl": attr.label(allow_single_file = True, mandatory = True),
        "code_gen_tool": attr.label(
            executable = True,
            cfg = "exec",
            allow_files = True,
            default = Label("//cmd:midlCmd.bat"),
        ),
    },
)

midl.bat:

"%WindowsSdkDir%\bin\%WindowsSDKVersion%\%Platform%\midl.exe" ^
/metadata_dir "%WINDOWS_SDK_REFERENCE_PATH%\Windows.Foundation.FoundationContract\4.0.0.0" ^
/reference "%WINDOWS_SDK_REFERENCE_PATH%\Windows.Foundation.FoundationContract\4.0.0.0\Windows.Foundation.FoundationContract.winmd" ^
/cpp_cmd "%VSINSTALLDIR%\VC\Tools\MSVC\%VCToolsVersion%\bin\Host%Platform%\%Platform%\cl.exe" ^
/notlb ^
/winrt ^
/nomidl ^
/nologo ^
/enum_class ^
/ns_prefix ^
/client none ^
/server none ^
/out %1 ^
%2
Sammi Song
  • 36
  • 7