-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[BOLT] Enable standalone build #97130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3c1a36e
aa51171
d0955ea
0995508
631f10d
62cf63d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,17 @@ | ||
cmake_minimum_required(VERSION 3.20.0) | ||
|
||
set(LLVM_SUBPROJECT_TITLE "BOLT") | ||
|
||
include(ExternalProject) | ||
if(NOT DEFINED LLVM_COMMON_CMAKE_UTILS) | ||
set(LLVM_COMMON_CMAKE_UTILS ${CMAKE_CURRENT_SOURCE_DIR}/../cmake) | ||
endif() | ||
include(${LLVM_COMMON_CMAKE_UTILS}/Modules/CMakePolicy.cmake | ||
NO_POLICY_SCOPE) | ||
|
||
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) | ||
project(bolt) | ||
set(BOLT_BUILT_STANDALONE TRUE) | ||
endif() | ||
|
||
set(BOLT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) | ||
set(BOLT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) | ||
|
@@ -9,6 +20,42 @@ set(CMAKE_CXX_STANDARD 17) | |
# Add path for custom modules. | ||
list(INSERT CMAKE_MODULE_PATH 0 "${BOLT_SOURCE_DIR}/cmake/modules") | ||
|
||
include(GNUInstallDirs) | ||
|
||
# standalone build, copied from clang | ||
if(BOLT_BUILT_STANDALONE) | ||
set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard to conform to") | ||
set(CMAKE_CXX_STANDARD_REQUIRED YES) | ||
set(CMAKE_CXX_EXTENSIONS NO) | ||
|
||
if(NOT MSVC_IDE) | ||
set(LLVM_ENABLE_ASSERTIONS ${ENABLE_ASSERTIONS} | ||
CACHE BOOL "Enable assertions") | ||
# Assertions should follow llvm-config's. | ||
mark_as_advanced(LLVM_ENABLE_ASSERTIONS) | ||
endif() | ||
|
||
find_package(LLVM REQUIRED HINTS "${LLVM_CMAKE_DIR}") | ||
list(APPEND CMAKE_MODULE_PATH "${LLVM_DIR}") | ||
|
||
set(LLVM_MAIN_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../llvm" CACHE PATH "Path to LLVM source tree") | ||
find_program(LLVM_TABLEGEN_EXE "llvm-tblgen" ${LLVM_TOOLS_BINARY_DIR} | ||
NO_DEFAULT_PATH) | ||
|
||
# They are used as destination of target generators. | ||
set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin) | ||
set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX}) | ||
|
||
include(AddLLVM) | ||
include(TableGen) | ||
include_directories(${LLVM_INCLUDE_DIRS}) | ||
link_directories("${LLVM_LIBRARY_DIR}") | ||
|
||
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_INSTALL_BINDIR}" ) | ||
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_INSTALL_LIBDIR}/${LLVM_LIBDIR_SUFFIX}" ) | ||
set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_INSTALL_LIBDIR}/${LLVM_LIBDIR_SUFFIX}") | ||
Comment on lines
+55
to
+56
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In clang, this part looks like this:
Notice the missing |
||
endif() # standalone | ||
|
||
# Determine default set of targets to build -- the intersection of | ||
# those BOLT supports and those LLVM is targeting. | ||
set(BOLT_TARGETS_TO_BUILD_all "AArch64;X86;RISCV") | ||
|
@@ -94,6 +141,8 @@ if (BOLT_ENABLE_RUNTIME) | |
if(CMAKE_SYSROOT) | ||
list(APPEND extra_args -DCMAKE_SYSROOT=${CMAKE_SYSROOT}) | ||
endif() | ||
|
||
include(ExternalProject) | ||
ExternalProject_Add(bolt_rt | ||
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/runtime" | ||
STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/bolt_rt-stamps | ||
|
@@ -104,6 +153,7 @@ if (BOLT_ENABLE_RUNTIME) | |
-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM} | ||
-DLLVM_LIBDIR_SUFFIX=${LLVM_LIBDIR_SUFFIX} | ||
-DLLVM_LIBRARY_DIR=${LLVM_LIBRARY_DIR} | ||
-DBOLT_BUILT_STANDALONE=${BOLT_BUILT_STANDALONE} | ||
${extra_args} | ||
INSTALL_COMMAND "" | ||
BUILD_ALWAYS True | ||
|
@@ -113,6 +163,8 @@ if (BOLT_ENABLE_RUNTIME) | |
add_llvm_install_targets(install-bolt_rt | ||
DEPENDS bolt_rt bolt | ||
COMPONENT bolt) | ||
set(LIBBOLT_RT_INSTR "${CMAKE_CURRENT_BINARY_DIR}/bolt_rt-bins/lib/libbolt_rt_instr.a") | ||
set(LIBBOLT_RT_HUGIFY "${CMAKE_CURRENT_BINARY_DIR}/bolt_rt-bins/lib/libbolt_rt_hugify.a") | ||
endif() | ||
|
||
find_program(GNU_LD_EXECUTABLE NAMES ${LLVM_DEFAULT_TARGET_TRIPLE}-ld.bfd ld.bfd DOC "GNU ld") | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,8 +26,8 @@ using namespace bolt; | |
|
||
void RuntimeLibrary::anchor() {} | ||
|
||
std::string RuntimeLibrary::getLibPath(StringRef ToolPath, | ||
StringRef LibFileName) { | ||
std::string RuntimeLibrary::getLibPathByToolPath(StringRef ToolPath, | ||
StringRef LibFileName) { | ||
StringRef Dir = llvm::sys::path::parent_path(ToolPath); | ||
SmallString<128> LibPath = llvm::sys::path::parent_path(Dir); | ||
llvm::sys::path::append(LibPath, "lib" LLVM_LIBDIR_SUFFIX); | ||
|
@@ -38,13 +38,36 @@ std::string RuntimeLibrary::getLibPath(StringRef ToolPath, | |
llvm::sys::path::append(LibPath, "lib" LLVM_LIBDIR_SUFFIX); | ||
} | ||
llvm::sys::path::append(LibPath, LibFileName); | ||
if (!llvm::sys::fs::exists(LibPath)) { | ||
errs() << "BOLT-ERROR: library not found: " << LibPath << "\n"; | ||
exit(1); | ||
} | ||
return std::string(LibPath); | ||
} | ||
|
||
std::string RuntimeLibrary::getLibPathByInstalled(StringRef LibFileName) { | ||
SmallString<128> LibPath(CMAKE_INSTALL_FULL_LIBDIR); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This embeds a full absolute path into the bolt binary. That doesn't seem great, since it means that that library has to be at that particular path. Other tools instead require a fixed relative path from executable to runtime library (with an overridable setting). See There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This particular method is meant only for when the binary is installed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "Installed" isn't a concept that always makes sense. On Windows, there's no system install. Even on other platforms, projects might download a hermetic toolchain to a random subdirectory. |
||
llvm::sys::path::append(LibPath, LibFileName); | ||
return std::string(LibPath); | ||
} | ||
|
||
std::string RuntimeLibrary::getLibPath(StringRef ToolPath, | ||
StringRef LibFileName) { | ||
if (llvm::sys::fs::exists(LibFileName)) { | ||
return std::string(LibFileName); | ||
} | ||
|
||
std::string ByTool = getLibPathByToolPath(ToolPath, LibFileName); | ||
if (llvm::sys::fs::exists(ByTool)) { | ||
return ByTool; | ||
} | ||
|
||
std::string ByInstalled = getLibPathByInstalled(LibFileName); | ||
if (llvm::sys::fs::exists(ByInstalled)) { | ||
return ByInstalled; | ||
} | ||
|
||
errs() << "BOLT-ERROR: library not found: " << ByTool << ", " << ByInstalled | ||
<< ", or " << LibFileName << "\n"; | ||
exit(1); | ||
} | ||
|
||
void RuntimeLibrary::loadLibrary(StringRef LibPath, BOLTLinker &Linker, | ||
BOLTLinker::SectionsMapper MapSections) { | ||
ErrorOr<std::unique_ptr<MemoryBuffer>> MaybeBuf = | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,39 @@ | ||
find_first_existing_vc_file("${LLVM_MAIN_SRC_DIR}" llvm_vc) | ||
find_first_existing_vc_file("${BOLT_SOURCE_DIR}" bolt_vc) | ||
|
||
# The VC revision include that we want to generate. | ||
set(version_inc "${CMAKE_CURRENT_BINARY_DIR}/VCSVersion.inc") | ||
|
||
set(generate_vcs_version_script "${LLVM_CMAKE_DIR}/GenerateVersionFromVCS.cmake") | ||
|
||
# Create custom target to generate the VC revision include. | ||
add_custom_command(OUTPUT "${version_inc}" | ||
DEPENDS "${llvm_vc}" "${bolt_vc}" "${generate_vcs_version_script}" | ||
COMMAND ${CMAKE_COMMAND} "-DNAMES=BOLT" | ||
"-DHEADER_FILE=${version_inc}" | ||
"-DBOLT_SOURCE_DIR=${BOLT_SOURCE_DIR}" | ||
"-DLLVM_VC_REPOSITORY=${llvm_vc_repository}" | ||
"-DLLVM_VC_REVISION=${llvm_vc_revision}" | ||
"-DLLVM_FORCE_VC_REVISION=${LLVM_FORCE_VC_REVISION}" | ||
"-DLLVM_FORCE_VC_REPOSITORY=${LLVM_FORCE_VC_REPOSITORY}" | ||
-P "${generate_vcs_version_script}") | ||
|
||
# Mark the generated header as being generated. | ||
set_source_files_properties("${version_inc}" | ||
PROPERTIES GENERATED TRUE | ||
HEADER_FILE_ONLY TRUE) | ||
|
||
include_directories(${CMAKE_CURRENT_BINARY_DIR}) | ||
|
||
add_llvm_library(LLVMBOLTUtils | ||
CommandLineOpts.cpp | ||
Utils.cpp | ||
|
||
${version_inc} | ||
DISABLE_LLVM_LINK_LLVM_DYLIB | ||
|
||
LINK_LIBS | ||
${LLVM_PTHREAD_LIB} | ||
|
||
DEPENDS | ||
llvm_vcsrevision_h | ||
|
||
LINK_COMPONENTS | ||
Support | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,15 +11,15 @@ | |
//===----------------------------------------------------------------------===// | ||
|
||
#include "bolt/Utils/CommandLineOpts.h" | ||
#include "llvm/Support/VCSRevision.h" | ||
#include "VCSVersion.inc" | ||
|
||
using namespace llvm; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. below in "#ifdef LLVM_REVISION LLVM_REVISION" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
namespace llvm { | ||
namespace bolt { | ||
const char *BoltRevision = | ||
#ifdef LLVM_REVISION | ||
LLVM_REVISION; | ||
#ifdef BOLT_REVISION | ||
BOLT_REVISION; | ||
#else | ||
"<unknown>"; | ||
#endif | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,12 +16,19 @@ add_library(bolt_rt_instr STATIC | |
instr.cpp | ||
${CMAKE_CURRENT_BINARY_DIR}/config.h | ||
) | ||
set_target_properties(bolt_rt_instr PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${LLVM_LIBRARY_DIR}") | ||
set_target_properties(bolt_rt_instr PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks just wrong. |
||
add_library(bolt_rt_hugify STATIC | ||
hugify.cpp | ||
${CMAKE_CURRENT_BINARY_DIR}/config.h | ||
) | ||
set_target_properties(bolt_rt_hugify PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${LLVM_LIBRARY_DIR}") | ||
set_target_properties(bolt_rt_hugify PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}") | ||
|
||
if(NOT BOLT_BUILT_STANDALONE) | ||
add_custom_command(TARGET bolt_rt_instr POST_BUILD | ||
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_BINARY_DIR}/lib/libbolt_rt_instr.a" "${LLVM_LIBRARY_DIR}") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How can you copr from |
||
add_custom_command(TARGET bolt_rt_hugify POST_BUILD | ||
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_BINARY_DIR}/lib/libbolt_rt_hugify.a" "${LLVM_LIBRARY_DIR}") | ||
endif() | ||
|
||
set(BOLT_RT_FLAGS | ||
-ffreestanding | ||
|
@@ -46,8 +53,8 @@ target_include_directories(bolt_rt_instr PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) | |
target_compile_options(bolt_rt_hugify PRIVATE ${BOLT_RT_FLAGS}) | ||
target_include_directories(bolt_rt_hugify PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) | ||
|
||
install(TARGETS bolt_rt_instr DESTINATION "lib${LLVM_LIBDIR_SUFFIX}") | ||
install(TARGETS bolt_rt_hugify DESTINATION "lib${LLVM_LIBDIR_SUFFIX}") | ||
install(TARGETS bolt_rt_instr DESTINATION "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}") | ||
install(TARGETS bolt_rt_hugify DESTINATION "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}") | ||
|
||
if (CMAKE_CXX_COMPILER_ID MATCHES ".*Clang.*" AND CMAKE_SYSTEM_NAME STREQUAL "Darwin") | ||
add_library(bolt_rt_instr_osx STATIC | ||
|
@@ -59,5 +66,10 @@ if (CMAKE_CXX_COMPILER_ID MATCHES ".*Clang.*" AND CMAKE_SYSTEM_NAME STREQUAL "Da | |
target_compile_options(bolt_rt_instr_osx PRIVATE | ||
-target x86_64-apple-darwin19.6.0 | ||
${BOLT_RT_FLAGS}) | ||
install(TARGETS bolt_rt_instr_osx DESTINATION "lib${LLVM_LIBDIR_SUFFIX}") | ||
install(TARGETS bolt_rt_instr_osx DESTINATION "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}") | ||
|
||
if(NOT BOLT_BUILT_STANDALONE) | ||
add_custom_command(TARGET bolt_rt_instr_osx POST_BUILD | ||
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_BINARY_DIR}/lib/libbolt_rt_instr_osx.a" "${LLVM_LIBRARY_DIR}") | ||
endif() | ||
endif() |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -92,10 +92,22 @@ | |
|
||
tool_dirs = [config.llvm_tools_dir, config.test_source_root] | ||
|
||
llvm_bolt_args = [] | ||
|
||
if config.libbolt_rt_instr: | ||
llvm_bolt_args.append(f"--runtime-instrumentation-lib={config.libbolt_rt_instr}") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In --runtime-instrumentation-lib description, it says: "specify file name of the runtime instrumentation library" But here we provide a full path to the library. It should fail to work, as #99806 implies. However, the reason it succeeds (at least on my system) is because we're adding here the getLibPathByInstalled() function that is currently broken, CMAKE_INSTALL_LIBDIR resolves to a single folder name (lib64), that then gets converted into an empty string via the call to root_path, and then we finally append the contents of --runtime-instrumentation-lib, which succeeds to find the file because it is already a full path. I think if the intent is to use --runtime-instrumentation-lib as a flag that contains the full path, we should at least update the description of that and properly support it in getLibPath() (instead of having it work by chance). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Ah, I kinda knew this was an issue but couldn't remember why until I looked at the GNUInstallDirs docs. I need to use the full variant and this should be fixed.
Yeah, that sounds good. I don't really understand why it's a filename only when there's proper use cases like with Nix (and probably many others) where you would want to specify a path. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alright, I've updated the description and switched to the full path now. |
||
|
||
if config.libbolt_rt_hugify: | ||
llvm_bolt_args.append(f"--runtime-hugify-lib={config.libbolt_rt_hugify}") | ||
|
||
tools = [ | ||
ToolSubst("llc", unresolved="fatal"), | ||
ToolSubst("llvm-dwarfdump", unresolved="fatal"), | ||
ToolSubst("llvm-bolt", unresolved="fatal"), | ||
ToolSubst( | ||
"llvm-bolt", | ||
unresolved="fatal", | ||
extra_args=llvm_bolt_args, | ||
), | ||
ToolSubst("llvm-boltdiff", unresolved="fatal"), | ||
ToolSubst("llvm-bolt-heatmap", unresolved="fatal"), | ||
ToolSubst("llvm-bat-dump", unresolved="fatal"), | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I doubt that this is a 1:1 copy from Clang. See comment below.