diff --git a/compiler-rt/cmake/Modules/CompilerRTAIXUtils.cmake b/compiler-rt/cmake/Modules/CompilerRTAIXUtils.cmake new file mode 100644 --- /dev/null +++ b/compiler-rt/cmake/Modules/CompilerRTAIXUtils.cmake @@ -0,0 +1,106 @@ +include(CMakeParseArguments) +include(CompilerRTUtils) + +set(AIX_LIBATOMIC_EXPORTED_ROUTINES + __atomic_compare_exchange + __atomic_compare_exchange_1 + __atomic_compare_exchange_2 + __atomic_compare_exchange_4 + __atomic_compare_exchange_8 + __atomic_exchange + __atomic_exchange_1 + __atomic_exchange_2 + __atomic_exchange_4 + __atomic_exchange_8 + __atomic_fetch_add_1 + __atomic_fetch_add_2 + __atomic_fetch_add_4 + __atomic_fetch_add_8 + __atomic_fetch_and_1 + __atomic_fetch_and_2 + __atomic_fetch_and_4 + __atomic_fetch_and_8 + __atomic_fetch_or_1 + __atomic_fetch_or_2 + __atomic_fetch_or_4 + __atomic_fetch_or_8 + __atomic_fetch_sub_1 + __atomic_fetch_sub_2 + __atomic_fetch_sub_4 + __atomic_fetch_sub_8 + __atomic_fetch_xor_1 + __atomic_fetch_xor_2 + __atomic_fetch_xor_4 + __atomic_fetch_xor_8 + __atomic_is_lock_free + __atomic_load + __atomic_load_1 + __atomic_load_2 + __atomic_load_4 + __atomic_load_8 + __atomic_store + __atomic_store_1 + __atomic_store_2 + __atomic_store_4 + __atomic_store_8 +) + +function(generate_aix_libatomic_export_list export_list) + # Write exported routines to export list file prior the build. + STRING(REGEX REPLACE ";" "\n" AIX_LIBATOMIC_EXPORTED_ROUTINES_TEXT + "${AIX_LIBATOMIC_EXPORTED_ROUTINES}") + file(GENERATE + OUTPUT ${export_list} + CONTENT ${AIX_LIBATOMIC_EXPORTED_ROUTINES_TEXT}) +endfunction() + +function(get_aix_libatomic_default_link_flags link_flags export_list) + set(${link_flags} + "-Wl,-b${bitmode} -Wl,-H512 -Wl,-D0 \ + -Wl,-T512 -Wl,-bhalt:4 -Wl,-bernotok \ + -Wl,-bnoentry -Wl,-bexport:${export_list} \ + -Wl,-bmodtype:SRE -Wl,-lc") +endfunction() + +macro(archive_aix_libatomic name) + cmake_parse_arguments(LIB + "" + "" + "ARCHS;PARENT_TARGET" + ${ARGN}) + set(built_shared_libatomic "") + set(shared_libraries_to_archive "") + foreach (arch ${LIB_ARCHS}) + if(CAN_TARGET_${arch}) + set(output_dir "${CMAKE_CURRENT_BINARY_DIR}/libatomic-${arch}.dir") + # FIXME: Target name should be kept consistent with definition + # in AddCompilerRT.cmake. + set(target ${name}-dynamic-${arch}) + if(TARGET ${target}) + file(MAKE_DIRECTORY ${output_dir}) + add_custom_command(TARGET ${target} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E + copy "$" + "${output_dir}/libatomic.so.1") + list(APPEND built_shared_libatomic ${target}) + list(APPEND shared_libraries_to_archive "${output_dir}/libatomic.so.1") + endif() + endif() + endforeach() + if(built_shared_libatomic) + set(output_dir "") + set(install_dir "") + get_compiler_rt_output_dir(${COMPILER_RT_DEFAULT_TARGET_ARCH} output_dir) + get_compiler_rt_install_dir(${COMPILER_RT_DEFAULT_TARGET_ARCH} install_dir) + add_custom_command(OUTPUT "${output_dir}/libatomic.a" + COMMAND ${CMAKE_AR} -X32_64 r "${output_dir}/libatomic.a" + ${shared_libraries_to_archive} + DEPENDS ${built_shared_libatomic}) + install(FILES "${output_dir}/libatomic.a" + DESTINATION ${install_dir}) + add_custom_target(aix-libatomic + DEPENDS "${output_dir}/libatomic.a") + endif() + add_dependencies(${LIB_PARENT_TARGET} aix-libatomic) +endmacro() diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt --- a/compiler-rt/lib/builtins/CMakeLists.txt +++ b/compiler-rt/lib/builtins/CMakeLists.txt @@ -48,6 +48,10 @@ include(builtin-config-ix) +if(${CMAKE_SYSTEM_NAME} MATCHES "AIX") + include(CompilerRTAIXUtils) +endif() + option(COMPILER_RT_BUILTINS_HIDE_SYMBOLS "Do not export any symbols from the static library." ON) @@ -747,4 +751,43 @@ endforeach () endif () +option(COMPILER_RT_BUILD_STANDALONE_LIBATOMIC + "Build standalone shared atomic library." + OFF) + +if(COMPILER_RT_BUILD_STANDALONE_LIBATOMIC) + add_custom_target(builtins-standalone-atomic) + set(BUILTIN_LINK_FLAGS "") + if(${CMAKE_SYSTEM_NAME} MATCHES "AIX") + if(NOT AIX_LIBATOMIC_LINK_FLAGS) + # On AIX, before building the library, an export list must be provided. + set(AIX_LIBATOMIC_EXPORT_LIST + ${CMAKE_CURRENT_BINARY_DIR}/export_list.atomic) + generate_aix_libatomic_export_list(${AIX_LIBATOMIC_EXPORT_LIST}) + get_aix_libatomic_default_link_flags(BUILTIN_LINK_FLAGS ${AIX_LIBATOMIC_EXPORT_LIST}) + else() + set(${BUILTIN_LINK_FLAGS} ${AIX_LIBATOMIC_LINK_FLAGS}) + endif() + endif() + foreach (arch ${BUILTIN_SUPPORTED_ARCH}) + if(CAN_TARGET_${arch}) + add_compiler_rt_runtime(clang_rt.atomic + SHARED + ARCHS ${arch} + SOURCES atomic.c + LINK_FLAGS ${BUILTIN_LINK_FLAGS} + PARENT_TARGET builtins-standalone-atomic) + endif() + endforeach() + # FIXME: On AIX, we have to archive built shared libraries into a static + # archive, i.e., libatomic.a. Once cmake adds support of such usage for AIX, + # this ad-hoc part can be removed. + if(${CMAKE_SYSTEM_NAME} MATCHES "AIX") + archive_aix_libatomic(clang_rt.atomic + ARCHS ${BUILTIN_SUPPORTED_ARCH} + PARENT_TARGET builtins-standalone-atomic) + endif() + add_dependencies(builtins builtins-standalone-atomic) +endif() + add_dependencies(compiler-rt builtins)