diff --git a/cmake/BuildSettings.cmake b/cmake/BuildSettings.cmake index 74f655d1f..180ec0f44 100644 --- a/cmake/BuildSettings.cmake +++ b/cmake/BuildSettings.cmake @@ -25,11 +25,16 @@ omnitrace_add_option(OMNITRACE_BUILD_STATIC_LIBGCC "Build with -static-libgcc if possible" OFF) omnitrace_add_option(OMNITRACE_BUILD_STATIC_LIBSTDCXX "Build with -static-libstdc++ if possible" OFF) +omnitrace_add_option(OMNITRACE_BUILD_STACK_PROTECTOR "Build with -fstack-protector" ON) omnitrace_add_interface_library(omnitrace-static-libgcc "Link to static version of libgcc") omnitrace_add_interface_library(omnitrace-static-libstdcxx "Link to static version of libstdc++") +omnitrace_add_interface_library(omnitrace-static-libgcc-optional + "Link to static version of libgcc") +omnitrace_add_interface_library(omnitrace-static-libstdcxx-optional + "Link to static version of libstdc++") target_compile_definitions(omnitrace-compile-options INTERFACE $<$:DEBUG>) @@ -194,6 +199,18 @@ if(OMNITRACE_USE_COMPILE_TIMING) target_link_libraries(omnitrace-compile-options INTERFACE omnitrace-compile-timing) endif() +# ----------------------------------------------------------------------------------------# +# fstack-protector +# +omnitrace_add_interface_library(omnitrace-stack-protector + "Adds stack-protector compiler flags") +add_target_flag_if_avail(omnitrace-stack-protector "-fstack-protector-strong" + "-Wstack-protector") + +if(OMNITRACE_BUILD_STACK_PROTECTOR) + target_link_libraries(omnitrace-compile-options INTERFACE omnitrace-stack-protector) +endif() + # ----------------------------------------------------------------------------------------# # developer build flags # @@ -281,13 +298,6 @@ else() set(OMNITRACE_USE_SANITIZER OFF) endif() -if(MSVC) - # VTune is much more helpful when debug information is included in the generated - # release code. - add_flag_if_avail("/Zi") - add_flag_if_avail("/DEBUG") -endif() - # ----------------------------------------------------------------------------------------# # static lib flags # @@ -308,6 +318,16 @@ target_link_options( omnitrace-static-libstdcxx INTERFACE $<$:$<$:-static-libstdc++>>) +if(OMNITRACE_BUILD_STATIC_LIBGCC) + target_link_libraries(omnitrace-static-libgcc-optional + INTERFACE omnitrace-static-libgcc) +endif() + +if(OMNITRACE_BUILD_STATIC_LIBSTDCXX) + target_link_libraries(omnitrace-static-libstdcxx-optional + INTERFACE omnitrace-static-libstdcxx) +endif() + # ----------------------------------------------------------------------------------------# # user customization # diff --git a/cmake/Formatting.cmake b/cmake/Formatting.cmake index b199739ca..4ebd539a3 100644 --- a/cmake/Formatting.cmake +++ b/cmake/Formatting.cmake @@ -41,8 +41,21 @@ find_program(OMNITRACE_CLANG_FORMAT_EXE NAMES clang-format-11 clang-format-mp-11 clang-format) find_program(OMNITRACE_CMAKE_FORMAT_EXE NAMES cmake-format) +find_program(OMNITRACE_BLACK_FORMAT_EXE NAMES black) -if(OMNITRACE_CLANG_FORMAT_EXE) +add_custom_target(format-omnitrace) +if(NOT TARGET format) + add_custom_target(format) +endif() +foreach(_TYPE source python cmake) + if(NOT TARGET format-${_TYPE}) + add_custom_target(format-${_TYPE}) + endif() +endforeach() + +if(OMNITRACE_CLANG_FORMAT_EXE + OR OMNITRACE_BLACK_FORMAT_EXE + OR OMNITRACE_CMAKE_FORMAT_EXE) file(GLOB_RECURSE sources ${PROJECT_SOURCE_DIR}/source/*.cpp) file(GLOB_RECURSE headers ${PROJECT_SOURCE_DIR}/source/*.hpp ${PROJECT_SOURCE_DIR}/source/*.hpp.in ${PROJECT_SOURCE_DIR}/source/*.h @@ -63,16 +76,25 @@ if(OMNITRACE_CLANG_FORMAT_EXE) list(REMOVE_ITEM examples ${external}) list(REMOVE_ITEM cmake_files ${external}) endif() - add_custom_target( - format-omnitrace-source - ${OMNITRACE_CLANG_FORMAT_EXE} -i ${sources} ${headers} ${examples} - COMMENT "[omnitrace] Running C++ formatter ${OMNITRACE_CLANG_FORMAT_EXE}...") - add_custom_target(format-omnitrace) - add_dependencies(format-omnitrace format-omnitrace-source) - if(NOT TARGET format) - add_custom_target(format) + + if(OMNITRACE_CLANG_FORMAT_EXE) + add_custom_target( + format-omnitrace-source + ${OMNITRACE_CLANG_FORMAT_EXE} -i ${sources} ${headers} ${examples} + COMMENT "[omnitrace] Running C++ formatter ${OMNITRACE_CLANG_FORMAT_EXE}...") + endif() + + if(OMNITRACE_BLACK_FORMAT_EXE) + add_custom_target( + format-omnitrace-python + ${OMNITRACE_BLACK_FORMAT_EXE} ${PROJECT_SOURCE_DIR} + COMMENT + "[omnitrace] Running Python formatter ${OMNITRACE_BLACK_FORMAT_EXE}...") + if(NOT TARGET format-python) + add_custom_target(format-python) + endif() endif() - add_dependencies(format format-omnitrace) + if(OMNITRACE_CMAKE_FORMAT_EXE) add_custom_target( format-omnitrace-cmake @@ -82,10 +104,20 @@ if(OMNITRACE_CLANG_FORMAT_EXE) if(NOT TARGET format-cmake) add_custom_target(format-cmake) endif() - add_dependencies(format-cmake format-omnitrace-cmake) endif() + + foreach(_TYPE source python cmake) + if(TARGET format-omnitrace-${_TYPE}) + add_dependencies(format-omnitrace format-omnitrace-${_TYPE}) + add_dependencies(format-${_TYPE} format-omnitrace-${_TYPE}) + endif() + endforeach() + + foreach(_TYPE source python) + if(TARGET format-omnitrace-${_TYPE}) + add_dependencies(format format-omnitrace-${_TYPE}) + endif() + endforeach() else() - message( - AUTHOR_WARNING - "clang-format could not be found. format build target not available.") + message(STATUS "clang-format could not be found. format build target not available.") endif() diff --git a/cmake/Packages.cmake b/cmake/Packages.cmake index 8045023ee..2ac9db549 100644 --- a/cmake/Packages.cmake +++ b/cmake/Packages.cmake @@ -505,6 +505,11 @@ endif() target_compile_definitions(omnitrace-timemory-config INTERFACE TIMEMORY_PAPI_ARRAY_SIZE=16 TIMEMORY_USE_ROOFLINE=0) +if(OMNITRACE_BUILD_STACK_PROTECTOR) + add_target_flag_if_avail(omnitrace-timemory-config "-fstack-protector-strong" + "-Wstack-protector") +endif() + set(TIMEMORY_EXTERNAL_INTERFACE_LIBRARY omnitrace-timemory-config CACHE STRING "timemory configuration interface library") diff --git a/scripts/build-release.sh b/scripts/build-release.sh index 2b230a153..33a84fc8a 100755 --- a/scripts/build-release.sh +++ b/scripts/build-release.sh @@ -10,7 +10,7 @@ : ${LTO:="OFF"} : ${STRIP:="ON"} : ${LIBGCC:="ON"} -: ${LIBSTDCXX:="OFF"} +: ${LIBSTDCXX:="ON"} : ${MAX_THREADS:=2048} : ${PERFETTO_TOOLS:="ON"} : ${HIDDEN_VIZ:="ON"} diff --git a/source/bin/omnitrace/CMakeLists.txt b/source/bin/omnitrace/CMakeLists.txt index 97eeaeb6c..5391286b4 100644 --- a/source/bin/omnitrace/CMakeLists.txt +++ b/source/bin/omnitrace/CMakeLists.txt @@ -6,7 +6,7 @@ set(CMAKE_INTERPROCEDURAL_OPTIMIZATION OFF) -add_executable(omnitrace-exe ${_EXCLUDE}) +add_executable(omnitrace-exe) target_sources( omnitrace-exe @@ -22,12 +22,9 @@ target_sources( target_link_libraries( omnitrace-exe - PRIVATE omnitrace::omnitrace-headers - omnitrace::omnitrace-dyninst - omnitrace::omnitrace-compile-options - omnitrace::omnitrace-compile-definitions - timemory::timemory-headers - $,omnitrace::omnitrace-sanitizer,>) + PRIVATE omnitrace::omnitrace-headers omnitrace::omnitrace-dyninst + omnitrace::omnitrace-compile-options omnitrace::omnitrace-compile-definitions + omnitrace::omnitrace-sanitizer timemory::timemory-headers) set_target_properties( omnitrace-exe diff --git a/source/lib/omnitrace-dl/CMakeLists.txt b/source/lib/omnitrace-dl/CMakeLists.txt index 08a33efc4..6c332abd9 100644 --- a/source/lib/omnitrace-dl/CMakeLists.txt +++ b/source/lib/omnitrace-dl/CMakeLists.txt @@ -23,13 +23,8 @@ target_include_directories( $) target_link_libraries( omnitrace-dl-library - PUBLIC - ${dl_LIBRARY} - $ - $ - $,omnitrace::omnitrace-static-libgcc,>> - $,omnitrace::omnitrace-static-libstdcxx,>> - ) + PUBLIC $ $ + $) add_target_cxx_flag_if_avail(omnitrace-dl-library "-ftls-model=global-dynamic") add_target_cxx_flag_if_avail(omnitrace-dl-library "-g") diff --git a/source/lib/omnitrace/CMakeLists.txt b/source/lib/omnitrace/CMakeLists.txt index 2533d2fd4..18a10a2ae 100644 --- a/source/lib/omnitrace/CMakeLists.txt +++ b/source/lib/omnitrace/CMakeLists.txt @@ -35,11 +35,10 @@ target_link_libraries( $ $ $ - $,omnitrace::omnitrace-lto,>> - $,omnitrace::omnitrace-static-libgcc,>> - $,omnitrace::omnitrace-static-libstdcxx,>> - $,omnitrace::omnitrace-sanitizer,>> - ) + $ + $ + $ + $,omnitrace::omnitrace-lto,>>) # ------------------------------------------------------------------------------# # diff --git a/source/python/CMakeLists.txt b/source/python/CMakeLists.txt index f9e958ff4..eaad46f97 100644 --- a/source/python/CMakeLists.txt +++ b/source/python/CMakeLists.txt @@ -5,8 +5,8 @@ # ######################################################################################## if(OMNITRACE_BUILD_STATIC_LIBSTDCXX) - omnitrace_message(FATAL_ERROR - "static libstdc++ is not compatible with python bindings") + # omnitrace_message(FATAL_ERROR "static libstdc++ is not compatible with python + # bindings") endif() # if set, will screw up loading library @@ -76,18 +76,16 @@ set(pybind_libs pybind11::module) add_library(libpyomnitrace-interface INTERFACE) target_link_libraries( libpyomnitrace-interface - INTERFACE - pybind11::module - timemory::timemory-headers - omnitrace::omnitrace-headers - omnitrace::omnitrace-compile-options - omnitrace::omnitrace-lto - omnitrace::omnitrace-dl-library - omnitrace::omnitrace-user-library - omnitrace::omnitrace-python - omnitrace::omnitrace-python-compile-options - $,omnitrace::omnitrace-static-libgcc,>> - ) + INTERFACE pybind11::module + timemory::timemory-headers + omnitrace::omnitrace-headers + omnitrace::omnitrace-compile-options + omnitrace::omnitrace-static-libgcc-optional + omnitrace::omnitrace-lto + omnitrace::omnitrace-dl-library + omnitrace::omnitrace-user-library + omnitrace::omnitrace-python + omnitrace::omnitrace-python-compile-options) omnitrace_target_compile_definitions(libpyomnitrace-interface INTERFACE OMNITRACE_PYBIND11_SOURCE) diff --git a/source/python/libpyomnitrace.cpp b/source/python/libpyomnitrace.cpp index 0f2cbb4ff..153cca77e 100644 --- a/source/python/libpyomnitrace.cpp +++ b/source/python/libpyomnitrace.cpp @@ -77,6 +77,9 @@ PYBIND11_MODULE(libpyomnitrace, omni) { using namespace pyomnitrace; + py::doc("Omnitrace Python bindings for profiling, user API, and code coverage " + "post-processing"); + static bool _is_initialized = false; static bool _is_finalized = false; static auto _get_use_mpi = []() { @@ -162,10 +165,25 @@ PYBIND11_MODULE(libpyomnitrace, omni) }, "Finalize omnitrace"); - py::doc("omnitrace profiler for python"); pyprofile::generate(omni); pycoverage::generate(omni); pyuser::generate(omni); + + auto _python_path = tim::get_env("OMNITRACE_PATH", std::string{}, false); + auto _libpath = std::string{ "libomnitrace-dl.so" }; + if(!_python_path.empty()) _libpath = TIMEMORY_JOIN("/", _python_path, _libpath); + // permit env override if default path fails/is wrong + _libpath = tim::get_env("OMNITRACE_DL_LIBRARY", _libpath); + // this is necessary when building with -static-libstdc++ + // without it, loading libomnitrace.so within libomnitrace-dl.so segfaults + if(!dlopen(_libpath.c_str(), RTLD_NOW | RTLD_GLOBAL)) + { + auto _msg = + TIMEMORY_JOIN("", "dlopen(\"", _libpath, "\", RTLD_NOW | RTLD_GLOBAL)"); + perror(_msg.c_str()); + fprintf(stderr, "[omnitrace][dl][pid=%i] %s :: %s\n", getpid(), _msg.c_str(), + dlerror()); + } } //======================================================================================// diff --git a/source/python/omnitrace/__init__.py b/source/python/omnitrace/__init__.py index 484fb232b..0773cbbeb 100644 --- a/source/python/omnitrace/__init__.py +++ b/source/python/omnitrace/__init__.py @@ -35,6 +35,12 @@ """ try: + import os + + os.environ["OMNITRACE_PATH"] = os.path.abspath( + os.path.join(os.path.dirname(__file__), "../../..") + ) + from .libpyomnitrace import coverage from . import user from .profiler import Profiler, FakeProfiler diff --git a/source/python/omnitrace/user.py b/source/python/omnitrace/user.py index 9b7411923..59f08f9b7 100644 --- a/source/python/omnitrace/user.py +++ b/source/python/omnitrace/user.py @@ -93,7 +93,7 @@ def stop(self): _count = Region._counter self._active = False if _count != self._count: - raise LogicError( + raise RuntimeError( f"{self._label} was not popped in the order it was pushed. Current stack number: {_count}, expected stack number: {self._count}" ) _libuser.pop_region(self._label)