1*4d6fc14bSjoerg 2*4d6fc14bSjoerg# This function generates a "unique" identifier based on various properties 3*4d6fc14bSjoerg# given as arguments. The idea is to encode all ABI-affecting properties 4*4d6fc14bSjoerg# in that identifier, so that we can store ABI information and associate it 5*4d6fc14bSjoerg# to a specific ABI configuration. 6*4d6fc14bSjoerg# 7*4d6fc14bSjoerg# Right now, this is done by using the ABI identifier as the filename containing 8*4d6fc14bSjoerg# the list of symbols exported by libc++ for that configuration, however we could 9*4d6fc14bSjoerg# make it more sophisticated if the number of ABI-affecting parameters grew. 10*4d6fc14bSjoergfunction(cxx_abi_list_identifier result triple abi_library abi_version unstable exceptions new_delete_in_libcxx) 11*4d6fc14bSjoerg set(abi_properties) 12*4d6fc14bSjoerg 13*4d6fc14bSjoerg if ("${triple}" MATCHES "darwin") 14*4d6fc14bSjoerg # Ignore the major, minor, and patchlevel versions of darwin targets. 15*4d6fc14bSjoerg string(REGEX REPLACE "darwin[0-9]+\\.[0-9]+\\.[0-9]+" "darwin" triple "${triple}") 16*4d6fc14bSjoerg elseif("${triple}" MATCHES "freebsd") 17*4d6fc14bSjoerg # Ignore the major and minor versions of freebsd targets. 18*4d6fc14bSjoerg string(REGEX REPLACE "freebsd[0-9]+\\.[0-9]+" "freebsd" triple "${triple}") 19*4d6fc14bSjoerg endif() 20*4d6fc14bSjoerg list(APPEND abi_properties "${triple}") 21*4d6fc14bSjoerg list(APPEND abi_properties "${abi_library}") 22*4d6fc14bSjoerg list(APPEND abi_properties "v${abi_version}") 23*4d6fc14bSjoerg if (${unstable}) 24*4d6fc14bSjoerg list(APPEND abi_properties "unstable") 25*4d6fc14bSjoerg else() 26*4d6fc14bSjoerg list(APPEND abi_properties "stable") 27*4d6fc14bSjoerg endif() 28*4d6fc14bSjoerg if (${exceptions}) 29*4d6fc14bSjoerg list(APPEND abi_properties "exceptions") 30*4d6fc14bSjoerg else() 31*4d6fc14bSjoerg list(APPEND abi_properties "noexceptions") 32*4d6fc14bSjoerg endif() 33*4d6fc14bSjoerg if (${new_delete_in_libcxx}) 34*4d6fc14bSjoerg list(APPEND abi_properties "new_in_libcxx") 35*4d6fc14bSjoerg else() 36*4d6fc14bSjoerg list(APPEND abi_properties "no_new_in_libcxx") 37*4d6fc14bSjoerg endif() 38*4d6fc14bSjoerg 39*4d6fc14bSjoerg list(JOIN abi_properties "." tmp) 40*4d6fc14bSjoerg set(${result} "${tmp}" PARENT_SCOPE) 41*4d6fc14bSjoergendfunction() 42*4d6fc14bSjoerg 43*4d6fc14bSjoergcxx_abi_list_identifier(abi_list_identifier 44*4d6fc14bSjoerg "${TARGET_TRIPLE}" 45*4d6fc14bSjoerg "${LIBCXX_CXX_ABI_LIBNAME}" 46*4d6fc14bSjoerg "${LIBCXX_ABI_VERSION}" 47*4d6fc14bSjoerg "${LIBCXX_ABI_UNSTABLE}" 48*4d6fc14bSjoerg "${LIBCXX_ENABLE_EXCEPTIONS}" 49*4d6fc14bSjoerg "${LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS}" 50*4d6fc14bSjoerg) 51*4d6fc14bSjoerg 52*4d6fc14bSjoergif (TARGET cxx_shared) 53*4d6fc14bSjoerg set(abi_list_file "${CMAKE_CURRENT_SOURCE_DIR}/${abi_list_identifier}.abilist") 54*4d6fc14bSjoerg 55*4d6fc14bSjoerg if (EXISTS "${abi_list_file}") 56*4d6fc14bSjoerg add_custom_target(check-cxx-abilist 57*4d6fc14bSjoerg "${Python3_EXECUTABLE}" "${LIBCXX_SOURCE_DIR}/utils/sym_diff.py" 58*4d6fc14bSjoerg --only-stdlib-symbols 59*4d6fc14bSjoerg --strict "${abi_list_file}" 60*4d6fc14bSjoerg $<TARGET_FILE:cxx_shared> 61*4d6fc14bSjoerg DEPENDS cxx_shared 62*4d6fc14bSjoerg COMMENT "Testing libc++'s exported symbols against the ABI list") 63*4d6fc14bSjoerg else() 64*4d6fc14bSjoerg message(STATUS "ABI list file not generated for configuration ${abi_list_identifier}, `check-cxx-abilist` will not be available.") 65*4d6fc14bSjoerg endif() 66*4d6fc14bSjoerg 67*4d6fc14bSjoerg add_custom_target(generate-cxx-abilist 68*4d6fc14bSjoerg COMMAND "${Python3_EXECUTABLE}" "${LIBCXX_SOURCE_DIR}/utils/generate_abi_list.py" 69*4d6fc14bSjoerg --output "${abi_list_file}" 70*4d6fc14bSjoerg "$<TARGET_FILE:cxx_shared>" 71*4d6fc14bSjoerg DEPENDS cxx_shared 72*4d6fc14bSjoerg COMMENT "Generating the ABI list file for configuration ${abi_list_identifier}") 73*4d6fc14bSjoergelse() 74*4d6fc14bSjoerg message(STATUS "Not building a shared library for libc++ -- the ABI list targets will not be available.") 75*4d6fc14bSjoergendif() 76