diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -602,6 +602,7 @@ set(LLVM_BUILD_LLVM_DYLIB_default ON) endif() option(LLVM_BUILD_LLVM_DYLIB "Build libllvm dynamic library" ${LLVM_BUILD_LLVM_DYLIB_default}) + option(LLVM_BUILD_LLVM_ARCHIVE "Build libllvm static archive" OFF) endif() if (LLVM_LINK_LLVM_DYLIB AND BUILD_SHARED_LIBS) @@ -1090,13 +1091,38 @@ get_property(LLVM_LIBS GLOBAL PROPERTY LLVM_LIBS) if(LLVM_LIBS) list(REMOVE_DUPLICATES LLVM_LIBS) - foreach(lib ${LLVM_LIBS}) - add_dependencies(llvm-libraries ${lib}) - if (NOT LLVM_ENABLE_IDE) - add_dependencies(install-llvm-libraries install-${lib}) - add_dependencies(install-llvm-libraries-stripped install-${lib}-stripped) + if(LLVM_BUILD_LLVM_ARCHIVE) + set(LLVM_ARCHIVE_LIBRARIES "${LLVM_LIBS}" CACHE STRING "Libraries to include in libllvm archive") + mark_as_advanced(LLVM_ARCHIVE_LIBRARIES) + set(libs "") + foreach(lib ${LLVM_LIBS}) + if(lib IN_LIST LLVM_ARCHIVE_LIBRARIES) + list(APPEND libs "$<$,${CMAKE_STATIC_LIBRARY_SUFFIX}>:$>") + endif() + endforeach() + if(${CMAKE_LIBTOOL}) + set(LIBTOOL_ARG --libtool ${CMAKE_LIBTOOL}) endif() - endforeach() + set(libllvm ${LLVM_LIBRARY_OUTPUT_INTDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}LLVM${CMAKE_STATIC_LIBRARY_SUFFIX}) + add_custom_command( + OUTPUT ${libllvm} + COMMAND ${CMAKE_COMMAND} -E remove ${libllvm} + COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/utils/merge-archives.py --ar ${CMAKE_AR} ${LIBTOOL_ARG} -o ${libllvm} ${libs} + ) + install(FILES ${libllvm} DESTINATION lib COMPONENT llvm-archive) + add_custom_target(llvm-archive DEPENDS ${libllvm}) + add_llvm_install_targets(install-llvm-archive COMPONENT llvm-archive DEPENDS ${libllvm}) + add_dependencies(install-llvm-libraries install-llvm-archive) + add_dependencies(install-llvm-libraries-stripped install-llvm-archive-stripped) + else() + foreach(lib ${LLVM_LIBS}) + add_dependencies(llvm-libraries ${lib}) + if (NOT LLVM_ENABLE_IDE) + add_dependencies(install-llvm-libraries install-${lib}) + add_dependencies(install-llvm-libraries-stripped install-${lib}-stripped) + endif() + endforeach() + endif() endif() endif() diff --git a/llvm/utils/merge-archives.py b/llvm/utils/merge-archives.py new file mode 100755 --- /dev/null +++ b/llvm/utils/merge-archives.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +#===----------------------------------------------------------------------===## +# +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +#===----------------------------------------------------------------------===## + +from argparse import ArgumentParser +import tempfile +import subprocess +import sys + + +def main(): + parser = ArgumentParser( + description="Merge multiple archives into a single library") + parser.add_argument('--ar', + required=True, + type=str, + help='The ar executable to use') + parser.add_argument('--libtool', + required=False, + type=str, + help='The libtool executable to use') + parser.add_argument('-o', + '--output', + dest='output', + required=True, + help='The output file', + type=str, + action='store') + parser.add_argument('archives', + metavar='archives', + nargs='+', + help='The archives to merge') + + args = parser.parse_args() + + if 'llvm-ar' in args.ar: + subprocess.check_call([args.ar, 'DqcsL', args.output] + args.archives) + return 0 + + with tempfile.TemporaryDirectory('.merge-archives') as tmpdir: + files = [] + for archive in args.archives: + subprocess.check_call([args.ar, 'x', archive], cwd=tmpdir) + out = subprocess.check_output([args.ar, 't', archive]) + files.extend( + [f for f in out.splitlines() if not f.startswith('__.SYMDEF')]) + + if args.libtool: + subprocess.check_call( + [args.libtool, '-static', '-o', args.output] + files, + cwd=tmpdir) + else: + subprocess.check_call([args.ar, 'Drcs', args.output] + files, + cwd=tmpdir) + + return 0 + + +if __name__ == '__main__': + sys.exit(main())