CHECK_CXX_SOURCE_COMPILES(" #ifdef _WIN32 #include /* Workaround for PR19898. */ #include #endif int main() { #ifdef _WIN32 volatile LONG val = 1; MemoryBarrier(); InterlockedCompareExchange(&val, 0, 1); InterlockedIncrement(&val); InterlockedDecrement(&val); #else volatile unsigned long val = 1; __sync_synchronize(); __sync_val_compare_and_swap(&val, 1, 0); __sync_add_and_fetch(&val, 1); __sync_sub_and_fetch(&val, 1); #endif return 0; } " COMPILER_RT_TARGET_HAS_ATOMICS) CHECK_CXX_SOURCE_COMPILES(" #if defined(__linux__) #include #endif #include int fd; int main() { struct flock s_flock; s_flock.l_type = F_WRLCK; fcntl(fd, F_SETLKW, &s_flock); return 0; } " COMPILER_RT_TARGET_HAS_FCNTL_LCK) CHECK_CXX_SOURCE_COMPILES(" #include int fd; int main() { flock(fd, LOCK_EX); return 0; } " COMPILER_RT_TARGET_HAS_FLOCK) CHECK_CXX_SOURCE_COMPILES(" #include int main() { return 0; } " COMPILER_RT_TARGET_HAS_UNAME) add_compiler_rt_component(profile) set(PROFILE_SOURCES InstrProfiling.c InstrProfilingInternal.c InstrProfilingBuffer.c InstrProfilingMerge.c InstrProfilingMergeFile.c InstrProfilingNameVar.c InstrProfilingVersionVar.c InstrProfilingWriter.c InstrProfilingPlatformAIX.c InstrProfilingPlatformDarwin.c InstrProfilingPlatformFuchsia.c InstrProfilingPlatformLinux.c InstrProfilingPlatformOther.c InstrProfilingPlatformWindows.c InstrProfilingPlatformGPU.c ) if (NOT COMPILER_RT_PROFILE_BAREMETAL) # For baremetal, exclude the following: # - Anything that contains filesystem operations (InstrProfilingFile.c, # InstrProfilingUtils.c) # - Initialization, because it isn't necesary without the filesystem bits # on ELF targets (InstrProfilingRuntime.cpp). # - Value profiling, because it requires malloc (InstrProfilingValue.c). # This could be optional if someone needs it. # - GCDA profiling, which is unrelated (GCDAProfiling.c) list(APPEND PROFILE_SOURCES GCDAProfiling.c InstrProfilingFile.c InstrProfilingRuntime.cpp InstrProfilingUtil.c InstrProfilingValue.c ) if(COMPILER_RT_BUILD_PROFILE_ROCM) list(APPEND PROFILE_SOURCES InstrProfilingPlatformROCm.cpp) endif() endif() set(PROFILE_HEADERS InstrProfiling.h InstrProfilingInternal.h InstrProfilingPort.h InstrProfilingUtil.h WindowsMMap.h ) if(WIN32) list(APPEND PROFILE_SOURCES WindowsMMap.c ) endif() include_directories(..) include_directories(../../include) if(FUCHSIA OR UNIX) set(EXTRA_FLAGS -fPIC -Wno-pedantic) endif() if(CMAKE_SYSTEM_NAME STREQUAL "WASI") set(EXTRA_FLAGS ${EXTRA_FLAGS} -D_WASI_EMULATED_MMAN -D_WASI_EMULATED_GETPID) endif() if(COMPILER_RT_TARGET_HAS_ATOMICS) set(EXTRA_FLAGS ${EXTRA_FLAGS} -DCOMPILER_RT_HAS_ATOMICS=1) endif() if(COMPILER_RT_TARGET_HAS_FCNTL_LCK) set(EXTRA_FLAGS ${EXTRA_FLAGS} -DCOMPILER_RT_HAS_FCNTL_LCK=1) endif() if(COMPILER_RT_TARGET_HAS_FLOCK) set(EXTRA_FLAGS ${EXTRA_FLAGS} -DCOMPILER_RT_HAS_FLOCK=1) endif() if(COMPILER_RT_TARGET_HAS_UNAME) set(EXTRA_FLAGS ${EXTRA_FLAGS} -DCOMPILER_RT_HAS_UNAME=1) endif() if(COMPILER_RT_PROFILE_BAREMETAL) set(EXTRA_FLAGS ${EXTRA_FLAGS} -DCOMPILER_RT_PROFILE_BAREMETAL=1) endif() # The HIP host interceptor in InstrProfilingPlatformROCm.cpp pulls in # RTInterception + sanitizer_common object libs. Those targets are only created # when COMPILER_RT_BUILD_SANITIZERS / _MEMPROF / _XRAY / _CTX_PROFILE is enabled # (see lib/CMakeLists.txt). In a profile-only build the targets do not exist; # skip both the object-lib merge and the ROCm source file so the static archive # remains self-contained. set(PROFILE_OBJECT_LIBS) set(PROFILE_HAS_HIP_INTERCEPTOR FALSE) if(COMPILER_RT_HAS_INTERCEPTION AND NOT COMPILER_RT_PROFILE_BAREMETAL AND TARGET RTInterception.${COMPILER_RT_DEFAULT_TARGET_ARCH} AND TARGET RTSanitizerCommon.${COMPILER_RT_DEFAULT_TARGET_ARCH} AND TARGET RTSanitizerCommonLibc.${COMPILER_RT_DEFAULT_TARGET_ARCH}) # RTInterception references __sanitizer_internal_{memcpy,memset,memmove} and other # sanitizer_common symbols; merge the same object libs as clang_rt.cfi (without # coverage/symbolizer) so -fprofile-instr-generate links stay self-contained. list(APPEND PROFILE_OBJECT_LIBS RTInterception RTSanitizerCommon RTSanitizerCommonLibc) set(PROFILE_HAS_HIP_INTERCEPTOR TRUE) endif() if(NOT PROFILE_HAS_HIP_INTERCEPTOR) list(REMOVE_ITEM PROFILE_SOURCES InstrProfilingPlatformROCm.cpp) endif() # Only advertise the ROCm interceptor to InstrProfilingFile.c when its # definition (InstrProfilingPlatformROCm.cpp) is actually compiled into the # archive. Otherwise InstrProfilingFile.c references # __llvm_profile_hip_collect_device_data with no definition; on COFF/Windows # there is no weak-undefined fallback, so the link fails (see PR #200111). if(COMPILER_RT_BUILD_PROFILE_ROCM AND PROFILE_HAS_HIP_INTERCEPTOR) set(EXTRA_FLAGS ${EXTRA_FLAGS} -DCOMPILER_RT_BUILD_PROFILE_ROCM=1) endif() if("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "amdgcn|nvptx") append_list_if(COMPILER_RT_HAS_FFREESTANDING_FLAG -ffreestanding EXTRA_FLAGS) append_list_if(COMPILER_RT_HAS_NOGPULIB_FLAG -nogpulib EXTRA_FLAGS) append_list_if(COMPILER_RT_HAS_FLTO_FLAG -flto EXTRA_FLAGS) if("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "amdgcn") append_list_if(COMPILER_RT_HAS_CODE_OBJECT_VERSION_FLAG "SHELL:-Xclang -mcode-object-version=none" EXTRA_FLAGS) elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "nvptx") list(APPEND EXTRA_FLAGS --cuda-feature=+ptx63) endif() endif() if(MSVC) # profile historically used the static CRT (/MT). When we merge RTInterception and # RTSanitizerCommon (same object libs as clang_rt.cfi on ELF), those targets are # built with MultiThreadedDLL (/MD) — see interception/CMakeLists.txt and # sanitizer_common/CMakeLists.txt. Mixing /MD objects into a /MT libclang_rt.profile # yields LNK2019 (__imp__stricmp from interception_win.cpp) and LNK4098 in Profile-*. if(PROFILE_HAS_HIP_INTERCEPTOR) set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDLL) else() set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded) endif() endif() # We don't use the C++ Standard Library here, so avoid including it by mistake. append_list_if(COMPILER_RT_HAS_NOSTDINCXX_FLAG -nostdinc++ EXTRA_FLAGS) # C++ profile sources (e.g. InstrProfilingPlatformROCm.cpp) must not emit exception # personality symbols: host libclang_rt.profile.a is linked from C code and from C++ # tests that do not pull in __gxx_personality_v0 (Profile-* / premerge). append_list_if(COMPILER_RT_HAS_FNO_EXCEPTIONS_FLAG -fno-exceptions EXTRA_FLAGS) # XRay uses C++ standard library headers. string(REGEX REPLACE "-?-stdlib=[a-zA-Z+]*" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") # This appears to be a C-only warning banning the use of locals in aggregate # initializers. All other compilers accept this, though. # nonstandard extension used : 'identifier' : cannot be initialized using address of automatic variable append_list_if(COMPILER_RT_HAS_WD4221_FLAG /wd4221 EXTRA_FLAGS) # Disable 'nonstandard extension used: translation unit is empty'. append_list_if(COMPILER_RT_HAS_WD4206_FLAG /wd4206 EXTRA_FLAGS) # In the GPU runtimes build, link `runtimes-libc-headers` for its # `-isystem` include dir and for waiting on header generation. # The target is created at compiler-rt top level from `HandleLibC.cmake` # when `LLVM_RUNTIMES_BUILD` is set. set(PROFILE_LINK_LIBS) if(COMPILER_RT_GPU_BUILD AND TARGET runtimes-libc-headers) list(APPEND PROFILE_LINK_LIBS runtimes-libc-headers) endif() if(APPLE) add_compiler_rt_runtime(clang_rt.profile STATIC OS ${PROFILE_SUPPORTED_OS} ARCHS ${PROFILE_SUPPORTED_ARCH} OBJECT_LIBS ${PROFILE_OBJECT_LIBS} CFLAGS ${EXTRA_FLAGS} SOURCES ${PROFILE_SOURCES} ADDITIONAL_HEADERS ${PROFILE_HEADERS} LINK_LIBS ${PROFILE_LINK_LIBS} PARENT_TARGET profile) else() add_compiler_rt_runtime(clang_rt.profile STATIC ARCHS ${PROFILE_SUPPORTED_ARCH} OBJECT_LIBS ${PROFILE_OBJECT_LIBS} CFLAGS ${EXTRA_FLAGS} SOURCES ${PROFILE_SOURCES} ADDITIONAL_HEADERS ${PROFILE_HEADERS} LINK_LIBS ${PROFILE_LINK_LIBS} PARENT_TARGET profile) endif()