build: use lld or mold linkers in supported platforms
This commit is contained in:
@@ -234,6 +234,36 @@ if(${CLANG} AND APPLE)
|
||||
set(STATIC_LINK_FLAGS)
|
||||
endif()
|
||||
|
||||
# Search for faster linkers mold and lld, and use them if available
|
||||
mark_as_advanced(MOLD LLD)
|
||||
find_program(MOLD mold)
|
||||
find_program(LLD ld.lld)
|
||||
|
||||
# USING_FAST_LINKER will be defined if a fast linker is being used and its
|
||||
# content will correspond to the fast linker name
|
||||
|
||||
# Mold support was added in GCC 12.1.0
|
||||
if(NOT USING_FAST_LINKER
|
||||
AND NOT (${MOLD} STREQUAL "MOLD-NOTFOUND")
|
||||
AND LINUX
|
||||
AND ${GCC}
|
||||
AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 12.1.0)
|
||||
)
|
||||
set(USING_FAST_LINKER MOLD)
|
||||
add_link_options("-fuse-ld=mold")
|
||||
endif()
|
||||
|
||||
if(NOT USING_FAST_LINKER AND NOT (${LLD} STREQUAL "LLD-NOTFOUND")
|
||||
AND (${GCC} OR ${CLANG})
|
||||
)
|
||||
set(USING_FAST_LINKER LLD)
|
||||
add_link_options("-fuse-ld=lld")
|
||||
if(WIN32)
|
||||
# Clear unsupported linker flags on Windows
|
||||
set(LIB_AS_NEEDED_PRE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Include CMake files used for compiler checks
|
||||
include(CheckIncludeFile) # Used to check a single C header at a time
|
||||
include(CheckIncludeFileCXX) # Used to check a single C++ header at a time
|
||||
|
||||
@@ -1484,6 +1484,10 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
|
||||
with open(version_cache_file, "r") as version:
|
||||
self.assertNotEqual(version.read(), version_cache_contents)
|
||||
|
||||
# Remove version cache file if it exists
|
||||
if os.path.exists(version_cache_file):
|
||||
os.remove(version_cache_file)
|
||||
|
||||
# Reconfigure to clean leftovers before the next test
|
||||
NS3ConfigureTestCase.cleaned_once = False
|
||||
|
||||
@@ -1530,6 +1534,86 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
|
||||
self.assertEqual(len(get_enabled_modules()), len(self.ns3_modules))
|
||||
self.assertEqual(len(get_programs_list()), len(self.ns3_executables))
|
||||
|
||||
def test_20_CheckFastLinkers(self):
|
||||
"""!
|
||||
Check if fast linkers LLD and Mold are correctly found and configured
|
||||
@return None
|
||||
"""
|
||||
|
||||
try:
|
||||
from python_on_whales import docker
|
||||
from python_on_whales.exceptions import DockerException
|
||||
except ModuleNotFoundError:
|
||||
self.skipTest("python-on-whales was not found")
|
||||
|
||||
run_ns3("clean")
|
||||
|
||||
# Import rootless docker settings from .bashrc
|
||||
with open(os.path.expanduser("~/.bashrc"), "r") as f:
|
||||
docker_settings = re.findall("(DOCKER_.*=.*)", f.read())
|
||||
for setting in docker_settings:
|
||||
key, value = setting.split("=")
|
||||
os.environ[key] = value
|
||||
del docker_settings, setting, key, value
|
||||
|
||||
# Create Docker client instance and start it
|
||||
with docker.run("gcc:12.1", # Debian with minimum supported version of GCC for Mold
|
||||
interactive=True, detach=True,
|
||||
tty=False,
|
||||
volumes=[(ns3_path, "/ns-3-dev")],
|
||||
) as container:
|
||||
# Redefine the execute command of the container
|
||||
def split_exec(self, cmd):
|
||||
return self._execute(cmd.split(), workdir="/ns-3-dev")
|
||||
|
||||
container._execute = container.execute
|
||||
container.execute = partial(split_exec, container)
|
||||
|
||||
# Install basic packages
|
||||
container.execute("apt-get update")
|
||||
container.execute("apt-get install -y python3 ninja-build cmake g++ lld")
|
||||
|
||||
# Configure should detect and use lld
|
||||
container.execute("./ns3 configure -G Ninja")
|
||||
|
||||
# Check if configuration properly detected lld
|
||||
self.assertTrue(os.path.exists(os.path.join(ns3_path, "cmake-cache", "build.ninja")))
|
||||
with open(os.path.join(ns3_path, "cmake-cache", "build.ninja"), "r") as f:
|
||||
self.assertIn("-fuse-ld=lld", f.read())
|
||||
|
||||
# Try to build using the lld linker
|
||||
try:
|
||||
container.execute("./ns3 build core")
|
||||
except Exception as e:
|
||||
self.assertTrue(False, "Build with lld failed")
|
||||
|
||||
# Now add mold to the PATH
|
||||
if not os.path.exists("./mold-1.4.2-x86_64-linux.tar.gz"):
|
||||
container.execute(
|
||||
"wget https://github.com/rui314/mold/releases/download/v1.4.2/mold-1.4.2-x86_64-linux.tar.gz")
|
||||
container.execute("tar xzfC mold-1.4.2-x86_64-linux.tar.gz /usr/local --strip-components=1")
|
||||
|
||||
# Configure should detect and use mold
|
||||
run_ns3("clean")
|
||||
container.execute("./ns3 configure -G Ninja")
|
||||
|
||||
# Check if configuration properly detected mold
|
||||
self.assertTrue(os.path.exists(os.path.join(ns3_path, "cmake-cache", "build.ninja")))
|
||||
with open(os.path.join(ns3_path, "cmake-cache", "build.ninja"), "r") as f:
|
||||
self.assertIn("-fuse-ld=mold", f.read())
|
||||
|
||||
# Try to build using the lld linker
|
||||
try:
|
||||
container.execute("./ns3 build core")
|
||||
except Exception as e:
|
||||
self.assertTrue(False, "Build with mold failed")
|
||||
|
||||
# Delete mold leftovers
|
||||
os.remove("./mold-1.4.2-x86_64-linux.tar.gz")
|
||||
|
||||
# Reconfigure to clean leftovers before the next test
|
||||
NS3ConfigureTestCase.cleaned_once = False
|
||||
|
||||
|
||||
class NS3BuildBaseTestCase(NS3BaseTestCase):
|
||||
"""!
|
||||
|
||||
Reference in New Issue
Block a user