mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-10 15:42:14 +00:00
ICU-22787 Fix ClangCL compilation on Windows
This commit is contained in:
parent
57ed0a2a53
commit
66ba09973a
5 changed files with 54 additions and 5 deletions
|
@ -235,7 +235,7 @@
|
|||
/**
|
||||
* \def U_PLATFORM_USES_ONLY_WIN32_API
|
||||
* Defines whether the platform uses only the Win32 API.
|
||||
* Set to 1 for Windows/MSVC and MinGW but not Cygwin.
|
||||
* Set to 1 for Windows/MSVC, ClangCL and MinGW but not Cygwin.
|
||||
* @internal
|
||||
*/
|
||||
#ifdef U_PLATFORM_USES_ONLY_WIN32_API
|
||||
|
@ -250,7 +250,7 @@
|
|||
/**
|
||||
* \def U_PLATFORM_HAS_WIN32_API
|
||||
* Defines whether the Win32 API is available on the platform.
|
||||
* Set to 1 for Windows/MSVC, MinGW and Cygwin.
|
||||
* Set to 1 for Windows/MSVC, ClangCL, MinGW and Cygwin.
|
||||
* @internal
|
||||
*/
|
||||
#ifdef U_PLATFORM_HAS_WIN32_API
|
||||
|
|
|
@ -70,6 +70,7 @@ enum {
|
|||
#ifdef CAN_GENERATE_OBJECTS
|
||||
kOptObject,
|
||||
kOptMatchArch,
|
||||
kOptCpuArch,
|
||||
kOptSkipDllExport,
|
||||
#endif
|
||||
kOptFilename,
|
||||
|
@ -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),
|
||||
|
@ -131,6 +133,8 @@ 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 Valid values for this opton are x64, x86 and arm64.\n"
|
||||
"\t--skip-dll-export Don't export the ICU data entry point symbol (for use when statically linking)\n");
|
||||
#endif
|
||||
fprintf(stderr,
|
||||
|
@ -193,9 +197,17 @@ main(int argc, char* argv[]) {
|
|||
break;
|
||||
#ifdef CAN_GENERATE_OBJECTS
|
||||
case CALL_WRITEOBJECT:
|
||||
if(options[kOptCpuArch].doesOccur) {
|
||||
if (!checkCpuArchitecture(options[kOptCpuArch].value)) {
|
||||
fprintf(stderr,
|
||||
"CPU architecture \"%s\" is unknown.\n", options[kOptCpuArch].value);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
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,
|
||||
|
|
|
@ -776,6 +776,7 @@ static int32_t pkg_executeOptions(UPKGOptions *o) {
|
|||
o->entryName,
|
||||
(optMatchArch[0] == 0 ? nullptr : optMatchArch),
|
||||
nullptr,
|
||||
nullptr,
|
||||
gencFilePath,
|
||||
sizeof(gencFilePath),
|
||||
true);
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
# define NOMCX
|
||||
#include <windows.h>
|
||||
#include <time.h>
|
||||
# if defined(__clang__)
|
||||
# include <exception>
|
||||
# endif
|
||||
# ifdef __GNUC__
|
||||
# define WINDOWS_WITH_GNUC
|
||||
# endif
|
||||
|
@ -294,6 +297,11 @@ checkAssemblyHeaderName(const char* optAssembly) {
|
|||
return false;
|
||||
}
|
||||
|
||||
U_CAPI UBool U_EXPORT2
|
||||
checkCpuArchitecture(const char* optCpuArch) {
|
||||
return strcmp(optCpuArch, "x64") == 0 || strcmp(optCpuArch, "x86") == 0 || strcmp(optCpuArch, "arm64") == 0;
|
||||
}
|
||||
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
printAssemblyHeadersToStdErr() {
|
||||
|
@ -799,7 +807,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
|
||||
|
@ -847,7 +860,25 @@ 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, "x86") == 0) {
|
||||
*pCPU = IMAGE_FILE_MACHINE_I386;
|
||||
} else if (strcmp(optCpuArch, "arm64") == 0) {
|
||||
*pCPU = IMAGE_FILE_MACHINE_ARM64;
|
||||
} else {
|
||||
std::terminate(); // Unreachable.
|
||||
}
|
||||
# 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?
|
||||
|
@ -934,6 +965,7 @@ writeObjectCode(
|
|||
const char *destdir,
|
||||
const char *optEntryPoint,
|
||||
const char *optMatchArch,
|
||||
const char *optCpuArch,
|
||||
const char *optFilename,
|
||||
char *outFilePath,
|
||||
size_t outFilePathCapacity,
|
||||
|
@ -1201,7 +1233,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);
|
||||
|
|
|
@ -73,6 +73,9 @@ printAssemblyHeadersToStdErr(void);
|
|||
U_CAPI UBool U_EXPORT2
|
||||
checkAssemblyHeaderName(const char* optAssembly);
|
||||
|
||||
U_CAPI UBool U_EXPORT2
|
||||
checkCpuArchitecture(const char* optCpuArch);
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
writeCCode(
|
||||
const char *filename,
|
||||
|
@ -98,6 +101,7 @@ writeObjectCode(
|
|||
const char *destdir,
|
||||
const char *optEntryPoint,
|
||||
const char *optMatchArch,
|
||||
const char *optCpuArch,
|
||||
const char *optFilename,
|
||||
char *outFilePath,
|
||||
size_t outFilePathCapacity,
|
||||
|
|
Loading…
Add table
Reference in a new issue