Skip to content

Commit

Permalink
ICU-22787 Fix ClangCL cross-compilation on Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
StefanStojanovic committed Jun 3, 2024
1 parent 81492ae commit 1343c73
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 3 deletions.
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

0 comments on commit 1343c73

Please sign in to comment.