1
1
mirror of https://github.com/rui314/mold.git synced 2024-09-19 08:57:39 +03:00
mold/CMakeLists.txt

369 lines
12 KiB
CMake
Raw Normal View History

# You can customize build by specifying CMake options. A option may be
# given in the -Dvariable=value form. For a boolean variable, `ON` or `1`
# means true while `OFF` or `0` means false.
#
# Here are a couple of common cmake options:
#
# -DCMAKE_C_COMPILER=<command-name>
#
# Specifies a C compiler name to use.
#
# -DCMAKE_CXX_COMPILER=<command-name>
#
# Specifies a C++ compiler name to use.
#
# -DCMAKE_INSTALL_PREFIX=<directory>
#
# Specifies an install target directory. For example, if you want to
# install mold as `/usr/bin/mold`, specify `-DCMAKE_INSTALL_PREFIX=/usr`.
# The default value is `/usr/local`.
#
# -DCMAKE_BUILD_TYPE=[Debug | Release | RelWithDebInfo | MinSizeRel]
#
# Specifies a build type. The default is `Release` which is the right
# option unless you are debugging mold.
#
# An example of a cmake command line is shown below:
#
# $ cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_CXX_COMPILER=g++-12 ..
#
# where `..` refers this directory.
#
# In order to see the current CMake variables and their values, run `cmake
# -N -L .` in a build directory.
#
# Note that in this file, we provide various dials and knobs to configure
# how to build mold. However, as a policy, we do not provide a way to
# enable/disable any individual mold's feature. In other words, we do not
# provide options like `--enable-foo` or `--disable-foo`. This policy
# guarantees that all builds of the mold linker of the same version will
# have the exactly same set of features and behave exactly the same.
cmake_minimum_required(VERSION 3.13)
2022-09-28 12:33:54 +03:00
project(mold VERSION 1.5.1)
include(CMakeDependentOption)
include(GNUInstallDirs)
# Build mold itself using mold if -DMOLD_USE_MOLD=ON.
option(MOLD_USE_MOLD "Use mold to build mold" OFF)
2022-08-08 07:07:47 +03:00
if(MOLD_USE_MOLD)
add_link_options(-fuse-ld=mold)
2022-08-08 07:07:47 +03:00
endif()
add_executable(mold)
target_compile_features(mold PRIVATE cxx_std_20)
target_compile_definitions(mold PRIVATE
"LIBDIR=\"${CMAKE_INSTALL_FULL_LIBDIR}\"")
target_link_libraries(mold PRIVATE ${CMAKE_DL_LIBS})
2022-08-20 11:07:14 +03:00
if(NOT "${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "MSVC")
target_compile_options(mold PRIVATE
-fno-exceptions
-fno-unwind-tables
-fno-asynchronous-unwind-tables
-Wno-sign-compare
-Wno-unused-function)
endif()
# Build mold with -flto if -DMOLD_LTO=ON
2022-08-08 08:30:14 +03:00
option(MOLD_LTO "Build mold with link-time optimization enabled")
if(MOLD_LTO)
set_property(TARGET mold PROPERTY INTERPROCEDURAL_OPTIMIZATION ON)
endif()
# Enable AddressSanitizer if -DMOLD_USE_ASAN=ON
2022-08-08 07:30:56 +03:00
option(MOLD_USE_ASAN "Build mold with AddressSanitizer" OFF)
if(MOLD_USE_ASAN)
2022-08-09 17:25:32 +03:00
target_compile_options(mold PRIVATE -fsanitize=address -fsanitize=undefined)
target_link_options(mold PRIVATE -fsanitize=address -fsanitize=undefined)
2022-08-08 07:30:56 +03:00
endif()
# Enabled ThreadSanitizer if -DMOLD_USE_TSAN=ON
option(MOLD_USE_TSAN "Build mold with ThreadSanitizer" OFF)
if(MOLD_USE_TSAN)
2022-08-08 07:30:56 +03:00
target_compile_options(mold PRIVATE -fsanitize=thread)
target_link_options(mold PRIVATE -fsanitize=thread)
endif()
# Statically-link libstdc++ and libcrypto if -DMOLD_MOSTLY_STATIC=ON.
#
# This option is intended to be used by `./dist.sh` script to create a
# mold binary that works on various Linux distros. You probably don't
# need nor want to set this to ON.
2022-08-08 12:11:32 +03:00
option(MOLD_MOSTLY_STATIC "Statically link libstdc++ and libcrypto" OFF)
if(MOLD_MOSTLY_STATIC)
2022-08-08 12:30:53 +03:00
target_link_options(mold PRIVATE -static-libstdc++)
2022-08-08 12:11:32 +03:00
target_link_libraries(mold PRIVATE libcrypto.a)
endif()
# Find zlib. If libz.so is not found, we compile a bundled one and
# statically-link it to mold.
find_package(ZLIB QUIET)
if(ZLIB_FOUND)
target_link_libraries(mold PRIVATE ZLIB::ZLIB)
else()
add_subdirectory(third-party/zlib EXCLUDE_FROM_ALL)
2022-08-14 08:12:16 +03:00
target_include_directories(zlibstatic INTERFACE third-party/zlib
$<TARGET_PROPERTY:zlibstatic,BINARY_DIR>)
target_link_libraries(mold PRIVATE zlibstatic)
endif()
# Find zstd compression library. Just like zlib, if libzstd.so is not
# found, we compile a bundled one and statically-link it to mold.
2022-09-13 11:21:22 +03:00
include(CheckIncludeFile)
check_include_file(zstd.h HAVE_ZSTD_H)
if(HAVE_ZSTD_H)
target_link_libraries(mold PRIVATE zstd)
else()
add_subdirectory(third-party/zstd/build/cmake EXCLUDE_FROM_ALL)
target_compile_definitions(libzstd_static PRIVATE
ZSTD_BUILD_STATIC=1
ZSTD_BUILD_SHARED=0
ZSTD_BUILD_PROGRAMS=0
ZSTD_MULTITHREAD_SUPPORT=0
ZSTD_BUILD_TESTS=0)
2022-09-13 10:09:14 +03:00
target_include_directories(mold PUBLIC third-party/zstd/lib)
target_link_libraries(mold PRIVATE libzstd_static)
endif()
# Find mimalloc. mimalloc is an alternative malloc implementation
# optimized for multi-threaded applications.
#
# If you do not want to use mimalloc, pass -DMOLD_USE_MIMALLOC=OFF.
include(CheckCSourceCompiles)
check_c_source_compiles("#ifdef __i386__\nint main() {}\n#endif" I386)
2022-08-08 07:30:56 +03:00
cmake_dependent_option(MOLD_USE_MIMALLOC "Use mimalloc" ON
"NOT APPLE; NOT ANDROID; NOT I386" OFF)
2022-08-08 07:30:56 +03:00
cmake_dependent_option(
MOLD_USE_SYSTEM_MIMALLOC "Use system or vendored mimalloc" OFF
MOLD_USE_MIMALLOC OFF)
# By default, we build a bundled mimalloc and statically-link it to
# mold. If you want to dynamically link to the system's
# libmimalloc.so, pass -DMOLD_USE_SYSTEM_MIMALLOC=ON.
if(MOLD_USE_MIMALLOC)
2022-08-08 06:04:08 +03:00
if(MOLD_USE_SYSTEM_MIMALLOC)
find_package(mimalloc REQUIRED)
target_link_libraries(mold PRIVATE mimalloc)
target_compile_definitions(mold PRIVATE USE_SYSTEM_MIMALLOC)
2022-08-08 06:04:08 +03:00
else()
function(mold_add_mimalloc)
set(MI_BUILD_STATIC ON)
option(MI_BUILD_TESTS "Build test executables" OFF)
add_subdirectory(third-party/mimalloc EXCLUDE_FROM_ALL)
target_compile_definitions(mimalloc-static PRIVATE MI_USE_ENVIRON=0)
target_link_libraries(mold PRIVATE mimalloc-static)
endfunction()
mold_add_mimalloc()
2022-08-08 06:04:08 +03:00
endif()
endif()
# Find TBB. TBB (OneTBB or Intel TBB) is a high-level threading library.
# Use of this library is mandatory.
#
# By default, we build a bundled one and statically-link the library
# to mold. If you want to link to the system's libtbb2.so, pass
# -DMOLD_USE_SYSTEM_TBB=ON.
2022-08-08 07:30:56 +03:00
option(MOLD_USE_SYSTEM_TBB "Use system or vendored TBB" OFF)
if(MOLD_USE_SYSTEM_TBB)
2022-08-08 06:04:08 +03:00
find_package(TBB REQUIRED)
target_link_libraries(mold PRIVATE TBB::tbb)
else()
2022-08-08 06:04:08 +03:00
function(mold_add_tbb)
set(BUILD_SHARED_LIBS OFF)
set(TBB_TEST OFF CACHE INTERNAL "")
set(TBB_STRICT OFF CACHE INTERNAL "")
add_subdirectory(third-party/tbb EXCLUDE_FROM_ALL)
target_compile_definitions(tbb PRIVATE __TBB_DYNAMIC_LOAD_ENABLED=0)
target_link_libraries(mold PRIVATE TBB::tbb)
endfunction()
2022-08-08 06:04:08 +03:00
mold_add_tbb()
endif()
2022-08-14 08:12:16 +03:00
if(WIN32)
if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
message(FATAL_ERROR
"Your compiler is not supported; install Clang from Visual Studio Installer and re-run cmake with '-T clangcl'")
2022-08-20 11:07:14 +03:00
endif()
2022-08-14 08:12:16 +03:00
target_compile_definitions(mold PRIVATE NOGDI NOMINMAX)
else()
2022-08-08 06:04:08 +03:00
include(CheckLibraryExists)
check_library_exists(m pow "" LIBM_FOUND)
if(LIBM_FOUND)
target_link_libraries(mold PRIVATE m)
endif()
endif()
if(NOT APPLE AND NOT WIN32)
add_library(mold-wrapper SHARED)
install(TARGETS mold-wrapper DESTINATION ${CMAKE_INSTALL_LIBDIR}/mold)
# Remove the default `lib` prefix
set_target_properties(mold-wrapper PROPERTIES PREFIX "")
target_link_libraries(mold-wrapper PRIVATE ${CMAKE_DL_LIBS})
target_sources(mold-wrapper PRIVATE elf/mold-wrapper.c)
endif()
2022-08-20 11:07:14 +03:00
if(NOT APPLE AND NOT WIN32 AND NOT MOLD_MOSTLY_STATIC)
find_package(OpenSSL REQUIRED COMPONENTS Crypto)
2022-08-08 06:04:08 +03:00
target_link_libraries(mold PRIVATE OpenSSL::Crypto)
endif()
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(riscv64|armv)")
2022-08-08 06:04:08 +03:00
target_link_libraries(mold PRIVATE atomic)
endif()
set_property(SOURCE main.cc APPEND PROPERTY
2022-08-08 06:04:08 +03:00
COMPILE_DEFINITIONS "MOLD_VERSION=\"${CMAKE_PROJECT_VERSION}\"")
# Create a .cc file containing the current git hash for `mold --version`.
2022-08-20 07:16:21 +03:00
add_custom_target(git_hash
COMMAND ${CMAKE_COMMAND}
2022-08-20 08:27:42 +03:00
-DSOURCE_DIR=${CMAKE_SOURCE_DIR}
2022-08-20 07:16:21 +03:00
-DOUTPUT_FILE=${CMAKE_BINARY_DIR}/git-hash.cc
-P ${CMAKE_SOURCE_DIR}/update-git-hash.cmake
DEPENDS update-git-hash.cmake
BYPRODUCTS git-hash.cc
VERBATIM)
2022-08-20 07:16:21 +03:00
add_dependencies(mold git_hash)
# Almost all functions are template in mold which take a target type
# (e.g. X86_64) as its type parameter. Since we suport more than 10
# targets, compiling a single source file for all the targets is very
# slow.
#
# As a workaround, we create a .cc file for each target and spawn many
# compiler instances. This is hacky but greatly reduces compile time.
list(APPEND MOLD_ELF_TARGETS
X86_64 I386 ARM64 ARM32 RV32LE RV32BE RV64LE RV64BE
PPC64V1 PPC64V2 SPARC64 S390X)
list(APPEND MOLD_ELF_TEMPLATE_FILES
2022-08-08 06:04:08 +03:00
elf/cmdline.cc
elf/dwarf.cc
elf/gc-sections.cc
elf/icf.cc
elf/input-files.cc
elf/input-sections.cc
elf/linker-script.cc
elf/lto.cc
2022-08-08 06:04:08 +03:00
elf/main.cc
elf/mapfile.cc
elf/output-chunks.cc
elf/passes.cc
elf/relocatable.cc
elf/subprocess.cc
elf/thunks.cc
)
list(APPEND MOLD_MACHO_TARGETS X86_64 ARM64)
list(APPEND MOLD_MACHO_TEMPLATE_FILES
2022-08-08 06:04:08 +03:00
macho/cmdline.cc
macho/dead-strip.cc
macho/input-files.cc
macho/input-sections.cc
macho/lto.cc
2022-08-08 06:04:08 +03:00
macho/main.cc
macho/mapfile.cc
macho/output-chunks.cc
macho/tapi.cc
)
function(mold_instantiate_templates SOURCE TARGET)
set(PATH ${CMAKE_BINARY_DIR}/${SOURCE}.${TARGET}.cc)
file(WRITE ${PATH} "#define MOLD_${TARGET} 1
#define MOLD_TARGET ${TARGET}
#include \"${CMAKE_SOURCE_DIR}/${SOURCE}\"
")
target_sources(mold PRIVATE ${PATH})
endfunction()
foreach (SOURCE IN LISTS MOLD_ELF_TEMPLATE_FILES)
foreach(TARGET IN LISTS MOLD_ELF_TARGETS)
mold_instantiate_templates(${SOURCE} ${TARGET})
endforeach()
endforeach()
foreach (SOURCE IN LISTS MOLD_MACHO_TEMPLATE_FILES)
foreach(TARGET IN LISTS MOLD_MACHO_TARGETS)
mold_instantiate_templates(${SOURCE} ${TARGET})
endforeach()
endforeach()
# Add other non-template source files.
target_sources(mold PRIVATE
compress.cc
demangle.cc
elf/arch-arm32.cc
elf/arch-arm64.cc
elf/arch-i386.cc
elf/arch-ppc64v1.cc
elf/arch-ppc64v2.cc
elf/arch-riscv.cc
elf/arch-s390x.cc
elf/arch-sparc64.cc
elf/arch-x86-64.cc
filepath.cc
git-hash.cc
glob.cc
hyperloglog.cc
macho/arch-arm64.cc
macho/arch-x86-64.cc
2022-08-08 06:04:08 +03:00
macho/yaml.cc
2022-08-14 08:45:25 +03:00
main.cc
multi-glob.cc
perf.cc
strerror.cc
tar.cc
third-party/rust-demangle/rust-demangle.c
2022-08-14 08:45:25 +03:00
uuid.cc
)
include(CTest)
if(BUILD_TESTING)
2022-08-08 06:04:08 +03:00
# Create the ld and ld64 symlinks required for testing
if(NOT WIN32)
add_custom_command(
TARGET mold POST_BUILD
COMMAND ${CMAKE_COMMAND} -E create_symlink mold ld
COMMAND ${CMAKE_COMMAND} -E create_symlink mold ld64
2022-08-19 10:15:32 +03:00
BYPRODUCTS ld ld64
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
VERBATIM)
endif()
2022-08-08 06:04:08 +03:00
if(${APPLE})
add_subdirectory(test/macho)
elseif(${UNIX})
add_subdirectory(test/elf)
endif()
endif()
if(NOT CMAKE_SKIP_INSTALL_RULES)
install(TARGETS mold RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR})
install(FILES docs/mold.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1/)
2022-08-08 12:37:47 +03:00
install(CODE "
2022-08-19 14:42:34 +03:00
file(RELATIVE_PATH RELPATH
/${CMAKE_INSTALL_FULL_LIBEXECDIR}/mold /${CMAKE_INSTALL_FULL_BINDIR}/mold)
2022-08-19 14:42:34 +03:00
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory
2022-09-29 10:04:23 +03:00
\$ENV{DESTDIR}/${CMAKE_INSTALL_FULL_LIBEXECDIR}/mold)
2022-08-19 14:42:34 +03:00
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink \${RELPATH}
2022-09-29 10:04:23 +03:00
\$ENV{DESTDIR}/${CMAKE_INSTALL_FULL_LIBEXECDIR}/mold/ld)
2022-08-19 14:42:34 +03:00
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink mold
2022-09-29 10:04:23 +03:00
\$ENV{DESTDIR}/${CMAKE_INSTALL_FULL_BINDIR}/ld.mold)
2022-08-19 14:42:34 +03:00
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink mold
2022-09-29 10:04:23 +03:00
\$ENV{DESTDIR}/${CMAKE_INSTALL_FULL_BINDIR}/ld64.mold)
2022-08-19 14:42:34 +03:00
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink mold.1
2022-09-29 10:04:23 +03:00
\$ENV{DESTDIR}/${CMAKE_INSTALL_FULL_MANDIR}/man1/ld.mold.1)")
endif()