diff --git a/.gitignore b/.gitignore index 51d48cd52..f02396562 100644 --- a/.gitignore +++ b/.gitignore @@ -36,4 +36,5 @@ autowiring/AutowiringConfig.h *.nupkg lib/*.* autowiring-*-*.zip -_CPack_Packages \ No newline at end of file +_CPack_Packages +win64/Autowiring.nuspec diff --git a/.travis.yml b/.travis.yml index d56e4f056..f4959f90e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -47,7 +47,7 @@ install: before_script: - export CPATH=/usr/include/c++/4.8:/usr/include/x86_64-linux-gnu/c++/4.8/:$CPATH - export LD_LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.8:$LD_LIBRARY_PATH - - cmake . -DCMAKE_BUILD_TYPE=Release + - cmake . -DCMAKE_BUILD_TYPE=Release -Dautowiring_ARCHITECTURE=x64 script: # Build Autowriring, run unit tests, and install @@ -60,7 +60,7 @@ script: # Build examples from installed Autowiring - cd examples - && cmake . + && cmake . -Dautowiring_ARCHITECTURE=x64 && make && cd .. diff --git a/Autowiring.nuspec b/Autowiring.nuspec.in similarity index 99% rename from Autowiring.nuspec rename to Autowiring.nuspec.in index 053839b2f..9525f586a 100644 --- a/Autowiring.nuspec +++ b/Autowiring.nuspec.in @@ -2,7 +2,7 @@ autowiring - 0.2.5 + @autowiring_VERSION@ Leap Motion Leap Motion http://autowiring.io diff --git a/AutowiringConfig.h.in b/AutowiringConfig.h.in index 8d666e1a8..30dcab4bc 100644 --- a/AutowiringConfig.h.in +++ b/AutowiringConfig.h.in @@ -9,8 +9,8 @@ #cmakedefine01 AUTOWIRING_BUILD_AUTONET // Are we linking with C++11 STL? -#cmakedefine01 USE_LIBCXX -#if USE_LIBCXX +#cmakedefine01 autowiring_USE_LIBCXX +#if autowiring_USE_LIBCXX #define AUTOWIRING_USE_LIBCXX 1 #else #define AUTOWIRING_USE_LIBCXX 0 diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a13809a3..cf0a3ca7e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,13 +1,28 @@ cmake_minimum_required(VERSION 3.0) include(version.cmake) project(autowiring VERSION ${autowiring_VERSION}) + include(CTest) +include(CheckTypeSize) + +# Need to classify the architecture before we run anything else +if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm") + set(autowiring_ARCHITECTURE "arm") + set(autowiring_BUILD_64 OFF) +elseif(CMAKE_SIZEOF_VOID_P STREQUAL 4) + set(autowiring_ARCHITECTURE "x86") + set(autowiring_BUILD_64 OFF) +else() + set(autowiring_ARCHITECTURE "x64") + set(autowiring_BUILD_64 ON) +endif() +message(STATUS "Using architecture: ${autowiring_ARCHITECTURE}") # Determine whether Autowiring has been embedded in another project if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) - set(AUTOWIRING_IS_EMBEDDED) + set(AUTOWIRING_IS_EMBEDDED OFF) else() - set(AUTOWIRING_IS_EMBEDDED "TRUE") + set(AUTOWIRING_IS_EMBEDDED ON) endif() # If there's an external libraries directory path, use it as a search prefix @@ -16,43 +31,71 @@ if(EXTERNAL_LIBRARY_DIR) list(APPEND CMAKE_INCLUDE_PATH ${EXTERNAL_LIBRARY_DIR}) endif() -# Offer option for autowiring_USE_LIBCXX only if not defined by enclosing project -# Check for existing definition of autowiring_USE_LIBCXX -if(NOT DEFINED autowiring_USE_LIBCXX) - option(autowiring_USE_LIBCXX "Build Autowiring using c++11" ON) +if(APPLE) + # Offer option for autowiring_USE_LIBCXX + # Check for existing definition of autowiring_USE_LIBCXX + if(NOT DEFINED autowiring_USE_LIBCXX) + option(autowiring_USE_LIBCXX "Build Autowiring using c++11" ON) + else() + if(NOT autowiring_USE_LIBCXX) + message("Parent project has set autowiring_USE_LIBCXX = OFF -> Build Autowiring using c++98") + endif() + endif() else() - if(NOT autowiring_USE_LIBCXX) - message("Parent project has set autowiring_USE_LIBCXX = OFF -> Build Autowiring using c++98") + # Always use libc++ on other platforms + set(autowiring_USE_LIBCXX ON) +endif() + +if(CMAKE_COMPILER_IS_GNUCC) + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.8") + message(FATAL_ERROR "GCC version 4.8 minimum is required to build Autowiring") + endif() +elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "18.0") + message(FATAL_ERROR "MSVC 2013 minimum is required to build Autowiring") endif() endif() +message("Version number ${CMAKE_CXX_COMPILER_VERSION}") + +# Always use c++11 compiler if(NOT WIN32) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") - set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libstdc++") endif() -if(autowiring_USE_LIBCXX) - # Clang needs special additional flags to build with C++11 - if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") - # Apple needs us to tell it that we're using libc++, or it will try to use libstdc++ instead + +# Clang needs special additional flags to build with C++11 +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") + # Apple needs us to tell it that we're using libc++, or it will try to use libstdc++ instead + if(autowiring_USE_LIBCXX) message("AppleClang C++11") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") - elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - message("Clang C++11") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lstdc++") - elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - message("GCC C++11") - endif() - - # Also need position-independent code to make things work correctly on certain 64-bit machines - if(${CMAKE_SIZEOF_VOID_P} STREQUAL 8) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") + else() + message("AppleClang C++11 with libstdc++") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libstdc++") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libstdc++") endif() +elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + message("Clang C++11") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lstdc++") +elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + message("GCC C++11") +endif() + +# Also need position-independent code to make things work correctly on certain 64-bit machines +if(NOT WIN32 AND autowiring_BUILD_64) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") endif() set_property(GLOBAL PROPERTY USE_FOLDERS ON) include(CMakeModules/pch.cmake) -set(AUTOWIRING_BUILD_AUTONET_DEFAULT ON) + +if(autowiring_ARCHITECTURE STREQUAL "arm") + # Currently cannot build Autonet for ARM, so default this off on that platform + set(AUTOWIRING_BUILD_AUTONET_DEFAULT OFF) +else() + set(AUTOWIRING_BUILD_AUTONET_DEFAULT ON) +endif() # We don't build tests unless we're being built by ourselves in our own source tree # When we're embedded in someone else's subtree, it's not likely that they will want @@ -80,10 +123,23 @@ else() set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/lib) endif() -# 64-bit installations should suffix with 64 -if(${CMAKE_SIZEOF_VOID_P} STREQUAL 8) - set(CMAKE_DEBUG_POSTFIX "64") - set(CMAKE_RELEASE_POSTFIX "64") +# ARM installations should have "arm" as the suffix for the generated libraries and should be +# position-independent +if(autowiring_ARCHITECTURE STREQUAL "arm") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") + + foreach(config IN LISTS CMAKE_CONFIGURATION_TYPES) + string(TOUPPER ${config} config) + string(CONCAT CMAKE_${config}_POSTFIX "${CMAKE_${config}_POSTFIX}" "64") + endforeach() +endif() + +# 64-bit installations should suffix with 64 regardless of the CPU type (arm or intel) +if(autowiring_BUILD_64) + foreach(config IN LISTS CMAKE_CONFIGURATION_TYPES) + string(TOUPPER ${config} config) + string(CONCAT CMAKE_${config}_POSTFIX "${CMAKE_${config}_POSTFIX}" "64") + endforeach() endif() # Postfix on all debug libraries should be "d" @@ -123,14 +179,10 @@ include_directories( ) # CMake configurations -if(${CMAKE_SIZEOF_VOID_P} STREQUAL 8) - set(autowiring_ARCHITECTURE "64") -else() - set(autowiring_ARCHITECTURE "32") -endif() configure_file(autowiring-config.cmake.in autowiring-config.cmake @ONLY) configure_file(autowiring-configVersion.cmake.in autowiring-configVersion.cmake @ONLY) configure_file(AutowiringConfig.h.in ${PROJECT_SOURCE_DIR}/autowiring/AutowiringConfig.h @ONLY) +configure_file(Autowiring.nuspec.in ${PROJECT_BINARY_DIR}/Autowiring.nuspec @ONLY) # Recurse through source directories add_subdirectory(src) @@ -160,7 +212,7 @@ if(NOT AUTOWIRING_IS_EMBEDDED) install(EXPORT AutowiringTargets FILE AutowiringTargets.cmake COMPONENT autowiring NAMESPACE Autowiring:: DESTINATION cmake CONFIGURATIONS ${CMAKE_CONFIGURATION_TYPES}) # 64-bit installations get a different upgrade GUID - if(CMAKE_SIZEOF_VOID_P STREQUAL 8) + if(autowiring_BUILD_64) set(autowiring_GUID_LAST_CHAR E) else() set(autowiring_GUID_LAST_CHAR D) diff --git a/README.md b/README.md index 0081715fb..0752f138d 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,10 @@ CentOS systems use yum. The major apparent difference to the user will be that make test sudo make install +If you want to build for 32-bit Linux, run the following CMake command instead: + + cmake . -DCMAKE_CXX_FLAGS=-m32 -DCMAKE_C_FLAGS=-m32 + ### Windows Unfortunately, Windows doesn't have any sort of nifty package manager, and this requires that you download and install the boost dependency by hand. Once @@ -47,6 +51,21 @@ At this point, you'll have a solution file in your root directory called "Autowi target then Autowiring will be installed on your system. As with the other platforms, CMake will be able to find autowiring when it's installed this way via the [find_package](http://www.cmake.org/cmake/help/v3.0/command/find_package.html) command. +### Arm-linux + +Building on Android requires the use of a toolchain file. You will need to use an alternate prefix path if you are trying to cross-compile, the prefix path +should contain your version of the Boost libraries built for Android. To configure, use the following invocation: + + cmake . -DCMAKE_TOOLCHAIN_FILE=toolchain-arm.cmake -DCMAKE_PREFIX_PATH:PATH=/your/lib/path + +### Android + +Similar requirements to Arm-linux, you must specify a toolchain file. You must also specify the path to your Android toolchain directory. Make sure you update +/opt/android-standalone-toolchain to point to your actual Android standalone toolchain directory. If you aren't cross-compiling, then simply run cmake with +no options. + + cmake . -DCMAKE_TOOLCHAIN_FILE=toolchain-android.cmake -DLLVM_ANDROID_TOOLCHAIN_DIR=/opt/android-standalone-toolchain + # Install Autowiring uses CPack, which knows how to use rpm/deb/wix/dragndrop, and will target the correct version depending on which system you're on. To build diff --git a/autowiring-configVersion.cmake.in b/autowiring-configVersion.cmake.in index c9603635f..14d5d9ae9 100644 --- a/autowiring-configVersion.cmake.in +++ b/autowiring-configVersion.cmake.in @@ -1,9 +1,63 @@ set(PACKAGE_VERSION "@autowiring_VERSION@") -# Verify that we have a bit depth matching the bit depth desired by the customer -if(NOT ${CMAKE_SIZEOF_VOID_P} STREQUAL @CMAKE_SIZEOF_VOID_P@) +if(autowiring_DEBUG) + message(STATUS "Debug mode on") + message(STATUS "Installed autowiring_VERSION: @autowiring_VERSION@") + + message(STATUS "Installed autowiring_ARCHITECTURE: @autowiring_ARCHITECTURE@") + message(STATUS "Configured autowiring_ARCHITECTURE: ${autowiring_ARCHITECTURE}") + + message(STATUS "Installed CMAKE_SIZEOF_VOID_P: @CMAKE_SIZEOF_VOID_P@") + message(STATUS "Configured CMAKE_SIZEOF_VOID_P: ${CMAKE_SIZEOF_VOID_P}") + + message(STATUS "Installed using autowiring_USE_LIBCXX: @autowiring_USE_LIBCXX@") + message(STATUS "Configured using autowiring_USE_LIBCXX: ${autowiring_USE_LIBCXX}") +endif() + +# If the customer has an override architecture requirement, use that +if(DEFINED autowiring_ARCHITECTURE) + string(REGEX MATCH "amd64|x86_64|x64" autowiring_is_x64 ${autowiring_ARCHITECTURE}) + string(REGEX MATCH "i386|x86" autowiring_is_x86 ${autowiring_ARCHITECTURE}) + string(REGEX MATCH "arm" autowiring_is_arm ${autowiring_ARCHITECTURE}) + + # Clear the autowiring_ARCHITECTURE variable so we can tell if something went wrong + set(autowiring_ARCHITECTURE) + + # Classify + if(autowiring_is_x86) + set(autowiring_ARCHITECTURE x86) + elseif(autowiring_is_x64) + set(autowiring_ARCHITECTURE x64) + elseif(autowiring_is_arm) + set(autowiring_ARCHITECTURE arm) + endif() + + if(NOT DEFINED autowiring_ARCHITECTURE) + message(WARNING "Unrecognized architecture ${autowiring_ARCHITECTURE}") + set(autowiring_WORD_WIDTH -1) + endif() +else() + # Try to infer what the user wants + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm") + set(autowiring_ARCHITECTURE arm) + elseif(CMAKE_SIZEOF_VOID_P EQUAL "8") + set(autowiring_ARCHITECTURE x64) + else() + set(autowiring_ARCHITECTURE x86) + endif() +endif() + +if(autowiring_DEBUG) + message(STATUS "autowiring_ARCHITECTURE: ${autowiring_ARCHITECTURE}") +endif() + +# Verify that we have a word width matching the bit depth desired by the customer +if(NOT autowiring_ARCHITECTURE STREQUAL "@autowiring_ARCHITECTURE@") set(PACKAGE_VERSION_COMPATIBLE FALSE) set(PACKAGE_VERSION_UNSUITABLE TRUE) + if(autowiring_DEBUG) + message(STATUS "Requested architecture of ${autowiring_ARCHITECTURE} not compatible with @autowiring_ARCHITECTURE@") + endif() return() endif() diff --git a/autowiring/AutoPacket.h b/autowiring/AutoPacket.h index 35d6cd168..1175db37a 100644 --- a/autowiring/AutoPacket.h +++ b/autowiring/AutoPacket.h @@ -2,15 +2,15 @@ #pragma once #include "AnySharedPointer.h" #include "at_exit.h" -#include "DataFlow.h" #include "AutoCheckout.h" +#include "DataFlow.h" #include "DecorationDisposition.h" #include "demangle.h" -#include "is_shared_ptr.h" -#include "ObjectPool.h" +#include "hash_tuple.h" #include "is_any.h" +#include "is_shared_ptr.h" #include "MicroAutoFilter.h" -#include "hash_tuple.h" +#include "ObjectPool.h" #include #include #include @@ -199,6 +199,8 @@ class AutoPacket: /// template const T& Get(const std::type_info& source = typeid(void)) const { + static_assert(!std::is_same::value, "Oops!"); + const T* retVal; if(!Get(retVal, source)) { std::stringstream ss; diff --git a/autowiring/AutoPacketFactory.h b/autowiring/AutoPacketFactory.h index d443e96c5..948a62e57 100644 --- a/autowiring/AutoPacketFactory.h +++ b/autowiring/AutoPacketFactory.h @@ -13,6 +13,7 @@ #include STL_UNORDERED_SET struct AdjacencyEntry; +class AutoPacketFactory; class Deferred; class DispatchQueue; @@ -210,12 +211,7 @@ class AutoPacketFactory: void PipeOneData(const std::type_info* nodeOutType, const std::type_info* nodeInType, const std::type_info* dataType, bool enable); void PipeAllData(const std::type_info* nodeOutType, const std::type_info* nodeInType, bool enable); - static bool IsAutoPacketType(const std::type_info& dataType) { - return - dataType == typeid(AutoPacket) || - dataType == typeid(auto_arg::id_type) || - dataType == typeid(auto_arg::id_type); - } + static bool IsAutoPacketType(const std::type_info& dataType); public: /// @@ -225,11 +221,13 @@ class AutoPacketFactory: std::shared_ptr NewPacket(void); /// the number of outstanding AutoPackets - size_t GetOutstanding(void) const { return m_packets.GetOutstanding(); } + size_t GetOutstanding(void) const; }; // Extern explicit template instantiation declarations added to prevent // exterior instantation of internally used template instances +extern template class ObjectPool; extern template class RegType; extern template struct SlotInformationStump; extern template const std::shared_ptr& SharedPointerSlot::as(void) const; +extern template std::shared_ptr autowiring::fast_pointer_cast(const std::shared_ptr& Other); \ No newline at end of file diff --git a/autowiring/C++11/cpp11.h b/autowiring/C++11/cpp11.h index 09ebd5304..fd79f29c4 100644 --- a/autowiring/C++11/cpp11.h +++ b/autowiring/C++11/cpp11.h @@ -89,7 +89,7 @@ /********************* * exception_ptr availability *********************/ -#if (defined(__APPLE__) && !defined(_LIBCPP_VERSION)) || __ANDROID__ +#if (defined(__APPLE__) && !defined(_LIBCPP_VERSION)) #define EXCEPTION_PTR_HEADER #else #define EXCEPTION_PTR_HEADER @@ -108,9 +108,10 @@ /********************* * future availability *********************/ -#if _MSC_VER >= 1700 || (STL11_ALLOWED && !__ANDROID__) +#if (_MSC_VER >= 1700 || (STL11_ALLOWED)) && !__ANDROID__ #define FUTURE_HEADER #else + // As of NDK r10, we still don't have an implementation of "future" for Android #define FUTURE_HEADER #endif @@ -290,7 +291,7 @@ /** * Mutex */ -#if STL11_ALLOWED && !__ANDROID__ +#if STL11_ALLOWED #define MUTEX_HEADER #else #define MUTEX_HEADER @@ -299,7 +300,7 @@ /** * Thread */ -#if STL11_ALLOWED && !__ANDROID__ +#if STL11_ALLOWED #define THREAD_HEADER #define _WEBSOCKETPP_CPP11_THREAD_ #else @@ -309,7 +310,7 @@ /** * Chrono */ -#if STL11_ALLOWED && !__ANDROID__ +#if STL11_ALLOWED #define CHRONO_HEADER #else #define CHRONO_HEADER diff --git a/autowiring/CallExtractor.h b/autowiring/CallExtractor.h index 4f8c7a462..a10988039 100644 --- a/autowiring/CallExtractor.h +++ b/autowiring/CallExtractor.h @@ -1,9 +1,9 @@ // Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved. #pragma once +#include "auto_arg.h" +#include "AutoPacket.h" #include "DataFlow.h" #include "Decompose.h" -#include "AutoPacket.h" -#include "auto_arg.h" class Deferred; diff --git a/autowiring/CoreContext.h b/autowiring/CoreContext.h index 2c3cdef97..775d1085d 100644 --- a/autowiring/CoreContext.h +++ b/autowiring/CoreContext.h @@ -34,7 +34,6 @@ #include STL_UNORDERED_SET class AutoInjectable; -class AutoPacketFactory; class DeferrableAutowiring; class BasicThread; class BoltBase; @@ -338,11 +337,6 @@ class CoreContext: /// void FindByTypeRecursive(AnySharedPointer& reference, const AutoSearchLambda& searchFn) const; - /// - /// Returns or constructs a new AutoPacketFactory instance - /// - std::shared_ptr GetPacketFactory(void); - /// /// Adds the specified deferrable autowiring to be satisfied at a later date when its matched type is inserted /// diff --git a/autowiring/MicroAutoFilter.h b/autowiring/MicroAutoFilter.h index 7043fb2f5..f03bb368f 100644 --- a/autowiring/MicroAutoFilter.h +++ b/autowiring/MicroAutoFilter.h @@ -2,6 +2,7 @@ #pragma once #include "Deferred.h" +#include FUNCTIONAL_HEADER /// /// Transmutes a function returning void to an instance that can be called by AutoPacket. diff --git a/autowiring/auto_arg.h b/autowiring/auto_arg.h index 1eaf51421..298b82167 100644 --- a/autowiring/auto_arg.h +++ b/autowiring/auto_arg.h @@ -1,6 +1,5 @@ // Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved. #pragma once - #include "auto_in.h" #include "auto_out.h" #include "optional_ptr.h" diff --git a/autowiring/demangle.h b/autowiring/demangle.h index aeb071f6c..2b565b91b 100644 --- a/autowiring/demangle.h +++ b/autowiring/demangle.h @@ -9,6 +9,8 @@ #include MEMORY_HEADER #endif +struct AnySharedPointer; + // // Demangle type names on mac and linux. // Just returns type_info.name() on windows @@ -17,8 +19,11 @@ namespace autowiring { std::string demangle(const std::type_info& ti); std::string demangle(const std::type_info* ti); + std::string demangle(const AnySharedPointer& ptr); + template std::string demangle(const T&) { return demangle(typeid(T)); } + }//namespace autowiring diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 07a5d1b32..13d5fc515 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -5,6 +5,7 @@ project(examples) set(autowiring_VERSION_REQUESTED ${autowiring_VERSION}) set(autowiring_VERSION) +set(autowiring_DEBUG ON) find_package(autowiring ${autowiring_VERSION_REQUESTED} EXACT REQUIRED NO_CMAKE_BUILDS_PATH) message("Found autowiring ${autowiring_VERSION}") message("Include dir is ${autowiring_INCLUDE_DIR}") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 718158e75..c6b6d477f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -22,6 +22,13 @@ if(NOT autowiring_USE_LIBCXX) endif() endif() +# Android also requires boost, but a more limited subset: +if(BUILD_ANDROID) + find_package(Boost COMPONENTS thread REQUIRED) + include_directories(${Boost_INCLUDE_DIR}) + message("Include dirs are ${Boost_INCLUDE_DIR}") +endif() + add_subdirectory(autonet) add_subdirectory(autowiring) add_subdirectory(autotesting) diff --git a/src/autonet/CMakeLists.txt b/src/autonet/CMakeLists.txt index aad2c66e1..7b255f1b1 100644 --- a/src/autonet/CMakeLists.txt +++ b/src/autonet/CMakeLists.txt @@ -9,6 +9,10 @@ if(NOT AUTOWIRING_BUILD_AUTONET) return() endif() +if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm") + message(FATAL_ERROR "Cannot currently build Autonet for ARM processors") +endif() + add_googletest(test) include_directories( ${Boost_INCLUDE_DIR} @@ -33,7 +37,7 @@ rewrite_header_paths(AutoNet_SRCS) ADD_MSVC_PRECOMPILED_HEADER("stdafx.h" "stdafx.cpp" AutoNet_SRCS) add_library(AutoNet SHARED ${AutoNet_SRCS}) -target_link_libraries(AutoNet Autowiring ${Boost_LIBRARIES}) +target_link_libraries(AutoNet PRIVATE ${Boost_LIBRARIES} Autowiring) set_target_properties(AutoNet PROPERTIES INTERFACE_LINK_LIBRARIES Autowiring) set_property(TARGET AutoNet PROPERTY FOLDER "Autowiring") diff --git a/src/autowiring/AutoPacketFactory.cpp b/src/autowiring/AutoPacketFactory.cpp index e803c21e0..fb755df4e 100644 --- a/src/autowiring/AutoPacketFactory.cpp +++ b/src/autowiring/AutoPacketFactory.cpp @@ -2,8 +2,11 @@ #include "stdafx.h" #include "AutoPacketFactory.h" #include "AutoPacket.h" +#include "fast_pointer_cast.h" #include "thread_specific_ptr.h" +template class ObjectPool; + AutoPacketFactory::AutoPacketFactory(void): ContextMember("AutoPacketFactory"), m_parent(GetContext()->GetParentContext()), @@ -30,6 +33,13 @@ std::shared_ptr AutoPacketFactory::NewPacket(void) { return retVal; } +bool AutoPacketFactory::IsAutoPacketType(const std::type_info& dataType) { + return + dataType == typeid(AutoPacket) || + dataType == typeid(auto_arg::id_type) || + dataType == typeid(auto_arg::id_type); +} + bool AutoPacketFactory::Start(std::shared_ptr outstanding) { std::lock_guard lk(m_lock); if(m_wasStopped) @@ -331,6 +341,11 @@ void AutoPacketFactory::PipeAllData(const std::type_info* nodeOutType, const std Invalidate(); } +size_t AutoPacketFactory::GetOutstanding(void) const { + return m_packets.GetOutstanding(); +} + template class RegType; template struct SlotInformationStump; template const std::shared_ptr& SharedPointerSlot::as(void) const; +template std::shared_ptr autowiring::fast_pointer_cast(const std::shared_ptr& Other); \ No newline at end of file diff --git a/src/autowiring/CMakeLists.txt b/src/autowiring/CMakeLists.txt index 4fc0da3a5..a1f127855 100644 --- a/src/autowiring/CMakeLists.txt +++ b/src/autowiring/CMakeLists.txt @@ -201,25 +201,17 @@ ADD_MSVC_PRECOMPILED_HEADER("stdafx.h" "stdafx.cpp" Autowiring_SRCS) add_library(Autowiring STATIC ${Autowiring_SRCS}) -# On Unix, 64-bit code will need to be compiled as position-independent code -if(UNIX) - if(${CMAKE_SIZEOF_VOID_P} STREQUAL 8) - set_target_properties(Autowiring PROPERTIES COMPILE_FLAGS "-fPIC -fvisibility=hidden") - else() - set_target_properties(Autowiring PROPERTIES COMPILE_FLAGS "-fvisibility=hidden") - endif() -endif() - target_include_directories(Autowiring INTERFACE "$" "$/include>" ) set_property(TARGET Autowiring PROPERTY FOLDER "Autowiring") -# The boost C++11 shim is required when building without autowiring_USE_LIBCXX -if(NOT autowiring_USE_LIBCXX) +# The boost C++11 shim is required when building without autowiring_USE_LIBCXX off Windows +# We do not mention the link libraries; rather, we require that downstream clients +# satisfy this link dependency. +if(NOT WIN32 AND NOT autowiring_USE_LIBCXX) find_package(Boost COMPONENTS thread atomic chrono system date_time QUIET) - target_link_libraries(Autowiring ${Boost_LIBRARIES}) endif() # Need multithreading services if available diff --git a/src/autowiring/CoreContext.cpp b/src/autowiring/CoreContext.cpp index 935b90ea2..173b0140c 100644 --- a/src/autowiring/CoreContext.cpp +++ b/src/autowiring/CoreContext.cpp @@ -793,14 +793,6 @@ void CoreContext::FilterFiringException(const JunctionBoxBase* pProxy, Object* p } } -std::shared_ptr CoreContext::GetPacketFactory(void) { - std::shared_ptr pf; - FindByType(pf); - if(!pf) - pf = Inject(); - return pf; -} - void CoreContext::AddDeferredUnsafe(DeferrableAutowiring* deferrable) { // Determine whether a type memo exists right now for the thing we're trying to defer. If it doesn't // exist, we need to inject one in order to allow deferred satisfaction to know what kind of type we @@ -835,7 +827,7 @@ void CoreContext::AddContextMember(const std::shared_ptr& ptr) { } void CoreContext::AddPacketSubscriber(const AutoFilterDescriptor& rhs) { - GetPacketFactory()->AddSubscriber(rhs); + Inject()->AddSubscriber(rhs); } void CoreContext::UnsnoopAutoPacket(const ObjectTraits& traits) { @@ -849,7 +841,7 @@ void CoreContext::UnsnoopAutoPacket(const ObjectTraits& traits) { } // Always remove from this context's PacketFactory: - GetPacketFactory()->RemoveSubscriber(traits.subscriber); + Inject()->RemoveSubscriber(traits.subscriber); // Handoff to parent: if (m_pParent) @@ -863,7 +855,7 @@ std::ostream& operator<<(std::ostream& os, const CoreContext& rhs) { void CoreContext::DebugPrintCurrentExceptionInformation() { try { - std::rethrow_exception(std::current_exception()); + throw; } catch(std::exception& ex) { std::cerr << ex.what() << std::endl; } catch(...) { diff --git a/src/autowiring/demangle.cpp b/src/autowiring/demangle.cpp index db43ed548..f2571d9a9 100644 --- a/src/autowiring/demangle.cpp +++ b/src/autowiring/demangle.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved. #include "stdafx.h" #include "demangle.h" +#include "AnySharedPointer.h" #if __GNUG__ // Mac and linux @@ -21,6 +22,11 @@ std::string autowiring::demangle(const std::type_info& ti) { #endif +std::string autowiring::demangle(const AnySharedPointer& ptr) { + return autowiring::demangle(ptr->type()); +} + std::string autowiring::demangle(const std::type_info* ti) { return autowiring::demangle(*ti); } + diff --git a/src/autowiring/test/CMakeLists.txt b/src/autowiring/test/CMakeLists.txt index f622e0e48..86d78610c 100644 --- a/src/autowiring/test/CMakeLists.txt +++ b/src/autowiring/test/CMakeLists.txt @@ -65,21 +65,41 @@ if(autowiring_USE_LIBCXX) endif() set(AutowiringFixture_SRCS - SelfSelectingFixture.hpp - SelfSelectingFixture.cpp - OtherSelectingFixture.hpp - OtherSelectingFixture.cpp HasForwardOnlyType.hpp HasForwardOnlyType.cpp + MentionsVariousOtherTypes.hpp + MentionsVariousOtherTypes.cpp + OtherSelectingFixture.hpp + OtherSelectingFixture.cpp + SelfSelectingFixture.hpp + SelfSelectingFixture.cpp ) ADD_MSVC_PRECOMPILED_HEADER("stdafx.h" "stdafx.cpp" AutowiringFixture_SRCS) add_library(AutowiringFixture ${AutowiringFixture_SRCS}) set_property(TARGET AutowiringFixture PROPERTY FOLDER "Autowiring") +if(NOT WIN32) + set_target_properties(AutowiringFixture PROPERTIES COMPILE_FLAGS "-fvisibility=hidden") +endif() ADD_MSVC_PRECOMPILED_HEADER("stdafx.h" "stdafx.cpp" AutowiringTest_SRCS) add_executable(AutowiringTest ${AutowiringTest_SRCS}) target_link_libraries(AutowiringTest Autowiring AutowiringFixture AutoTesting) +if(NOT WIN32 AND NOT autowiring_USE_LIBCXX) + find_package(Boost COMPONENTS thread atomic chrono system date_time QUIET) + target_link_libraries(AutowiringTest ${Boost_LIBRARIES}) +endif() + +# Need boost thread on android, because of our use of std::async +if(BUILD_ANDROID) + target_link_libraries(AutowiringTest ${Boost_LIBRARIES}) +endif() + +# Need boost thread on android, because of our use of std::async +if(BUILD_ANDROID) + find_package(Boost COMPONENTS atomic system thread REQUIRED QUIET) + target_link_libraries(AutowiringTest ${Boost_LIBRARIES}) +endif() # Link AutoNet if we've got it if(TARGET AutoNet) diff --git a/src/autowiring/test/ContextEnumeratorTest.cpp b/src/autowiring/test/ContextEnumeratorTest.cpp index 25e088a60..488e62733 100644 --- a/src/autowiring/test/ContextEnumeratorTest.cpp +++ b/src/autowiring/test/ContextEnumeratorTest.cpp @@ -108,9 +108,9 @@ TEST_F(ContextEnumeratorTest, VerifyComplexEnumeration) { // Verify global context structure auto enumerator = ContextEnumeratorT(AutoGlobalContext()); - int globalCount = std::distance(enumerator.begin(), enumerator.end()); + size_t globalCount = std::distance(enumerator.begin(), enumerator.end()); - ASSERT_EQ(globalCount, 2) << "Expected exactly one context in the parent context, found " << globalCount; + ASSERT_EQ(globalCount, 2UL) << "Expected exactly one context in the parent context, found " << globalCount; } TEST_F(ContextEnumeratorTest, SimpleRemovalInterference) { diff --git a/src/autowiring/test/CoreContextTest.cpp b/src/autowiring/test/CoreContextTest.cpp index d9388a74d..3e61a8dbb 100644 --- a/src/autowiring/test/CoreContextTest.cpp +++ b/src/autowiring/test/CoreContextTest.cpp @@ -201,12 +201,17 @@ TEST_F(CoreContextTest, NoEnumerateBeforeBoltReturn) { AutoRequired longTime; // Spin off a thread which will create the new context - auto t = std::async(std::launch::async, [ctxt] { + auto finished = std::make_shared(false); + std::thread t([finished, ctxt] { AutoCreateContextT(); + *finished = true; }); // Verify that the context does not appear until the bolt has finished running: - while(t.wait_for(std::chrono::milliseconds(1)) != std::future_status::ready) + while(!*finished) for(auto cur : ContextEnumeratorT(ctxt)) ASSERT_TRUE(longTime->m_bDoneRunning) << "A context was enumerated before a bolt finished running"; + + // Need to block until this thread is done + t.join(); } \ No newline at end of file diff --git a/src/autowiring/test/CoreJobTest.cpp b/src/autowiring/test/CoreJobTest.cpp index f9869c93e..ea24a0c46 100644 --- a/src/autowiring/test/CoreJobTest.cpp +++ b/src/autowiring/test/CoreJobTest.cpp @@ -2,7 +2,6 @@ #include "stdafx.h" #include #include THREAD_HEADER -#include FUTURE_HEADER class CoreJobTest: public testing::Test @@ -15,21 +14,34 @@ TEST_F(CoreJobTest, VerifySimpleProperties) { ASSERT_FALSE(ctxt->IsInitiated()) << "CoreJob reported it could receive events before its enclosing context was created"; // Create a thread which will delay for acceptance, and then quit: - auto future = std::async(std::launch::async, [this, &ctxt] { + std::mutex lock; + std::condition_variable cv; + auto done = std::make_shared(false); + std::thread t([&] { ctxt->DelayUntilInitiated(); + + (std::lock_guard)lock, + *done = true, + cv.notify_all(); }); + auto wait = [&] (std::chrono::milliseconds timeout) { + std::unique_lock lk(lock); + return cv.wait_for(lk, timeout, [&] { return *done; }); + }; + // Verify that this thread doesn't back out right away: - ASSERT_EQ(std::future_status::timeout, future.wait_for(std::chrono::milliseconds(10))) << "CoreJob did not block a client who was waiting for its readiness to accept dispatchers"; + ASSERT_FALSE(wait(std::chrono::milliseconds(10))) << "CoreJob did not block a client who was waiting for its readiness to accept dispatchers"; // Now start the context and verify that certain properties changed as anticipated: ctxt->Initiate(); ASSERT_TRUE(ctxt->DelayUntilInitiated()) << "CoreJob did not correctly delay for dispatch acceptance"; // Verify that the blocked thread has become unblocked and quits properly: - ASSERT_EQ(std::future_status::ready, future.wait_for(std::chrono::seconds(1))) << "CoreJob did not correctly signal a blocked thread that it was ready to accept dispatchers"; + ASSERT_TRUE(wait(std::chrono::seconds(1))) << "CoreJob did not correctly signal a blocked thread that it was ready to accept dispatchers"; ctxt->SignalShutdown(true); + t.join(); } TEST_F(CoreJobTest, VerifySimpleSubmission) { diff --git a/src/autowiring/test/ForeignTest.cpp b/src/autowiring/test/ForeignTest.cpp index ac16b45a7..b27868bdd 100644 --- a/src/autowiring/test/ForeignTest.cpp +++ b/src/autowiring/test/ForeignTest.cpp @@ -28,7 +28,7 @@ class ForeignFactoryA { class ForeignFactoryB { public: std::tuple New(void) { - ForeignTypeImpl* rv; + ForeignTypeImpl* rv = nullptr; return std::tuple(rv, rv); } }; diff --git a/src/autowiring/test/MentionsVariousOtherTypes.cpp b/src/autowiring/test/MentionsVariousOtherTypes.cpp new file mode 100644 index 000000000..180d1f363 --- /dev/null +++ b/src/autowiring/test/MentionsVariousOtherTypes.cpp @@ -0,0 +1,7 @@ +// Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved. +#include "stdafx.h" +#include "MentionsVariousOtherTypes.hpp" + +MentionsVariousOtherTypes::MentionsVariousOtherTypes(void) { + AutoRequired(); +} \ No newline at end of file diff --git a/src/autowiring/test/MentionsVariousOtherTypes.hpp b/src/autowiring/test/MentionsVariousOtherTypes.hpp new file mode 100644 index 000000000..4a55e4345 --- /dev/null +++ b/src/autowiring/test/MentionsVariousOtherTypes.hpp @@ -0,0 +1,7 @@ +// Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved. +#pragma once + +class MentionsVariousOtherTypes { +public: + MentionsVariousOtherTypes(void); +}; \ No newline at end of file diff --git a/src/autowiring/test/ObjectPoolTest.cpp b/src/autowiring/test/ObjectPoolTest.cpp index 42abc0d35..c047b5c5d 100644 --- a/src/autowiring/test/ObjectPoolTest.cpp +++ b/src/autowiring/test/ObjectPoolTest.cpp @@ -328,3 +328,25 @@ TEST_F(ObjectPoolTest, MovableObjectPoolAysnc) { // Verify that new pool got all of the objects: ASSERT_EQ(s_count, to.GetCached()) << "Object pool move operation did not correctly relay checked out types"; } + +TEST_F(ObjectPoolTest, VerifyInitializerFinalizer) { + auto initFlag = std::make_shared(false); + auto termFlag = std::make_shared(false); + + ObjectPool pool( + &DefaultCreate, + [initFlag](bool&) { *initFlag = true; }, + [termFlag](bool&) { *termFlag = true; } + ); + + // Issue a shared pointer, this shouldn't invoke the finalizer but should invoke the initializer + auto issued = pool.Wait(); + ASSERT_TRUE(*initFlag) << "Item issued from a pool was not properly initialized"; + ASSERT_FALSE(*termFlag) << "Item issued from a pool was finalized before it was released"; + + // Now return the issued item, and verify that the correct functions get called + *initFlag = false; + issued.reset(); + ASSERT_FALSE(*initFlag) << "Returned item incorrectly caused a new initialization"; + ASSERT_TRUE(*termFlag) << "Returned item was not correctly finalized"; +} \ No newline at end of file diff --git a/src/autowiring/test/SelfSelectingFixture.cpp b/src/autowiring/test/SelfSelectingFixture.cpp index bce19e60b..b31b7d75e 100644 --- a/src/autowiring/test/SelfSelectingFixture.cpp +++ b/src/autowiring/test/SelfSelectingFixture.cpp @@ -5,7 +5,8 @@ SelfSelectingFixture::SelfSelectingFixture(void) : magic(10010) -{} +{ +} bool SelfSelectingFixture::IsMagicCorrect(void) const { return magic == 10010; diff --git a/src/autowiring/test/SelfSelectingFixtureTest.cpp b/src/autowiring/test/SelfSelectingFixtureTest.cpp index a6a35b1fc..ec72e9be2 100644 --- a/src/autowiring/test/SelfSelectingFixtureTest.cpp +++ b/src/autowiring/test/SelfSelectingFixtureTest.cpp @@ -1,7 +1,8 @@ // Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved. #include "stdafx.h" -#include "SelfSelectingFixture.hpp" #include "OtherSelectingFixture.hpp" +#include "MentionsVariousOtherTypes.hpp" +#include "SelfSelectingFixture.hpp" #include class SelfSelectingFixtureTest: @@ -69,3 +70,7 @@ TEST_F(SelfSelectingFixtureTest, ExteriorFixtureTest) { // Verify that both bolts, including the one we shall not name, made it in: ASSERT_EQ(2UL, created->GetMemberCount()) << "An unuttered fixture was eliminated by the linker unexpectedly"; } + +TEST_F(SelfSelectingFixtureTest, DoNothingExceptMention) { + MentionsVariousOtherTypes mvot; +} \ No newline at end of file diff --git a/toolchain-android.cmake b/toolchain-android.cmake new file mode 100644 index 000000000..7d7a9593a --- /dev/null +++ b/toolchain-android.cmake @@ -0,0 +1,16 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR arm) +set(CMAKE_SYSTEM_VERSION 1) +set(BUILD_ARM 0) +set(BUILD_ANDROID 1) +set(ARM_TARGET "armeabi-v7a") +set(LOCAL_ARM_NEON "true") +set(ANDROID_COMMON_FLAGS " --sysroot=${LLVM_ANDROID_TOOLCHAIN_DIR}/sysroot -B${LLVM_ANDROID_TOOLCHAIN_DIR} ") +set(CMAKE_C_FLAGS "${ANDROID_COMMON_FLAGS}" CACHE STRING "toolchain_cflags" FORCE) +set(CMAKE_CXX_FLAGS "${ANDROID_COMMON_FLAGS}" CACHE STRING "toolchain_cxxflags" FORCE) +set(CMAKE_LINK_FLAGS "${ANDROID_COMMON_FLAGS}" CACHE STRING "toolchain_linkflags" FORCE) +set(CMAKE_C_COMPILER ${LLVM_ANDROID_TOOLCHAIN_DIR}/bin/arm-linux-androideabi-gcc) +set(CMAKE_CXX_COMPILER ${LLVM_ANDROID_TOOLCHAIN_DIR}/bin/arm-linux-androideabi-g++) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/toolchain-arm.cmake b/toolchain-arm.cmake new file mode 100644 index 000000000..7e7da4cd2 --- /dev/null +++ b/toolchain-arm.cmake @@ -0,0 +1,8 @@ + set(CMAKE_SYSTEM_NAME Linux) + set(CMAKE_SYSTEM_PROCESSOR arm) + set(CMAKE_SYSTEM_VERSION 1) + set(CMAKE_C_COMPILER /usr/bin/arm-linux-gnueabihf-gcc) + set(CMAKE_CXX_COMPILER /usr/bin/arm-linux-gnueabihf-g++) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/version.cmake b/version.cmake index b98e22762..f16ac467e 100644 --- a/version.cmake +++ b/version.cmake @@ -1 +1 @@ -set(autowiring_VERSION 0.2.6) +set(autowiring_VERSION 0.2.7)