cmake_minimum_required(VERSION 2.8) project(CN24 C CXX) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Build type: Select either Debug, RelWithDebInfo or Release" FORCE) endif() enable_testing() set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") # Get Git SHA1 hash include(GetGitRevisionDescription) get_git_head_revision(GIT_REFSPEC GIT_SHA1) #git_describe(GIT_SHA1) add_definitions("-DGIT_SHA1=\"${GIT_SHA1} ${GIT_REFSPEC}\"") # Definitions set(CN24_SRC "${CN24_SOURCE_DIR}/src") set(CN24_INC "${CN24_SOURCE_DIR}/include" "${CN24_SOURCE_DIR}/include/cn24" "${CN24_SOURCE_DIR}/include/cn24/util" "${CN24_SOURCE_DIR}/include/cn24/net" "${CN24_SOURCE_DIR}/include/cn24/math" "${CN24_SOURCE_DIR}/include/cn24/factory" "${CN24_SOURCE_DIR}/include/private") SET(CN24_TES "${CN24_SOURCE_DIR}/tests") set(CN24_TOO "${CN24_SOURCE_DIR}/tools") set(CN24_BSH "${CN24_SOURCE_DIR}/scripts") set(CN24_KER "${CN24_SOURCE_DIR}/kernels") set(CN24_LIBS "") if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8) message(FATAL_ERROR "CN24 needs a 64-bit system!") endif() macro (currentdate RESULT) if (WIN32) EXECUTE_PROCESS(COMMAND "cmd" " /C date /T" OUTPUT_VARIABLE ${RESULT}) string(REGEX REPLACE "(..)/(..)/..(..).*" "\\1/\\2/\\3" ${RESULT} ${${RESULT}}) string(REGEX REPLACE "\n" "" ${RESULT} ${${RESULT}}) elseif(UNIX) EXECUTE_PROCESS(COMMAND "date" "+%d/%m/%Y" OUTPUT_VARIABLE ${RESULT}) string(REGEX REPLACE "(..)/(..)/..(..).*" "\\1/\\2/\\3" ${RESULT} ${${RESULT}}) else (WIN32) message(SEND_ERROR "date not implemented") set(${RESULT} 000000) endif (WIN32) endmacro (currentdate) if(CMAKE_COMPILER_IS_GNUCXX) # We need C++11 execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) if (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7) message(STATUS "This is the right compiler, using -std=c++11.") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") else() message(WARNING "Your version of GCC doesn't support the -std=c++11 flag.") message(WARNING "Using -std=c++0x at your own risk!") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic -Wall -Wextra") elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL Clang) message(STATUS "This is the right compiler, using -std=c++11.") if(APPLE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lc++") else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") endif() elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC) message(STATUS "This is the right compiler, no switches needed") else() message(WARNING "This compiler is not yet supported by CN24.") message(WARNING "Let's hope it understands GCC-like arguments...") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") endif() # Profiling option set(CN24_PROFILE OFF CACHE BOOL "Build with profiling flag") if(CN24_PROFILE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") endif() set(CN24_TENSORDEBUG OFF CACHE BOOL "Debug Tensor offset") if(CN24_TENSORDEBUG) add_definitions("-DTENSORDEBUG") endif() set(CN24_LAYERTIME OFF CACHE BOOL "Debug layer time") if(CN24_LAYERTIME) add_definitions("-DLAYERTIME") endif() set(CN24_LAYERVIEW OFF CACHE BOOL "Debug layer view") if(CN24_LAYERVIEW) add_definitions("-DLAYERVIEW") endif() # Save the date for versioning currentdate(CN24_DATE) add_definitions("-DBUILD_DATE=\"${CN24_DATE}\"") # Tell CN24 the operating system if(WIN32) add_definitions("-DBUILD_WIN32") else() if(APPLE) add_definitions("-DBUILD_OSX") add_definitions("-DBUILD_POSIX") else() if(UNIX) add_definitions("-DBUILD_LINUX") add_definitions("-DBUILD_POSIX") else() message(STATUS "Unsupported OS, good luck!") endif() endif() endif() # The library comes first # Recurse over files file(GLOB_RECURSE CN24_SOURCES ${CN24_SRC}/*.cpp) file(GLOB_RECURSE CN24_HEADERS ${CN24_INC}/*.h) set(CN24_VERBOSE OFF CACHE BOOL "Enable CN24 verbose debug output") if(CN24_VERBOSE) add_definitions("-DBUILD_VERBOSE") message("Verbose output enabled") endif() set(CN24_FORCE_BOOST OFF CACHE BOOL "Build CN24 with Boost::Xpressive support even if std::regex is supported") if(CMAKE_COMPILER_IS_GNUCXX) # We need GCC >= 4.9 for std::regex execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) if (GCC_VERSION VERSION_GREATER 4.9 OR GCC_VERSION VERSION_EQUAL 4.9) message(STATUS "This is the right compiler, Boost not needed") set(CN24_BUILD_BOOST OFF) else() message(STATUS "GCC too old, Boost required") set(CN24_BUILD_BOOST ON) endif() elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL Clang) if(APPLE) message(STATUS "Clang on OS X detected, Boost not needed") set(CN24_BUILD_BOOST OFF) else() set(CN24_BUILD_BOOST ON) endif() else() message(STATUS "Unknown compiler, Boost required") set(CN24_BUILD_BOOST ON) endif() if(CN24_BUILD_BOOST OR CN24_FORCE_BOOST) # set(Boost_USE_STATIC_LIBS ON) # set(Boost_USE_MULTITHREADED ON) # set(Boost_USE_STATIC_RUNTIME OFF) find_package(Boost 1.35.1 COMPONENTS regex REQUIRED) if(Boost_FOUND) include_directories(${BOOST_INCLUDE_DIRS}) set(CN24_LIBS ${CN24_LIBS} ${Boost_LIBRARIES}) add_definitions("-DBUILD_BOOST") else() message(FATAL_ERROR "Boost not found!") endif() endif() set(CN24_BUILD_SQLITE3 OFF CACHE BOOL "Build CN24 with SQLITE3 logging support") if(CN24_BUILD_SQLITE3) include_directories("${CN24_SOURCE_DIR}/external/sqlite3") set(CN24_SOURCES ${CN24_SOURCES} "${CN24_SOURCE_DIR}/external/sqlite3/sqlite3.c") add_definitions("-DBUILD_SQLITE3") message(STATUS "Using integrated SQLite3") endif() include_directories(${CN24_INC}) if(${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC) add_library(cn24 STATIC ${CN24_SOURCES} ${CN24_HEADERS}) else() add_library(cn24 STATIC SHARED ${CN24_SOURCES} ${CN24_HEADERS}) endif() # And now for some dependencies set(CN24_BUILD_PNG ON CACHE BOOL "Build CN24 with libpng support") if(CN24_BUILD_PNG) set(CMAKE_FIND_FRAMEWORK "LAST") find_package(PNG) if(PNG_FOUND) include_directories(${PNG_INCLUDE_DIR}) set(CN24_LIBS ${CN24_LIBS} ${PNG_LIBRARY}) add_definitions("-DBUILD_PNG") else() message(STATUS "libpng not found!") endif() endif() set(CN24_BUILD_JPG ON CACHE BOOL "Build CN24 with libjpeg support") if(CN24_BUILD_JPG) find_package(JPEG) if(JPEG_FOUND) include_directories(${JPEG_INCLUDE_DIR}) set(CN24_LIBS ${CN24_LIBS} ${JPEG_LIBRARY}) add_definitions("-DBUILD_JPG") else() message(STATUS "libjpeg not found!") endif() endif() set(CN24_BUILD_ATLASBLAS OFF CACHE BOOL "Build CN24 with ATLAS BLAS support") if(CN24_BUILD_ATLASBLAS) find_library(BLAS_ATLAS NAMES atlas libatlas PATH_SUFFIXES atlas) find_library(BLAS_CBLAS NAMES ptcblas libptcblas cblas libcblas PATH_SUFFIXES atlas) set(BLAS_LIBRARIES ${BLAS_CBLAS} ${BLAS_ATLAS}) message(STATUS "Using BLAS: ${BLAS_LIBRARIES}") set(CN24_LIBS ${CN24_LIBS} ${BLAS_LIBRARIES}) add_definitions("-DBUILD_BLAS") add_definitions("-DBLAS_ATLAS") find_package(Threads REQUIRED) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") set(CN24_LIBS ${CN24_LIBS} ${CMAKE_THREAD_LIBS_INIT}) endif() set(CN24_BUILD_ACMLCBLAS OFF CACHE BOOL "Build CN24 with CBLAS/ACML support") if(CN24_BUILD_ACMLCBLAS) find_library(BLAS_ACML NAMES acml_mp libacml_mp) find_library(BLAS_CBLAS NAMES cblas_LINUX.a libcblas_LINUX.a cblas_LINUX libcblas_LINUX) set(BLAS_LIBRARIES ${BLAS_CBLAS} ${BLAS_ACML}) message(STATUS "Using BLAS: ${BLAS_LIBRARIES}") set(CN24_LIBS ${CN24_LIBS} ${BLAS_LIBRARIES}) add_definitions("-DBUILD_BLAS") add_definitions("-DBLAS_ACML") endif() set(CN24_BUILD_ACCELERATE OFF CACHE BOOL "Build CN24 with Accelerate BLAS support") if(CN24_BUILD_ACCELERATE) find_library(ACCELERATE_BLAS NAMES libBlas.dylib) find_path(ACCELERATE_INCLUDE_DIR Accelerate/Accelerate.h) message(STATUS "Using Accelerate BLAS: ${ACCELERATE_BLAS}") message(STATUS "Using Accelerate include directory: ${ACCELERATE_INCLUDE_DIR}") include_directories(${ACCELERATE_INCLUDE_DIR}) set(CN24_LIBS ${CN24_LIBS} ${ACCELERATE_BLAS}) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flax-vector-conversions") add_definitions("-DBUILD_BLAS") add_definitions("-DBLAS_ACCELERATE") endif() set(CN24_BUILD_OPENCL OFF CACHE BOOL "Build CN24 with OpenCL support") if(CN24_BUILD_OPENCL) find_library(OPENCL_ICDL NAMES OpenCL libOpenCL PATHS $ENV{CUDA_PATH}/lib/x64 $ENV{INTELOCLSDKROOT}/lib/x64 $ENV{AMDAPPSDKROOT}/lib/x86_64) find_path(OPENCL_INCLUDE_DIR CL/cl.h cl.h PATHS $ENV{CUDA_PATH}/include $ENV{INTELOCLSDKROOT}/include $ENV{AMDAPPSDKROOT}/include) message(STATUS "Using OpenCL library: ${OPENCL_ICDL}") message(STATUS "Using OpenCL include directory: ${OPENCL_INCLUDE_DIR}") include_directories(${OPENCL_INCLUDE_DIR}) set(CN24_LIBS ${CN24_LIBS} ${OPENCL_ICDL}) add_definitions("-DBUILD_OPENCL") else() message(STATUS "Enable OpenCL with -DCN24_BUILD_OPENCL:BOOL=ON to use your GPU") endif() set(CN24_BUILD_OPENCL_CLBLAS OFF CACHE BOOL "Build CN24 with OpenCL/clBLAS") if(CN24_BUILD_OPENCL_CLBLAS) if(CN24_BUILD_OPENCL) find_library(CLBLAS_LIBRARY clBLAS libclBLAS PATHS $ENV{AMDAPPSDKROOT}/lib64/import) find_path(CLBLAS_INCLUDE_DIR clBLAS.h PATHS $ENV{AMDAPPSDKROOT}/include) message(STATUS "Using OpenCL/clBLAS library: ${CLBLAS_LIBRARY}") message(STATUS "Using OpenCL/clBLAS include directory: ${CLBLAS_INCLUDE_DIR}") include_directories(${CLBLAS_INCLUDE_DIR}) set(CN24_LIBS ${CN24_LIBS} ${CLBLAS_LIBRARY}) add_definitions("-DBUILD_CLBLAS") else() message(STATUS "OpenCL needs to be enabled for clBLAS!") endif() endif() set(CN24_BUILD_OPENMP OFF CACHE BOOL "Build CN24 with OpenMP support if possible") if(CN24_BUILD_OPENMP) if(${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC) message(WARNING "OpenMP 3.0 is not supported by Visual Studio!") else() find_package(OpenMP) if(OPENMP_FOUND) message(STATUS "Using OpenMP") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") else() message(FATAL_ERROR "OpenMP not found!") endif() endif() else() message(STATUS "OpenMP disabled, disabling warnings with GCC") if(CMAKE_COMPILER_IS_GNUCXX) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-pragmas") endif() endif() set(CN24_BUILD_MKL OFF CACHE BOOL "Build CN24 with MKL support") if(CN24_BUILD_MKL) set(CN24_MKL_ROOT "~/intel/mkl" CACHE STRING "MKL root directory") set(CN24_MKL_LIBS ${CN24_MKL_ROOT}/lib/intel64) set(CN24_MKL_INCLUDE ${CN24_MKL_ROOT}/include) include_directories(${CN24_MKL_INCLUDE}) find_library(MKL_INTELLP64 NAMES mkl_intel_lp64 libmkl_intel_lp64 PATHS ${CN24_MKL_LIBS}) set(CN24_LIBS ${CN24_LIBS} ${MKL_INTELLP64}) find_library(MKL_CORE NAMES mkl_core libmkl_core PATHS ${CN24_MKL_LIBS}) set(CN24_LIBS ${CN24_LIBS} ${MKL_CORE}) if(CN24_BUILD_OPENMP) message(STATUS "Using OpenMP MKL") find_library(MKL_GNU_THREAD NAMES mkl_gnu_thread libmkl_gnu_thread PATHS ${CN24_MKL_LIBS}) set(CN24_LIBS ${CN24_LIBS} ${MKL_GNU_THREAD} dl) else() message(STATUS "Using sequential MKL") find_library(MKL_SEQUENTIAL NAMES mkl_sequential libmkl_sequential PATHS ${CN24_MKL_LIBS}) set(CN24_LIBS ${CN24_LIBS} ${MKL_SEQUENTIAL}) endif() find_package(Threads REQUIRED) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") set(CN24_LIBS ${CN24_LIBS} ${CMAKE_THREAD_LIBS_INIT} m) add_definitions("-DBUILD_BLAS") add_definitions("-DBLAS_MKL") endif() set(CN24_BUILD_GUI OFF CACHE BOOL "Build CN24 with GTK+ support") if(CN24_BUILD_GUI) find_package(PkgConfig) if(PKGCONFIG_FOUND) pkg_check_modules(GTK3 gtk+-3.0) if(GTK3_FOUND) include_directories(${GTK3_INCLUDE_DIRS}) link_directories(${GTK3_LIBRARY_DIRS}) add_definitions(${GTK3_CFLAGS}) add_definitions("-DBUILD_GUI") set(CN24_LIBS ${CN24_LIBS} ${GTK3_LIBRARIES}) message(STATUS "GTK3 found, building GUI") endif() endif() endif() # Link CN24 to libraries message(STATUS "Final links: ${CN24_LIBS}") target_link_libraries(cn24 ${CN24_LIBS}) # Tools # Recurse over files file(GLOB_RECURSE CN24_TOOL_SOURCES ${CN24_TOO}/*.cpp) foreach(TOOL_SOURCE ${CN24_TOOL_SOURCES}) get_filename_component(TOOL_NAME ${TOOL_SOURCE} NAME_WE) add_executable(${TOOL_NAME} ${TOOL_SOURCE}) target_link_libraries(${TOOL_NAME} cn24 ${CN24_LIBS}) message(STATUS "Added ${TOOL_NAME} tool.") endforeach() # Tests # Recurse over files file(GLOB_RECURSE CN24_TEST_SOURCES ${CN24_TES}/*.cpp) foreach(TEST_SOURCE ${CN24_TEST_SOURCES}) get_filename_component(TEST_NAME ${TEST_SOURCE} NAME_WE) add_executable(${TEST_NAME} ${TEST_SOURCE}) add_test(${TEST_NAME} ${TEST_NAME}) target_link_libraries(${TEST_NAME} cn24 ${CN24_LIBS}) message(STATUS "Added ${TEST_NAME} test.") endforeach() # Scripts #get_target_property(CN24_OUTPUT_DIR cn24 RUNTIME_OUTPUT_DIRECTORY) set(CN24_OUTPUT_DIR ${CMAKE_BINARY_DIR}) set(CN24_SCRIPT_DESTINATION ${CN24_OUTPUT_DIR}/) set(CN24_KERNEL_DESTINATION ${CN24_OUTPUT_DIR}/kernels) message(STATUS "Copying scripts to ${CN24_SCRIPT_DESTINATION}.") # Recurse over files file(GLOB_RECURSE CN24_BASH_SOURCES ${CN24_BSH}/*.sh) file(GLOB_RECURSE CN24_KERN_SOURCES ${CN24_KER}/*.cl) foreach(BASH_SOURCE ${CN24_BASH_SOURCES}) file(COPY ${BASH_SOURCE} DESTINATION ${CN24_SCRIPT_DESTINATION}) message(STATUS "Added ${BASH_SOURCE} script.") endforeach() foreach(KERN_SOURCE ${CN24_KERN_SOURCES}) file(COPY ${KERN_SOURCE} DESTINATION ${CN24_KERNEL_DESTINATION}) message(STATUS "Added ${KERN_SOURCE} kernel.") endforeach()