diff --git a/.github/workflows/ubuntu-focal.yml b/.github/workflows/ubuntu-focal.yml index 1bc8ee0929..aaeb7467d8 100644 --- a/.github/workflows/ubuntu-focal.yml +++ b/.github/workflows/ubuntu-focal.yml @@ -7,7 +7,6 @@ on: branches: [ main, develop ] env: - BUILD_TYPE: Release ELFUTILS_DOWNLOAD_VERSION: 0.186 OMNITRACE_VERBOSE: 1 OMNITRACE_CI: ON @@ -19,6 +18,21 @@ jobs: matrix: compiler: ['g++'] mpi: [ '', 'libmpich-dev mpich', 'libopenmpi-dev openmpi-bin libfabric-dev' ] + boost: ['OFF'] + tbb: ['OFF'] + build-type: ['Release'] + python: ['ON'] + ompt: ['ON'] + papi: ['ON'] + include: + - compiler: 'g++' + mpi: '' + boost: 'ON' + tbb: 'ON' + build-type: 'Release' + python: 'OFF' + ompt: 'OFF' + papi: 'OFF' steps: - uses: actions/checkout@v2 @@ -48,16 +62,19 @@ jobs: cmake -B ${{ github.workspace }}/build -DCMAKE_C_COMPILER=$(echo '${{ matrix.compiler }}' | sed 's/+/c/g') -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} - -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} + -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} -DCMAKE_INSTALL_PREFIX=/opt/omnitrace -DOMNITRACE_BUILD_TESTING=ON -DOMNITRACE_BUILD_DYNINST=ON -DOMNITRACE_USE_MPI=${USE_MPI} -DOMNITRACE_USE_HIP=OFF - -DOMNITRACE_USE_PYTHON=ON - -DOMNITRACE_USE_OMPT=ON + -DOMNITRACE_USE_PYTHON=${{ matrix.python }} + -DOMNITRACE_USE_OMPT=${{ matrix.ompt }} + -DOMNITRACE_USE_PAPI=${{ matrix.papi }} -DDYNINST_BUILD_ELFUTILS=ON -DDYNINST_BUILD_LIBIBERTY=ON + -DDYNINST_BUILD_TBB=${{ matrix.tbb }} + -DDYNINST_BUILD_BOOST=${{ matrix.boost }} -DDYNINST_BUILD_SHARED_LIBS=ON -DDYNINST_BUILD_STATIC_LIBS=OFF -DDYNINST_ELFUTILS_DOWNLOAD_VERSION=${{ env.ELFUTILS_DOWNLOAD_VERSION }} @@ -67,10 +84,6 @@ jobs: run: cmake --build ${{ github.workspace }}/build --target all --parallel 2 -- VERBOSE=1 - - name: Install - run: - cmake --build ${{ github.workspace }}/build --target install --parallel 2 - - name: Test timeout-minutes: 45 working-directory: ${{ github.workspace }}/build @@ -78,6 +91,13 @@ jobs: ctest -V -N -O ${{ github.workspace }}/build/omnitrace-ctest-${{ github.job }}-commands.log && ctest -V --output-log ${{ github.workspace }}/build/omnitrace-ctest-${{ github.job }}.log --stop-on-failure + - name: Install + working-directory: ${{ github.workspace }}/build + run: | + cpack -G STGZ + mkdir -p /opt/omnitrace + ./omnitrace-*.sh --prefix=/opt/omnitrace --exclude-subdir --skip-license + - name: Test Install timeout-minutes: 10 run: | diff --git a/cmake/ConfigCPack.cmake b/cmake/ConfigCPack.cmake index 0f49ed7ae6..c8a1d83bed 100644 --- a/cmake/ConfigCPack.cmake +++ b/cmake/ConfigCPack.cmake @@ -1,15 +1,4 @@ -if(DYNINST_BUILD_ELFUTILS AND DYNINST_ELFUTILS_DOWNLOAD_VERSION) - omnitrace_add_feature(DYNINST_ELFUTILS_DOWNLOAD_VERSION "ElfUtils download version") - foreach(_LIB dw elf) - install( - PROGRAMS - ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/dyninst-tpls/lib/lib${_LIB}${CMAKE_SHARED_LIBRARY_SUFFIX} - ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/dyninst-tpls/lib/lib${_LIB}${CMAKE_SHARED_LIBRARY_SUFFIX}.1 - ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/dyninst-tpls/lib/lib${_LIB}-${DYNINST_ELFUTILS_DOWNLOAD_VERSION}${CMAKE_SHARED_LIBRARY_SUFFIX} - DESTINATION ${CMAKE_INSTALL_LIBDIR}/dyninst-tpls/lib - OPTIONAL) - endforeach() -endif() +# configure packaging function(omnitrace_parse_release) if(EXISTS /etc/lsb-release AND NOT IS_DIRECTORY /etc/lsb-release) diff --git a/cmake/MacroUtilities.cmake b/cmake/MacroUtilities.cmake index 77c9921079..40bc75a661 100644 --- a/cmake/MacroUtilities.cmake +++ b/cmake/MacroUtilities.cmake @@ -781,4 +781,57 @@ function(OMNITRACE_FIND_SHARED_LIBRARY) find_library(${ARGN}) endfunction() +function(OMNITRACE_INSTALL_TPL _TPL_TARGET _NEW_NAME _BUILD_TREE_DIR) + get_target_property(_TPL_VERSION ${_TPL_TARGET} VERSION) + get_target_property(_TPL_SOVERSION ${_TPL_TARGET} SOVERSION) + get_target_property(_TPL_NAME ${_TPL_TARGET} OUTPUT_NAME) + set(_TPL_PREFIX ${CMAKE_SHARED_LIBRARY_PREFIX}) + set(_TPL_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}) + + foreach(_TAIL ${_TPL_SUFFIX} ${_TPL_SUFFIX}.${_TPL_SOVERSION} + ${_TPL_SUFFIX}.${_TPL_VERSION}) + set(_INP ${_TPL_PREFIX}${_TPL_NAME}${_TAIL}) + set(_OUT ${_TPL_PREFIX}${_NEW_NAME}${_TAIL}) + endforeach() + + # build tree symbolic links + add_custom_target( + ${_NEW_NAME}-library ALL + ${CMAKE_COMMAND} -E create_symlink $ + ${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_VERSION} + COMMAND + ${CMAKE_COMMAND} -E create_symlink + ${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_VERSION} + ${_BUILD_TREE_DIR}/${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_SOVERSION} + COMMAND + ${CMAKE_COMMAND} -E create_symlink + ${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_SOVERSION} + ${_BUILD_TREE_DIR}/${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX} + WORKING_DIRECTORY ${_BUILD_TREE_DIR} + DEPENDS ${_TPL_TARGET} + COMMENT "Creating ${_NEW_NAME} symbolic links to ${_TPL_TARGET}...") + + install( + FILES $ + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RENAME ${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_VERSION}) + + execute_process( + COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/install-tree + COMMAND + ${CMAKE_COMMAND} -E create_symlink + ${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_VERSION} + ${PROJECT_BINARY_DIR}/install-tree/${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_SOVERSION} + COMMAND + ${CMAKE_COMMAND} -E create_symlink + ${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_SOVERSION} + ${PROJECT_BINARY_DIR}/install-tree/${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}) + install( + FILES + ${PROJECT_BINARY_DIR}/install-tree/${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_SOVERSION} + ${PROJECT_BINARY_DIR}/install-tree/${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX} + DESTINATION ${CMAKE_INSTALL_LIBDIR}) + +endfunction() + cmake_policy(POP) diff --git a/cmake/Packages.cmake b/cmake/Packages.cmake index d527c6abd3..4179880100 100644 --- a/cmake/Packages.cmake +++ b/cmake/Packages.cmake @@ -208,14 +208,50 @@ if(OMNITRACE_BUILD_DYNINST) omnitrace_save_variables(PIC VARIABLES CMAKE_POSITION_INDEPENDENT_CODE) set(CMAKE_POSITION_INDEPENDENT_CODE ON) - add_subdirectory(external/dyninst) + set(DYNINST_TPL_INSTALL_PREFIX + "omnitrace" + CACHE PATH "Third-party library install-tree install prefix" FORCE) + set(DYNINST_TPL_INSTALL_LIB_DIR + "omnitrace" + CACHE PATH "Third-party library install-tree install library prefix" FORCE) + add_subdirectory(external/dyninst EXCLUDE_FROM_ALL) omnitrace_restore_variables(PIC VARIABLES CMAKE_POSITION_INDEPENDENT_CODE) add_library(Dyninst::Dyninst INTERFACE IMPORTED) - foreach(_LIB common dyninstAPI parseAPI instructionAPI symtabAPI stackwalk Boost TBB) + foreach(_LIB common dyninstAPI parseAPI instructionAPI symtabAPI stackwalk) target_link_libraries(Dyninst::Dyninst INTERFACE Dyninst::${_LIB}) endforeach() + foreach( + _LIB + common + dynDwarf + dynElf + dyninstAPI + dyninstAPI_RT + instructionAPI + parseAPI + patchAPI + pcontrol + stackwalk + symtabAPI) + if(TARGET ${_LIB}) + install( + TARGETS ${_LIB} + DESTINATION ${CMAKE_INSTALL_LIBDIR}/omnitrace + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_LIBDIR}/omnitrace/include) + endif() + endforeach() + + omnitrace_install_tpl(dyninstAPI_RT omnitrace-rt "${PROJECT_BINARY_DIR}") + + # for packaging + install( + DIRECTORY ${DYNINST_TPL_STAGING_PREFIX}/lib/ + DESTINATION ${CMAKE_INSTALL_LIBDIR}/omnitrace + FILES_MATCHING + PATTERN "*${CMAKE_SHARED_LIBRARY_SUFFIX}*") + target_link_libraries(omnitrace-dyninst INTERFACE Dyninst::Dyninst) set(OMNITRACE_DYNINST_API_RT @@ -529,7 +565,16 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug") CACHE BOOL "" FORCE) endif() -add_subdirectory(external/timemory) +add_subdirectory(external/timemory EXCLUDE_FROM_ALL) + +install(TARGETS gotcha DESTINATION ${CMAKE_INSTALL_LIBDIR}/omnitrace) +if(OMNITRACE_BUILD_LIBUNWIND) + install( + DIRECTORY ${PROJECT_BINARY_DIR}/external/timemory/external/libunwind/install/lib/ + DESTINATION ${CMAKE_INSTALL_LIBDIR}/omnitrace + FILES_MATCHING + PATTERN "*${CMAKE_SHARED_LIBRARY_SUFFIX}*") +endif() omnitrace_restore_variables( BUILD_CONFIG VARIABLES BUILD_SHARED_LIBS BUILD_STATIC_LIBS @@ -590,7 +635,7 @@ if(NOT TARGET PTL::ptl-shared) set(CMAKE_CXX_VISIBILITY_PRESET "hidden") set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) - add_subdirectory(external/PTL) + add_subdirectory(external/PTL EXCLUDE_FROM_ALL) omnitrace_restore_variables( BUILD_CONFIG diff --git a/external/dyninst b/external/dyninst index 8d2ee28ac4..d380d57aec 160000 --- a/external/dyninst +++ b/external/dyninst @@ -1 +1 @@ -Subproject commit 8d2ee28ac44cd34c33192bf234d3435d25d36ca8 +Subproject commit d380d57aec27a6b5e44e0301e6f46f6996160d1b diff --git a/source/bin/CMakeLists.txt b/source/bin/CMakeLists.txt index 0c1cf69cf9..6dcaefe8a1 100644 --- a/source/bin/CMakeLists.txt +++ b/source/bin/CMakeLists.txt @@ -1,7 +1,6 @@ # executable RPATH set(OMNITRACE_EXE_INSTALL_RPATH - "\$ORIGIN/../${CMAKE_INSTALL_LIBDIR}:\$ORIGIN/../${CMAKE_INSTALL_LIBDIR}/omnitrace:\$ORIGIN/../${CMAKE_INSTALL_LIBDIR}/timemory/libunwind:\$ORIGIN/../${CMAKE_INSTALL_LIBDIR}/dyninst-tpls/lib" - ) + "\$ORIGIN/../${CMAKE_INSTALL_LIBDIR}:\$ORIGIN/../${CMAKE_INSTALL_LIBDIR}/omnitrace") # executables add_subdirectory(omnitrace-avail) diff --git a/source/bin/omnitrace/CMakeLists.txt b/source/bin/omnitrace/CMakeLists.txt index 62606e2ab3..110e9af068 100644 --- a/source/bin/omnitrace/CMakeLists.txt +++ b/source/bin/omnitrace/CMakeLists.txt @@ -36,6 +36,10 @@ set_target_properties( INSTALL_RPATH_USE_LINK_PATH ON INSTALL_RPATH "${OMNITRACE_EXE_INSTALL_RPATH}") +if(OMNITRACE_BUILD_DYNINST) + target_compile_definitions(omnitrace-exe PRIVATE OMNITRACE_BUILD_DYNINST=1) +endif() + omnitrace_strip_target(omnitrace-exe) if(CMAKE_BUILD_TYPE MATCHES "^(DEBUG|Debug)") diff --git a/source/bin/omnitrace/omnitrace.cpp b/source/bin/omnitrace/omnitrace.cpp index b64339150e..86991f127e 100644 --- a/source/bin/omnitrace/omnitrace.cpp +++ b/source/bin/omnitrace/omnitrace.cpp @@ -24,6 +24,7 @@ #include "fwd.hpp" #include +#include #include #include #include @@ -128,12 +129,20 @@ strset_t print_formats = { "txt", "json std::string modfunc_dump_dir = {}; auto regex_opts = std::regex_constants::egrep | std::regex_constants::optimize; +#if defined(DYNINST_API_RT) +auto _dyn_api_rt_paths = tim::delimit(DYNINST_API_RT, ":"); +#else +auto _dyn_api_rt_paths = std::vector{}; +#endif + std::string get_absolute_exe_filepath(std::string exe_name, const std::string& env_path = "PATH"); std::string -get_absolute_lib_filepath(std::string lib_name, - const std::string& env_path = "LD_LIBRARY_PATH"); +get_absolute_lib_filepath(std::string lib_name, + const std::string& env_path = "LD_LIBRARY_PATH", + std::vector suffixes = {}, + std::vector fallbacks = {}); bool file_exists(const std::string& name); @@ -143,6 +152,9 @@ get_realpath(const std::string&); std::string get_cwd(); + +void +find_dyn_api_rt(); } // namespace //======================================================================================// @@ -154,36 +166,8 @@ get_cwd(); int main(int argc, char** argv) { -#if defined(DYNINST_API_RT) - auto _dyn_api_rt_paths = tim::delimit(DYNINST_API_RT, ":"); -#else - auto _dyn_api_rt_paths = std::vector{}; -#endif - auto _dyn_api_rt_abs = get_absolute_lib_filepath("libdyninstAPI_RT.so"); - _dyn_api_rt_paths.insert(_dyn_api_rt_paths.begin(), _dyn_api_rt_abs); - for(auto&& itr : _dyn_api_rt_paths) - { - auto _file_exists = [](const std::string& _fname) { - struct stat _buffer; - if(stat(_fname.c_str(), &_buffer) == 0) - return (S_ISREG(_buffer.st_mode) != 0 || S_ISLNK(_buffer.st_mode) != 0); - return false; - }; - if(_file_exists(itr)) - tim::set_env("DYNINSTAPI_RT_LIB", itr, 0); - else if(_file_exists(TIMEMORY_JOIN('/', itr, "libdyninstAPI_RT.so"))) - tim::set_env("DYNINSTAPI_RT_LIB", - TIMEMORY_JOIN('/', itr, "libdyninstAPI_RT.so"), 0); - else if(_file_exists(TIMEMORY_JOIN('/', itr, "libdyninstAPI_RT.a"))) - tim::set_env("DYNINSTAPI_RT_LIB", - TIMEMORY_JOIN('/', itr, "libdyninstAPI_RT.a"), 0); - } - verbprintf(0, "DYNINST_API_RT: %s\n", - tim::get_env("DYNINSTAPI_RT_LIB", "").c_str()); - argv0 = argv[0]; - bpatch = std::make_shared(); address_space_t* addr_space = nullptr; string_t mutname = {}; string_t outfile = {}; @@ -201,16 +185,6 @@ main(int argc, char** argv) { &overlapping_module_functions, false }, }; - bpatch->setTypeChecking(true); - bpatch->setSaveFPR(true); - bpatch->setDelayedParsing(true); - bpatch->setDebugParsing(false); - bpatch->setInstrStackFrames(false); - bpatch->setLivenessAnalysis(false); - bpatch->setBaseTrampDeletion(false); - bpatch->setTrampRecursive(false); - bpatch->setMergeTramp(true); - std::set dyninst_defs = { "TypeChecking", "SaveFPR", "DelayedParsing", "MergeTramp" }; @@ -733,7 +707,15 @@ main(int argc, char** argv) .count(1) .dtype("int") .action([](parser_t& p) { batch_size = p.get("batch-size"); }); - + parser.add_argument({ "--dyninst-rt" }, "Path(s) to the dyninstAPI_RT library") + .dtype("filepath") + .min_count(1) + .action([](parser_t& _p) { + auto _v = _p.get("dyninst-rt"); + std::copy(_dyn_api_rt_paths.begin(), _dyn_api_rt_paths.end(), + std::back_inserter(_v)); + std::swap(_dyn_api_rt_paths, _v); + }); parser .add_argument({ "--dyninst-options" }, "Advanced dyninst options: BPatch::set