diff options
Diffstat (limited to 'Modules/Platform')
-rw-r--r-- | Modules/Platform/Android-Clang.cmake | 3 | ||||
-rw-r--r-- | Modules/Platform/Android-Determine.cmake | 61 | ||||
-rw-r--r-- | Modules/Platform/Android-Initialize.cmake | 2 | ||||
-rw-r--r-- | Modules/Platform/Android/Determine-Compiler-NDK.cmake | 2 | ||||
-rw-r--r-- | Modules/Platform/Android/VCXProjInspect.vcxproj.in | 38 | ||||
-rw-r--r-- | Modules/Platform/Darwin-Initialize.cmake | 43 | ||||
-rw-r--r-- | Modules/Platform/HP-UX.cmake | 2 | ||||
-rw-r--r-- | Modules/Platform/Windows-Clang.cmake | 49 | ||||
-rw-r--r-- | Modules/Platform/Windows-Intel-ISPC.cmake | 8 | ||||
-rw-r--r-- | Modules/Platform/Windows-MSVC.cmake | 13 |
10 files changed, 170 insertions, 51 deletions
diff --git a/Modules/Platform/Android-Clang.cmake b/Modules/Platform/Android-Clang.cmake index 759448b..160eada 100644 --- a/Modules/Platform/Android-Clang.cmake +++ b/Modules/Platform/Android-Clang.cmake @@ -53,4 +53,7 @@ macro(__android_compiler_clang lang) endif() list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "--target=${CMAKE_${lang}_COMPILER_TARGET}") endif() + if(CMAKE_GENERATOR MATCHES "Visual Studio") + set(_ANDROID_STL_NOSTDLIBXX 1) + endif() endmacro() diff --git a/Modules/Platform/Android-Determine.cmake b/Modules/Platform/Android-Determine.cmake index 2225897..11a0504 100644 --- a/Modules/Platform/Android-Determine.cmake +++ b/Modules/Platform/Android-Determine.cmake @@ -7,8 +7,8 @@ # Support for NVIDIA Nsight Tegra Visual Studio Edition was previously # implemented in the CMake VS IDE generators. Avoid interfering with -# that functionality for now. Later we may try to integrate this. -if(CMAKE_GENERATOR MATCHES "Visual Studio") +# that functionality for now. +if(CMAKE_GENERATOR_PLATFORM STREQUAL "Tegra-Android") return() endif() @@ -27,6 +27,63 @@ endif() cmake_policy(PUSH) cmake_policy(SET CMP0057 NEW) # if IN_LIST +# If using Android tools for Visual Studio, compile a sample project to get the +# sysroot. +if(CMAKE_GENERATOR MATCHES "Visual Studio") + if(NOT CMAKE_SYSROOT) + set(vcx_platform ${CMAKE_GENERATOR_PLATFORM}) + if(CMAKE_GENERATOR MATCHES "Visual Studio 1[45]") + set(vcx_sysroot_var "Sysroot") + else() + set(vcx_sysroot_var "SysrootLink") + endif() + if(CMAKE_GENERATOR MATCHES "Visual Studio 14") + set(vcx_revision "2.0") + elseif(CMAKE_GENERATOR MATCHES "Visual Studio 1[56]") + set(vcx_revision "3.0") + else() + set(vcx_revision "") + endif() + configure_file(${CMAKE_ROOT}/Modules/Platform/Android/VCXProjInspect.vcxproj.in + ${CMAKE_PLATFORM_INFO_DIR}/VCXProjInspect.vcxproj @ONLY) + execute_process( + COMMAND "${CMAKE_VS_MSBUILD_COMMAND}" "VCXProjInspect.vcxproj" + "/p:Configuration=Debug" "/p:Platform=${vcx_platform}" + WORKING_DIRECTORY ${CMAKE_PLATFORM_INFO_DIR} + OUTPUT_VARIABLE VCXPROJ_INSPECT_OUTPUT + ERROR_VARIABLE VCXPROJ_INSPECT_OUTPUT + RESULT_VARIABLE VCXPROJ_INSPECT_RESULT + ) + if(NOT CMAKE_SYSROOT AND VCXPROJ_INSPECT_OUTPUT MATCHES "CMAKE_SYSROOT=([^%\r\n]+)[\r\n]") + # Strip VS diagnostic output from the end of the line. + string(REGEX REPLACE " \\(TaskId:[0-9]*\\)$" "" _sysroot "${CMAKE_MATCH_1}") + if(EXISTS "${_sysroot}") + file(TO_CMAKE_PATH "${_sysroot}" CMAKE_SYSROOT) + endif() + endif() + if(VCXPROJ_INSPECT_RESULT) + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + "Determining the sysroot for the Android NDK failed. +The output was: +${VCXPROJ_INSPECT_RESULT} +${VCXPROJ_INSPECT_OUTPUT} + +") + else() + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + "Determining the sysroot for the Android NDK succeeded. +The output was: +${VCXPROJ_INSPECT_RESULT} +${VCXPROJ_INSPECT_OUTPUT} + +") + endif() + endif() + if(NOT CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION) + set(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION "clang") + endif() +endif() + # If the user provided CMAKE_SYSROOT for us, extract information from it. set(_ANDROID_SYSROOT_NDK "") set(_ANDROID_SYSROOT_API "") diff --git a/Modules/Platform/Android-Initialize.cmake b/Modules/Platform/Android-Initialize.cmake index b90dd7a..5019c28 100644 --- a/Modules/Platform/Android-Initialize.cmake +++ b/Modules/Platform/Android-Initialize.cmake @@ -6,7 +6,7 @@ # Support for NVIDIA Nsight Tegra Visual Studio Edition was previously # implemented in the CMake VS IDE generators. Avoid interfering with -# that functionality for now. Later we may try to integrate this. +# that functionality for now. if(CMAKE_VS_PLATFORM_NAME STREQUAL "Tegra-Android") return() endif() diff --git a/Modules/Platform/Android/Determine-Compiler-NDK.cmake b/Modules/Platform/Android/Determine-Compiler-NDK.cmake index f56e1d5..a4d67c4 100644 --- a/Modules/Platform/Android/Determine-Compiler-NDK.cmake +++ b/Modules/Platform/Android/Determine-Compiler-NDK.cmake @@ -184,7 +184,7 @@ foreach(line IN LISTS _ANDROID_TOOL_SETUP) # We just matched the gcc toolchain name without version number. Save it for later. set(_ANDROID_TOOL_NAME_ONLY "${CMAKE_MATCH_1}") elseif(line MATCHES [[^TOOLCHAIN_PREFIX +:= +.*/bin/(\$\(TOOLCHAIN_NAME\)-) *$]]) - # We just matched the toolchain prefix with a name placholder, so substitute it. + # We just matched the toolchain prefix with a name placeholder, so substitute it. # The gcc toolchain name will have already been extracted without version number from a TOOLCHAIN_NAME line. string(REPLACE "$(TOOLCHAIN_NAME)" "${_ANDROID_TOOL_NAME_ONLY}" _ANDROID_TOOL_PREFIX "${CMAKE_MATCH_1}") elseif(line MATCHES [[^LLVM_VERSION +:= +([0-9.]+)$]]) diff --git a/Modules/Platform/Android/VCXProjInspect.vcxproj.in b/Modules/Platform/Android/VCXProjInspect.vcxproj.in new file mode 100644 index 0000000..6919d2c --- /dev/null +++ b/Modules/Platform/Android/VCXProjInspect.vcxproj.in @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|@vcx_platform@"> + <Configuration>Debug</Configuration> + <Platform>@vcx_platform@</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{14D44772-ECF7-47BD-9E29-BC62FAF940A5}</ProjectGuid> + <RootNamespace>VCXProjInspect</RootNamespace> + <Keyword>Android</Keyword> + <ApplicationType>Android</ApplicationType> + <ApplicationTypeRevision>@vcx_revision@</ApplicationTypeRevision> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@vcx_platform@'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|@vcx_platform@'">false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@vcx_platform@'"> + <PostBuildEvent> + <Command>%40echo CMAKE_SYSROOT=$(@vcx_sysroot_var@)</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/Modules/Platform/Darwin-Initialize.cmake b/Modules/Platform/Darwin-Initialize.cmake index 80e9a40..d087412 100644 --- a/Modules/Platform/Darwin-Initialize.cmake +++ b/Modules/Platform/Darwin-Initialize.cmake @@ -62,45 +62,36 @@ elseif("${CMAKE_GENERATOR}" MATCHES Xcode # Find installed SDKs in either Xcode-4.3+ or pre-4.3 SDKs directory. set(_CMAKE_OSX_SDKS_DIR "") if(OSX_DEVELOPER_ROOT) - foreach(d Platforms/MacOSX.platform/Developer/SDKs SDKs) - file(GLOB _CMAKE_OSX_SDKS ${OSX_DEVELOPER_ROOT}/${d}/*) + foreach(_d Platforms/MacOSX.platform/Developer/SDKs SDKs) + file(GLOB _CMAKE_OSX_SDKS ${OSX_DEVELOPER_ROOT}/${_d}/*) if(_CMAKE_OSX_SDKS) - set(_CMAKE_OSX_SDKS_DIR ${OSX_DEVELOPER_ROOT}/${d}) + set(_CMAKE_OSX_SDKS_DIR ${OSX_DEVELOPER_ROOT}/${_d}) break() endif() endforeach() endif() if(_CMAKE_OSX_SDKS_DIR) - # Select SDK for current OSX version accounting for the known - # specially named SDKs. - set(_CMAKE_OSX_SDKS_VER_SUFFIX_10.4 "u") - set(_CMAKE_OSX_SDKS_VER_SUFFIX_10.3 ".9") - - # find the latest SDK + # Find the latest SDK as recommended by Apple (Technical Q&A QA1806) set(_CMAKE_OSX_LATEST_SDK_VERSION "0.0") file(GLOB _CMAKE_OSX_SDKS RELATIVE "${_CMAKE_OSX_SDKS_DIR}" "${_CMAKE_OSX_SDKS_DIR}/MacOSX*.sdk") foreach(_SDK ${_CMAKE_OSX_SDKS}) - if(_SDK MATCHES "MacOSX([0-9]+\\.[0-9]+)[^/]*\\.sdk" AND CMAKE_MATCH_1 VERSION_GREATER ${_CMAKE_OSX_LATEST_SDK_VERSION}) + if(IS_DIRECTORY "${_CMAKE_OSX_SDKS_DIR}/${_SDK}" + AND _SDK MATCHES "MacOSX([0-9]+\\.[0-9]+)[^/]*\\.sdk" + AND CMAKE_MATCH_1 VERSION_GREATER ${_CMAKE_OSX_LATEST_SDK_VERSION}) set(_CMAKE_OSX_LATEST_SDK_VERSION "${CMAKE_MATCH_1}") endif() endforeach() - # pick an SDK that works - set(_CMAKE_OSX_SYSROOT_DEFAULT) - foreach(ver ${CMAKE_OSX_DEPLOYMENT_TARGET} - ${_CURRENT_OSX_VERSION} - ${_CMAKE_OSX_LATEST_SDK_VERSION}) - set(_CMAKE_OSX_DEPLOYMENT_TARGET ${ver}) - set(_CMAKE_OSX_SDKS_VER ${_CMAKE_OSX_DEPLOYMENT_TARGET}${_CMAKE_OSX_SDKS_VER_SUFFIX_${_CMAKE_OSX_DEPLOYMENT_TARGET}}) - set(_CMAKE_OSX_SYSROOT_CHECK "${_CMAKE_OSX_SDKS_DIR}/MacOSX${_CMAKE_OSX_SDKS_VER}.sdk") - if(IS_DIRECTORY "${_CMAKE_OSX_SYSROOT_CHECK}") - set(_CMAKE_OSX_SYSROOT_DEFAULT "${_CMAKE_OSX_SYSROOT_CHECK}") - break() - endif() - endforeach() + if(NOT _CMAKE_OSX_LATEST_SDK_VERSION STREQUAL "0.0") + set(_CMAKE_OSX_SYSROOT_DEFAULT "${_CMAKE_OSX_SDKS_DIR}/MacOSX${_CMAKE_OSX_LATEST_SDK_VERSION}.sdk") + else() + message(WARNING "Could not find any valid SDKs in ${_CMAKE_OSX_SDKS_DIR}") + endif() - if(NOT CMAKE_CROSSCOMPILING AND NOT CMAKE_OSX_DEPLOYMENT_TARGET AND _CURRENT_OSX_VERSION VERSION_LESS _CMAKE_OSX_DEPLOYMENT_TARGET) + if(NOT CMAKE_CROSSCOMPILING AND NOT CMAKE_OSX_DEPLOYMENT_TARGET + AND (_CURRENT_OSX_VERSION VERSION_LESS _CMAKE_OSX_LATEST_SDK_VERSION + OR _CMAKE_OSX_LATEST_SDK_VERSION STREQUAL "0.0")) set(CMAKE_OSX_DEPLOYMENT_TARGET ${_CURRENT_OSX_VERSION} CACHE STRING "Minimum OS X version to target for deployment (at runtime); newer APIs weak linked. Set to empty string for default value." FORCE) endif() @@ -113,8 +104,8 @@ endif() # Set cache variable - end user may change this during ccmake or cmake-gui configure. # Choose the type based on the current value. set(_CMAKE_OSX_SYSROOT_TYPE STRING) -foreach(v CMAKE_OSX_SYSROOT _CMAKE_OSX_SYSROOT_DEFAULT) - if("x${${v}}" MATCHES "/") +foreach(_v CMAKE_OSX_SYSROOT _CMAKE_OSX_SYSROOT_DEFAULT) + if("x${${_v}}" MATCHES "/") set(_CMAKE_OSX_SYSROOT_TYPE PATH) break() endif() diff --git a/Modules/Platform/HP-UX.cmake b/Modules/Platform/HP-UX.cmake index 9572a7e..425a13f 100644 --- a/Modules/Platform/HP-UX.cmake +++ b/Modules/Platform/HP-UX.cmake @@ -22,7 +22,7 @@ set(CMAKE_PLATFORM_USES_PATH_WHEN_NO_SONAME 1) # set flags for gcc support include(Platform/UnixPaths) -# Look in both 32-bit and 64-bit implict link directories, but tell +# Look in both 32-bit and 64-bit implicit link directories, but tell # CMake not to pass the paths to the linker. The linker will find the # library for the proper architecture. In the future we should detect # which path will be used by the linker. Since the pointer type size diff --git a/Modules/Platform/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake index a23d664..0d74d30 100644 --- a/Modules/Platform/Windows-Clang.cmake +++ b/Modules/Platform/Windows-Clang.cmake @@ -102,6 +102,27 @@ macro(__windows_compiler_clang_gnu lang) enable_language(RC) endmacro() +macro(__enable_llvm_rc_preprocessing clang_option_prefix) + # Feed the preprocessed rc file to llvm-rc + if(CMAKE_RC_COMPILER_INIT MATCHES "llvm-rc" OR CMAKE_RC_COMPILER MATCHES "llvm-rc") + if(DEFINED CMAKE_C_COMPILER_ID) + set(CMAKE_RC_PREPROCESSOR CMAKE_C_COMPILER) + elseif(DEFINED CMAKE_CXX_COMPILER_ID) + set(CMAKE_RC_PREPROCESSOR CMAKE_CXX_COMPILER) + endif() + if(DEFINED CMAKE_RC_PREPROCESSOR) + set(CMAKE_DEPFILE_FLAGS_RC "${clang_option_prefix}-MD ${clang_option_prefix}-MF ${clang_option_prefix}<DEPFILE>") + set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_COMMAND> -E cmake_llvm_rc <SOURCE> <OBJECT>.pp <${CMAKE_RC_PREPROCESSOR}> <DEFINES> -DRC_INVOKED <INCLUDES> <FLAGS> -E -- <SOURCE> ++ <CMAKE_RC_COMPILER> <DEFINES> -I <SOURCE_DIR> <INCLUDES> /fo <OBJECT> <OBJECT>.pp") + if(CMAKE_GENERATOR MATCHES "Ninja") + set(CMAKE_NINJA_CMCLDEPS_RC 0) + set(CMAKE_NINJA_DEP_TYPE_RC gcc) + endif() + unset(CMAKE_RC_PREPROCESSOR) + endif() + endif() +endmacro() + + if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC" OR "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") @@ -129,7 +150,10 @@ if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC" if(__RC_COMPILER_PATH) set(CMAKE_RC_COMPILER_INIT rc) else() - set(CMAKE_RC_COMPILER_INIT llvm-rc) + find_program(__RC_COMPILER_PATH NAMES llvm-rc) + if(__RC_COMPILER_PATH) + set(CMAKE_RC_COMPILER_INIT llvm-rc) + endif() endif() unset(__RC_COMPILER_PATH CACHE) @@ -137,25 +161,8 @@ if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC" if ( "x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC" OR "x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC" ) include(Platform/Windows-MSVC) - - # Feed the preprocessed rc file to llvm-rc - if(CMAKE_RC_COMPILER_INIT MATCHES "llvm-rc") - if(DEFINED CMAKE_C_COMPILER_ID) - set(CMAKE_RC_PREPROCESSOR CMAKE_C_COMPILER) - elseif(DEFINED CMAKE_CXX_COMPILER_ID) - set(CMAKE_RC_PREPROCESSOR CMAKE_CXX_COMPILER) - endif() - if(DEFINED CMAKE_RC_PREPROCESSOR) - set(CMAKE_DEPFILE_FLAGS_RC "-clang:-MD -clang:-MF -clang:<DEPFILE>") - set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_COMMAND> -E cmake_llvm_rc <SOURCE> <OBJECT>.pp <${CMAKE_RC_PREPROCESSOR}> <DEFINES> -DRC_INVOKED <INCLUDES> <FLAGS> -E <SOURCE> -- <CMAKE_RC_COMPILER> <DEFINES> -I <SOURCE_DIR> <INCLUDES> /fo <OBJECT> <OBJECT>.pp") - if(CMAKE_GENERATOR STREQUAL "Ninja") - set(CMAKE_NINJA_CMCLDEPS_RC 0) - set(CMAKE_NINJA_DEP_TYPE_RC gcc) - endif() - unset(CMAKE_RC_PREPROCESSOR) - endif() - endif() - + # Set the clang option forwarding prefix for clang-cl usage in the llvm-rc processing stage + __enable_llvm_rc_preprocessing("-clang:") macro(__windows_compiler_clang lang) set(_COMPILE_${lang} "${_COMPILE_${lang}_MSVC}") __windows_compiler_msvc(${lang}) @@ -171,6 +178,7 @@ if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC" set(CMAKE_BUILD_TYPE_INIT Debug) + __enable_llvm_rc_preprocessing("") macro(__windows_compiler_clang lang) __windows_compiler_clang_gnu(${lang}) endmacro() @@ -178,6 +186,7 @@ if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC" else() include(Platform/Windows-GNU) + __enable_llvm_rc_preprocessing("") macro(__windows_compiler_clang lang) __windows_compiler_gnu(${lang}) endmacro() diff --git a/Modules/Platform/Windows-Intel-ISPC.cmake b/Modules/Platform/Windows-Intel-ISPC.cmake new file mode 100644 index 0000000..cd26302 --- /dev/null +++ b/Modules/Platform/Windows-Intel-ISPC.cmake @@ -0,0 +1,8 @@ + +if(CMAKE_VERBOSE_MAKEFILE) + set(CMAKE_CL_NOLOGO) +else() + set(CMAKE_CL_NOLOGO "/nologo") +endif() + +set(CMAKE_ISPC_CREATE_STATIC_LIBRARY "<CMAKE_AR> ${CMAKE_CL_NOLOGO} <LINK_FLAGS> /out:<TARGET> <OBJECTS> ") diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake index 2476a33..de31dab 100644 --- a/Modules/Platform/Windows-MSVC.cmake +++ b/Modules/Platform/Windows-MSVC.cmake @@ -333,6 +333,14 @@ macro(__windows_compiler_msvc lang) set(CMAKE_LINK_PCH ON) if (CMAKE_${lang}_COMPILER_ID STREQUAL "Clang") set(CMAKE_PCH_PROLOGUE "#pragma clang system_header") + + # macOS paths usually start with /Users/*. Unfortunately, clang-cl interprets + # paths starting with /U as macro undefines, so we need to put a -- before the + # input file path to force it to be treated as a path. + string(REPLACE "-c <SOURCE>" "-c -- <SOURCE>" CMAKE_${lang}_COMPILE_OBJECT "${CMAKE_${lang}_COMPILE_OBJECT}") + string(REPLACE "-c <SOURCE>" "-c -- <SOURCE>" CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "${CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE}") + string(REPLACE "-c <SOURCE>" "-c -- <SOURCE>" CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "${CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE}") + elseif(MSVC_VERSION GREATER_EQUAL 1913) # At least MSVC toolet 14.13 from VS 2017 15.6 set(CMAKE_PCH_PROLOGUE "#pragma system_header") @@ -356,6 +364,11 @@ macro(__windows_compiler_msvc lang) set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES) set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES) + if(CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.4.0) + set(CMAKE_${lang}_COMPILE_OPTIONS_TARGET "-target ") + else() + set(CMAKE_${lang}_COMPILE_OPTIONS_TARGET "--target=") + endif() # '-flto=thin' available since Clang 3.9 and Xcode 8 # * http://clang.llvm.org/docs/ThinLTO.html#clang-llvm # * https://trac.macports.org/wiki/XcodeVersionInfo |