# Copyright 2013-2015 Numenta Inc. # # Copyright may exist in Contributors' modifications # and/or contributions to the work. # # Use of this source code is governed by the MIT # license that can be found in the LICENSE file or at # https://opensource.org/licenses/MIT. cmake_minimum_required(VERSION 3.3) project(nupic_core CXX) set_property(GLOBAL PROPERTY USE_FOLDERS ON) set(CMAKE_VERBOSE_MAKEFILE OFF) # toggle for cmake debug # if( POLICY CMP0046 ) # cmake_policy(VERSION 3.3) # # The new policy for add_dependencies is to now error if a dependency target # # is not found. The old policy didn't care and continued through configuration # cmake_policy(SET CMP0046 OLD) # endif() # if( POLICY CMP0054 ) # # The OLD behavior for this policy is to dereference variables and interpret # # keywords even if they are quoted or bracketed. The NEW behavior is to not # # dereference variables or interpret keywords that have been quoted or bracketed. # cmake_policy(SET CMP0054 OLD) # endif() # # NuPIC CMake options # option(NUPIC_IWYU "Enable include-what-you-use (http://include-what-you-use.org/). This requires the iwyu binary to be discoverable by CMake's find_program, with a minimum CMake version of 3.3.") if(${NUPIC_IWYU}) find_program(iwyu_path NAMES include-what-you-use iwyu) if(NOT iwyu_path) message(FATAL_ERROR "Could not find the program include-what-you-use") endif() endif() option(NUPIC_TOGGLE_INSTALL "Toggle whether to install headers, libraries, and executables to the install location for C++ clients" OFF) # # Set up compile flags for internal sources and for swig-generated sources # set(src_compile_flags "${INTERNAL_CXX_FLAGS_OPTIMIZED}") set(src_swig_generated_file_compile_flags "${EXTERNAL_CXX_FLAGS_OPTIMIZED}") if(MINGW) # This is for GCC 4.8.x # http://stackoverflow.com/questions/10660524/error-building-boost-1-49-0-with-gcc-4-7-0 set(src_compile_flags "${src_compile_flags} -include cmath") set(src_swig_generated_file_compile_flags "${src_swig_generated_file_compile_flags} -include cmath") endif() # # Compiler definitions specific to nupic.core code # string(TOUPPER ${PLATFORM} platform_uppercase) set(src_compiler_definitions ${COMMON_COMPILER_DEFINITIONS} ${CAPNP_COMPILER_DEFINITIONS} -DNTA_OS_${platform_uppercase} -DNTA_ARCH_${BITNESS} -DHAVE_CONFIG_H -DNTA_INTERNAL -DBOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS -DBOOST_NO_WREGEX -DNUPIC2 -DAPR_DECLARE_STATIC -DAPU_DECLARE_STATIC) if(NOT ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7l" OR "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64")) set(src_compiler_definitions ${src_compiler_definitions} -DNTA_ASM) endif() if(NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Release") set(src_compiler_definitions ${src_compiler_definitions} -DNTA_ASSERTIONS_ON) endif() if(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") set(src_compiler_definitions ${src_compiler_definitions} -DNTA_COMPILER_GNU) elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") set(src_compiler_definitions ${src_compiler_definitions} -DNTA_COMPILER_CLANG) elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC") set(src_compiler_definitions ${src_compiler_definitions} -DNTA_COMPILER_MSVC) elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "MinGW") set(src_compiler_definitions ${src_compiler_definitions} -DNTA_COMPILER_GNU -D_hypot=hypot) endif() add_definitions(${src_compiler_definitions}) # # Find Python Interp, min. v2.7 # And NumPy core directory # find_package(PythonInterp 2.7 REQUIRED) message(STATUS "CMAKE Found python interpreter ${PYTHON_EXECUTABLE} version=${PYTHON_VERSION_STRING}") execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" "import numpy; import os; import sys; sys.stdout.write(os.path.dirname(numpy.get_include()))" OUTPUT_VARIABLE src_numpy_core) # Quick way to fixup directory paths to NumPy get_filename_component(src_numpy_core ${src_numpy_core}/include/.. ABSOLUTE) message(STATUS "src_numpy_core = ${src_numpy_core}") # # Setup include paths # if("${PROJECT_BUILD_ARTIFACTS_DIR}" STREQUAL "") set(PROJECT_BUILD_ARTIFACTS_DIR "${PROJECT_BINARY_DIR}/artifacts") endif() include_directories(SYSTEM ${src_numpy_core}/include ${PROJECT_BINARY_DIR}) include_directories(${PROJECT_SOURCE_DIR}) # # Let CMake know where all of the external files are. # set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${REPOSITORY_DIR}/external/common/ ${REPOSITORY_DIR}/external/${PLATFORM}${BITNESS}${PLATFORM_SUFFIX}/ ${src_numpy_core}/) message(STATUS "CMAKE_PREFIX_PATH = ${CMAKE_PREFIX_PATH}") # # Extract current git sha and record in nupic/Version.hpp # execute_process(COMMAND git rev-parse HEAD OUTPUT_VARIABLE NUPIC_CORE_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) configure_file( "${PROJECT_SOURCE_DIR}/nupic/Version.hpp.in" "${PROJECT_BINARY_DIR}/Version.hpp") # # Setup gtest # set(src_lib_static_gtest gtest) add_library(${src_lib_static_gtest} STATIC ${REPOSITORY_DIR}/external/common/src/gtest/gtest-all.cpp) set_target_properties(${src_lib_static_gtest} PROPERTIES COMPILE_FLAGS "${src_compile_flags}" LINK_FLAGS "${INTERNAL_LINKER_FLAGS_OPTIMIZED}") # # Locate Python artifacts # find_package(PythonLibs REQUIRED) include_directories(SYSTEM ${PYTHON_INCLUDE_DIRS}) message(STATUS "PYTHON_EXECUTABLE = ${PYTHON_EXECUTABLE}") message(STATUS "PYTHON_INCLUDE_DIRS = ${PYTHON_INCLUDE_DIRS}") message(STATUS "PYTHON_LIBRARIES = ${PYTHON_LIBRARIES}") # # Python support # set(src_py_support_files nupic/py_support/NumpyArrayObject.cpp nupic/py_support/NumpyVector.cpp nupic/py_support/PyArray.cpp nupic/py_support/PyHelpers.cpp nupic/py_support/PythonStream.cpp nupic/bindings/PySparseTensor.cpp ) # List all .capnp files here. The C++ files will be generated and included # when compiling later on. set(src_capnp_specs_rel nupic/proto/ArrayProto.capnp nupic/proto/BitHistory.capnp nupic/proto/Cell.capnp nupic/proto/Cells4.capnp nupic/proto/ClaClassifier.capnp nupic/proto/ConnectionsProto.capnp nupic/proto/LinkProto.capnp nupic/proto/Map.capnp nupic/proto/NetworkProto.capnp nupic/proto/PyRegionProto.capnp nupic/proto/RandomProto.capnp nupic/proto/RegionProto.capnp nupic/proto/Segment.capnp nupic/proto/SegmentUpdate.capnp nupic/proto/SparseBinaryMatrixProto.capnp nupic/proto/SparseMatrixProto.capnp nupic/proto/SpatialPoolerProto.capnp nupic/proto/SdrClassifier.capnp nupic/proto/SvmProto.capnp nupic/proto/TemporalMemoryProto.capnp nupic/proto/TestNodeProto.capnp nupic/proto/VectorFileSensorProto.capnp ) # Create custom command for generating C++ code from .capnp schema files. foreach(spec ${src_capnp_specs_rel}) list(APPEND src_capnp_specs ${PROJECT_SOURCE_DIR}/${spec}) list(APPEND src_capnp_generated_hdrs ${PROJECT_BINARY_DIR}/${spec}.h) list(APPEND src_capnp_generated_srcs ${PROJECT_BINARY_DIR}/${spec}.c++) endforeach(spec) set(src_capnp_all_spec_hdrs_and_srcs ${src_capnp_generated_hdrs} ${src_capnp_generated_srcs}) create_capnpc_command("${src_capnp_specs}" ${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR} "${src_capnp_all_spec_hdrs_and_srcs}") message(STATUS "CAPNP_EXECUTABLE = ${CAPNP_EXECUTABLE}") message(STATUS "CAPNP_CMAKE_DEFINITIONS = ${CAPNP_CMAKE_DEFINITIONS}") message(STATUS "CAPNP_INCLUDE_DIRS = ${CAPNP_INCLUDE_DIRS}") message(STATUS "CAPNP_STATIC_LIB_TARGET = ${CAPNP_STATIC_LIB_TARGET}") message(STATUS "SWIG_EXECUTABLE = ${SWIG_EXECUTABLE}") message(STATUS "SWIG_DIR = ${SWIG_DIR}") # # Common system libraries for shared libraries and executables # set(src_common_os_libs) if("${PLATFORM}" STREQUAL "linux") list(APPEND src_common_os_libs pthread dl) elseif("${PLATFORM}" STREQUAL "darwin") list(APPEND src_common_os_libs c++abi) elseif(MSYS OR MINGW) list(APPEND src_common_os_libs psapi ws2_32 wsock32 rpcrt4) elseif("${PLATFORM}" STREQUAL "windows") list(APPEND src_common_os_libs oldnames.lib psapi.lib ws2_32.lib) endif() message(STATUS "src_common_os_libs = ${src_common_os_libs}") # # Setup nupic_core_solo static library, consisting of our own sources; # # this is an intermediate archive that will be merged with external static # libraries in a subsequent step to produce the nupic_core "combined" static # library. # set(src_lib_static_nupiccore_solo nupic_core_solo) set(src_nupiccore_srcs nupic/algorithms/Anomaly.cpp nupic/algorithms/BitHistory.cpp nupic/algorithms/Cell.cpp nupic/algorithms/Cells4.cpp nupic/algorithms/ClassifierResult.cpp nupic/algorithms/CondProbTable.cpp nupic/algorithms/Connections.cpp nupic/algorithms/GaborNode.cpp nupic/algorithms/ImageSensorLite.cpp nupic/algorithms/InSynapse.cpp nupic/algorithms/OutSynapse.cpp nupic/algorithms/Segment.cpp nupic/algorithms/SegmentUpdate.cpp nupic/algorithms/SDRClassifier.cpp nupic/algorithms/SpatialPooler.cpp nupic/algorithms/TemporalMemory.cpp nupic/algorithms/Svm.cpp nupic/encoders/ScalarEncoder.cpp nupic/encoders/ScalarSensor.cpp nupic/engine/Collections.cpp nupic/engine/Input.cpp nupic/engine/Link.cpp nupic/engine/LinkPolicyFactory.cpp nupic/engine/Network.cpp nupic/engine/NuPIC.cpp nupic/engine/Output.cpp nupic/engine/Region.cpp nupic/engine/RegionImpl.cpp nupic/engine/RegionImplFactory.cpp nupic/engine/RegionIo.cpp nupic/engine/RegionParameters.cpp nupic/engine/Spec.cpp nupic/engine/TestFanIn2LinkPolicy.cpp nupic/engine/TestNode.cpp nupic/engine/UniformLinkPolicy.cpp nupic/engine/YAMLUtils.cpp nupic/math/SparseMatrixAlgorithms.cpp nupic/math/SparseMatrixConnections.cpp nupic/math/StlIo.cpp nupic/math/Topology.cpp nupic/ntypes/ArrayBase.cpp nupic/ntypes/Buffer.cpp nupic/ntypes/BundleIO.cpp nupic/ntypes/Collection.cpp nupic/ntypes/Dimensions.cpp nupic/ntypes/MemParser.cpp nupic/ntypes/Scalar.cpp nupic/ntypes/Value.cpp nupic/os/Directory.cpp nupic/os/DynamicLibrary.cpp nupic/os/Env.cpp nupic/os/FStream.cpp nupic/os/OS.cpp nupic/os/OSUnix.cpp nupic/os/OSWin.cpp nupic/os/Path.cpp nupic/os/Regex.cpp nupic/os/Timer.cpp nupic/regions/PyRegion.cpp nupic/regions/VectorFile.cpp nupic/regions/VectorFileEffector.cpp nupic/regions/VectorFileSensor.cpp nupic/types/BasicType.cpp nupic/types/Fraction.cpp nupic/utils/ArrayProtoUtils.cpp nupic/utils/LoggingException.cpp nupic/utils/LogItem.cpp nupic/utils/MovingAverage.cpp nupic/utils/Random.cpp nupic/utils/StringUtils.cpp nupic/utils/TRandom.cpp nupic/utils/Watcher.cpp) set(src_lib_static_nupiccore_srcs ${src_capnp_generated_srcs} ${src_py_support_files} ${src_nupiccore_srcs}) set(src_lib_static_nupiccore_compile_flags "${src_compile_flags} -I${src_numpy_core}/include") message(STATUS "src_compile_flags = ${src_compile_flags}") message(STATUS "src_lib_static_nupiccore_compile_flags = ${src_lib_static_nupiccore_compile_flags}") add_library(${src_lib_static_nupiccore_solo} STATIC ${src_lib_static_nupiccore_srcs}) # nupic_core_solo sources depend on headers installed by these external projects add_dependencies(${src_lib_static_nupiccore_solo} ${YAML_CPP_STATIC_LIB_TARGET} ${YAML_STATIC_LIB_TARGET} ${APR1_STATIC_LIB_TARGET} ${APRUTIL1_STATIC_LIB_TARGET} ${Z_STATIC_LIB_TARGET}) set_target_properties(${src_lib_static_nupiccore_solo} PROPERTIES COMPILE_FLAGS ${src_lib_static_nupiccore_compile_flags}) if(${NUPIC_IWYU}) # TODO: Create a target that doesn't include the generated capnp schema files # since we don't want to run iwyu on them and iwyu can only be applied to # CMake targets (not source files directly). set_target_properties(${src_lib_static_nupiccore_solo} PROPERTIES CXX_INCLUDE_WHAT_YOU_USE ${iwyu_path}) endif() # # Create the nupic_core "combined" static library by merging nupic_core_solo # with our external static libraries # include(src/NupicLibraryUtils) # for MERGE_STATIC_LIBRARIES set(src_lib_static_nupiccore_combined nupic_core) set(src_external_static_libs ${CAPNP_STATIC_LIB_TARGET} ${YAML_CPP_STATIC_LIB_TARGET} ${YAML_STATIC_LIB_TARGET} ${APR1_STATIC_LIB_TARGET} ${APRUTIL1_STATIC_LIB_TARGET} ${Z_STATIC_LIB_TARGET}) set(src_combined_nupiccore_source_archives ${src_lib_static_nupiccore_solo} ${src_external_static_libs}) # Create a top-level library target for the combined static lib merge_static_libraries(${src_lib_static_nupiccore_combined} "${src_combined_nupiccore_source_archives}") # # Build tests of the nupic_core "combined" static library # # Common libs for test executables set(src_common_test_exe_libs ${src_lib_static_nupiccore_combined} ${PYTHON_LIBRARIES} ${src_common_os_libs}) message(STATUS "src_common_test_exe_libs = ${src_common_test_exe_libs}") # # Setup test_cpp_region # set(src_executable_cppregiontest cpp_region_test) add_executable(${src_executable_cppregiontest} test/integration/CppRegionTest.cpp) target_link_libraries(${src_executable_cppregiontest} ${src_common_test_exe_libs}) set_target_properties(${src_executable_cppregiontest} PROPERTIES COMPILE_FLAGS ${src_compile_flags}) set_target_properties(${src_executable_cppregiontest} PROPERTIES LINK_FLAGS "${INTERNAL_LINKER_FLAGS_OPTIMIZED}") add_custom_target(tests_cpp_region COMMAND ${src_executable_cppregiontest} DEPENDS ${src_executable_cppregiontest} COMMENT "Executing test ${src_executable_cppregiontest}" VERBATIM) # # Setup test_py_region # set(src_executable_pyregiontest py_region_test) add_executable(${src_executable_pyregiontest} test/integration/PyRegionTest.cpp) target_link_libraries(${src_executable_pyregiontest} ${src_common_test_exe_libs}) set_target_properties(${src_executable_pyregiontest} PROPERTIES COMPILE_FLAGS ${src_compile_flags}) set_target_properties(${src_executable_pyregiontest} PROPERTIES LINK_FLAGS "${INTERNAL_LINKER_FLAGS_OPTIMIZED}") add_custom_target(tests_py_region COMMAND ${src_executable_pyregiontest} DEPENDS ${src_executable_pyregiontest} COMMENT "Executing test ${src_executable_pyregiontest}" VERBATIM) # # Setup test_connections_performance # set(src_executable_connectionsperformancetest connections_performance_test) add_executable(${src_executable_connectionsperformancetest} test/integration/ConnectionsPerformanceTest.cpp) target_link_libraries(${src_executable_connectionsperformancetest} ${src_common_test_exe_libs}) set_target_properties(${src_executable_connectionsperformancetest} PROPERTIES COMPILE_FLAGS ${src_compile_flags}) set_target_properties(${src_executable_connectionsperformancetest} PROPERTIES LINK_FLAGS "${INTERNAL_LINKER_FLAGS_OPTIMIZED}") add_custom_target(tests_connections_performance COMMAND ${src_executable_connectionsperformancetest} DEPENDS ${src_executable_connectionsperformancetest} COMMENT "Executing test ${src_executable_connectionsperformancetest}" VERBATIM) # # Setup helloregion example # set(src_executable_helloregion helloregion) add_executable(${src_executable_helloregion} examples/regions/HelloRegions.cpp) target_link_libraries(${src_executable_helloregion} ${src_common_test_exe_libs}) set_target_properties(${src_executable_helloregion} PROPERTIES COMPILE_FLAGS ${src_compile_flags}) set_target_properties(${src_executable_helloregion} PROPERTIES LINK_FLAGS "${INTERNAL_LINKER_FLAGS_OPTIMIZED}") # # Setup prototest example # set(src_executable_prototest prototest) add_executable(${src_executable_prototest} examples/prototest.cpp) target_link_libraries(${src_executable_prototest} ${src_common_test_exe_libs}) set_target_properties(${src_executable_prototest} PROPERTIES COMPILE_FLAGS ${src_compile_flags}) set_target_properties(${src_executable_prototest} PROPERTIES LINK_FLAGS "${INTERNAL_LINKER_FLAGS_OPTIMIZED}") # # Setup HelloSP_TP example # set(src_executable_hellosptp hello_sp_tp) add_executable(${src_executable_hellosptp} examples/algorithms/HelloSP_TP.cpp) target_link_libraries(${src_executable_hellosptp} ${src_common_test_exe_libs}) set_target_properties(${src_executable_hellosptp} PROPERTIES COMPILE_FLAGS ${src_compile_flags}) set_target_properties(${src_executable_hellosptp} PROPERTIES LINK_FLAGS "${INTERNAL_LINKER_FLAGS_OPTIMIZED}") # # Setup gtests # set(src_executable_gtests unit_tests) add_executable(${src_executable_gtests} test/unit/algorithms/AnomalyTest.cpp test/unit/algorithms/Cells4Test.cpp test/unit/algorithms/CondProbTableTest.cpp test/unit/algorithms/ConnectionsTest.cpp test/unit/algorithms/NearestNeighborUnitTest.cpp test/unit/algorithms/SDRClassifierTest.cpp test/unit/algorithms/SegmentTest.cpp test/unit/algorithms/SpatialPoolerTest.cpp test/unit/algorithms/SvmTest.cpp test/unit/algorithms/TemporalMemoryTest.cpp test/unit/encoders/ScalarEncoderTest.cpp test/unit/engine/InputTest.cpp test/unit/engine/LinkTest.cpp test/unit/engine/NetworkTest.cpp test/unit/engine/UniformLinkPolicyTest.cpp test/unit/engine/YAMLUtilsTest.cpp test/unit/math/DenseTensorUnitTest.cpp test/unit/math/DomainUnitTest.cpp test/unit/math/IndexUnitTest.cpp test/unit/math/MathsTest.cpp test/unit/math/SegmentMatrixAdapterTest.cpp test/unit/math/SparseBinaryMatrixTest.cpp test/unit/math/SparseMatrix01UnitTest.cpp test/unit/math/SparseMatrixTest.cpp test/unit/math/SparseMatrixUnitTest.cpp test/unit/math/SparseTensorUnitTest.cpp test/unit/math/TopologyTest.cpp test/unit/ntypes/ArrayTest.cpp test/unit/ntypes/BufferTest.cpp test/unit/ntypes/CollectionTest.cpp test/unit/ntypes/DimensionsTest.cpp test/unit/ntypes/MemParserTest.cpp test/unit/ntypes/MemStreamTest.cpp test/unit/ntypes/NodeSetTest.cpp test/unit/ntypes/ScalarTest.cpp test/unit/ntypes/ValueTest.cpp test/unit/os/DirectoryTest.cpp test/unit/os/EnvTest.cpp test/unit/os/OSTest.cpp test/unit/os/PathTest.cpp test/unit/os/RegexTest.cpp test/unit/os/TimerTest.cpp test/unit/py_support/PyHelpersTest.cpp test/unit/types/BasicTypeTest.cpp test/unit/types/ExceptionTest.cpp test/unit/types/FractionTest.cpp test/unit/UnitTestMain.cpp test/unit/utils/GroupByTest.cpp test/unit/utils/MovingAverageTest.cpp test/unit/utils/RandomTest.cpp test/unit/utils/WatcherTest.cpp) target_link_libraries(${src_executable_gtests} ${src_lib_static_gtest} ${src_common_test_exe_libs}) set_target_properties(${src_executable_gtests} PROPERTIES COMPILE_FLAGS ${src_compile_flags} LINK_FLAGS "${INTERNAL_LINKER_FLAGS_OPTIMIZED}") add_custom_target(tests_unit COMMAND ${src_executable_gtests} DEPENDS ${src_executable_gtests} COMMENT "Executing test ${src_executable_gtests}" VERBATIM) # # tests_all just calls other targets # # TODO This doesn't seem to have any effect; it's probably because the DEPENDS # of add_custom_target must be files, not other high-level targets. If really # need to run these tests during build, then either the individual # add_custom_target of the individual test runners should be declared with the # ALL option, or tests_all target whould be declared without DEPENDS, and # add_dependencies should be used to set it's dependencies on the custom targets # of the inidividual test runners. add_custom_target(tests_all DEPENDS tests_cpp_region DEPENDS tests_unit COMMENT "Running all tests" VERBATIM) # # Use SWIG to generate Python extensions. # if (NUPIC_BUILD_PYEXT_MODULES) include(UseSWIG) # Set the output location for the language modules that are created. set(CMAKE_SWIG_OUTDIR ${PROJECT_BINARY_DIR}) # Make sure the directory exists for the generated C++ files. file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/nupic/bindings) # TODO ZZZ set COMPILE_FLAGS on swig targets # SWIG options from: # https://github.com/swig/swig/blob/master/Source/Modules/python.cxx#L111 set(src_swig_flags -c++ -features autodoc=0,directors=0 -noproxyimport -keyword -modern -modernargs -noproxydel -fvirtual -fastunpack -nofastproxy -fastquery -outputtuple -castmode -nosafecstrings -w402 -w503 -w511 -w302 -w362 -w312 -w389 -DSWIG_PYTHON_LEGACY_BOOL -I${SWIG_DIR}/python -I${SWIG_DIR} ${src_compiler_definitions} ) file(GLOB_RECURSE swig_header_deps *.i *.hpp *.h) message(STATUS "src_swig_flags = ${src_swig_flags}") # Tell swig which command-line options to use, allowing user to override set(CMAKE_SWIG_FLAGS ${src_swig_flags} ${CMAKE_SWIG_FLAGS}) # Set up linker flags for python extension shared libraries set(_SRC_SWIG_EXTENSION_LINK_FLAGS "${PYEXT_LINKER_FLAGS_OPTIMIZED}") # NOTE Non-Windows Python extensions shouldn't be linking against libpython; # symbols should be available automatically when python loads the extension. # set(_SRC_SWIG_LINK_LIBRARIES ${src_lib_static_nupiccore_combined} ${src_common_os_libs}) # Common dependencies for our python extensions for use with # SWIG_MODULE_name_EXTRA_DEPS # Make sure we don't execute the swig executable before it is built set(_SRC_SWIG_EXTRA_DEPS Swig) # NOTE Windows DLLs are shared executables with their own main; they require # all symbols to resolve at link time, so we have to add libpython for this # platform # # NOTE On Windows nupic.bindings builds we presently build self-contained # CAPNP_LITE, and Windows nupic/nupic.bindings presently has no # dependency on pycapnp. if("${PLATFORM}" STREQUAL "windows") list(APPEND _SRC_SWIG_LINK_LIBRARIES ${PYTHON_LIBRARIES}) endif() message(STATUS "_SRC_SWIG_EXTRA_DEPS = ${_SRC_SWIG_EXTRA_DEPS}") message(STATUS "_SRC_SWIG_LINK_LIBRARIES = ${_SRC_SWIG_LINK_LIBRARIES}") message(STATUS "_SRC_SWIG_EXTENSION_LINK_FLAGS= ${_SRC_SWIG_EXTENSION_LINK_FLAGS}") message(STATUS "CMAKE_SWIG_FLAGS = ${CMAKE_SWIG_FLAGS}") function(PREPEND_BOILERPLATE_TO_PYTHON_PROXY_MODULE MODULE_NAME) # Add a custom command to the Swig target to prepend boilerplate to the # swig-generated python proxy module # ${CMAKE_SWIG_OUTDIR}/${MODULE_NAME}.py. # # :param MODULE_NAME: the custom command will be added to the target # corresponding to this Swig module name. set(preamble_filepath "${CMAKE_SOURCE_DIR}/src/nupic/bindings/swig_proxy_preamble.py") set(module_filepath "${CMAKE_SWIG_OUTDIR}/${MODULE_NAME}.py") add_custom_command( TARGET ${SWIG_MODULE_${MODULE_NAME}_REAL_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -DSRC_FILE_1=${preamble_filepath} -DSRC_FILE_2=${module_filepath} -DTARGET_FILE=${module_filepath} -P ${CMAKE_SOURCE_DIR}/src/ConcatTwoFiles.cmake COMMENT "Prepending ${preamble_filepath} to swig-generated module ${module_filepath}" ) endfunction(PREPEND_BOILERPLATE_TO_PYTHON_PROXY_MODULE) function(BUILD_EXTENSION MODULE_NAME) # Create a nupic.bindings swig extension target with the given Swig module # name. Also, if PY_EXTENSIONS_DIR is specified, request # installation of the extension library and python proxy module. # # The real target name is ${SWIG_MODULE_${MODULE_NAME}_REAL_NAME}. set(source_interface_file nupic/bindings/${MODULE_NAME}.i) set_source_files_properties(${source_interface_file} PROPERTIES CPLUSPLUS ON SWIG_MODULE_NAME ${MODULE_NAME}) # Regenerate SWIG bindings if any headers change. set(SWIG_MODULE_${MODULE_NAME}_EXTRA_DEPS ${swig_header_deps}) # # Create custom command for generating files from SWIG # # Note: swig_add_module outputs ${swig_generated_file_fullname} if (CMAKE_VERSION VERSION_LESS "3.8") swig_add_module(${MODULE_NAME} python ${source_interface_file}) else() SWIG_ADD_LIBRARY(${MODULE_NAME} LANGUAGE python SOURCES ${source_interface_file}) endif() set_source_files_properties( ${swig_generated_file_fullname} PROPERTIES GENERATED TRUE COMPILE_FLAGS ${src_swig_generated_file_compile_flags}) swig_link_libraries(${MODULE_NAME} ${_SRC_SWIG_LINK_LIBRARIES}) prepend_boilerplate_to_python_proxy_module(${MODULE_NAME}) set(real_target "${SWIG_MODULE_${MODULE_NAME}_REAL_NAME}") set(extra_deps ${_SRC_SWIG_EXTRA_DEPS}) set(link_flags ${_SRC_SWIG_EXTENSION_LINK_FLAGS}) # Create an export map and update extra dependencies and link flags. This # export map prevents runtime-link preemption of statically-linked # libraries, such as -static-libstdc++, and limits the shared object's # symbol visibility to only the python extension's init function. NOTE Not # sure what, if anything, to do for MSVC at this time. set(extension_init_func "init${real_target}") if("${PLATFORM}" STREQUAL "darwin") set(link_flags "${link_flags} -Wl,-exported_symbol,_${extension_init_func}") elseif("${PLATFORM}" STREQUAL "linux" OR MINGW) set(export_map_file "${CMAKE_CURRENT_BINARY_DIR}/${real_target}_generated.expmap") # list(APPEND extra_deps "${export_map_file}") set(link_flags "${link_flags} -Wl,--version-script=${export_map_file}") set(export_map_contents "{global: ${extension_init_func}; local: *;};") message(STATUS "Writing export map file ${export_map_file} " "(${export_map_contents}).") file(WRITE ${export_map_file} "${export_map_contents}") endif() add_dependencies(${real_target} ${extra_deps}) set_target_properties(${real_target} PROPERTIES LINK_FLAGS "${link_flags}") # If a path is specified, copy extensions files to proper location. if (PY_EXTENSIONS_DIR) install(TARGETS ${real_target} LIBRARY DESTINATION ${PY_EXTENSIONS_DIR}) install(FILES ${PROJECT_BINARY_DIR}/${MODULE_NAME}.py DESTINATION ${PY_EXTENSIONS_DIR}) endif(PY_EXTENSIONS_DIR) message( STATUS "Created Swig target ${real_target} for swig module ${MODULE_NAME}. " "extra_deps=${extra_deps}, link_flags=${link_flags}") endfunction(BUILD_EXTENSION) # Algorithms build_extension("algorithms") # Engine build_extension("engine_internal") # Math build_extension("math") endif() # NUPIC_BUILD_PYEXT_MODULES # # Install targets into CMAKE_INSTALL_PREFIX # install(TARGETS ${src_lib_static_nupiccore_combined} ${src_lib_static_gtest} ${src_executable_helloregion} ${src_executable_cppregiontest} ${src_executable_pyregiontest} ${src_executable_connectionsperformancetest} ${src_executable_hellosptp} ${src_executable_prototest} ${src_executable_gtests} RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) # Version.hpp is also used by the nupic.bindings release/deployment system install(FILES ${PROJECT_BINARY_DIR}/Version.hpp DESTINATION include/nupic) if ((NOT NUPIC_BUILD_PYEXT_MODULES) OR NUPIC_TOGGLE_INSTALL) install(DIRECTORY nupic DESTINATION include MESSAGE_NEVER FILES_MATCHING PATTERN "*.h*" PATTERN "*.hpp.in" EXCLUDE) install(DIRECTORY nupic DESTINATION include MESSAGE_NEVER FILES_MATCHING PATTERN "*.i") install(DIRECTORY nupic DESTINATION include MESSAGE_NEVER FILES_MATCHING PATTERN "*.capnp") install(DIRECTORY ${PROJECT_BINARY_DIR}/nupic DESTINATION include MESSAGE_NEVER FILES_MATCHING PATTERN "*.capnp.h") install(DIRECTORY ${REPOSITORY_DIR}/external/common/include/gtest MESSAGE_NEVER DESTINATION include/gtest FILES_MATCHING PATTERN "*.h*") install(DIRECTORY "${REPOSITORY_DIR}/external/common/include/" MESSAGE_NEVER DESTINATION include) install(DIRECTORY "${src_numpy_core}/lib/" MESSAGE_NEVER DESTINATION lib) install(DIRECTORY "${src_numpy_core}/include/" MESSAGE_NEVER DESTINATION include) foreach(directory ${CAPNP_INCLUDE_DIRS}) install(DIRECTORY "${directory}/capnp" MESSAGE_NEVER DESTINATION include) install(DIRECTORY "${directory}/kj" MESSAGE_NEVER DESTINATION include) endforeach() install(DIRECTORY nupic/py_support DESTINATION include/nupic MESSAGE_NEVER FILES_MATCHING PATTERN "*.c*") install(DIRECTORY nupic DESTINATION include/nupic MESSAGE_NEVER FILES_MATCHING PATTERN "*.py") install(DIRECTORY "${CAPNP_BINARIES}" MESSAGE_NEVER DESTINATION "${CMAKE_INSTALL_PREFIX}" USE_SOURCE_PERMISSIONS FILES_MATCHING PATTERN "capnp*") install(DIRECTORY "${SWIG_DIR}" MESSAGE_NEVER DESTINATION share/swig) install(PROGRAMS "${SWIG_EXECUTABLE}" DESTINATION bin) install(DIRECTORY "${APR1_STATIC_LIB_INC_DIR}/" MESSAGE_NEVER DESTINATION include) install(DIRECTORY "${APRUTIL1_STATIC_LIB_INC_DIR}/" MESSAGE_NEVER DESTINATION include) endif ((NOT NUPIC_BUILD_PYEXT_MODULES) OR NUPIC_TOGGLE_INSTALL) # # `make package` results in # nupic_core-${NUPIC_CORE_VERSION}-${PLATFORM}${BITNESS}${PLATFORM_SUFFIX}.tar.gz binary release # set(CPACK_GENERATOR "TGZ") set(CPACK_PACKAGE_FILE_NAME "nupic_core-${NUPIC_CORE_VERSION}-${PLATFORM}${BITNESS}${PLATFORM_SUFFIX}") include(CPack)