# Copyright (c) PLUMgrid, Inc.
# Licensed under the Apache License, Version 2.0 (the "License")
cmake_minimum_required(VERSION 2.8.7)

if (${CMAKE_VERSION} VERSION_EQUAL 3.12.0 OR ${CMAKE_VERSION} VERSION_GREATER 3.12.0)
  cmake_policy(SET CMP0074 NEW)
endif()

project(bcc)
if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE Release)
endif()

if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
  set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "path to install" FORCE)
endif()

enable_testing()

# populate submodules (libbpf)
if(NOT CMAKE_USE_LIBBPF_PACKAGE)
   if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/src/cc/libbpf/src)
	execute_process(COMMAND git submodule update --init --recursive
                  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
                  RESULT_VARIABLE UPDATE_RESULT)
  if(UPDATE_RESULT AND NOT UPDATE_RESULT EQUAL 0)
    message(WARNING "Failed to update submodule libbpf")
  endif()
   else()
	execute_process(COMMAND git diff --shortstat ${CMAKE_CURRENT_SOURCE_DIR}/src/cc/libbpf/
		OUTPUT_VARIABLE DIFF_STATUS)
	if("${DIFF_STATUS}" STREQUAL "")
		execute_process(COMMAND git submodule update --init --recursive
                    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
                    RESULT_VARIABLE UPDATE_RESULT)
  if(UPDATE_RESULT AND NOT UPDATE_RESULT EQUAL 0)
    message(WARNING "Failed to update submodule libbpf")
  endif()
	else()
		message(WARNING "submodule libbpf dirty, so no sync")
	endif()
   endif()
endif()

# It's possible to use other kernel headers with
# KERNEL_INCLUDE_DIRS build variable, like:
#  $ cd <kernel-dir>
#  $ make INSTALL_HDR_PATH=/tmp/headers headers_install
#  $ cd <bcc-dir>
#  $ cmake -DKERNEL_INCLUDE_DIRS=/tmp/headers/include/ ...
include_directories(${KERNEL_INCLUDE_DIRS})

option(ENABLE_NO_PIE "Build bcc-lua without PIE" ON)

include(cmake/GetGitRevisionDescription.cmake)
include(cmake/version.cmake)
include(CMakeDependentOption)
include(GNUInstallDirs)
include(CheckCXXCompilerFlag)
include(cmake/FindCompilerFlag.cmake)

option(ENABLE_LLVM_NATIVECODEGEN "Enable use of llvm nativecodegen module (needed by rw-engine)" ON)
option(ENABLE_RTTI "Enable compiling with real time type information" OFF)
option(ENABLE_LLVM_SHARED "Enable linking LLVM as a shared library" OFF)
option(ENABLE_CLANG_JIT "Enable Loading BPF through Clang Frontend" ON)
option(ENABLE_USDT "Enable User-level Statically Defined Tracing" ON)
option(ENABLE_EXAMPLES "Build examples" ON)
option(ENABLE_MAN "Build man pages" ON)
option(ENABLE_TESTS "Build tests" ON)
option(RUN_LUA_TESTS "Run lua tests" ON)
CMAKE_DEPENDENT_OPTION(ENABLE_CPP_API "Enable C++ API" ON "ENABLE_USDT" OFF)

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)

if (CMAKE_USE_LIBBPF_PACKAGE)
  find_package(LibBpf)
endif()

if(NOT PYTHON_ONLY)
find_package(LLVM REQUIRED CONFIG)
message(STATUS "Found LLVM: ${LLVM_INCLUDE_DIRS} ${LLVM_PACKAGE_VERSION} (Use LLVM_ROOT envronment variable for another version of LLVM)")

if(ENABLE_CLANG_JIT)
find_package(BISON)
find_package(FLEX)
find_package(LibElf REQUIRED)
find_package(LibDebuginfod)
if(CLANG_DIR)
  set(CMAKE_FIND_ROOT_PATH "${CLANG_DIR}")
  include_directories("${CLANG_DIR}/include")
endif()

# clang is linked as a library, but the library path searching is
# primitively supported, unlike libLLVM
set(CLANG_SEARCH "/opt/local/llvm/lib;/usr/lib/llvm-3.7/lib;${LLVM_LIBRARY_DIRS}")
find_library(libclangAnalysis NAMES clangAnalysis clang-cpp HINTS ${CLANG_SEARCH})
find_library(libclangAST NAMES clangAST clang-cpp HINTS ${CLANG_SEARCH})
find_library(libclangBasic NAMES clangBasic clang-cpp HINTS ${CLANG_SEARCH})
find_library(libclangCodeGen NAMES clangCodeGen clang-cpp HINTS ${CLANG_SEARCH})
find_library(libclangDriver NAMES clangDriver clang-cpp HINTS ${CLANG_SEARCH})
find_library(libclangEdit NAMES clangEdit clang-cpp HINTS ${CLANG_SEARCH})
find_library(libclangFrontend NAMES clangFrontend clang-cpp HINTS ${CLANG_SEARCH})
find_library(libclangLex NAMES clangLex clang-cpp HINTS ${CLANG_SEARCH})
find_library(libclangParse NAMES clangParse clang-cpp HINTS ${CLANG_SEARCH})
find_library(libclangRewrite NAMES clangRewrite clang-cpp HINTS ${CLANG_SEARCH})
find_library(libclangSema NAMES clangSema clang-cpp HINTS ${CLANG_SEARCH})
find_library(libclangSerialization NAMES clangSerialization clang-cpp HINTS ${CLANG_SEARCH})
find_library(libclangASTMatchers NAMES clangASTMatchers clang-cpp HINTS ${CLANG_SEARCH})
find_library(libclang-shared libclang-cpp.so HINTS ${CLANG_SEARCH})
if(libclangBasic STREQUAL "libclangBasic-NOTFOUND")
  message(FATAL_ERROR "Unable to find clang libraries")
endif()
FOREACH(DIR ${LLVM_INCLUDE_DIRS})
  include_directories("${DIR}/../tools/clang/include")
ENDFOREACH()
endif(ENABLE_CLANG_JIT)

# Set to a string path if system places kernel lib directory in
# non-default location.
if(NOT DEFINED BCC_KERNEL_MODULES_DIR)
  set(BCC_KERNEL_MODULES_DIR "/lib/modules")
endif()

if(NOT DEFINED BCC_PROG_TAG_DIR)
  set(BCC_PROG_TAG_DIR "/var/tmp/bcc")
endif()

# As reported in issue #735, GCC 6 has some behavioral problems when
# dealing with -isystem. Hence, skip the warning optimization
# altogether on that compiler.
option(USINGISYSTEM "using -isystem" ON)
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
if (USINGISYSTEM AND GCC_VERSION VERSION_LESS 6.0)
  # iterate over all available directories in LLVM_INCLUDE_DIRS to
  # generate a correctly tokenized list of parameters
  foreach(ONE_LLVM_INCLUDE_DIR ${LLVM_INCLUDE_DIRS})
    set(CXX_ISYSTEM_DIRS "${CXX_ISYSTEM_DIRS} -isystem ${ONE_LLVM_INCLUDE_DIR}")
  endforeach()
endif()

set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 14)

endif(NOT PYTHON_ONLY)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall ${CXX_ISYSTEM_DIRS}")

add_subdirectory(src)
add_subdirectory(introspection)
if(ENABLE_CLANG_JIT)
if(ENABLE_EXAMPLES)
add_subdirectory(examples)
endif(ENABLE_EXAMPLES)
if(ENABLE_MAN)
add_subdirectory(man)
endif(ENABLE_MAN)
if(ENABLE_TESTS)
add_subdirectory(tests)
endif(ENABLE_TESTS)
add_subdirectory(tools)
endif(ENABLE_CLANG_JIT)
