From 6d1944f2c33b8622ae751efbd3c23f8ddb4c2db6 Mon Sep 17 00:00:00 2001 From: Natsu Date: Fri, 19 Jul 2019 10:55:32 +0800 Subject: [PATCH] CMake improvement (#1115) * CMake improvement * Fix bugs * Fix typo * Propagate vulkan dependency * import vulkan * add config files, now exported target cmake should be able to find packages * Propagate no-rtti and no-exception * Provide a option to control rtti and exception in mobile platform * Make cmake clean * Resolve conflicts * Update CMake PIE is propagated by INTERFACE_POSITION_INDEPENDENT_CODE * Remove bad things --- CMakeLists.txt | 81 ++++----------------- benchmark/CMakeLists.txt | 10 --- benchmark/benchncnn.cpp | 1 - cmake/ncnnConfig.cmake.in | 16 ++++ src/CMakeLists.txt | 133 +++++++++++++++++++++++++++------- src/allocator.h | 2 +- src/modelbin.cpp | 4 + src/modelbin.h | 1 + tools/CMakeLists.txt | 5 -- tools/caffe/CMakeLists.txt | 10 ++- tools/onnx/CMakeLists.txt | 10 ++- tools/quantize/CMakeLists.txt | 7 +- 12 files changed, 158 insertions(+), 122 deletions(-) create mode 100644 cmake/ncnnConfig.cmake.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 3bbc70684..5d2a878c3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,17 +1,17 @@ if(CMAKE_TOOLCHAIN_FILE) -set(LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_BINARY_DIR} CACHE PATH "root for library output, set this to change where android libs are compiled to") -# get absolute path, but get_filename_component ABSOLUTE only refer with source dir, so find_file here :( -get_filename_component(CMAKE_TOOLCHAIN_FILE_NAME ${CMAKE_TOOLCHAIN_FILE} NAME) -find_file(CMAKE_TOOLCHAIN_FILE ${CMAKE_TOOLCHAIN_FILE_NAME} PATHS ${CMAKE_SOURCE_DIR} NO_DEFAULT_PATH) -message(STATUS "CMAKE_TOOLCHAIN_FILE = ${CMAKE_TOOLCHAIN_FILE}") + set(LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_BINARY_DIR} CACHE PATH "root for library output, set this to change where android libs are compiled to") + # get absolute path, but get_filename_component ABSOLUTE only refer with source dir, so find_file here :( + get_filename_component(CMAKE_TOOLCHAIN_FILE_NAME ${CMAKE_TOOLCHAIN_FILE} NAME) + find_file(CMAKE_TOOLCHAIN_FILE ${CMAKE_TOOLCHAIN_FILE_NAME} PATHS ${CMAKE_SOURCE_DIR} NO_DEFAULT_PATH) + message(STATUS "CMAKE_TOOLCHAIN_FILE = ${CMAKE_TOOLCHAIN_FILE}") endif() if(NOT DEFINED CMAKE_INSTALL_PREFIX) -set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "Installation Directory") + set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "Installation Directory") endif() message(STATUS "CMAKE_INSTALL_PREFIX = ${CMAKE_INSTALL_PREFIX}") -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.10) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE release CACHE STRING "Choose the type of build" FORCE) @@ -32,67 +32,16 @@ option(NCNN_VULKAN "vulkan compute support" OFF) option(NCNN_REQUANT "auto merge int8 quant and dequant" OFF) option(NCNN_AVX2 "optimize x86 platform with avx2" OFF) -if(NCNN_OPENMP) - find_package(OpenMP) - if(NOT TARGET OpenMP::OpenMP_CXX AND (OpenMP_CXX_FOUND OR OPENMP_FOUND)) - 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}") - endif() -endif() - -if(NCNN_VULKAN) - find_package(Vulkan REQUIRED) - include_directories(${Vulkan_INCLUDE_DIR}) -endif() - -if(WIN32) - add_definitions(-D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE) - add_definitions(-DNOMINMAX) +if(ANDROID OR IOS) + option(NCNN_DISABLE_RTTI "disable rtti" ON) else() - add_definitions(-Wall -Wextra -Wno-unused-function) - - add_definitions(-fPIC) - if(CMAKE_BUILD_TYPE MATCHES "(Release|RELEASE|release)") - if(NOT CMAKE_SYSTEM_NAME STREQUAL "Emscripten") - add_definitions(-Ofast) - endif() - - add_definitions(-ffast-math) - endif() - - if(PI3) - add_definitions(-march=native) - add_definitions(-mfpu=neon) - add_definitions(-mfloat-abi=hard) - add_definitions(-D__ARM_NEON) - add_definitions(-D__ANDROID__) - endif() - # add_definitions(-march=native) - # add_definitions(-flto) - add_definitions(-fvisibility=hidden -fvisibility-inlines-hidden) + option(NCNN_DISABLE_RTTI "disable rtti" OFF) endif() -if(ANDROID) - # disable shared library on android - set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions") -elseif(IOS) - # disable shared library on xcode ios - set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions") -elseif(NCNN_AVX2) - #set up according to your own system environment - #Windows - if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:AVX2 /DAVX2") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /arch:AVX2 /DAVX2") - #Linux - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfma") - endif() -elseif(LINUX) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-exceptions") +if(ANDROID OR IOS OR LINUX) + option(NCNN_DISABLE_EXCEPTION "disable exception" ON) +else() + option(NCNN_DISABLE_EXCEPTION "disable exception" OFF) endif() ############################################## @@ -101,5 +50,5 @@ endif() add_subdirectory(benchmark) add_subdirectory(src) if(NOT ANDROID AND NOT IOS) -add_subdirectory(tools) + add_subdirectory(tools) endif() diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index db33731f8..815f3f622 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -1,12 +1,2 @@ - -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../src) -include_directories(${CMAKE_CURRENT_BINARY_DIR}/../src) - add_executable(benchncnn benchncnn.cpp) -set_property(TARGET benchncnn PROPERTY COMPILE_FLAGS "-fpie") -set_property(TARGET benchncnn PROPERTY LINK_FLAGS "-pie") target_link_libraries(benchncnn PRIVATE ncnn) - -if(NCNN_VULKAN) - target_link_libraries(benchncnn PRIVATE ${Vulkan_LIBRARY}) -endif() diff --git a/benchmark/benchncnn.cpp b/benchmark/benchncnn.cpp index 7ab189e12..8c9c631a5 100644 --- a/benchmark/benchncnn.cpp +++ b/benchmark/benchncnn.cpp @@ -16,7 +16,6 @@ #include #ifdef _WIN32 -#define NOMINMAX #include #include // Sleep() #else diff --git a/cmake/ncnnConfig.cmake.in b/cmake/ncnnConfig.cmake.in new file mode 100644 index 000000000..2b7aef7de --- /dev/null +++ b/cmake/ncnnConfig.cmake.in @@ -0,0 +1,16 @@ +set(NCNN_OPENMP @NCNN_OPENMP@) +set(NCNN_VULKAN @NCNN_VULKAN@) + +if(NCNN_OPENMP) + find_package(OpenMP) +endif() + +if(NCNN_VULKAN) + find_package(Vulkan REQUIRED) + + add_library(Vulkan UNKNOWN IMPORTED) + set_target_properties(Vulkan PROPERTIES IMPORTED_LOCATION ${Vulkan_LIBRARY}) + set_target_properties(Vulkan PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${Vulkan_INCLUDE_DIR}) +endif() + +include(${CMAKE_CURRENT_LIST_DIR}/ncnn.cmake) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 31be90223..26d45d61d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,10 +3,6 @@ configure_file(platform.h.in ${CMAKE_CURRENT_BINARY_DIR}/platform.h) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/layer) - if(NCNN_VULKAN) find_program(GLSLANGVALIDATOR_EXECUTABLE NAMES glslangValidator PATHS $ENV{VULKAN_SDK}/bin NO_CMAKE_FIND_ROOT_PATH) message(STATUS "Found glslangValidator: ${GLSLANGVALIDATOR_EXECUTABLE}") @@ -277,6 +273,85 @@ configure_file(layer_shader_spv_data.h.in ${CMAKE_CURRENT_BINARY_DIR}/layer_shad add_library(ncnn STATIC ${ncnn_SRCS}) +target_include_directories(ncnn + PUBLIC + $ + $ + $ + PRIVATE + $) + +if(NCNN_OPENMP) + find_package(OpenMP) + if(NOT TARGET OpenMP::OpenMP_CXX AND (OpenMP_CXX_FOUND OR OPENMP_FOUND)) + target_compile_options(ncnn PRIVATE ${OpenMP_CXX_FLAGS}) + endif() +endif() + +if(NCNN_VULKAN) + find_package(Vulkan REQUIRED) + + add_library(Vulkan UNKNOWN IMPORTED) + set_target_properties(Vulkan PROPERTIES IMPORTED_LOCATION ${Vulkan_LIBRARY}) + set_target_properties(Vulkan PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${Vulkan_INCLUDE_DIR}) + target_link_libraries(ncnn PUBLIC Vulkan) +endif() + +if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC" + OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_SIMULATE_ID MATCHES "MSVC")) + target_compile_definitions(ncnn + PRIVATE _SCL_SECURE_NO_WARNINGS _CRT_SECURE_NO_DEPRECATE + PUBLIC NOMINMAX) +else() + target_compile_options(ncnn + PRIVATE -Wall -Wextra -Wno-unused-function) + set_target_properties(ncnn + PROPERTIES + POSITION_INDEPENDENT_CODE ON + INTERFACE_POSITION_INDEPENDENT_CODE ON) + + if(CMAKE_BUILD_TYPE MATCHES "(Release|RELEASE|release)") + if(NOT CMAKE_SYSTEM_NAME STREQUAL "Emscripten") + target_compile_options(ncnn PRIVATE -Ofast) + endif() + + target_compile_options(ncnn PRIVATE -ffast-math) + endif() + + if(PI3) + target_compile_options(ncnn + PRIVATE -march=native -mfpu=neon -mfloat-abi=hard) + target_compile_definitions(ncnn + PRIVATE __ARM_NEON __ANDROID__) + endif() + # target_compile_options(ncnn PRIVATE -march=native) + # set_target_properties(ncnn PROPERTIES INTERPROCEDURAL_OPTIMIZATION ON) + target_compile_options(ncnn PRIVATE -fvisibility=hidden -fvisibility-inlines-hidden) +endif() + +if(NCNN_DISABLE_RTTI) + target_compile_options(ncnn PUBLIC -fno-rtti) +endif() + +if(NCNN_DISABLE_EXCEPTION) + target_compile_options(ncnn PUBLIC -fno-exceptions) +endif() + +if(ANDROID OR IOS) + # disable shared library on android and xcode ios + set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE) +elseif(NCNN_AVX2) + #set up according to your own system environment + #Windows + if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC" + OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_SIMULATE_ID MATCHES "MSVC")) + target_compile_options(ncnn PRIVATE /arch:AVX2 /DAVX2) + #Linux + else() + target_compile_options(ncnn PRIVATE -mfma) + endif() +endif() + add_dependencies(ncnn generate-spirv) if(NCNN_OPENMP AND OpenMP_CXX_FOUND) @@ -287,25 +362,33 @@ if(NCNN_OPENMP AND OpenMP_CXX_FOUND) endif() if(NCNN_INSTALL_SDK) - install(TARGETS ncnn ARCHIVE DESTINATION lib) - install(FILES - allocator.h - blob.h - command.h - cpu.h - gpu.h - layer.h - layer_type.h - mat.h - modelbin.h - net.h - opencv.h - option.h - paramdict.h - pipeline.h - benchmark.h - ${CMAKE_CURRENT_BINARY_DIR}/layer_type_enum.h - ${CMAKE_CURRENT_BINARY_DIR}/platform.h - DESTINATION include - ) + install(TARGETS ncnn EXPORT ncnn ARCHIVE DESTINATION lib) + install(FILES + allocator.h + blob.h + command.h + cpu.h + gpu.h + layer.h + layer_type.h + mat.h + modelbin.h + net.h + opencv.h + option.h + paramdict.h + pipeline.h + benchmark.h + ${CMAKE_CURRENT_BINARY_DIR}/layer_type_enum.h + ${CMAKE_CURRENT_BINARY_DIR}/platform.h + DESTINATION include + ) + install(EXPORT ncnn + DESTINATION share/ncnn) + configure_file(${CMAKE_CURRENT_LIST_DIR}/../cmake/ncnnConfig.cmake.in + ncnnConfig.cmake + @ONLY) + install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/ncnnConfig.cmake + DESTINATION share/ncnn) endif() diff --git a/src/allocator.h b/src/allocator.h index 9bca3c4d8..36d414274 100644 --- a/src/allocator.h +++ b/src/allocator.h @@ -122,7 +122,7 @@ static inline int NCNN_XADD(int* addr, int delta) { int tmp = *addr; *addr += de class Allocator { public: - virtual ~Allocator() = 0; + virtual ~Allocator(); virtual void* fastMalloc(size_t size) = 0; virtual void fastFree(void* ptr) = 0; }; diff --git a/src/modelbin.cpp b/src/modelbin.cpp index e38c59ed3..b821086ce 100644 --- a/src/modelbin.cpp +++ b/src/modelbin.cpp @@ -21,6 +21,10 @@ namespace ncnn { +ModelBin::~ModelBin() +{ +} + Mat ModelBin::load(int w, int h, int type) const { Mat m = load(w * h, type); diff --git a/src/modelbin.h b/src/modelbin.h index 3237beed1..176273ce7 100644 --- a/src/modelbin.h +++ b/src/modelbin.h @@ -25,6 +25,7 @@ class Net; class ModelBin { public: + virtual ~ModelBin(); // element type // 0 = auto // 1 = float32 diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 7e3843301..8ccd02753 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -4,11 +4,6 @@ add_subdirectory(mxnet) add_subdirectory(onnx) # add_subdirectory(quantize) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../src) -include_directories(${CMAKE_CURRENT_BINARY_DIR}/../src) - -include_directories(${CMAKE_SOURCE_DIR}/src) - add_executable(ncnn2mem ncnn2mem.cpp) target_link_libraries(ncnn2mem PRIVATE ncnn) diff --git a/tools/caffe/CMakeLists.txt b/tools/caffe/CMakeLists.txt index 16a4748ae..31d81ab9d 100644 --- a/tools/caffe/CMakeLists.txt +++ b/tools/caffe/CMakeLists.txt @@ -2,12 +2,14 @@ find_package(Protobuf) if(PROTOBUF_FOUND) - include_directories(${PROTOBUF_INCLUDE_DIR}) - include_directories(${CMAKE_CURRENT_BINARY_DIR}) protobuf_generate_cpp(CAFFE_PROTO_SRCS CAFFE_PROTO_HDRS caffe.proto) add_executable(caffe2ncnn caffe2ncnn.cpp ${CAFFE_PROTO_SRCS} ${CAFFE_PROTO_HDRS}) - set_target_properties(caffe2ncnn PROPERTIES CXX_STANDARD 11) - target_link_libraries(caffe2ncnn ${PROTOBUF_LIBRARIES}) + target_include_directories(caffe2ncnn + PRIVATE + ${PROTOBUF_INCLUDE_DIR} + ${CMAKE_CURRENT_BINARY_DIR}) + target_compile_features(caffe2ncnn PRIVATE cxx_std_11) + target_link_libraries(caffe2ncnn PRIVATE ${PROTOBUF_LIBRARIES}) else() message(WARNING "Protobuf not found, caffe model convert tool won't be built") endif() diff --git a/tools/onnx/CMakeLists.txt b/tools/onnx/CMakeLists.txt index 361ab81a8..a869ca7b9 100644 --- a/tools/onnx/CMakeLists.txt +++ b/tools/onnx/CMakeLists.txt @@ -2,12 +2,14 @@ find_package(Protobuf) if(PROTOBUF_FOUND) - include_directories(${PROTOBUF_INCLUDE_DIR}) - include_directories(${CMAKE_CURRENT_BINARY_DIR}) protobuf_generate_cpp(ONNX_PROTO_SRCS ONNX_PROTO_HDRS onnx.proto) add_executable(onnx2ncnn onnx2ncnn.cpp ${ONNX_PROTO_SRCS} ${ONNX_PROTO_HDRS}) - set_target_properties(onnx2ncnn PROPERTIES CXX_STANDARD 11) - target_link_libraries(onnx2ncnn ${PROTOBUF_LIBRARIES}) + target_include_directories(onnx2ncnn + PRIVATE + ${PROTOBUF_INCLUDE_DIR} + ${CMAKE_CURRENT_BINARY_DIR}) + target_compile_features(onnx2ncnn PRIVATE cxx_std_11) + target_link_libraries(onnx2ncnn PRIVATE ${PROTOBUF_LIBRARIES}) else() message(WARNING "Protobuf not found, onnx model convert tool won't be built") endif() diff --git a/tools/quantize/CMakeLists.txt b/tools/quantize/CMakeLists.txt index db6e3752f..205472745 100644 --- a/tools/quantize/CMakeLists.txt +++ b/tools/quantize/CMakeLists.txt @@ -3,13 +3,8 @@ if(NOT OpenCV_FOUND) find_package(OpenCV REQUIRED COMPONENTS core highgui imgproc) endif() -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src) -include_directories(${CMAKE_CURRENT_BINARY_DIR}/../../src) - -include_directories(${CMAKE_SOURCE_DIR}/src) - add_executable(ncnn2table ncnn2table.cpp) target_link_libraries(ncnn2table PRIVATE ncnn ${OpenCV_LIBS}) add_executable(ncnn2int8 ncnn2int8.cpp) -target_link_libraries(ncnn2int8 PRIVATE ncnn) \ No newline at end of file +target_link_libraries(ncnn2int8 PRIVATE ncnn)