Skip to content
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

chore(profiling): build dd_wrapper once and share that #11472

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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: 11 additions & 0 deletions ddtrace/internal/datadog/profiling/cmake/AnalysisFunc.cmake
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
include(CheckIPOSupported)

function(add_ddup_config target)
# Profiling native extensions are built with C++17, even though underlying
# repo adheres to the manylinux 2014 standard. This isn't currently a
# problem, but if it becomes one, we may have to structure the library
# differently.
target_compile_features(${target} PUBLIC cxx_std_17)

# Common compile options
target_compile_options(${target} PRIVATE "$<$<CONFIG:Release>:-Os>" -ffunction-sections
-Wall
Expand Down Expand Up @@ -82,4 +88,9 @@ function(add_ddup_config target)
if(DO_FANALYZER AND CMAKE_CXX_COMPILER_ID MATCHES "GNU")
target_compile_options(${target} PRIVATE -fanalyzer)
endif()

# The main targets, ddup, crashtracker, stack_v2, and dd_wrapper are built
# as dynamic libraries, so PIC is required. And setting this is also fine
# for tests as they're loading those dynamic libraries.
set_target_properties(${target} PROPERTIES POSITION_INDEPENDENT_CODE ON)
endfunction()
28 changes: 7 additions & 21 deletions ddtrace/internal/datadog/profiling/crashtracker/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,24 +44,13 @@ add_custom_command(
# Specify the target C-extension that we want to build
add_library(${EXTENSION_NAME} SHARED ${CRASHTRACKER_CPP_SRC})

# We can't add common Profiling configuration because cython generates messy code, so we just setup some basic flags and
# features
target_compile_options(${EXTENSION_NAME} PRIVATE "$<$<CONFIG:Release>:-Os>" -ffunction-sections)

if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
# macOS-specific options
target_compile_options(${EXTENSION_NAME} PRIVATE "$<$<CONFIG:Debug>:-Og;-g>")
target_link_options(${EXTENSION_NAME} PRIVATE "$<$<CONFIG:Release>:-Wl,-dead_strip>")
else()
# Linux/ELF-based options
target_compile_options(${EXTENSION_NAME} PRIVATE "$<$<CONFIG:Debug>:-Og;-ggdb3>" -fno-semantic-interposition)
target_link_options(${EXTENSION_NAME} PRIVATE "$<$<CONFIG:Release>:-s>" -Wl,--as-needed -Wl,-Bsymbolic-functions
-Wl,--gc-sections)
endif()

set_property(TARGET ${EXTENSION_NAME} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)

target_compile_features(${EXTENSION_NAME} PUBLIC cxx_std_17)
add_ddup_config(${EXTENSION_NAME})
# Cython generates code that produces errors for the following, so relax compile
# options
target_compile_options(
${EXTENSION_NAME}
PRIVATE -Wno-old-style-cast -Wno-shadow
)

# cmake may mutate the name of the library (e.g., lib- and -.so for dynamic libraries). This suppresses that behavior,
# which is required to ensure all paths can be inferred correctly by setup.py.
Expand All @@ -81,9 +70,6 @@ else()
target_link_libraries(${EXTENSION_NAME} PRIVATE dd_wrapper)
endif()

# Extensions are built as dynamic libraries, so PIC is required.
set_target_properties(${EXTENSION_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON)

# Set the output directory for the built library
if(LIB_INSTALL_DIR)
install(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ add_library(
# Add common configuration flags
add_ddup_config(dd_wrapper)

target_compile_features(dd_wrapper PUBLIC cxx_std_17)

target_include_directories(dd_wrapper PRIVATE include ${Datadog_INCLUDE_DIRS})

target_link_libraries(dd_wrapper PRIVATE ${Datadog_LIBRARIES} Threads::Threads)
Expand All @@ -75,7 +73,7 @@ string(TOLOWER ${PLATFORM_SUFFIX} PLATFORM_SUFFIX)
# but as long as it encodes the major moving parts, it's fine
set(DD_WRAPPER_TARGET_NAME "dd_wrapper-${PLATFORM_SUFFIX}")

set_target_properties(dd_wrapper PROPERTIES POSITION_INDEPENDENT_CODE ON OUTPUT_NAME "${DD_WRAPPER_TARGET_NAME}")
set_target_properties(dd_wrapper PROPERTIES OUTPUT_NAME "${DD_WRAPPER_TARGET_NAME}")

# The name of the crashtracker executable has to be propagated to a a few different targets, and it needs to be inferred
# at runtime, so we set it here. Any component which used dd_wrapper will have access to a uniform name.
Expand Down
28 changes: 7 additions & 21 deletions ddtrace/internal/datadog/profiling/ddup/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,24 +49,13 @@ add_custom_command(
# Specify the target C-extension that we want to build
add_library(${EXTENSION_NAME} SHARED ${DDUP_CPP_SRC})

# We can't add common Profiling configuration because cython generates messy code, so we just setup some basic flags and
# features
target_link_options(${EXTENSION_NAME} PRIVATE "$<$<CONFIG:Release>:-Os>" -ffunction-sections)

if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
# macOS-specific options
target_compile_options(${EXTENSION_NAME} PRIVATE "$<$<CONFIG:Debug>:-Og;-g>")
target_link_options(${EXTENSION_NAME} PRIVATE "$<$<CONFIG:Release>:-Wl,-dead_strip>")
else()
# Linux/ELF-based options
target_compile_options(${EXTENSION_NAME} PRIVATE "$<$<CONFIG:Debug>:-Og;-ggdb3>" -fno-semantic-interposition)
target_link_options(${EXTENSION_NAME} PRIVATE "$<$<CONFIG:Release>:-s>" -Wl,--as-needed -Wl,-Bsymbolic-functions
-Wl,--gc-sections)
endif()

set_property(TARGET ${EXTENSION_NAME} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)

target_compile_features(${EXTENSION_NAME} PUBLIC cxx_std_17)
add_ddup_config(${EXTENSION_NAME})
# Cython generates code that produces errors for the following, so relax compile
# options
target_compile_options(
${EXTENSION_NAME}
PRIVATE -Wno-old-style-cast -Wno-shadow
)

# cmake may mutate the name of the library (e.g., lib- and -.so for dynamic libraries). This suppresses that behavior,
# which is required to ensure all paths can be inferred correctly by setup.py.
Expand All @@ -85,9 +74,6 @@ else()
target_link_libraries(${EXTENSION_NAME} PRIVATE dd_wrapper)
endif()

# Extensions are built as dynamic libraries, so PIC is required.
set_target_properties(${EXTENSION_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON)

# Set the output directory for the built library
if(LIB_INSTALL_DIR)
install(
Expand Down
7 changes: 0 additions & 7 deletions ddtrace/internal/datadog/profiling/stack_v2/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,6 @@ add_cppcheck_target(
SRC
${CMAKE_CURRENT_SOURCE_DIR}/src)

# This project is build with C++17, even though the underlying repo adheres to the manylinux 2014 standard. This isn't
# currently a problem, but if it becomes one, we may have to structure the library differently.
target_compile_features(${EXTENSION_NAME} PUBLIC cxx_std_17)

# Never build with native unwinding, since this is not currently used
target_compile_definitions(${EXTENSION_NAME} PRIVATE UNWIND_NATIVE_DISABLE)

Expand Down Expand Up @@ -106,9 +102,6 @@ if(Python3_LIBRARIES)
target_link_libraries(${EXTENSION_NAME} PRIVATE ${Python3_LIBRARIES})
endif()

# Extensions are built as dynamic libraries, so PIC is required.
set_target_properties(${EXTENSION_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON)

# Set the output directory for the built library
if(LIB_INSTALL_DIR)
install(
Expand Down
106 changes: 83 additions & 23 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
LIBDDWAF_DOWNLOAD_DIR = HERE / "ddtrace" / "appsec" / "_ddwaf" / "libddwaf"
IAST_DIR = HERE / "ddtrace" / "appsec" / "_iast" / "_taint_tracking"
DDUP_DIR = HERE / "ddtrace" / "internal" / "datadog" / "profiling" / "ddup"
DD_WRAPPER_DIR = HERE / "ddtrace" / "internal" / "datadog" / "profiling" / "dd_wrapper"
CRASHTRACKER_DIR = HERE / "ddtrace" / "internal" / "datadog" / "profiling" / "crashtracker"
STACK_V2_DIR = HERE / "ddtrace" / "internal" / "datadog" / "profiling" / "stack_v2"

Expand Down Expand Up @@ -534,31 +535,90 @@ def get_exts_for(name):
if (
platform.system() == "Linux" or (platform.system() == "Darwin" and platform.machine() == "arm64")
) and is_64_bit_python():
ext_modules.append(
CMakeExtension(
"ddtrace.internal.datadog.profiling.ddup._ddup",
source_dir=DDUP_DIR,
optional=False,
)
)

ext_modules.append(
CMakeExtension(
"ddtrace.internal.datadog.profiling.crashtracker._crashtracker",
source_dir=CRASHTRACKER_DIR,
optional=False,
)
)
def build_libdd_wrapper(build_type="Debug", build_args=None):
source_dir = DD_WRAPPER_DIR
output_dir = Path(DD_WRAPPER_DIR).resolve()

cmake_build_dir = (output_dir / "build")
cmake_build_dir.mkdir(exist_ok=True)
print(source_dir, output_dir, cmake_build_dir, "================================================")

cmake_args = [
"-S{}".format(source_dir), # cmake>=3.13
"-B{}".format(cmake_build_dir), # cmake>=3.13
"-DPython3_ROOT_DIR={}".format(sysconfig.get_config_var("prefix")),
"-DPYTHON_EXECUTABLE={}".format(sys.executable),
"-DCMAKE_BUILD_TYPE={}".format(build_type),
"-DLIB_INSTALL_DIR={}".format(output_dir),
]

# Echion doesn't build on 3.7, so just skip it outright for now
if sys.version_info >= (3, 8):
ext_modules.append(
CMakeExtension(
"ddtrace.internal.datadog.profiling.stack_v2._stack_v2",
source_dir=STACK_V2_DIR,
optional=False,
),
)
if BUILD_PROFILING_NATIVE_TESTS:
cmake_args += ["-DBUILD_TESTING=ON"]

if IS_EDITABLE:
# the INPLACE_LIB_INSTALL_DIR should be the source dir of the extension
cmake_args.append("-DINPLACE_LIB_INSTALL_DIR={}".format(source_dir))

# Arguments to the cmake --build command
build_args = build_args or []
build_args += ["--config {}".format(build_type)]

# Arguments to cmake --install command
install_args = []
install_args += ["--config {}".format(build_type)]

# platform/version-specific arguments--may go into cmake, build, or install as needed
if CURRENT_OS == "Windows":
cmake_args += [
"-A{}".format("x64" if platform.architecture()[0] == "64bit" else "Win32"),
]
if CURRENT_OS == "Darwin" and sys.version_info >= (3, 8, 0):
# Cross-compile support for macOS - respect ARCHFLAGS if set
# Darwin Universal2 should bundle both architectures
# This is currently specific to IAST and requires cmakefile support
archs = re.findall(r"-arch (\S+)", os.environ.get("ARCHFLAGS", ""))
if archs:
cmake_args += [
"-DBUILD_MACOS=ON",
"-DCMAKE_OSX_ARCHITECTURES={}".format(";".join(archs)),
]

cmake_command = (
Path(cmake.CMAKE_BIN_DIR) / "cmake"
).resolve() # explicitly use the cmake provided by the cmake package
subprocess.run([cmake_command, *cmake_args], cwd=cmake_build_dir, check=True)
subprocess.run([cmake_command, "--build", ".", *build_args], cwd=cmake_build_dir, check=True)
subprocess.run([cmake_command, "--install", ".", *install_args], cwd=cmake_build_dir, check=True)


build_libdd_wrapper()
pass
# ext_modules.append(
# CMakeExtension(
# "ddtrace.internal.datadog.profiling.ddup._ddup",
# source_dir=DDUP_DIR,
# optional=False,
# )
# )

# ext_modules.append(
# CMakeExtension(
# "ddtrace.internal.datadog.profiling.crashtracker._crashtracker",
# source_dir=CRASHTRACKER_DIR,
# optional=False,
# )
# )

# # Echion doesn't build on 3.7, so just skip it outright for now
# if sys.version_info >= (3, 8):
# ext_modules.append(
# CMakeExtension(
# "ddtrace.internal.datadog.profiling.stack_v2._stack_v2",
# source_dir=STACK_V2_DIR,
# optional=False,
# ),
# )

else:
ext_modules = []
Expand Down
Loading