From f275d3dbbccd2ec0f987a96ef64ac076691826f4 Mon Sep 17 00:00:00 2001 From: Brenden Blanco Date: Mon, 6 Jul 2015 23:41:23 -0700 Subject: [PATCH] Add multiple build support styles * Add RPM and DEB packaging targets (using CPack from CMake) to build binary packages for Fedora and Ubuntu targets. * Add Docker build scripts for each of the above that run the build in the right environment (assuming docker is available). - In Ubuntu, build against the LLVM 3.7 nightly snapshots - In Fedora, build against LLVM 3.7 from git (takes longer) * Depending on packages installed on the build machine, it may be possible to cross-package for other targets without invoking Docker. * Re-introduce src/cc/compat directory to keep the build stable for the time being. Similarly, it was necessary to #define some ugly constants that should eventually show up in libc. * Add a few simple version checks to allow a partially working (really tracing only) libbcc in 4.1 kernels. TODO (followup commit): Re-work the READMEs Signed-off-by: Brenden Blanco --- .dockerignore | 3 + CMakeLists.txt | 20 ++- Dockerfile.fedora | 21 +++ Dockerfile.ubuntu | 19 +++ scripts/CMakeLists.txt | 18 +- scripts/bpf_demo.ks.erb | 1 - src/cc/CMakeLists.txt | 2 + src/cc/b_frontend_action.cc | 3 + src/cc/compat/linux/bpf.h | 274 +++++++++++++++++++++++++++++++ src/cc/compat/linux/bpf_common.h | 55 +++++++ src/cc/export/helpers.h | 2 + src/cc/libbpf.c | 18 ++ src/python/CMakeLists.txt | 6 +- src/python/bpf/__init__.py | 35 ++-- src/python/setup.py.in | 8 +- 15 files changed, 453 insertions(+), 32 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile.fedora create mode 100644 Dockerfile.ubuntu create mode 100644 src/cc/compat/linux/bpf.h create mode 100644 src/cc/compat/linux/bpf_common.h diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000000..d963b7ea70ad --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +Dockerfile* +build +.*.swp diff --git a/CMakeLists.txt b/CMakeLists.txt index c5a268c6e531..7d3b0abf5138 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,8 +2,8 @@ # Licensed under the Apache License, Version 2.0 (the "License") cmake_minimum_required(VERSION 2.8.7) -project(bpf-tools) -set(CMAKE_BUILD_TYPE Debug) +project(bcc) +set(CMAKE_BUILD_TYPE Release) enable_testing() @@ -21,7 +21,7 @@ message(STATUS "Found LLVM: ${LLVM_INCLUDE_DIRS}") # clang is linked as a library, but the library path searching is # primitively supported, unlike libLLVM -set(CLANG_SEARCH "/opt/local/llvm/lib;${LLVM_LIBRARY_DIRS}") +set(CLANG_SEARCH "/opt/local/llvm/lib;/usr/lib/llvm-3.7/lib;${LLVM_LIBRARY_DIRS}") find_library(libclangAnalysis NAMES clangAnalysis HINTS ${CLANG_SEARCH}) find_library(libclangAST NAMES clangAST HINTS ${CLANG_SEARCH}) find_library(libclangBasic NAMES clangBasic HINTS ${CLANG_SEARCH}) @@ -48,3 +48,17 @@ endif() add_subdirectory(scripts) add_subdirectory(src) add_subdirectory(tests) + +set(CPACK_PACKAGE_NAME "libbcc") +set(CPACK_PACKAGE_VERSION "${REVISION}") +set(CPACK_PACKAGE_CONTACT "Brenden Blanco + +RUN dnf -y install @rpm-development-tools @c-development @development-tools cmake libstdc++-static + +WORKDIR /root +RUN git clone https://github.com/llvm-mirror/llvm.git +RUN git clone https://github.com/llvm-mirror/clang.git llvm/tools/clang +RUN mkdir -p /root/llvm/build +WORKDIR /root/llvm/build +RUN cmake .. -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD="ARM;CppBackend;X86;BPF" +RUN make -j$(grep -c ^process /proc/cpuinfo) + +RUN mkdir -p /root/bcc/build +COPY ./ /root/bcc/ +WORKDIR /root/bcc/build +RUN cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_PREFIX_PATH=/root/llvm/build +RUN make -j$(grep -c ^process /proc/cpuinfo) package diff --git a/Dockerfile.ubuntu b/Dockerfile.ubuntu new file mode 100644 index 000000000000..6b3fbb572326 --- /dev/null +++ b/Dockerfile.ubuntu @@ -0,0 +1,19 @@ +# File to be used for building an Ubuntu .deb + +FROM ubuntu:trusty + +MAINTAINER Brenden Blanco + +RUN apt-get -y install wget +RUN printf "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty main\ndeb-src http://llvm.org/apt/trusty/ llvm-toolchain-trusty main\n" > /etc/apt/sources.list.d/llvm.list +RUN wget -q -O - http://llvm.org/apt/llvm-snapshot.gpg.key | apt-key add - +RUN apt-get -y update + +RUN apt-get -y install bison build-essential cmake flex git libedit-dev python zlib1g-dev +RUN apt-get -y install libllvm3.7 llvm-3.7-dev libclang-3.7-dev + +RUN mkdir -p /root/bcc/build +COPY ./ /root/bcc/ +WORKDIR /root/bcc/build +RUN cmake .. -DCMAKE_INSTALL_PREFIX=/usr +RUN make -j$(grep -c ^process /proc/cpuinfo) package diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index 6e13a7189c9c..2c12c5558e00 100644 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -5,15 +5,17 @@ string(SUBSTRING "${GIT_SHA1}" 0 8 GIT_SHA1_SHORT) git_describe(GIT_DESCRIPTION) git_describe(GIT_TAG_LAST "--abbrev=0") git_get_exact_tag(GIT_TAG_EXACT) -string(SUBSTRING "${GIT_TAG_LAST}-${GIT_SHA1_SHORT}" 1 -1 REVISION) -if(GIT_TAG_EXACT) - string(SUBSTRING "${GIT_TAG_EXACT}" 1 -1 REVISION) - message(STATUS "Currently on Git tag ${GIT_TAG_EXACT}") -else () - message(STATUS "Latest recognized Git tag is ${GIT_TAG_LAST}") - set(GIT_TAG_EXACT "") +if(NOT REVISION) + string(SUBSTRING "${GIT_TAG_LAST}-${GIT_SHA1_SHORT}" 1 -1 REVISION) + if(GIT_TAG_EXACT) + string(SUBSTRING "${GIT_TAG_EXACT}" 1 -1 REVISION) + message(STATUS "Currently on Git tag ${GIT_TAG_EXACT}") + else () + message(STATUS "Latest recognized Git tag is ${GIT_TAG_LAST}") + set(GIT_TAG_EXACT "") + endif() + message(STATUS "Git HEAD is ${GIT_SHA1}") endif() -message(STATUS "Git HEAD is ${GIT_SHA1}") # strip leading 'v', and make unique for the tag message(STATUS "Revision is ${REVISION}") diff --git a/scripts/bpf_demo.ks.erb b/scripts/bpf_demo.ks.erb index 7fd843d71585..a32f0b69b403 100644 --- a/scripts/bpf_demo.ks.erb +++ b/scripts/bpf_demo.ks.erb @@ -117,7 +117,6 @@ numcpu=$(grep -c ^processor /proc/cpuinfo) git clone https://github.com/iovisor/bcc.git mkdir bcc/build/ cd bcc/build/ -git checkout bblanco_dev export PATH=/opt/local/llvm/bin:$PATH cmake .. -DCMAKE_INSTALL_PREFIX=/usr make -j$numcpu diff --git a/src/cc/CMakeLists.txt b/src/cc/CMakeLists.txt index 351a26568f09..9f78c9580d4a 100644 --- a/src/cc/CMakeLists.txt +++ b/src/cc/CMakeLists.txt @@ -3,6 +3,8 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${LLVM_INCLUDE_DIRS}) +# todo: if check for kernel version +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/compat) add_definitions(${LLVM_DEFINITIONS}) BISON_TARGET(Parser parser.yy ${CMAKE_CURRENT_BINARY_DIR}/parser.yy.cc COMPILE_FLAGS "-o parser.yy.cc -v --debug") diff --git a/src/cc/b_frontend_action.cc b/src/cc/b_frontend_action.cc index f3180b8eda54..38c63fdb40df 100644 --- a/src/cc/b_frontend_action.cc +++ b/src/cc/b_frontend_action.cc @@ -14,6 +14,7 @@ * limitations under the License. */ #include +#include #include #include @@ -373,8 +374,10 @@ bool BTypeVisitor::VisitVarDecl(VarDecl *Decl) { map_type = BPF_MAP_TYPE_HASH; else if (A->getName() == "maps/array") map_type = BPF_MAP_TYPE_ARRAY; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,2,0) else if (A->getName() == "maps/prog") map_type = BPF_MAP_TYPE_PROG_ARRAY; +#endif table.fd = bpf_create_map(map_type, table.key_size, table.leaf_size, table.max_entries); if (table.fd < 0) { llvm::errs() << "error: could not open bpf fd\n"; diff --git a/src/cc/compat/linux/bpf.h b/src/cc/compat/linux/bpf.h new file mode 100644 index 000000000000..29ef6f99e43d --- /dev/null +++ b/src/cc/compat/linux/bpf.h @@ -0,0 +1,274 @@ +/* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + */ +#ifndef _UAPI__LINUX_BPF_H__ +#define _UAPI__LINUX_BPF_H__ + +#include +#include + +/* Extended instruction set based on top of classic BPF */ + +/* instruction classes */ +#define BPF_ALU64 0x07 /* alu mode in double word width */ + +/* ld/ldx fields */ +#define BPF_DW 0x18 /* double word */ +#define BPF_XADD 0xc0 /* exclusive add */ + +/* alu/jmp fields */ +#define BPF_MOV 0xb0 /* mov reg to reg */ +#define BPF_ARSH 0xc0 /* sign extending arithmetic shift right */ + +/* change endianness of a register */ +#define BPF_END 0xd0 /* flags for endianness conversion: */ +#define BPF_TO_LE 0x00 /* convert to little-endian */ +#define BPF_TO_BE 0x08 /* convert to big-endian */ +#define BPF_FROM_LE BPF_TO_LE +#define BPF_FROM_BE BPF_TO_BE + +#define BPF_JNE 0x50 /* jump != */ +#define BPF_JSGT 0x60 /* SGT is signed '>', GT in x86 */ +#define BPF_JSGE 0x70 /* SGE is signed '>=', GE in x86 */ +#define BPF_CALL 0x80 /* function call */ +#define BPF_EXIT 0x90 /* function return */ + +/* Register numbers */ +enum { + BPF_REG_0 = 0, + BPF_REG_1, + BPF_REG_2, + BPF_REG_3, + BPF_REG_4, + BPF_REG_5, + BPF_REG_6, + BPF_REG_7, + BPF_REG_8, + BPF_REG_9, + BPF_REG_10, + __MAX_BPF_REG, +}; + +/* BPF has 10 general purpose 64-bit registers and stack frame. */ +#define MAX_BPF_REG __MAX_BPF_REG + +struct bpf_insn { + __u8 code; /* opcode */ + __u8 dst_reg:4; /* dest register */ + __u8 src_reg:4; /* source register */ + __s16 off; /* signed offset */ + __s32 imm; /* signed immediate constant */ +}; + +/* BPF syscall commands */ +enum bpf_cmd { + /* create a map with given type and attributes + * fd = bpf(BPF_MAP_CREATE, union bpf_attr *, u32 size) + * returns fd or negative error + * map is deleted when fd is closed + */ + BPF_MAP_CREATE, + + /* lookup key in a given map + * err = bpf(BPF_MAP_LOOKUP_ELEM, union bpf_attr *attr, u32 size) + * Using attr->map_fd, attr->key, attr->value + * returns zero and stores found elem into value + * or negative error + */ + BPF_MAP_LOOKUP_ELEM, + + /* create or update key/value pair in a given map + * err = bpf(BPF_MAP_UPDATE_ELEM, union bpf_attr *attr, u32 size) + * Using attr->map_fd, attr->key, attr->value, attr->flags + * returns zero or negative error + */ + BPF_MAP_UPDATE_ELEM, + + /* find and delete elem by key in a given map + * err = bpf(BPF_MAP_DELETE_ELEM, union bpf_attr *attr, u32 size) + * Using attr->map_fd, attr->key + * returns zero or negative error + */ + BPF_MAP_DELETE_ELEM, + + /* lookup key in a given map and return next key + * err = bpf(BPF_MAP_GET_NEXT_KEY, union bpf_attr *attr, u32 size) + * Using attr->map_fd, attr->key, attr->next_key + * returns zero and stores next key or negative error + */ + BPF_MAP_GET_NEXT_KEY, + + /* verify and load eBPF program + * prog_fd = bpf(BPF_PROG_LOAD, union bpf_attr *attr, u32 size) + * Using attr->prog_type, attr->insns, attr->license + * returns fd or negative error + */ + BPF_PROG_LOAD, +}; + +enum bpf_map_type { + BPF_MAP_TYPE_UNSPEC, + BPF_MAP_TYPE_HASH, + BPF_MAP_TYPE_ARRAY, + BPF_MAP_TYPE_PROG_ARRAY, +}; + +enum bpf_prog_type { + BPF_PROG_TYPE_UNSPEC, + BPF_PROG_TYPE_SOCKET_FILTER, + BPF_PROG_TYPE_KPROBE, + BPF_PROG_TYPE_SCHED_CLS, + BPF_PROG_TYPE_SCHED_ACT, +}; + +#define BPF_PSEUDO_MAP_FD 1 + +/* flags for BPF_MAP_UPDATE_ELEM command */ +#define BPF_ANY 0 /* create new element or update existing */ +#define BPF_NOEXIST 1 /* create new element if it didn't exist */ +#define BPF_EXIST 2 /* update existing element */ + +union bpf_attr { + struct { /* anonymous struct used by BPF_MAP_CREATE command */ + __u32 map_type; /* one of enum bpf_map_type */ + __u32 key_size; /* size of key in bytes */ + __u32 value_size; /* size of value in bytes */ + __u32 max_entries; /* max number of entries in a map */ + }; + + struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */ + __u32 map_fd; + __aligned_u64 key; + union { + __aligned_u64 value; + __aligned_u64 next_key; + }; + __u64 flags; + }; + + struct { /* anonymous struct used by BPF_PROG_LOAD command */ + __u32 prog_type; /* one of enum bpf_prog_type */ + __u32 insn_cnt; + __aligned_u64 insns; + __aligned_u64 license; + __u32 log_level; /* verbosity level of verifier */ + __u32 log_size; /* size of user buffer */ + __aligned_u64 log_buf; /* user supplied buffer */ + __u32 kern_version; /* checked when prog_type=kprobe */ + }; +} __attribute__((aligned(8))); + +/* integer value in 'imm' field of BPF_CALL instruction selects which helper + * function eBPF program intends to call + */ +enum bpf_func_id { + BPF_FUNC_unspec, + BPF_FUNC_map_lookup_elem, /* void *map_lookup_elem(&map, &key) */ + BPF_FUNC_map_update_elem, /* int map_update_elem(&map, &key, &value, flags) */ + BPF_FUNC_map_delete_elem, /* int map_delete_elem(&map, &key) */ + BPF_FUNC_probe_read, /* int bpf_probe_read(void *dst, int size, void *src) */ + BPF_FUNC_ktime_get_ns, /* u64 bpf_ktime_get_ns(void) */ + BPF_FUNC_trace_printk, /* int bpf_trace_printk(const char *fmt, int fmt_size, ...) */ + BPF_FUNC_get_prandom_u32, /* u32 prandom_u32(void) */ + BPF_FUNC_get_smp_processor_id, /* u32 raw_smp_processor_id(void) */ + + /** + * skb_store_bytes(skb, offset, from, len, flags) - store bytes into packet + * @skb: pointer to skb + * @offset: offset within packet from skb->mac_header + * @from: pointer where to copy bytes from + * @len: number of bytes to store into packet + * @flags: bit 0 - if true, recompute skb->csum + * other bits - reserved + * Return: 0 on success + */ + BPF_FUNC_skb_store_bytes, + + /** + * l3_csum_replace(skb, offset, from, to, flags) - recompute IP checksum + * @skb: pointer to skb + * @offset: offset within packet where IP checksum is located + * @from: old value of header field + * @to: new value of header field + * @flags: bits 0-3 - size of header field + * other bits - reserved + * Return: 0 on success + */ + BPF_FUNC_l3_csum_replace, + + /** + * l4_csum_replace(skb, offset, from, to, flags) - recompute TCP/UDP checksum + * @skb: pointer to skb + * @offset: offset within packet where TCP/UDP checksum is located + * @from: old value of header field + * @to: new value of header field + * @flags: bits 0-3 - size of header field + * bit 4 - is pseudo header + * other bits - reserved + * Return: 0 on success + */ + BPF_FUNC_l4_csum_replace, + + /** + * bpf_tail_call(ctx, prog_array_map, index) - jump into another BPF program + * @ctx: context pointer passed to next program + * @prog_array_map: pointer to map which type is BPF_MAP_TYPE_PROG_ARRAY + * @index: index inside array that selects specific program to run + * Return: 0 on success + */ + BPF_FUNC_tail_call, + + /** + * bpf_clone_redirect(skb, ifindex, flags) - redirect to another netdev + * @skb: pointer to skb + * @ifindex: ifindex of the net device + * @flags: bit 0 - if set, redirect to ingress instead of egress + * other bits - reserved + * Return: 0 on success + */ + BPF_FUNC_clone_redirect, + + /** + * u64 bpf_get_current_pid_tgid(void) + * Return: current->tgid << 32 | current->pid + */ + BPF_FUNC_get_current_pid_tgid, + + /** + * u64 bpf_get_current_uid_gid(void) + * Return: current_gid << 32 | current_uid + */ + BPF_FUNC_get_current_uid_gid, + + /** + * bpf_get_current_comm(char *buf, int size_of_buf) + * stores current->comm into buf + * Return: 0 on success + */ + BPF_FUNC_get_current_comm, + __BPF_FUNC_MAX_ID, +}; + +/* user accessible mirror of in-kernel sk_buff. + * new fields can only be added to the end of this structure + */ +struct __sk_buff { + __u32 len; + __u32 pkt_type; + __u32 mark; + __u32 queue_mapping; + __u32 protocol; + __u32 vlan_present; + __u32 vlan_tci; + __u32 vlan_proto; + __u32 priority; + __u32 ingress_ifindex; + __u32 ifindex; + __u32 tc_index; + __u32 cb[5]; +}; + +#endif /* _UAPI__LINUX_BPF_H__ */ diff --git a/src/cc/compat/linux/bpf_common.h b/src/cc/compat/linux/bpf_common.h new file mode 100644 index 000000000000..a5c220e0828f --- /dev/null +++ b/src/cc/compat/linux/bpf_common.h @@ -0,0 +1,55 @@ +#ifndef _UAPI__LINUX_BPF_COMMON_H__ +#define _UAPI__LINUX_BPF_COMMON_H__ + +/* Instruction classes */ +#define BPF_CLASS(code) ((code) & 0x07) +#define BPF_LD 0x00 +#define BPF_LDX 0x01 +#define BPF_ST 0x02 +#define BPF_STX 0x03 +#define BPF_ALU 0x04 +#define BPF_JMP 0x05 +#define BPF_RET 0x06 +#define BPF_MISC 0x07 + +/* ld/ldx fields */ +#define BPF_SIZE(code) ((code) & 0x18) +#define BPF_W 0x00 +#define BPF_H 0x08 +#define BPF_B 0x10 +#define BPF_MODE(code) ((code) & 0xe0) +#define BPF_IMM 0x00 +#define BPF_ABS 0x20 +#define BPF_IND 0x40 +#define BPF_MEM 0x60 +#define BPF_LEN 0x80 +#define BPF_MSH 0xa0 + +/* alu/jmp fields */ +#define BPF_OP(code) ((code) & 0xf0) +#define BPF_ADD 0x00 +#define BPF_SUB 0x10 +#define BPF_MUL 0x20 +#define BPF_DIV 0x30 +#define BPF_OR 0x40 +#define BPF_AND 0x50 +#define BPF_LSH 0x60 +#define BPF_RSH 0x70 +#define BPF_NEG 0x80 +#define BPF_MOD 0x90 +#define BPF_XOR 0xa0 + +#define BPF_JA 0x00 +#define BPF_JEQ 0x10 +#define BPF_JGT 0x20 +#define BPF_JGE 0x30 +#define BPF_JSET 0x40 +#define BPF_SRC(code) ((code) & 0x08) +#define BPF_K 0x00 +#define BPF_X 0x08 + +#ifndef BPF_MAXINSNS +#define BPF_MAXINSNS 4096 +#endif + +#endif /* _UAPI__LINUX_BPF_COMMON_H__ */ diff --git a/src/cc/export/helpers.h b/src/cc/export/helpers.h index e5c8bc4496f7..0d5a76e77990 100644 --- a/src/cc/export/helpers.h +++ b/src/cc/export/helpers.h @@ -63,6 +63,7 @@ static u64 (*bpf_ktime_get_ns)(void) = static int (*bpf_trace_printk_)(const char *fmt, u64 fmt_size, ...) = (void *) BPF_FUNC_trace_printk; int bpf_trace_printk(const char *fmt, ...) asm("llvm.bpf.extra"); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,2,0) static u64 (*bpf_clone_redirect)(void *ctx, u64 ifindex, u64 flags) = (void *) BPF_FUNC_clone_redirect; static u64 (*bpf_get_smp_processor_id)(void) = @@ -76,6 +77,7 @@ static int (*bpf_get_current_comm)(void *buf, int buf_size) = static void bpf_tail_call_(u64 map_fd, void *ctx, int index) { ((void (*)(void *, u64, int))BPF_FUNC_tail_call)(ctx, map_fd, index); } +#endif /* llvm builtin functions that eBPF C program may use to * emit BPF_LD_ABS and BPF_LD_IND instructions diff --git a/src/cc/libbpf.c b/src/cc/libbpf.c index a011447a82ed..fe172efc55bd 100644 --- a/src/cc/libbpf.c +++ b/src/cc/libbpf.c @@ -34,6 +34,24 @@ #include "libbpf.h" +// TODO: remove these defines when linux-libc-dev exports them properly + +#ifndef __NR_bpf +#define __NR_bpf 321 +#endif + +#ifndef SO_ATTACH_BPF +#define SO_ATTACH_BPF 50 +#endif + +#ifndef PERF_EVENT_IOC_SET_BPF +#define PERF_EVENT_IOC_SET_BPF _IOW('$', 8, __u32) +#endif + +#ifndef PERF_FLAG_FD_CLOEXEC +#define PERF_FLAG_FD_CLOEXEC (1UL << 3) +#endif + static __u64 ptr_to_u64(void *ptr) { return (__u64) (unsigned long) ptr; diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index f62048e26231..fbe12ba984e0 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -16,5 +16,9 @@ add_custom_command(OUTPUT ${PIP_INSTALLABLE} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bpf/__init__.py ${CMAKE_CURRENT_BINARY_DIR}/setup.py ) add_custom_target(bpf_py ALL DEPENDS ${PIP_INSTALLABLE}) -install(CODE "execute_process(COMMAND python setup.py install -f + +if(EXISTS "/etc/debian_version") + set(PYTHON_FLAGS "${PYTHON_FLAGS} --install-layout deb") +endif() +install(CODE "execute_process(COMMAND python setup.py install -f ${PYTHON_FLAGS} --prefix=${CMAKE_INSTALL_PREFIX} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})") diff --git a/src/python/bpf/__init__.py b/src/python/bpf/__init__.py index 729b0dac1b23..691258bf9c6c 100644 --- a/src/python/bpf/__init__.py +++ b/src/python/bpf/__init__.py @@ -16,8 +16,9 @@ from collections import MutableMapping import ctypes as ct import json -from past.builtins import basestring import os +import sys +basestring = (unicode if sys.version_info[0] < 3 else str) lib = ct.CDLL("libbpfprog.so") @@ -187,22 +188,22 @@ def load_func(self, func_name, prog_type): return fn str2ctype = { - "_Bool": ct.c_bool, - "char": ct.c_char, - "wchar_t": ct.c_wchar, - "char": ct.c_byte, - "unsigned char": ct.c_ubyte, - "short": ct.c_short, - "unsigned short": ct.c_ushort, - "int": ct.c_int, - "unsigned int": ct.c_uint, - "long": ct.c_long, - "unsigned long": ct.c_ulong, - "long long": ct.c_longlong, - "unsigned long long": ct.c_ulonglong, - "float": ct.c_float, - "double": ct.c_double, - "long double": ct.c_longdouble + u"_Bool": ct.c_bool, + u"char": ct.c_char, + u"wchar_t": ct.c_wchar, + u"char": ct.c_byte, + u"unsigned char": ct.c_ubyte, + u"short": ct.c_short, + u"unsigned short": ct.c_ushort, + u"int": ct.c_int, + u"unsigned int": ct.c_uint, + u"long": ct.c_long, + u"unsigned long": ct.c_ulong, + u"long long": ct.c_longlong, + u"unsigned long long": ct.c_ulonglong, + u"float": ct.c_float, + u"double": ct.c_double, + u"long double": ct.c_longdouble } @staticmethod def _decode_table_type(desc): diff --git a/src/python/setup.py.in b/src/python/setup.py.in index c1cc140107c1..64efbb71b461 100644 --- a/src/python/setup.py.in +++ b/src/python/setup.py.in @@ -1,6 +1,11 @@ # Copyright (c) PLUMgrid, Inc. # Licensed under the Apache License, Version 2.0 (the "License") from distutils.core import setup +import os +import sys + +if os.environ.get('DESTDIR'): + sys.argv += ['--root', os.environ['DESTDIR']] setup(name='bpf', version='@REVISION@', @@ -9,5 +14,4 @@ setup(name='bpf', author_email='bblanco@plumgrid.com', url='http://plumgrid.com', packages=['bpf'], - platforms=['Linux'], - install_requires=['future']) + platforms=['Linux'])