diff --git a/CMakeLists.txt b/CMakeLists.txt index c6a9bb3d6f..b8fc44f1b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,22 +75,37 @@ find_package(OpenSSL REQUIRED) find_package(BIND REQUIRED) find_package(BinPAC REQUIRED) +include_directories(BEFORE + ${PCAP_INCLUDE_DIR} + ${OpenSSL_INCLUDE_DIR} + ${BIND_INCLUDE_DIR} + ${BinPAC_INCLUDE_DIR} +) + +# Optional Dependencies + set(HAVE_LIBMAGIC false) find_package(LibMagic) if (LIBMAGIC_FOUND) set(HAVE_LIBMAGIC true) + include_directories(BEFORE ${LibMagic_INCLUDE_DIR}) + list(APPEND OPTLIBS ${LibMagic_LIBRARY}) endif () set(HAVE_LIBZ false) find_package(ZLIB) if (ZLIB_FOUND) set(HAVE_LIBZ true) + include_directories(BEFORE ${ZLIB_INCLUDE_DIR}) + list(APPEND OPTLIBS ${ZLIB_LIBRARY}) endif () set(USE_GEOIP false) find_package(LibGeoIP) if (LIBGEOIP_FOUND) set(USE_GEOIP true) + include_directories(BEFORE ${LibGeoIP_INCLUDE_DIR}) + list(APPEND OPTLIBS ${LibGeoIP_LIBRARY}) endif () set(USE_PERFTOOLS false) @@ -98,20 +113,11 @@ if (ENABLE_PERFTOOLS) find_package(GooglePerftools) if (GOOGLEPERFTOOLS_FOUND) set(USE_PERFTOOLS true) + include_directories(BEFORE ${GooglePerftools_INCLUDE_DIR}) + list(APPEND OPTLIBS ${GooglePerftools_LIBRARIES}) endif () endif () -include_directories(BEFORE - ${PCAP_INCLUDE_DIR} - ${OPENSSL_INCLUDE_DIR} - ${BIND_INCLUDE_DIR} - ${BinPAC_INCLUDE_DIR} - ${LibMagic_INCLUDE_DIR} - ${ZLIB_INCLUDE_DIR} - ${LibGeoIP_INCLUDE_DIR} - ${GooglePerftools_INCLUDE_DIR} -) - ## ## Configuration Checks/Tests ## @@ -148,6 +154,50 @@ if (INSTALL_AUXTOOLS) add_subdirectory(aux) endif () +## +## Packaging Setup +## + +include(SetPackageVersion) +SetPackageVersion(${VERSION}) +include(SetPackageGenerators) +include(SetPackageFileName) + +set(CPACK_PACKAGE_VENDOR "Lawrence Berkeley National Laboratory") +set(CPACK_PACKAGE_CONTACT "info@bro-ids.org") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY + "The Bro Network Intrusion Detection System") + +# CPack may enforce file name extensions for certain package generators +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/README + ${CMAKE_CURRENT_BINARY_DIR}/README.txt + COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/COPYING + ${CMAKE_CURRENT_BINARY_DIR}/COPYING.txt + COPYONLY) + +set(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_CURRENT_BINARY_DIR}/README.txt) +set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_BINARY_DIR}/COPYING.txt) +set(CPACK_RESOURCE_FILE_README ${CMAKE_CURRENT_BINARY_DIR}/README.txt) +set(CPACK_RESOURCE_FILE_WELCOME ${CMAKE_CURRENT_BINARY_DIR}/README.txt) + +if (APPLE) + # /usr prefix is hardcoded for PackageMaker generator, but that + # directory may not be ideal for OS X (it's tricky to remove + # packages installed there). So instead we rely on CMAKE_INSTALL_PREFIX + # and set the following variable to workaround the hardcoded /usr prefix + set(CPACK_PACKAGING_INSTALL_PREFIX "/") + set(CPACK_PACKAGE_DEFAULT_LOCATION ${CMAKE_INSTALL_PREFIX}) +elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") + # A prefix of /usr would follow Filesystem Hierarchy Standard. + # For RPM packaging by CPack, /usr should be a default, but + # CMAKE_INSTALL_PREFIX also needs to be set to /usr so that + # the default BROPATH is set right at build time + set(CPACK_RPM_PACKAGE_LICENSE "BSD") +endif () + +include(CPack) + ## ## Build Summary ## diff --git a/cmake/ChangeMacInstallNames.cmake b/cmake/ChangeMacInstallNames.cmake new file mode 100644 index 0000000000..1e7370d3e7 --- /dev/null +++ b/cmake/ChangeMacInstallNames.cmake @@ -0,0 +1,87 @@ +# Calling this macro with the name of a list variable will modify that +# list such that any third party libraries that do not come with a +# vanilla Mac OS X system will be replaced by an adjusted library that +# has an install_name relative to the location of any executable that +# links to it. +# +# Also, it will schedule the modified libraries for installation in a +# 'support_libs' subdirectory of the CMAKE_INSTALL_PREFIX. +# +# The case of third party libraries depending on other third party +# libraries is currently not handled by this macro. +# +# Ex. +# +# set(libs /usr/lib/libz.dylib +# /usr/lib/libssl.dylib +# /usr/local/lib/libmagic.dylib +# /usr/local/lib/libGeoIP.dylib +# /usr/local/lib/somestaticlib.a) +# +# include(ChangeMacInstallNames) +# ChangeMacInstallNames(libs) +# +# Should result in ${libs} containing: +# /usr/lib/libz.dylib +# /usr/lib/libssl.dylib +# ${CMAKE_BINARY_DIR}/darwin_support_libs/libmagic.dylib +# ${CMAKE_BINARY_DIR}/darwin_support_libs/libGeoIP.dylib +# /usr/local/lib/somestaticlib.a +# +# such that we can now do: +# +# add_executable(some_exe ${srcs}) +# target_link_libraries(some_exe ${libs}) +# +# Any binary packages created from such a build should be self-contained +# and provide working installs on vanilla OS X systems. + +macro(ChangeMacInstallNames libListVar) + if (APPLE) + find_program(INSTALL_NAME_TOOL install_name_tool) + + set(MAC_INSTALL_NAME_DEPS) + set(SUPPORT_BIN_DIR ${CMAKE_BINARY_DIR}/darwin_support_libs) + set(SUPPORT_INSTALL_DIR support_libs) + + file(MAKE_DIRECTORY ${SUPPORT_BIN_DIR}) + + foreach (_lib ${${libListVar}}) + # only care about install_name for shared libraries that are + # not shipped in Apple's vanilla OS X installs + string(REGEX MATCH ^/usr/lib/* apple_provided_lib ${_lib}) + string(REGEX MATCH dylib$ is_shared_lib ${_lib}) + + if (NOT apple_provided_lib AND is_shared_lib) + get_filename_component(_libname ${_lib} NAME) + set(_adjustedLib ${SUPPORT_BIN_DIR}/${_libname}) + set(_tmpLib + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_libname}) + + # make a tempory copy so we can adjust permissions + configure_file(${_lib} ${_tmpLib} COPYONLY) + + # copy to build directory with correct write permissions + file(COPY ${_tmpLib} + DESTINATION ${SUPPORT_BIN_DIR} + FILE_PERMISSIONS OWNER_READ OWNER_WRITE + GROUP_READ WORLD_READ) + + # remove the old library from the list provided as macro + # argument and add the new library with modified install_name + list(REMOVE_ITEM ${libListVar} ${_lib}) + list(APPEND ${libListVar} ${_adjustedLib}) + + # update the install target to install the third party libs + # with modified install_name + install(FILES ${_adjustedLib} + DESTINATION ${SUPPORT_INSTALL_DIR}) + + # perform the install_name change + execute_process(COMMAND install_name_tool -id + @executable_path/../${SUPPORT_INSTALL_DIR}/${_libname} + ${_adjustedLib}) + endif () + endforeach () + endif () +endmacro() diff --git a/cmake/FindOpenSSL.cmake b/cmake/FindOpenSSL.cmake new file mode 100644 index 0000000000..353961ffc7 --- /dev/null +++ b/cmake/FindOpenSSL.cmake @@ -0,0 +1,56 @@ +# - Try to find openssl include dirs and libraries +# +# Usage of this module as follows: +# +# find_package(OpenSSL) +# +# Variables used by this module, they can change the default behaviour and need +# to be set before calling find_package: +# +# OpenSSL_ROOT_DIR Set this variable to the root installation of +# openssl if the module has problems finding the +# proper installation path. +# +# Variables defined by this module: +# +# OpenSSL_FOUND System has openssl, include and library dirs found +# OpenSSL_INCLUDE_DIR The openssl include directories. +# OpenSSL_LIBRARIES The openssl libraries. +# OpenSSL_CYRPTO_LIBRARY The openssl crypto library. +# OpenSSL_SSL_LIBRARY The openssl ssl library. + +find_path(OpenSSL_ROOT_DIR + NAMES include/openssl/ssl.h +) + +find_path(OpenSSL_INCLUDE_DIR + NAMES openssl/ssl.h + HINTS ${OpenSSL_ROOT_DIR}/include +) + +find_library(OpenSSL_SSL_LIBRARY + NAMES ssl ssleay32 ssleay32MD + HINTS ${OpenSSL_ROOT_DIR}/lib +) + +find_library(OpenSSL_CRYPTO_LIBRARY + NAMES crypto + HINTS ${OpenSSL_ROOT_DIR}/lib +) + +set(OpenSSL_LIBRARIES ${OpenSSL_SSL_LIBRARY} ${OpenSSL_CRYPTO_LIBRARY} + CACHE STRING "OpenSSL SSL and crypto libraries" FORCE) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OpenSSL DEFAULT_MSG + OpenSSL_LIBRARIES + OpenSSL_INCLUDE_DIR +) + +mark_as_advanced( + OpenSSL_ROOT_DIR + OpenSSL_INCLUDE_DIR + OpenSSL_LIBRARIES + OpenSSL_CRYPTO_LIBRARY + OpenSSL_SSL_LIBRARY +) diff --git a/cmake/OSSpecific.cmake b/cmake/OSSpecific.cmake index f8709a24bf..568427e177 100644 --- a/cmake/OSSpecific.cmake +++ b/cmake/OSSpecific.cmake @@ -1,16 +1,16 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") + # alternate malloc is faster for FreeBSD, but needs more testing + # need to add way to set this from the command line set(USE_NMALLOC true) elseif (${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") - set(HAVE_OPENBSD true) set(USE_NMALLOC true) elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") set(HAVE_LINUX true) - # TODO: configure.in sets -I/${top_srcdir}/linux-include; necessary? - #include_directories(${CMAKE_SOURCE_DIR}/linux-include) + include_directories(BEFORE ${CMAKE_SOURCE_DIR}/linux-include) elseif (${CMAKE_SYSTEM_NAME} MATCHES "Solaris") set(SOCKET_LIBS nsl socket) diff --git a/cmake/OpenSSLTests.cmake b/cmake/OpenSSLTests.cmake index d8212ade43..e8dda34b41 100644 --- a/cmake/OpenSSLTests.cmake +++ b/cmake/OpenSSLTests.cmake @@ -1,6 +1,9 @@ include(CheckCSourceCompiles) include(CheckCXXSourceCompiles) +set(CMAKE_REQUIRED_LIBRARIES ${OpenSSL_LIBRARIES}) +set(CMAKE_REQUIRED_INCLUDES ${OpenSSL_INCLUDE_DIR}) + check_c_source_compiles(" #include int main() { return 0; } @@ -8,13 +11,13 @@ check_c_source_compiles(" if (NOT including_ssl_h_works) # On Red Hat we may need to include Kerberos header. - set(CMAKE_REQUIRED_INCLUDES "/usr/kerberos/include") + set(CMAKE_REQUIRED_INCLUDES ${OpenSSL_INCLUDE_DIR} /usr/kerberos/include) check_c_source_compiles(" #include #include int main() { return 0; } " NEED_KRB5_H) - unset(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_INCLUDES ${OpenSSL_INCLUDE_DIR}) if (NOT NEED_KRB5_H) message(FATAL_ERROR "OpenSSL test failure. See CmakeError.log for details.") @@ -26,7 +29,6 @@ endif () # check for OPENSSL_add_all_algorithms_conf function # and thus OpenSSL >= v0.9.7 -set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES}) check_c_source_compiles(" #include int main() { @@ -34,12 +36,11 @@ check_c_source_compiles(" return 0; } " openssl_greater_than_0_9_7) -unset(CMAKE_REQUIRED_LIBRARIES) + if (NOT openssl_greater_than_0_9_7) message(FATAL_ERROR "OpenSSL >= v0.9.7 required") endif () -set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES}) check_cxx_source_compiles(" #include int main() { @@ -66,4 +67,6 @@ if (NOT OPENSSL_D2I_X509_USES_CONST_CHAR) "Can't determine if openssl_d2i_x509() takes const char parameter") endif () endif () + +unset(CMAKE_REQUIRED_INCLUDES) unset(CMAKE_REQUIRED_LIBRARIES) diff --git a/cmake/SetPackageFileName.cmake b/cmake/SetPackageFileName.cmake new file mode 100644 index 0000000000..759f72ab82 --- /dev/null +++ b/cmake/SetPackageFileName.cmake @@ -0,0 +1,18 @@ +# Sets CPACK_PACKAGE_FILE name in the following format: +# +# --- +# +# The version must already be set in the VERSION variable + +set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${VERSION}") +set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-${CMAKE_SYSTEM_NAME}") +if (APPLE) + # Only Intel-based Macs are supported. CMAKE_SYSTEM_PROCESSOR may + # return the confusing 'i386' if running a 32-bit kernel, but chances + # are the binary is x86_64 (or more generally 'Intel') compatible. + set(arch "Intel") +else () + set (arch ${CMAKE_SYSTEM_PROCESSOR}) +endif () + +set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-${arch}") diff --git a/cmake/SetPackageGenerators.cmake b/cmake/SetPackageGenerators.cmake new file mode 100644 index 0000000000..489441cc83 --- /dev/null +++ b/cmake/SetPackageGenerators.cmake @@ -0,0 +1,22 @@ +# Sets the list of desired package types to be created by the make +# package target. A .tar.gz is always made, and depending on the +# operating system, more are added: +# +# Darwin - PackageMaker +# Linux - RPM if the platform has rpmbuild installed +# DEB is ommitted because CPack does not give enough +# control over how the package is created and lacks support +# for automatic dependency detection. +# +# +# CPACK_GENERATOR is set by this module + +set(CPACK_GENERATOR TGZ) +if (APPLE) + list(APPEND CPACK_GENERATOR PackageMaker) +elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") + find_program(RPMBUILD_EXE rpmbuild) + if (RPMBUILD_EXE) + set(CPACK_GENERATOR ${CPACK_GENERATOR} RPM) + endif () +endif () diff --git a/cmake/SetPackageVersion.cmake b/cmake/SetPackageVersion.cmake new file mode 100644 index 0000000000..19c9d404e3 --- /dev/null +++ b/cmake/SetPackageVersion.cmake @@ -0,0 +1,27 @@ +# Sets CPack version variables by splitting the first macro argument +# using "." as a delimiter. If the length of the split list is +# greater than 2, all remaining elements are tacked on to the patch +# level version. + +macro(SetPackageVersion _version) + string(REPLACE "." " " version_numbers ${_version}) + separate_arguments(version_numbers) + + list(GET version_numbers 0 CPACK_PACKAGE_VERSION_MAJOR) + list(REMOVE_AT version_numbers 0) + list(GET version_numbers 0 CPACK_PACKAGE_VERSION_MINOR) + list(REMOVE_AT version_numbers 0) + list(LENGTH version_numbers version_length) + + while (version_length GREATER 0) + list(GET version_numbers 0 patch_level) + if (CPACK_PACKAGE_VERSION_PATCH) + set(CPACK_PACKAGE_VERSION_PATCH + "${CPACK_PACKAGE_VERSION_PATCH}.${patch_level}") + else () + set(CPACK_PACKAGE_VERSION_PATCH ${patch_level}) + endif () + list(REMOVE_AT version_numbers 0) + list(LENGTH version_numbers version_length) + endwhile () +endmacro(SetPackageVersion) diff --git a/configure b/configure index 00730750c0..60ae763bb2 100755 --- a/configure +++ b/configure @@ -3,7 +3,7 @@ # the project's CMake scripts will recognize # check for `cmake` command -type -P cmake &>/dev/null || { +type cmake > /dev/null 2>&1 || { echo "\ This package requires CMake, please install it first, then you may use this configure script to access CMake equivalent functionality.\ @@ -19,7 +19,7 @@ Usage: $0 [OPTION]... [VAR=VALUE]... Installation Directories: --prefix=PREFIX installation directory [/usr/local/bro] - --datadir=PATH policy file installation directory + --datadir=DIR policy file installation subdirectory [PREFIX/share/bro] Optional Features: @@ -54,14 +54,14 @@ Usage: $0 [OPTION]... [VAR=VALUE]... " sourcedir=`dirname $0` -if [ "$sourcedir" == "." ]; then +if [ "$sourcedir" = "." ]; then sourcedir=`pwd` fi # set defaults builddir=build prefix=/usr/local/bro -datadir=$prefix/share/bro +datadir=share/bro debug=false release=false use_IPv6=false @@ -86,11 +86,6 @@ while [ $# -ne 0 ]; do builddir=$optarg ;; --prefix=*) - if [ "$datadir" == "${prefix}/share/bro" ]; then - # User has not explicitly set datadir, so re-root - # it to the chosen prefix - datadir=$optarg/share/bro - fi prefix=$optarg ;; --datadir=*) @@ -177,7 +172,9 @@ set(CMAKE_INSTALL_PREFIX $prefix CACHE STRING "installation directory" FORCE) set(DATADIR $datadir - CACHE STRING "installation directory for Bro policy files" FORCE) + CACHE STRING + "installation subdirectory (under PREFIX) for Bro policy files" + FORCE) ####################################################################### # Optional Features @@ -240,7 +237,7 @@ ${comment} CACHE STRING "Non-Standard install root" FORCE) EOF } -add_search_path_hint OPENSSL_ROOT_DIR ${openssl_root} +add_search_path_hint OpenSSL_ROOT_DIR ${openssl_root} add_search_path_hint BIND_ROOT_DIR ${bind_root} add_search_path_hint PCAP_ROOT_DIR ${pcap_root} add_search_path_hint BinPAC_ROOT_DIR ${binpac_root} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9e64046ad5..5cdf2dff66 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -348,21 +348,22 @@ set(bro_SRCS ${openssl_SRCS} ) -add_definitions(-DPOLICYDEST="${DATADIR}") +add_definitions(-DPOLICYDEST="${CMAKE_INSTALL_PREFIX}/${DATADIR}") add_executable(bro ${bro_SRCS}) -target_link_libraries(bro - m - ${BinPAC_LIBRARY} - ${PCAP_LIBRARY} - ${OPENSSL_LIBRARIES} - ${BIND_LIBRARY} - ${LibMagic_LIBRARY} - ${ZLIB_LIBRARIES} - ${LibGeoIP_LIBRARY} - ${GooglePerftools_LIBRARIES} +set(brolibs + ${BinPAC_LIBRARY} + ${PCAP_LIBRARY} + ${OpenSSL_LIBRARIES} + ${BIND_LIBRARY} + ${OPTLIBS} ) +include(ChangeMacInstallNames) +ChangeMacInstallNames(brolibs) + +target_link_libraries(bro ${brolibs}) + install(TARGETS bro DESTINATION bin) install(FILES ${INSTALL_BIF_OUTPUTS} DESTINATION ${DATADIR})