From f190114ffaa835a7c3947fe0c9a0975cc4f52097 Mon Sep 17 00:00:00 2001 From: Alexey Klimkin Date: Mon, 19 Oct 2020 08:22:59 -0700 Subject: [PATCH 1/3] libelfin: reading ELF binaries and DWARFv4 debug information C++11 library for reading ELF binaries and DWARFv4 debug information. --- recipes/libelfin/all/CMakeLists.txt | 76 ++++++++ recipes/libelfin/all/conandata.yml | 8 + recipes/libelfin/all/conanfile.py | 61 +++++++ ...de57e5caef8297b9339f3a7971401d540840.patch | 165 ++++++++++++++++++ .../libelfin/all/test_package/CMakeLists.txt | 13 ++ recipes/libelfin/all/test_package/Makefile | 5 + .../libelfin/all/test_package/conanfile.py | 19 ++ recipes/libelfin/all/test_package/hello | Bin 0 -> 8468 bytes recipes/libelfin/all/test_package/hello.asm | 16 ++ .../all/test_package/test_package.cpp | 29 +++ recipes/libelfin/config.yml | 3 + 11 files changed, 395 insertions(+) create mode 100644 recipes/libelfin/all/CMakeLists.txt create mode 100644 recipes/libelfin/all/conandata.yml create mode 100644 recipes/libelfin/all/conanfile.py create mode 100644 recipes/libelfin/all/patches/946dde57e5caef8297b9339f3a7971401d540840.patch create mode 100644 recipes/libelfin/all/test_package/CMakeLists.txt create mode 100644 recipes/libelfin/all/test_package/Makefile create mode 100644 recipes/libelfin/all/test_package/conanfile.py create mode 100644 recipes/libelfin/all/test_package/hello create mode 100644 recipes/libelfin/all/test_package/hello.asm create mode 100644 recipes/libelfin/all/test_package/test_package.cpp create mode 100644 recipes/libelfin/config.yml diff --git a/recipes/libelfin/all/CMakeLists.txt b/recipes/libelfin/all/CMakeLists.txt new file mode 100644 index 0000000000000..6b56d28ca292c --- /dev/null +++ b/recipes/libelfin/all/CMakeLists.txt @@ -0,0 +1,76 @@ +cmake_minimum_required(VERSION 3.1) +project(libelfin CXX) + +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup() + +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 11) +endif() +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(PythonInterp 3 REQUIRED) + +file(GLOB_RECURSE elf_sources source_subfolder/elf/*.cc) +set(elf_headers + source_subfolder/elf/common.hh + source_subfolder/elf/data.hh + source_subfolder/elf/elf++.hh) +file(GLOB_RECURSE dwarf_sources source_subfolder/dwarf/*.cc) +set(dwarf_headers + source_subfolder/dwarf/data.hh + source_subfolder/dwarf/dwarf++.hh + source_subfolder/dwarf/small_vector.hh) + +add_custom_command( + OUTPUT source_subfolder/elf/to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo '// Automatically generated' > to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo '// DO NOT EDIT' >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo '\#include \"data.hh\"' >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo '\#include \"to_hex.hh\"' >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo 'ELFPP_BEGIN_NAMESPACE' >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo >> to_string.cc + COMMAND ${PYTHON_EXECUTABLE} enum-print.py -u --hex --no-type --mask shf --mask pf -x loos -x hios -x loproc -x hiproc < data.hh >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo 'ELFPP_END_NAMESPACE' >> to_string.cc + DEPENDS source_subfolder/elf/enum-print.py source_subfolder/elf/data.hh + WORKING_DIRECTORY source_subfolder/elf) + +add_custom_command( + OUTPUT source_subfolder/dwarf/to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo '// Automatically generated' > to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo '// DO NOT EDIT' >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo '\#include \"internal.hh\"' >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo 'DWARFPP_BEGIN_NAMESPACE' >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo >> to_string.cc + COMMAND ${PYTHON_EXECUTABLE} ../elf/enum-print.py < dwarf++.hh >> to_string.cc + COMMAND ${PYTHON_EXECUTABLE} ../elf/enum-print.py -s _ -u --hex -x hi_user -x lo_user < data.hh >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo 'DWARFPP_END_NAMESPACE' >> to_string.cc + DEPENDS source_subfolder/elf/enum-print.py source_subfolder/dwarf/data.hh + WORKING_DIRECTORY source_subfolder/dwarf) + +add_library(elf++ ${elf_sources} source_subfolder/elf/to_string.cc) +set_target_properties(elf++ PROPERTIES + PUBLIC_HEADER "${elf_headers}" + VERSION ${CONAN_PACKAGE_VERSION}) + +add_library(dwarf++ ${dwarf_sources} source_subfolder/dwarf/to_string.cc) +set_target_properties(dwarf++ PROPERTIES + PUBLIC_HEADER "${dwarf_headers}" + VERSION ${CONAN_PACKAGE_VERSION}) + +install(TARGETS elf++ + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin + PUBLIC_HEADER DESTINATION include/libelfin/elf) +install(TARGETS dwarf++ + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin + PUBLIC_HEADER DESTINATION include/libelfin/dwarf) + +install(FILES source_subfolder/LICENSE DESTINATION licenses) diff --git a/recipes/libelfin/all/conandata.yml b/recipes/libelfin/all/conandata.yml new file mode 100644 index 0000000000000..a6e44dd4a5c40 --- /dev/null +++ b/recipes/libelfin/all/conandata.yml @@ -0,0 +1,8 @@ +sources: + "0.3": + url: "https://github.com/aclements/libelfin/archive/v0.3.tar.gz" + sha256: "c338942b967582922b3514b54b93175ca9051a9668db92dd8ef619824d443ac7" +patches: + "0.3": + - patch_file: "patches/946dde57e5caef8297b9339f3a7971401d540840.patch" + base_path: "source_subfolder" diff --git a/recipes/libelfin/all/conanfile.py b/recipes/libelfin/all/conanfile.py new file mode 100644 index 0000000000000..06ade3b58d246 --- /dev/null +++ b/recipes/libelfin/all/conanfile.py @@ -0,0 +1,61 @@ +import os +from conans import ConanFile, CMake, tools +from conans.errors import ConanInvalidConfiguration + + +class LibelfinConan(ConanFile): + name = "libelfin" + description = "C++11 library for reading ELF binaries and DWARFv4 debug information" + url = "https://github.com/conan-io/conan-center-index" + homepage = "https://github.com/aclements/libelfin" + license = "MIT" + topics = ("conan", "elf", "dwarf", "libelfin") + + generators = "cmake" + settings = "os", "arch", "compiler", "build_type" + options = {"shared": [True, False], "fPIC": [True, False]} + default_options = {"shared": False, "fPIC": True} + + exports_sources = "CMakeLists.txt", "patches/*" + + _source_subfolder = "source_subfolder" + _cmake = None + + def _configure_cmake(self): + if self._cmake: + return self._cmake + self._cmake = CMake(self) + self._cmake.configure() + return self._cmake + + def config_options(self): + if self.settings.os == "Windows": + del self.options.fPIC + + def configure(self): + if self.settings.compiler == "Visual Studio": + raise ConanInvalidConfiguration("libelfin doesn't support compiler: {} on OS: {}.". + format(self.settings.compiler, self.settings.os)) + if self.options.shared: + del self.options.fPIC + if self.settings.compiler.cppstd: + tools.check_min_cppstd(self, "11") + + def source(self): + tools.get(**self.conan_data["sources"][self.version]) + extracted_dir = self.name + "-" + self.version + os.rename(extracted_dir, self._source_subfolder) + + def build(self): + for patch in self.conan_data.get("patches", {}).get(self.version, []): + tools.patch(**patch) + cmake = self._configure_cmake() + if self.should_build: + cmake.build() + + def package(self): + cmake = self._configure_cmake() + cmake.install() + + def package_info(self): + self.cpp_info.libs = ["dwarf++", "elf++"] diff --git a/recipes/libelfin/all/patches/946dde57e5caef8297b9339f3a7971401d540840.patch b/recipes/libelfin/all/patches/946dde57e5caef8297b9339f3a7971401d540840.patch new file mode 100644 index 0000000000000..598b3be1c912d --- /dev/null +++ b/recipes/libelfin/all/patches/946dde57e5caef8297b9339f3a7971401d540840.patch @@ -0,0 +1,165 @@ +diff --git a/dwarf/abbrev.cc b/dwarf/abbrev.cc +index c780b8e..f77dc0c 100644 +--- a/dwarf/abbrev.cc ++++ b/dwarf/abbrev.cc +@@ -133,6 +133,10 @@ resolve_type(DW_AT name, DW_FORM form) + case DW_AT::ranges: + return value::type::rangelist; + ++ case DW_AT::lo_user...DW_AT::hi_user: ++ //HACK: ignore vendor extensions ++ return value::type::invalid; ++ + default: + throw format_error("DW_FORM_sec_offset not expected for attribute " + + to_string(name)); +diff --git a/dwarf/dwarf.cc b/dwarf/dwarf.cc +index fe9b947..2465eef 100644 +--- a/dwarf/dwarf.cc ++++ b/dwarf/dwarf.cc +@@ -289,8 +289,7 @@ compilation_unit::get_line_table() const + { + if (!m->lt.valid()) { + const die &d = root(); +- if (!d.has(DW_AT::stmt_list) || !d.has(DW_AT::name) || +- !d.has(DW_AT::comp_dir)) ++ if (!d.has(DW_AT::stmt_list) || !d.has(DW_AT::name)) + goto done; + + shared_ptr
sec; +@@ -300,8 +299,10 @@ compilation_unit::get_line_table() const + goto done; + } + ++ auto comp_dir = d.has(DW_AT::comp_dir) ? at_comp_dir(d) : ""; ++ + m->lt = line_table(sec, d[DW_AT::stmt_list].as_sec_offset(), +- m->subsec->addr_size, at_comp_dir(d), ++ m->subsec->addr_size, comp_dir, + at_name(d)); + } + done: +diff --git a/elf/elf++.hh b/elf/elf++.hh +index 562d1de..ee59ed0 100644 +--- a/elf/elf++.hh ++++ b/elf/elf++.hh +@@ -48,7 +48,7 @@ public: + * section data. Hence, callers must ensure that the loader passed to + * this file remains live as long as any such pointer is in use. + * Keeping any object that can return such a pointer live is +- * sufficieint to keep the loader live. ++ * sufficient to keep the loader live. + */ + class elf + { +@@ -204,7 +204,7 @@ public: + + /** + * Return the in-memory size of this segment in bytes. +- * Bytes between file_size() and mem_size() are implicity zeroes. ++ * Bytes between file_size() and mem_size() are implicitly zeroes. + */ + size_t mem_size() const; + +diff --git a/elf/elf.cc b/elf/elf.cc +index 587329f..61172ac 100644 +--- a/elf/elf.cc ++++ b/elf/elf.cc +@@ -167,12 +167,10 @@ elf::get_segment(unsigned index) const + + struct segment::impl { + impl(const elf &f) +- : f(f) { } ++ : f(f), data(nullptr) { } + + const elf f; + Phdr<> hdr; +- // const char *name; +- // size_t name_len; + const void *data; + }; + +diff --git a/elf/mmap_loader.cc b/elf/mmap_loader.cc +index 69d8acb..875d7bd 100644 +--- a/elf/mmap_loader.cc ++++ b/elf/mmap_loader.cc +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + +diff --git a/examples/dump-lines.cc b/examples/dump-lines.cc +index ec58be1..9fed1fa 100644 +--- a/examples/dump-lines.cc ++++ b/examples/dump-lines.cc +@@ -1,6 +1,7 @@ + #include "elf++.hh" + #include "dwarf++.hh" + ++#include + #include + #include + +diff --git a/examples/dump-sections.cc b/examples/dump-sections.cc +index 12e7569..22526ec 100644 +--- a/examples/dump-sections.cc ++++ b/examples/dump-sections.cc +@@ -2,6 +2,7 @@ + + #include + #include ++#include + #include + #include + +diff --git a/examples/dump-segments.cc b/examples/dump-segments.cc +index f9e07d3..4c6319f 100644 +--- a/examples/dump-segments.cc ++++ b/examples/dump-segments.cc +@@ -2,6 +2,7 @@ + + #include + #include ++#include + #include + #include + +diff --git a/examples/dump-syms.cc b/examples/dump-syms.cc +index e7c2c3b..af7f484 100644 +--- a/examples/dump-syms.cc ++++ b/examples/dump-syms.cc +@@ -2,6 +2,7 @@ + + #include + #include ++#include + #include + #include + +diff --git a/examples/dump-tree.cc b/examples/dump-tree.cc +index 57d2b70..8bf2a63 100644 +--- a/examples/dump-tree.cc ++++ b/examples/dump-tree.cc +@@ -1,6 +1,7 @@ + #include "elf++.hh" + #include "dwarf++.hh" + ++#include + #include + #include + +diff --git a/examples/find-pc.cc b/examples/find-pc.cc +index dc40b85..2e324fc 100644 +--- a/examples/find-pc.cc ++++ b/examples/find-pc.cc +@@ -1,6 +1,7 @@ + #include "elf++.hh" + #include "dwarf++.hh" + ++#include + #include + #include + #include diff --git a/recipes/libelfin/all/test_package/CMakeLists.txt b/recipes/libelfin/all/test_package/CMakeLists.txt new file mode 100644 index 0000000000000..70862c0071b9e --- /dev/null +++ b/recipes/libelfin/all/test_package/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.1) +project(test_package CXX) + +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup() + +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 11) +endif() +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +add_executable(${PROJECT_NAME} test_package.cpp) +target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS}) diff --git a/recipes/libelfin/all/test_package/Makefile b/recipes/libelfin/all/test_package/Makefile new file mode 100644 index 0000000000000..ccf962b53e8bc --- /dev/null +++ b/recipes/libelfin/all/test_package/Makefile @@ -0,0 +1,5 @@ +# From http://timelessname.com/elfbin/ + +hello: hello.asm + nasm -f elf hello.asm + gcc -m32 -s -o hello hello.o -nostartfiles -nostdlib -nodefaultlibs diff --git a/recipes/libelfin/all/test_package/conanfile.py b/recipes/libelfin/all/test_package/conanfile.py new file mode 100644 index 0000000000000..e2a48eb337ec0 --- /dev/null +++ b/recipes/libelfin/all/test_package/conanfile.py @@ -0,0 +1,19 @@ +from conans import ConanFile, CMake, tools +import os + + +class TestPackageConan(ConanFile): + settings = "os", "compiler", "build_type", "arch" + generators = "cmake" + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def test(self): + if tools.cross_building(self.settings): + return + bin_path = os.path.join("bin", "test_package") + elf_path = os.path.join(self.source_folder, "hello") + self.run("{} {}".format(bin_path, elf_path), run_environment=True) diff --git a/recipes/libelfin/all/test_package/hello b/recipes/libelfin/all/test_package/hello new file mode 100644 index 0000000000000000000000000000000000000000..7202f6f7d512e8c01b1232fcd5add1c235e17609 GIT binary patch literal 8468 zcmeI2u}T9$5QgW>MG|eavK_3FX3-GrEfkAjC8WOO781xAxLeT9djty~z{iN@8S+lf zf9IyM5p0Bi;Ady&ANJtu_I6%wCbvnFNQ?vNNV9uQdt)n3v~|X!<_x4OY3rk0r#Ce;!|&=XKC(e!S0iPR011!)36KB@kN^pg011!)36KB@{AU7pOP#LE zRemH73$OP+JS}st*Hz_<*~*tXau-+S{Bk7Xsznvbkj=ye{~W~SS;)lA*G1tU!*3WI zTQmMGH1GYG5wJIZ%m>7XBLJsXKwk$2W(BmJ6TlYH%p2HxWMi3 HfA0GNLVqe< literal 0 HcmV?d00001 diff --git a/recipes/libelfin/all/test_package/hello.asm b/recipes/libelfin/all/test_package/hello.asm new file mode 100644 index 0000000000000..0cc26b9d3a4a8 --- /dev/null +++ b/recipes/libelfin/all/test_package/hello.asm @@ -0,0 +1,16 @@ + SECTION .data +msg: db "Hi World",10 +len: equ $-msg + + SECTION .text + global main +main: + mov edx,len + mov ecx,msg + mov ebx,1 + mov eax,4 + int 0x80 + mov ebx,0 + mov eax,1 + int 0x80 + diff --git a/recipes/libelfin/all/test_package/test_package.cpp b/recipes/libelfin/all/test_package/test_package.cpp new file mode 100644 index 0000000000000..41843df23299f --- /dev/null +++ b/recipes/libelfin/all/test_package/test_package.cpp @@ -0,0 +1,29 @@ +#include +#include +#include +#include +#include + +int +main(int argc, char** argv) +{ + using elf::to_string; + + int fd = open(argv[1], O_RDONLY); + elf::elf f(elf::create_mmap_loader(fd)); + + auto& hdr = f.get_hdr(); + std::cout << "ELF Header:\n"; + std::cout << " Magic: " << std::hex; + for (auto c : hdr.ei_magic) + std::cout << ' ' << static_cast(c); + std::cout << '\n'; + std::cout << " Class: " << to_string(hdr.ei_class) << '\n'; + std::cout << " Data: " << to_string(hdr.ei_data) << '\n'; + std::cout << " Version: " << static_cast(hdr.ei_version) << '\n'; + std::cout << " OS/ABI: " << to_string(hdr.ei_osabi) << '\n'; + std::cout << " ABI Version: " << static_cast(hdr.ei_abiversion) << '\n'; + std::cout << " Type: " << to_string(hdr.type) << '\n'; + + return 0; +} diff --git a/recipes/libelfin/config.yml b/recipes/libelfin/config.yml new file mode 100644 index 0000000000000..1d91bf4e0169c --- /dev/null +++ b/recipes/libelfin/config.yml @@ -0,0 +1,3 @@ +versions: + "0.3": + folder: all From 3ad80188d9496d644df5f27a397c32fe89d60735 Mon Sep 17 00:00:00 2001 From: Alexey Klimkin Date: Wed, 28 Oct 2020 11:27:19 -0700 Subject: [PATCH 2/3] Apply suggestions from code review Co-authored-by: SpaceIm <30052553+SpaceIm@users.noreply.github.com> --- recipes/libelfin/all/conanfile.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/recipes/libelfin/all/conanfile.py b/recipes/libelfin/all/conanfile.py index 06ade3b58d246..a49fdbca76197 100644 --- a/recipes/libelfin/all/conanfile.py +++ b/recipes/libelfin/all/conanfile.py @@ -11,23 +11,16 @@ class LibelfinConan(ConanFile): license = "MIT" topics = ("conan", "elf", "dwarf", "libelfin") - generators = "cmake" settings = "os", "arch", "compiler", "build_type" options = {"shared": [True, False], "fPIC": [True, False]} default_options = {"shared": False, "fPIC": True} exports_sources = "CMakeLists.txt", "patches/*" + generators = "cmake" _source_subfolder = "source_subfolder" _cmake = None - def _configure_cmake(self): - if self._cmake: - return self._cmake - self._cmake = CMake(self) - self._cmake.configure() - return self._cmake - def config_options(self): if self.settings.os == "Windows": del self.options.fPIC @@ -46,16 +39,26 @@ def source(self): extracted_dir = self.name + "-" + self.version os.rename(extracted_dir, self._source_subfolder) + def _configure_cmake(self): + if self._cmake: + return self._cmake + self._cmake = CMake(self) + self._cmake.configure() + return self._cmake + def build(self): for patch in self.conan_data.get("patches", {}).get(self.version, []): tools.patch(**patch) cmake = self._configure_cmake() - if self.should_build: - cmake.build() + cmake.build() def package(self): cmake = self._configure_cmake() cmake.install() def package_info(self): - self.cpp_info.libs = ["dwarf++", "elf++"] + self.cpp_info.components["libelf++"].names["pkg_config"] = "libelf++" + self.cpp_info.components["libelf++"].libs = ["elf++"] + self.cpp_info.components["libdwarf++"].names["pkg_config"] = "libdwarf++" + self.cpp_info.components["libdwarf++"].libs = ["dwarf++"] + self.cpp_info.components["libdwarf++"].requires = ["libelf++"] From fbae9dfbbc801d4924b688a170e3afa60cefb0a3 Mon Sep 17 00:00:00 2001 From: Alexey Klimkin Date: Mon, 19 Oct 2020 18:00:02 -0700 Subject: [PATCH 3/3] coz: Causal profiler Coz is a new kind of profiler that unlocks optimization opportunities missed by traditional profilers. Coz employs a novel technique we call causal profiling that measures optimization potential. This measurement matches developers' assumptions about profilers: that optimizing highly-ranked code will have the greatest impact on performance. Causal profiling measures optimization potential for serial, parallel, and asynchronous programs without instrumentation of special handling for library calls and concurrency primitives. Instead, a causal profiler uses performance experiments to predict the effect of optimizations. This allows the profiler to establish causality: "optimizing function X will have effect Y," exactly the measurement developers had assumed they were getting all along. https://github.com/plasma-umass/coz --- recipes/coz/all/CMakeLists.txt | 33 ++++++++++++ recipes/coz/all/conandata.yml | 8 +++ recipes/coz/all/conanfile.py | 59 +++++++++++++++++++++ recipes/coz/all/patches/gettid.patch | 26 +++++++++ recipes/coz/all/test_package/CMakeLists.txt | 8 +++ recipes/coz/all/test_package/conanfile.py | 19 +++++++ recipes/coz/all/test_package/test_package.c | 11 ++++ recipes/coz/config.yml | 3 ++ 8 files changed, 167 insertions(+) create mode 100644 recipes/coz/all/CMakeLists.txt create mode 100644 recipes/coz/all/conandata.yml create mode 100644 recipes/coz/all/conanfile.py create mode 100644 recipes/coz/all/patches/gettid.patch create mode 100644 recipes/coz/all/test_package/CMakeLists.txt create mode 100644 recipes/coz/all/test_package/conanfile.py create mode 100644 recipes/coz/all/test_package/test_package.c create mode 100644 recipes/coz/config.yml diff --git a/recipes/coz/all/CMakeLists.txt b/recipes/coz/all/CMakeLists.txt new file mode 100644 index 0000000000000..8df7604461eab --- /dev/null +++ b/recipes/coz/all/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.1) +project(coz CXX) + +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup() + +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 11) +endif() +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Threads REQUIRED) + +file(GLOB_RECURSE sources source_subfolder/libcoz/*.cpp) +file(GLOB_RECURSE headers source_subfolder/include/*.h) + +add_library(${PROJECT_NAME} SHARED ${sources}) +set_target_properties(${PROJECT_NAME} PROPERTIES + PUBLIC_HEADER "${headers}" + VERSION ${CONAN_PACKAGE_VERSION}) +target_include_directories(${PROJECT_NAME} + PUBLIC source_subfolder/libcoz + PRIVATE source_subfolder/include) +target_link_libraries(${PROJECT_NAME} PUBLIC dl rt Threads::Threads elf++ dwarf++) + +install(TARGETS ${PROJECT_NAME} + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin + PUBLIC_HEADER DESTINATION include/${PROJECT_NAME}) + +install(PROGRAMS source_subfolder/coz DESTINATION bin) +install(FILES source_subfolder/LICENSE.md DESTINATION licenses) diff --git a/recipes/coz/all/conandata.yml b/recipes/coz/all/conandata.yml new file mode 100644 index 0000000000000..b9f978acac4ba --- /dev/null +++ b/recipes/coz/all/conandata.yml @@ -0,0 +1,8 @@ +sources: + "0.2.2": + url: "https://github.com/plasma-umass/coz/archive/0.2.2.tar.gz" + sha256: "5e671c5b7e2920e295d2da793e5eb4d60b36889fd86c9dc40cacfe0d3ec24d0f" +patches: + "0.2.2": + - patch_file: "patches/gettid.patch" + base_path: "source_subfolder" diff --git a/recipes/coz/all/conanfile.py b/recipes/coz/all/conanfile.py new file mode 100644 index 0000000000000..574eb59435003 --- /dev/null +++ b/recipes/coz/all/conanfile.py @@ -0,0 +1,59 @@ +import os +from conans import ConanFile, CMake, tools +from conans.errors import ConanInvalidConfiguration + + +class CozConan(ConanFile): + name = "coz" + description = "Causal profiler, uses performance experiments to predict the effect of optimizations" + url = "https://github.com/conan-io/conan-center-index" + homepage = "http://coz-profiler.org" + license = "BSD-2-Clause" + topics = ("conan", "coz", "profiler", "causal") + + settings = "os", "arch", "compiler", "build_type" + + requires = "libelfin/0.3" + exports_sources = "CMakeLists.txt", "patches/*" + generators = "cmake" + + _source_subfolder = "source_subfolder" + _cmake = None + + def config_options(self): + if self.settings.os == "Windows": + del self.options.fPIC + + def configure(self): + if self.settings.compiler == "Visual Studio": + raise ConanInvalidConfiguration("libelfin doesn't support compiler: {} on OS: {}.". + format(self.settings.compiler, self.settings.os)) + if self.settings.compiler.cppstd: + tools.check_min_cppstd(self, "11") + + def source(self): + tools.get(**self.conan_data["sources"][self.version]) + extracted_dir = self.name + "-" + self.version + os.rename(extracted_dir, self._source_subfolder) + + def _configure_cmake(self): + if self._cmake: + return self._cmake + self._cmake = CMake(self) + self._cmake.configure() + return self._cmake + + def build(self): + for patch in self.conan_data.get("patches", {}).get(self.version, []): + tools.patch(**patch) + cmake = self._configure_cmake() + cmake.build() + + def package(self): + cmake = self._configure_cmake() + cmake.install() + + def package_info(self): + self.cpp_info.names["cmake_find_package"] = "Coz" + if self.settings.os != "Windows": + self.cpp_info.system_libs = ["-Wl,--push-state,--no-as-needed", "-ldl", "-Wl,--pop-state"] diff --git a/recipes/coz/all/patches/gettid.patch b/recipes/coz/all/patches/gettid.patch new file mode 100644 index 0000000000000..fbcd3742a42de --- /dev/null +++ b/recipes/coz/all/patches/gettid.patch @@ -0,0 +1,26 @@ +commit 040144656146014d1ae356f73af96fefda1a3090 +Author: pmcgleenon +Date: Fri Oct 9 12:42:55 2020 +0100 + + Fixed issue with gettid() not available with glibc < 2.30. + + In that case use the syscall interface directly + + https://stackoverflow.com/questions/30680550/c-gettid-was-not-declared-in-this-scope + +diff --git a/libcoz/perf.h b/libcoz/perf.h +index 88f26cf..4ad60f8 100644 +--- a/libcoz/perf.h ++++ b/libcoz/perf.h +@@ -18,6 +18,11 @@ + #include "ccutil/log.h" + #include "ccutil/wrapped_array.h" + ++#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 30 ++#include ++#define gettid() syscall(SYS_gettid) ++#endif ++ + // Workaround for missing hw_breakpoint.h include file: + // This include file just defines constants used to configure watchpoint registers. + // This will be constant across x86 systems. diff --git a/recipes/coz/all/test_package/CMakeLists.txt b/recipes/coz/all/test_package/CMakeLists.txt new file mode 100644 index 0000000000000..7b9b613cbb24a --- /dev/null +++ b/recipes/coz/all/test_package/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.1) +project(test_package C) + +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup() + +add_executable(${PROJECT_NAME} test_package.c) +target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS}) diff --git a/recipes/coz/all/test_package/conanfile.py b/recipes/coz/all/test_package/conanfile.py new file mode 100644 index 0000000000000..6c11f187d4d09 --- /dev/null +++ b/recipes/coz/all/test_package/conanfile.py @@ -0,0 +1,19 @@ +from conans import ConanFile, CMake, tools +import os + + +class TestPackageConan(ConanFile): + settings = "os", "compiler", "build_type", "arch" + generators = "cmake" + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def test(self): + if tools.cross_building(self.settings): + return + bin_path = os.path.join("bin", "test_package") + self.run("coz run --- " + bin_path, run_environment=True) + print(open("profile.coz").read()) diff --git a/recipes/coz/all/test_package/test_package.c b/recipes/coz/all/test_package/test_package.c new file mode 100644 index 0000000000000..a1213a1bfe7b4 --- /dev/null +++ b/recipes/coz/all/test_package/test_package.c @@ -0,0 +1,11 @@ +#include +#include + +int +main(int argc, char **argv) +{ + COZ_PROGRESS_NAMED("something"); + printf("Hello, Coz!\n"); + + return 0; +} diff --git a/recipes/coz/config.yml b/recipes/coz/config.yml new file mode 100644 index 0000000000000..3ef51590ecf2d --- /dev/null +++ b/recipes/coz/config.yml @@ -0,0 +1,3 @@ +versions: + "0.2.2": + folder: "all"