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

ICU-21633 Fix ClangCL cross-compilation on Windows #3013

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions icu4c/source/tools/genccode/genccode.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ enum {
#ifdef CAN_GENERATE_OBJECTS
kOptObject,
kOptMatchArch,
kOptCpuArch,
kOptSkipDllExport,
#endif
kOptFilename,
Expand All @@ -86,6 +87,7 @@ static UOption options[]={
#ifdef CAN_GENERATE_OBJECTS
/*6*/UOPTION_DEF("object", 'o', UOPT_NO_ARG),
UOPTION_DEF("match-arch", 'm', UOPT_REQUIRES_ARG),
UOPTION_DEF("cpu-arch", 'c', UOPT_REQUIRES_ARG),
UOPTION_DEF("skip-dll-export", '\0', UOPT_NO_ARG),
#endif
UOPTION_DEF("filename", 'f', UOPT_REQUIRES_ARG),
Expand Down Expand Up @@ -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"
"\t--skip-dll-export Don't export the ICU data entry point symbol (for use when statically linking)\n");
#endif
fprintf(stderr,
Expand Down Expand Up @@ -196,6 +199,7 @@ main(int argc, char* argv[]) {
writeObjectCode(filename, options[kOptDestDir].value,
options[kOptEntryPoint].doesOccur ? options[kOptEntryPoint].value : NULL,
options[kOptMatchArch].doesOccur ? options[kOptMatchArch].value : NULL,
options[kOptCpuArch].doesOccur ? options[kOptCpuArch].value : NULL,
options[kOptFilename].doesOccur ? options[kOptFilename].value : NULL,
NULL,
0,
Expand Down
1 change: 1 addition & 0 deletions icu4c/source/tools/pkgdata/pkgdata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,7 @@ static int32_t pkg_executeOptions(UPKGOptions *o) {
o->entryName,
(optMatchArch[0] == 0 ? nullptr : optMatchArch),
nullptr,
nullptr,
gencFilePath,
sizeof(gencFilePath),
true);
Expand Down
29 changes: 26 additions & 3 deletions icu4c/source/tools/toolutil/pkg_genc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,12 @@ getOutFilename(

#ifdef CAN_GENERATE_OBJECTS
static void
getArchitecture(uint16_t *pCPU, uint16_t *pBits, UBool *pIsBigEndian, const char *optMatchArch) {
getArchitecture(
uint16_t *pCPU,
uint16_t *pBits,
UBool *pIsBigEndian,
const char *optMatchArch,
[[maybe_unused]] const char *optCpuArch) {
union {
char bytes[2048];
#ifdef U_ELF
Expand Down Expand Up @@ -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
// linker for MSVC. Because of this optCpuArch is used to define the CPU
// architecture in that case. While _M_AMD64 and _M_ARM64 could be used,
// this would potentially be problematic when cross-compiling as this code
// would most likely be ran on host machine to generate the .obj file for
// the target architecture.
# if defined(__clang__)
if (strcmp(optCpuArch, "x64") == 0) {
*pCPU = IMAGE_FILE_MACHINE_AMD64;
} else if (strcmp(optCpuArch, "arm64") == 0) {
*pCPU = IMAGE_FILE_MACHINE_ARM64;
} else {
// This should never happen.
*pCPU = IMAGE_FILE_MACHINE_UNKNOWN;
}
# else
*pCPU = IMAGE_FILE_MACHINE_UNKNOWN;
# endif
# endif
# if defined(_M_IA64) || defined(_M_AMD64) || defined (_M_ARM64)
*pBits = 64; // Doesn't seem to be used for anything interesting though?
Expand Down Expand Up @@ -934,6 +956,7 @@ writeObjectCode(
const char *destdir,
const char *optEntryPoint,
const char *optMatchArch,
const char *optCpuArch,
const char *optFilename,
char *outFilePath,
size_t outFilePathCapacity,
Expand Down Expand Up @@ -1201,7 +1224,7 @@ writeObjectCode(
#endif

/* deal with options, files and the entry point name */
getArchitecture(&cpu, &bits, &makeBigEndian, optMatchArch);
getArchitecture(&cpu, &bits, &makeBigEndian, optMatchArch, optCpuArch);
if (optMatchArch)
{
printf("genccode: --match-arch cpu=%hu bits=%hu big-endian=%d\n", cpu, bits, makeBigEndian);
Expand Down
1 change: 1 addition & 0 deletions icu4c/source/tools/toolutil/pkg_genc.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ writeObjectCode(
const char *destdir,
const char *optEntryPoint,
const char *optMatchArch,
const char *optCpuArch,
const char *optFilename,
char *outFilePath,
size_t outFilePathCapacity,
Expand Down