Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding rule to build Windows .rc files #581

Closed
wants to merge 6 commits into from

Conversation

Overhatted
Copy link
Contributor

Adds the ability to compile resource files: https://learn.microsoft.com/en-us/windows/win32/menurc/about-resource-files

More details are in the commit messages.

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Feb 26, 2024
The rc.exe and cvtres.exe are, respectively, called "Windows Resource Compiler" and "Windows Resource to Object Converter".

I made finding rc.exe in vswhere.py optional since it is part of the Windows SDK which is already being handled as optional in that script. Although I'm not sure the optional part is currently working.
…soft.com/en-us/windows/win32/menurc/about-resource-files

The "Windows Resource Compiler" compiles .rc files into .res files which the "Windows Resource to Object Converter" then converts into .obj files, to be used by the linker.

The .res files can also be passed directly to the linker which will call the "Windows Resource to Object Converter" in the same directory to convert the file. Since with Buck2 we want explicit dependencies as much as possible I opted to convert the resource file to an .obj file explicitly in the windows_resouce rule.
@Overhatted Overhatted marked this pull request as ready for review February 29, 2024 08:43
@ndmitchell
Copy link
Contributor

CC @lmvasquezg @KapJI as Windows experts

Copy link
Member

@KapJI KapJI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good but please add a end to end test which uses windows_resource.

@@ -81,6 +86,9 @@ def find_with_vswhere_exe():
reverse=True,
)

vc_exe_names = "cl.exe", "cvtres.exe", "lib.exe", "ml64.exe", "link.exe"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Semantically these are lists, not tuples.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I do:

vc_exe_names = "cl.exe", "cvtres.exe", "lib.exe", "ml64.exe", "link.exe"
type(vc_exe_names)

I get tuple.
Is it some obscure Python feature that it is actually a list? Unless I'm misunderstanding what you mean.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I means it should be a list instead of tuple.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course, you're right, semantically they are lists

prelude/toolchains/msvc/vswhere.py Outdated Show resolved Hide resolved
prelude/toolchains/msvc/vswhere.py Outdated Show resolved Hide resolved
prelude/cxx/cxx_toolchain.bzl Show resolved Hide resolved
prelude/cxx/windows_resource.bzl Show resolved Hide resolved
prelude/decls/cxx_rules.bzl Outdated Show resolved Hide resolved
@KapJI
Copy link
Member

KapJI commented Mar 4, 2024

It seems our test suite isn't open sourced, I can add test later myself. If you can, please post some basic example which I can turn into test.

Co-authored-by: Ruslan Sayfutdinov <ruslan@sayfutdinov.com>
@Overhatted
Copy link
Contributor Author

Overhatted commented Mar 6, 2024

My sample test:
BUCK:

# A rule that includes a single .rc file and compiles it into an object file.
windows_resource(
    name = "resources",
    srcs = [
        "resources.rc",
    ],
)
# A rule that links against the above windows_resource rule.
cxx_binary(
    name = "app",
    srcs = [
        "main.cpp",
    ],
    deps = [
        ":resources"
    ],
    linker_flags = [
        "User32.lib",
    ],
)

main.cpp:

#include <iostream>
#include <Windows.h>

int main(int argc, const char* argv[])
{
	std::string message;
	message.resize(50);
	int returnValue = LoadStringA(NULL, 4, message.data(), message.size());
	if (returnValue == 0)
	{
		std::cout << "Failed to read resource";
		return 1;
	}

	message.resize(returnValue);
	std::cout << message;
	return 0;
}

message.h:

#define MESSAGE_TO_PRINT "Hello from header"

resources.rc:

#include <winresrc.h>

#include "message.h"

STRINGTABLE
BEGIN
4 MESSAGE_TO_PRINT
END

Edit: Not sure if the "MESSAGE_TO_PRINT" in a separate header will work because I haven't implemented the include_directories and raw_headers logic, but it can be just copied into resources.rc.

@facebook-github-bot
Copy link
Contributor

@KapJI has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

facebook-github-bot pushed a commit to facebook/buck2-prelude that referenced this pull request Mar 11, 2024
Summary:
Adds the ability to compile resource files: https://learn.microsoft.com/en-us/windows/win32/menurc/about-resource-files

More details are in the commit messages.

X-link: facebook/buck2#581

Reviewed By: JakobDegen

Differential Revision: D54603649

Pulled By: KapJI

fbshipit-source-id: fcf56a919b8b6245000e71565894dc7c5e1c0c3f
facebook-github-bot pushed a commit to facebook/buck2-prelude that referenced this pull request Apr 2, 2024
Summary:
Like other cxx rules it supports specifying "headers" or "include_directories" and "raw_headers".

As a test, I added a header dependency to the test I provided in the previous PR: facebook/buck2#581.

The final result being the following files:
BUCK:
```
# A rule that includes a single .rc file and compiles it into an object file.
windows_resource(
    name = "resources",
    srcs = [
        "resources.rc",
    ],
    header_namespace = "",
    headers = ["message.h"],
)

# A rule that links against the above windows_resource rule.
# A rule that includes a single .rc file and compiles it into an object file.
windows_resource(
    name = "resources",
    srcs = [
        "resources.rc",
    ],
    header_namespace = "",
    headers = ["message.h"],
)

# A rule that links against the above windows_resource rule.
cxx_binary(
    name = "app",
    srcs = [
        "main.cpp",
    ],
    deps = [
        ":resources"
    ],
    linker_flags = [
        "User32.lib",
    ],
)
```
main.cpp:
```
#include <iostream>
#include <Windows.h>

int main(int argc, const char* argv[])
{
	std::string message;
	message.resize(50);
	int returnValue = LoadStringA(NULL, 4, message.data(), message.size());
	if (returnValue == 0)
	{
		std::cout << "Failed to read resource";
		return 1;
	}

	message.resize(returnValue);
	std::cout << message;
	return 0;
}
```
message.h:
```
#define MESSAGE_TO_PRINT "Hello from header"
```
resources.rc:
```
#include <winresrc.h>

#include "message.h"

STRINGTABLE
BEGIN
4 MESSAGE_TO_PRINT
END
```

X-link: facebook/buck2#607

Reviewed By: JakobDegen

Differential Revision: D55633608

Pulled By: KapJI

fbshipit-source-id: 6d47acaaa0eb77a653b33d46c8c26088fbf8f0f8
facebook-github-bot pushed a commit that referenced this pull request Apr 2, 2024
Summary:
Like other cxx rules it supports specifying "headers" or "include_directories" and "raw_headers".

As a test, I added a header dependency to the test I provided in the previous PR: #581.

The final result being the following files:
BUCK:
```
# A rule that includes a single .rc file and compiles it into an object file.
windows_resource(
    name = "resources",
    srcs = [
        "resources.rc",
    ],
    header_namespace = "",
    headers = ["message.h"],
)

# A rule that links against the above windows_resource rule.
# A rule that includes a single .rc file and compiles it into an object file.
windows_resource(
    name = "resources",
    srcs = [
        "resources.rc",
    ],
    header_namespace = "",
    headers = ["message.h"],
)

# A rule that links against the above windows_resource rule.
cxx_binary(
    name = "app",
    srcs = [
        "main.cpp",
    ],
    deps = [
        ":resources"
    ],
    linker_flags = [
        "User32.lib",
    ],
)
```
main.cpp:
```
#include <iostream>
#include <Windows.h>

int main(int argc, const char* argv[])
{
	std::string message;
	message.resize(50);
	int returnValue = LoadStringA(NULL, 4, message.data(), message.size());
	if (returnValue == 0)
	{
		std::cout << "Failed to read resource";
		return 1;
	}

	message.resize(returnValue);
	std::cout << message;
	return 0;
}
```
message.h:
```
#define MESSAGE_TO_PRINT "Hello from header"
```
resources.rc:
```
#include <winresrc.h>

#include "message.h"

STRINGTABLE
BEGIN
4 MESSAGE_TO_PRINT
END
```

Pull Request resolved: #607

Reviewed By: JakobDegen

Differential Revision: D55633608

Pulled By: KapJI

fbshipit-source-id: 6d47acaaa0eb77a653b33d46c8c26088fbf8f0f8
wavewave pushed a commit to MercuryTechnologies/buck2-prelude that referenced this pull request Apr 26, 2024
Summary:
Adds the ability to compile resource files: https://learn.microsoft.com/en-us/windows/win32/menurc/about-resource-files

More details are in the commit messages.

X-link: facebook/buck2#581

Reviewed By: JakobDegen

Differential Revision: D54603649

Pulled By: KapJI

fbshipit-source-id: fcf56a919b8b6245000e71565894dc7c5e1c0c3f
wavewave pushed a commit to MercuryTechnologies/buck2-prelude that referenced this pull request Apr 26, 2024
Summary:
Like other cxx rules it supports specifying "headers" or "include_directories" and "raw_headers".

As a test, I added a header dependency to the test I provided in the previous PR: facebook/buck2#581.

The final result being the following files:
BUCK:
```
# A rule that includes a single .rc file and compiles it into an object file.
windows_resource(
    name = "resources",
    srcs = [
        "resources.rc",
    ],
    header_namespace = "",
    headers = ["message.h"],
)

# A rule that links against the above windows_resource rule.
# A rule that includes a single .rc file and compiles it into an object file.
windows_resource(
    name = "resources",
    srcs = [
        "resources.rc",
    ],
    header_namespace = "",
    headers = ["message.h"],
)

# A rule that links against the above windows_resource rule.
cxx_binary(
    name = "app",
    srcs = [
        "main.cpp",
    ],
    deps = [
        ":resources"
    ],
    linker_flags = [
        "User32.lib",
    ],
)
```
main.cpp:
```
#include <iostream>
#include <Windows.h>

int main(int argc, const char* argv[])
{
	std::string message;
	message.resize(50);
	int returnValue = LoadStringA(NULL, 4, message.data(), message.size());
	if (returnValue == 0)
	{
		std::cout << "Failed to read resource";
		return 1;
	}

	message.resize(returnValue);
	std::cout << message;
	return 0;
}
```
message.h:
```
#define MESSAGE_TO_PRINT "Hello from header"
```
resources.rc:
```
#include <winresrc.h>

#include "message.h"

STRINGTABLE
BEGIN
4 MESSAGE_TO_PRINT
END
```

X-link: facebook/buck2#607

Reviewed By: JakobDegen

Differential Revision: D55633608

Pulled By: KapJI

fbshipit-source-id: 6d47acaaa0eb77a653b33d46c8c26088fbf8f0f8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants