Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions build/fbcode_builder/getdeps/shared_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

from __future__ import annotations

import os
import typing

if typing.TYPE_CHECKING:
Expand All @@ -36,14 +37,20 @@ def apply_shared_lib_top_level_cmake_defines(
- On Linux: append -Wl,--exclude-libs=ALL to the shared/module linker
flags so the deps' symbols stay out of the produced .so's dynamic
export table (avoids ODR clashes if the host process loads another
copy of any dep).
copy of any dep). Defining CMAKE_*_LINKER_FLAGS on the command line
stops CMake from seeding them from $LDFLAGS, so start from $LDFLAGS
(as CMake would) to keep the caller's linker flags, e.g. a distro's
hardening flags, on the shared library links.
"""
if not build_opts.shared_lib:
return
defines.setdefault("BUILD_SHARED_LIBS", "ON")
if build_opts.is_linux():
ldflags = os.environ.get("LDFLAGS", "")
for var in ("CMAKE_SHARED_LINKER_FLAGS", "CMAKE_MODULE_LINKER_FLAGS"):
defines[var] = _append_token(defines.get(var, ""), "-Wl,--exclude-libs=ALL")
defines[var] = _append_token(
defines.get(var, ldflags), "-Wl,--exclude-libs=ALL"
)


def apply_shared_lib_dep_env(
Expand Down
28 changes: 27 additions & 1 deletion build/fbcode_builder/getdeps/test/shared_lib_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
# LICENSE file in the root directory of this source tree.


import os
import unittest
from unittest.mock import MagicMock
from unittest.mock import MagicMock, patch

from ..envfuncs import Env
from ..shared_lib import (
Expand Down Expand Up @@ -79,6 +80,31 @@ def test_idempotent(self) -> None:
apply_shared_lib_top_level_cmake_defines(defines, opts)
self.assertEqual(defines["CMAKE_SHARED_LINKER_FLAGS"], "-Wl,--exclude-libs=ALL")

def test_env_ldflags_seed_the_linker_flags(self) -> None:
defines = {}
with patch.dict(os.environ, {"LDFLAGS": "-Wl,-z,relro -Wl,-z,now"}):
apply_shared_lib_top_level_cmake_defines(
defines, make_build_opts(is_linux=True)
)
for var in ("CMAKE_SHARED_LINKER_FLAGS", "CMAKE_MODULE_LINKER_FLAGS"):
self.assertEqual(
defines[var], "-Wl,-z,relro -Wl,-z,now -Wl,--exclude-libs=ALL"
)

def test_explicit_linker_flags_win_over_env_ldflags(self) -> None:
defines = {"CMAKE_SHARED_LINKER_FLAGS": "-Wl,--as-needed"}
with patch.dict(os.environ, {"LDFLAGS": "-Wl,-z,now"}):
apply_shared_lib_top_level_cmake_defines(
defines, make_build_opts(is_linux=True)
)
self.assertEqual(
defines["CMAKE_SHARED_LINKER_FLAGS"],
"-Wl,--as-needed -Wl,--exclude-libs=ALL",
)
self.assertEqual(
defines["CMAKE_MODULE_LINKER_FLAGS"], "-Wl,-z,now -Wl,--exclude-libs=ALL"
)


class ApplyDepEnvTest(unittest.TestCase):
def test_no_op_when_shared_lib_off(self) -> None:
Expand Down
Loading