-
-
Notifications
You must be signed in to change notification settings - Fork 742
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
ICU-22787 Fix ClangCL compilation on Windows #3023
ICU-22787 Fix ClangCL compilation on Windows #3023
Conversation
} else if (strcmp(optCpuArch, "arm64") == 0) { | ||
*pCPU = IMAGE_FILE_MACHINE_ARM64; | ||
} else { | ||
// This should never happen. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case, I'd say that it'd be easier to debug if the process terminated with an error message if that which should never happen ever happened anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense. I've changed it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As this code never will be executed, I recommend keeping it as simple as possible, it really doesn't need to print any custom error message that never will be printed anyway and a simple source code comment would suffice:
#include <exception>
std::terminate(); // Unreachable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added it based on your previous comment:
In that case, I'd say that it'd be easier to debug if the process terminated with an error message if that which should never happen ever happened anyway.
Although I didn't think about it before you mentioned it, this log makes sense to me. For example, imagine someone makes a typo and passes -c X64
or -c amr64
, this log would help them fix it much quicker.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For example, imagine someone makes a typo and passes
-c X64
or-c amr64
, this log would help them fix it much quicker.
Wait a second, your original comment here was "This should never happen." but the user making a typo on the commandline is the total opposite of that, that's something that certainly is going to happen, sooner or later.
But verifying that the commandline arguments are correct should be done already in main()
in genccode.c
, in the same way that the arguments to -a
are being verified there by calling the checkAssemblyHeaderName()
helper function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand the confusion. My comment was misleading. Sorry for that. I checked the code now and saw the checkAssemblyHeaderName
helper, I'll add that type of check to the -c
option as well. Thanks for pointing that out. Once I add that the else branch should really never happen, and then the change you suggested with std::terminate()
will be correct.
@@ -131,6 +133,7 @@ main(int argc, char* argv[]) { | |||
"\t-o or --object write a .obj file instead of .c\n" | |||
"\t-m or --match-arch file.o match the architecture (CPU, 32/64 bits) of the specified .o\n" | |||
"\t ELF format defaults to i386. Windows defaults to the native platform.\n" | |||
"\t-c or --cpu-arch Specify a CPU architecture for which to write a .obj file for ClangCL on Windows\n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be easier to use this tool correctly if this commandline flag was #ifdef
'ed out altogether on platforms where it isn't implemented?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For now, I've only #ifdef
ed out the parts in genccode.c
, as I didn't want to make writeObjectCode
signature different depending on which compiler is used on Windows. I just pass it NULL
if Clang isn't used. If you think I should make the signature #ifdef
ed too, let me know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better to leave it a generic argument, even if it is only currently valid for ClangCL. It may be needed in other situations.
@@ -847,7 +852,24 @@ getArchitecture(uint16_t *pCPU, uint16_t *pBits, UBool *pIsBigEndian, const char | |||
# if defined(_M_IX86) | |||
*pCPU = IMAGE_FILE_MACHINE_I386; | |||
# else | |||
*pCPU = IMAGE_FILE_MACHINE_UNKNOWN; | |||
// Linker for ClangCL doesn't handle IMAGE_FILE_MACHINE_UNKNOWN the same as |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I read the existing U_PLATFORM_HAS_WIN32_API
block correctly it's all about Microsoft's link.exe
, so it seems odd to now mix in another linker in that. Wouldn't this become easier to read if Microsoft's and LLVM's linkers got each their separate #if
block?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In platform.h
for U_PLATFORM_HAS_WIN32_API
it says: Defines whether the Win32 API is available on the platform.
. This is true for ClangCL, so I've added a new constant U_CLANG_CL
to distinguish when using Clang on Windows. After that, I changed to using that constant inside the mentioned block.
Wouldn't this become easier to read if Microsoft's and LLVM's linkers got each their separate #if block
It would, but I do not know how to write linker-specific code (I'm not saying it is impossible). What can be done from my perspective is to detect the compiler (MSVC or Clang) and then infer a linker (link.exe or lld-link.exe), which is more or less what we have now after these changes.
// the target architecture. | ||
# if defined(__clang__) | ||
if (strcmp(optCpuArch, "x64") == 0) { | ||
*pCPU = IMAGE_FILE_MACHINE_AMD64; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are 32-bit builds not supported? It's been a long time since I last had any reason to do one, but I wasn't aware that they're no longer supported.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense. I've added a strcmp(optCpuArch, "x86") == 0
branch in case someone needs it since it is still supported.
Above this code there is:
# if defined(_M_IX86)
*pCPU = IMAGE_FILE_MACHINE_I386;
but that would only apply if genccode
was compiled targeting x86, which is not necessarily the case.
1343c73
to
a539dde
Compare
Notice: the branch changed across the force-push!
~ Your Friendly Jira-GitHub PR Checker Bot |
Thanks for the review @roubert, I tried to address all your comments in a new commit. I see 2 checks failed: |
Please wait with squashing until after feedback is resolved. |
Will do. By the way, I see that in |
Hey everyone, I wanted to check if there is anything else for me to do after my initial changes? If you think it is better to leave the new option I can every my latest changes in |
The CI is currently broken, you'll just have to wait for it to get fixed (and then those tests should pass again). |
It has now been fixed and the tests pass. |
* @internal | ||
*/ | ||
#if (defined(_MSC_VER) && defined(__clang__) && __clang__) | ||
# define U_CLANG_CL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd recommend against adding a new macro to the public API for a check that's only used in one single internal tool. (That would also make the icu4c-docs-build failure disappear, without you having to actually update the documentation.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, I'll remove it.
} else if (strcmp(optCpuArch, "arm64") == 0) { | ||
*pCPU = IMAGE_FILE_MACHINE_ARM64; | ||
} else { | ||
// This should never happen. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As this code never will be executed, I recommend keeping it as simple as possible, it really doesn't need to print any custom error message that never will be printed anyway and a simple source code comment would suffice:
#include <exception>
std::terminate(); // Unreachable.
} else if (strcmp(optCpuArch, "arm64") == 0) { | ||
*pCPU = IMAGE_FILE_MACHINE_ARM64; | ||
} else { | ||
// This should never happen. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For example, imagine someone makes a typo and passes
-c X64
or-c amr64
, this log would help them fix it much quicker.
Wait a second, your original comment here was "This should never happen." but the user making a typo on the commandline is the total opposite of that, that's something that certainly is going to happen, sooner or later.
But verifying that the commandline arguments are correct should be done already in main()
in genccode.c
, in the same way that the arguments to -a
are being verified there by calling the checkAssemblyHeaderName()
helper function.
a539dde
to
d5fe469
Compare
Notice: the branch changed across the force-push!
~ Your Friendly Jira-GitHub PR Checker Bot |
@roubert I pushed the changes in a new commit. I addressed your comments and made changes based on this comment. Please let me know if there is something else I should change. Regards. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, this all looks reasonable to me now, so I'll leave it to @rp9-next (@microsoft) to take this review from here (and verify that what this does really is what it should be doing, and that this is the preferred way of doing that, and so on).
@roubert , merging is blocked by a change requested check which I believe is outdated.. @StefanStojanovic, please squash all the commits to a single commit for merging (you could use the squash branch tool as well) |
d5fe469
to
d0712de
Compare
Notice: the branch changed across the force-push!
~ Your Friendly Jira-GitHub PR Checker Bot |
Thanks for the review @rp9-next. I rebased to the latest main branch and squashed commits afterward. |
Done. |
- Floating patch for ICU 75.x ICU Bug: https://unicode-org.atlassian.net/browse/ICU-22787 Backport of: unicode-org/icu#3023
- Floating patch for ICU 75.x ICU Bug: https://unicode-org.atlassian.net/browse/ICU-22787 Backport of: unicode-org/icu#3023
- Floating patch for ICU 75.x ICU Bug: https://unicode-org.atlassian.net/browse/ICU-22787 Backport of: unicode-org/icu#3023
- Floating patch for ICU 75.x ICU Bug: https://unicode-org.atlassian.net/browse/ICU-22787 Backport of: unicode-org/icu#3023 PR-URL: #54502 Reviewed-By: Steven R Loomis <[email protected]> Reviewed-By: Richard Lau <[email protected]>
- Floating patch for ICU 75.x ICU Bug: https://unicode-org.atlassian.net/browse/ICU-22787 Backport of: unicode-org/icu#3023 PR-URL: #54502 Reviewed-By: Steven R Loomis <[email protected]> Reviewed-By: Richard Lau <[email protected]>
- Floating patch for ICU 75.x ICU Bug: https://unicode-org.atlassian.net/browse/ICU-22787 Backport of: unicode-org/icu#3023 PR-URL: #54502 Reviewed-By: Steven R Loomis <[email protected]> Reviewed-By: Richard Lau <[email protected]>
- Floating patch for ICU 75.x ICU Bug: https://unicode-org.atlassian.net/browse/ICU-22787 Backport of: unicode-org/icu#3023 PR-URL: nodejs#54502 Reviewed-By: Steven R Loomis <[email protected]> Reviewed-By: Richard Lau <[email protected]>
I'm working on supporting Node.js on Windows. There is an ongoing effort to enable it to be compiled with ClangCL. While working on it I noticed an issue when creating
.obj
file in ICU because of the*pCPU = IMAGE_FILE_MACHINE_UNKNOWN;
line, and the code I made fixes that by adding a new option. Although this is a broader problem that should be fixed for multiple compilers and platforms, my change is aimed toward ClangCL and Windows, but can be used as a good foundation to work on fixes for other platforms and compilers and make corrections in future iterations.This issue is currently our main blocker for enabling ClangCL compilation for Node.js and it'd be greatly appreciated if it could be reviewed soon.
Refs: nodejs/node#53003
Checklist