<NME> OpenSimMacros.cmake
<BEF> include(CMakeParseArguments)

# Add a relative path to the run-path of a shared library. The run-path allows
# a library to find the libraries it depends on without the need to set the
#   argument. Otherwise, omit.
# LOWERINCLUDEDIRNAME: When installing the headers for this library, make the
#   name of the library all lower-case (e.g., Lepton -> lepton).
# KIT: Name of the library (e.g., Common).
# AUTHORS: A string listing authors of the library.
# LINKLIBS: List of libraries (targets) to link against.
#   affects Mac.
# FROM: The path (relative to the OpenSim installation root) of the
#   executable/library that is loading a dependent library.
# TO: The path (relative to the OpenSim installation root) where the dependent
#   library is located.
function(OpenSimAddInstallRPATH)
    set(options EXECUTABLE LOADER)
    set(oneValueArgs TARGET FROM TO)
    set(multiValueArgs)
    cmake_parse_arguments(
        OSIMRP "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
    if(OSIMRP_EXECUTABLE EQUAL OSIMRP_LOADER) 
        message(AUTHOR_WARNING "Cannot specify both EXECUTABLE and LOADER.")
    endif()

    if(NOT OPENSIM_USE_INSTALL_RPATH)
        return()
    endif()

    if(APPLE)
        if(OSIMRP_EXECUTABLE)
            set(rpath_macro "\@executable_path")
    # Parse arguments.
    # ----------------
    # http://www.cmake.org/cmake/help/v2.8.9/cmake.html#module:CMakeParseArguments
    set(options VENDORLIB LOWERINCLUDEDIRNAME)
    set(oneValueArgs KIT AUTHORS)
    set(multiValueArgs LINKLIBS INCLUDES SOURCES TESTDIRS INCLUDEDIRS)
    cmake_parse_arguments(
    file(RELATIVE_PATH to_root "${CMAKE_INSTALL_PREFIX}/${OSIMRP_FROM}"
        "${CMAKE_INSTALL_PREFIX}")
    set_property(TARGET ${OSIMRP_TARGET} APPEND PROPERTY INSTALL_RPATH
        "${rpath_macro}/${to_root}${OSIMRP_TO}")
endfunction()

# Similar to OpenSimAddInstallRPATH except the run-path is the same directory
# loader (e.g., "@loader_path/"). Arguments:
#
# TARGET: The CMake target to which the run-path should be added.
function(OpenSimAddInstallRPATHSelf)
    set(options)
    set(oneValueArgs TARGET)
    set(multiValueArgs)
    cmake_parse_arguments(
        OSIMRP "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

    if(NOT OPENSIM_USE_INSTALL_RPATH)
        return()
    endif()

    # By specifing "" and "" for FROM and TO, the resulting RPATH will simply
    # be "${rpath_macro}/".
    OpenSimAddInstallRPATH(TARGET ${OSIMRP_TARGET} LOADER FROM "" TO "")

endfunction()

# Similar to OpenSimAddInstallRPATH, but specifically for adding a run-path to
# the Simbody libraries copied into the OpenSim installation. If Simbody is not
# copied into the OpenSim installation (OPENSIM_COPY_DEPENDENCIES=OFF) or the
# copied Simbody libraries are installed to the same folder as the OpenSim
# libraries (OPENSIM_INSTALL_UNIX_FHS=ON), then this function does nothing.
#
# TARGET: The CMake target to which the run-path should be added.
# ABSOLUTE: Add an absolute run-path to the Simbody libraries in the OpenSim
#   installation. If you specify this argument, then you should not specify
#   EXECTUABLE, LOADER, or FROM.
# EXECUTABLE, LOADER: Specify one of these flags to indicate whether the
#   run-path is relative to the executable's location or relative to the loader
#   (the library/executable that attempts to load the dependent library). Only
#   affects Mac.
# FROM: The path (relative to the OpenSim installation root) of the
#   executable/library that is loading a dependent Simbody library.
function(OpenSimAddInstallRPATHSimbody)
    set(options EXECUTABLE LOADER ABSOLUTE)
    set(oneValueArgs TARGET FROM)
    set(multiValueArgs)
    cmake_parse_arguments(
        OSIMRP "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
    if(OSIMRP_ABSOLUTE AND (OSIMRP_FROM OR OSIMRP_EXECUTABLE OR OSIMRP_LOADER))
        message(AUTHOR_WARNING
            "Cannot specify both ABSOLUTE and FROM, EXECUTABLE, or LOADER.")
    endif()

    if(NOT OPENSIM_USE_INSTALL_RPATH OR NOT OPENSIM_COPY_DEPENDENCIES
            OR OPENSIM_INSTALL_UNIX_FHS)
        return()
        RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
        LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
        ARCHIVE DESTINATION "${OPENSIM_INSTALL_ARCHIVEDIR}")

    # Install headers.
    # ----------------
                FROM ${OSIMRP_FROM} TO ${root_to_simbody_lib_dir})
        endif()
    endif()
endfunction()

# Similar to OpenSimAddInstallRPATH, but specifically for adding an absolute
# run-path.
#
# TARGET: The CMake target to which the run-path should be added.
# TO: The path (relative to the OpenSim installation root) where the dependent
#   library is located.
function(OpenSimAddInstallRPATHAbsolute)
    set(options)
    set(oneValueArgs TARGET TO)
    set(multiValueArgs)
    cmake_parse_arguments(
        OSIMRP "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

    if(NOT OPENSIM_USE_INSTALL_RPATH)
        return()
    endif()

    set_property(TARGET ${OSIMRP_TARGET} APPEND PROPERTY INSTALL_RPATH
        "${CMAKE_INSTALL_PREFIX}/${OSIMRP_TO}")
endfunction()

# Create an OpenSim API library. Here are the arguments:
# VENDORLIB: If this is a vendor library, specify "VENDORLIB" as the first
#   argument. Otherwise, omit.
# LOWERINCLUDEDIRNAME: When installing the headers for this library, make the
#   name of the library all lower-case (e.g., Lepton -> lepton).
# EXCLUDEFROMPYTHON: Do not install this library into the python package.
# KIT: Name of the library (e.g., Common).
# AUTHORS: A string listing authors of the library.
# LINKLIBS: List of libraries (targets) to link against.
# INCLUDES: List of header files for the library (obtain via file(GLOB ...)).
# SOURCES: List of cpp files for the library (obtain via file(GLOB ...)).
# TESTDIRS: List of subdirectories that contain tests (and a CMakeLists.txt).
# INCLUDEDIRS (optional): Affects how header files are installed. Use this if
#   the library directory contains subdirectories with header files. If this is
#   the case, this variable should be a list of those subdirectories (relative
#   paths). See OpenSim/Simulation/CMakeLists.txt for an example. If omitted,
#   all the headers specified under INCLUDES are installed into the same
#   directory in the installation tree.
# INCLUDEINSTALLREL (optional): If INCLUDEDIRS is specified, remove
#   "INCLUDEINSTALLREL" from the location of the installed headers.
#
        #    list(APPEND run_path_list
        #           "\@loader_path/${lib_dir_to_simbody_lib_dir}")
        #endif()
        # Use APPEND to include the BTK RPATH, set in CMAKE_INSTALL_RPATH.
        set_property(TARGET ${OSIMADDLIB_LIBRARY_NAME} APPEND PROPERTY
            INSTALL_RPATH "${run_path_list}"
#       TESTDIRS "Test"
#       )
function(OpenSimAddLibrary)

    # Parse arguments.
    # ----------------
    # http://www.cmake.org/cmake/help/v2.8.9/cmake.html#module:CMakeParseArguments
    set(options VENDORLIB LOWERINCLUDEDIRNAME EXCLUDEFROMPYTHON)
    set(oneValueArgs KIT AUTHORS INCLUDEINSTALLREL)
    set(multiValueArgs LINKLIBS INCLUDES SOURCES TESTDIRS INCLUDEDIRS)
    cmake_parse_arguments(
        OSIMADDLIB "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

    string(TOUPPER "${OSIMADDLIB_KIT}" OSIMADDLIB_UKIT)


    # Version stuff.
    # --------------
    set(OSIMADDLIB_LIBRARY_NAME osim${OSIMADDLIB_KIT})

    add_definitions(
        -DOPENSIM_${OSIMADDLIB_UKIT}_LIBRARY_NAME=${OSIMADDLIB_LIBRARY_NAME}
        -DOPENSIM_${OSIMADDLIB_UKIT}_MAJOR_VERSION=${OPENSIM_MAJOR_VERSION}
        -DOPENSIM_${OSIMADDLIB_UKIT}_MINOR_VERSION=${OPENSIM_MINOR_VERSION}
        -DOPENSIM_${OSIMADDLIB_UKIT}_BUILD_VERSION=${OPENSIM_PATCH_VERSION}
        -DOPENSIM_${OSIMADDLIB_UKIT}_COPYRIGHT_YEARS="2005-2017"
        -DOPENSIM_${OSIMADDLIB_UKIT}_AUTHORS="${AUTHORS}"
        -DOPENSIM_${OSIMADDLIB_UKIT}_TYPE="Shared"
        )


    # Add the library.
    # ----------------
    # These next few lines are the most important:

    # Create the library using the provided source and include files.
    add_library(${OSIMADDLIB_LIBRARY_NAME} SHARED
        ${OSIMADDLIB_SOURCES} ${OSIMADDLIB_INCLUDES})

    target_include_directories(${OSIMADDLIB_LIBRARY_NAME} 
        # Used when building this target:
        PRIVATE "${OpenSim_SOURCE_DIR}"
                "${OpenSim_SOURCE_DIR}/Vendors/lepton/include"
        # Used by other targets in this project:
        INTERFACE $<BUILD_INTERFACE:${OpenSim_SOURCE_DIR}>
                  $<BUILD_INTERFACE:${OpenSim_SOURCE_DIR}/Vendors/lepton/include>
        # Used by client projects using an installed OpenSim:
        INTERFACE $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
                  $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/OpenSim>
        )

    # This target links to the libraries provided as arguments to this func.
    target_link_libraries(${OSIMADDLIB_LIBRARY_NAME} ${OSIMADDLIB_LINKLIBS})

    # This is for exporting classes on Windows.
    if(OSIMADDLIB_VENDORLIB)
	    set(OSIMADDLIB_FOLDER "Vendor Libraries")
    else()
		set(OSIMADDLIB_FOLDER "Libraries")
    endif()
    set_target_properties(${OSIMADDLIB_LIBRARY_NAME} PROPERTIES
       DEFINE_SYMBOL OSIM${OSIMADDLIB_UKIT}_EXPORTS
       FOLDER "${OSIMADDLIB_FOLDER}" # For Visual Studio.
    )

    # Install.
    # --------
    # Shared libraries are needed at runtime for applications, so we put them
    # at the top level in OpenSim/bin/*.dll (Windows) or OpenSim/lib/*.so
    # (Linux) or OpemSim/lib/*.dylib (Mac). Windows .lib files, and Linux/Mac
    # .a static archives are only needed at link time so go in sdk/lib.
    if(WIN32)
        set(OSIMADDLIB_LIBRARY_DESTINATION sdk/lib)
    else()
        set(OSIMADDLIB_LIBRARY_DESTINATION lib)
    endif()
    install(TARGETS ${OSIMADDLIB_LIBRARY_NAME}
        EXPORT OpenSimTargets
        RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
        LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
        ARCHIVE DESTINATION "${OPENSIM_INSTALL_ARCHIVEDIR}")
    if(BUILD_PYTHON_WRAPPING AND OPENSIM_PYTHON_STANDALONE
            AND NOT OSIMADDLIB_EXCLUDEFROMPYTHON)
        if (WIN32)
            install(TARGETS ${OSIMADDLIB_LIBRARY_NAME}
                RUNTIME DESTINATION "${OPENSIM_INSTALL_PYTHONDIR}/opensim")
        else()
            install(TARGETS ${OSIMADDLIB_LIBRARY_NAME}
                LIBRARY DESTINATION "${OPENSIM_INSTALL_PYTHONDIR}/opensim")
        endif()
    endif()

    # Install headers.
    # ----------------
    set(_INCLUDE_PREFIX "${CMAKE_INSTALL_INCLUDEDIR}/OpenSim")
    if(OSIMADDLIB_LOWERINCLUDEDIRNAME)
        string(TOLOWER "${OSIMADDLIB_KIT}" OSIMADDLIB_LKIT)
        set(_INCLUDE_LIBNAME ${OSIMADDLIB_LKIT})
    else()
        set(_INCLUDE_LIBNAME ${OSIMADDLIB_KIT})
    endif()
    if(OSIMADDLIB_INCLUDEDIRS)
        foreach(dir ${OSIMADDLIB_INCLUDEDIRS})
            file(GLOB HEADERS ${dir}/*.h) # returns full pathnames
            if(OSIMADDLIB_INCLUDEINSTALLREL)
                # Remove "INCLUDEINSTALLREL" from the installed location.
                file(RELATIVE_PATH subdir
                    "${CMAKE_CURRENT_SOURCE_DIR}${OSIMADDLIB_INCLUDEINSTALLREL}"
                    "${CMAKE_CURRENT_SOURCE_DIR}${dir}")
            else()
                set(subdir ${dir})
            endif()
            install(FILES ${HEADERS}
                DESTINATION ${_INCLUDE_PREFIX}/${_INCLUDE_LIBNAME}/${subdir})
        endforeach(dir)
    else()
        install(FILES ${OSIMADDLIB_INCLUDES}
            DESTINATION ${_INCLUDE_PREFIX}/${_INCLUDE_LIBNAME})
    endif()

    # RPATH (so that libraries find library dependencies)
    # ---------------------------------------------------
    OpenSimAddInstallRPATHSelf(TARGET ${OSIMADDLIB_LIBRARY_NAME} LOADER)
    OpenSimAddInstallRPATHSimbody(TARGET ${OSIMADDLIB_LIBRARY_NAME} LOADER
        FROM "${CMAKE_INSTALL_LIBDIR}")

    # Testing.
    # --------
    enable_testing()

    if(BUILD_TESTING)
        foreach(OSIMADDLIB_TESTDIR ${OSIMADDLIB_TESTDIRS})
            subdirs("${OSIMADDLIB_TESTDIR}")
        endforeach()
    endif()

endfunction()

# Copy a file from the directory containing test files (model files, data,
# etc.) to the directory in which a test will be executed. This function makes
# it easy to re-use files that are used in tests. With an easier mechanism for
# re-using these files, we won't end up version-controlling the same file in
# multiple test directories.
#
# Arguments are a list of files in the test resources directory
# (OPENSIM_SHARED_TEST_FILES_DIR) to copy.
function(OpenSimCopySharedTestFiles)
    if(BUILD_TESTING)
endfunction()


# Function to copy DLL files from dependency install directory into OpenSim 
# build and install directories. This is a Windows specific function enabled 
# only for Windows platform. Intention is to allow runtime loader to find all 
        if(EXECUTABLE_OUTPUT_PATH)
            set(TEST_PATH "${EXECUTABLE_OUTPUT_PATH}")
        else()
            set(TEST_PATH "${CMAKE_CURRENT_BINARY_DIR}")
        endif()

        # Make test targets.
        foreach(test_program ${OSIMADDTESTS_TESTPROGRAMS})
            # NAME_WE stands for "name without extension"
            get_filename_component(TEST_NAME ${test_program} NAME_WE)

            add_executable(${TEST_NAME} ${test_program}
                ${OSIMADDTESTS_SOURCES})
            target_link_libraries(${TEST_NAME} ${OSIMADDTESTS_LINKLIBS})
            add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME})
            set_target_properties(${TEST_NAME} PROPERTIES
                FOLDER "Tests"
				)

        endforeach()

        # Copy data files to build directory.
        foreach(data_file ${OSIMADDTESTS_DATAFILES})
            # This command re-copies the data files if they are modified;
            # custom commands don't do this.
            file(COPY "${data_file}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
        endforeach()

        #if(UNIX)
        #  add_definitions(-fprofile-arcs -ftest-coverage)
        #  link_libraries(gcov)
        #endif(UNIX)

    endif()

endfunction()


# Create an application/executable. To be used in the Appliations directory.
# NAME: Name of the application. Must also be the name of the source file
#   containing main() (without the .cpp extension).
# SOURCES: Additional header/source files to compile into this target. 
#
# Here's an example:
#   OpenSimAddApplication(NAME opensim-cmd SOURCES opensim-cmd_run-tool.h)
function(OpenSimAddApplication)

    # Parse arguments.
    # ----------------
    # http://www.cmake.org/cmake/help/v2.8.9/cmake.html#module:CMakeParseArguments
    set(options)
    set(oneValueArgs NAME)
    set(multiValueArgs SOURCES)
    cmake_parse_arguments(
        OSIMADDAPP "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
    
    # Build.
    add_executable(${OSIMADDAPP_NAME} ${OSIMADDAPP_NAME}.cpp
                                      ${OSIMADDAPP_SOURCES})
    target_link_libraries(${OSIMADDAPP_NAME} osimTools)
    set_target_properties(${OSIMADDAPP_NAME} PROPERTIES
        FOLDER "Applications")

    # Install.
    install(TARGETS ${OSIMADDAPP_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})

    # RPATH (so that the executable finds libraries without using env. vars).
    OpenSimAddInstallRPATH(TARGET ${OSIMADDAPP_NAME} EXECUTABLE
        FROM "${CMAKE_INSTALL_BINDIR}" TO "${CMAKE_INSTALL_LIBDIR}")
    OpenSimAddInstallRPATHSimbody(TARGET ${OSIMADDAPP_NAME} EXECUTABLE
        FROM "${CMAKE_INSTALL_BINDIR}")

endfunction()


# Add a target to the OpenSim project for building an example with the given
# NAME. The example must be within a source file named ${NAME}.cpp, or could
# contain multiple executable files, listed via the EXECUTABLES argument
# (omitting the .cpp extension). This function also installs the example files
# with a CMakeLists that can find the OpenSim installation and build the
# example.
#
# If SUBDIR is provided, the example is installed into this subdirectory of the
# C++ Examples folder.
#
# This function can only be used from the source distribution of OpenSim
# (e.g., not via the UseOpenSim.cmake file in a binary distribution).
function(OpenSimAddExampleCXX)
    set(options)
    set(oneValueArgs NAME SUBDIR)
    set(multiValueArgs RESOURCES EXECUTABLES)
    cmake_parse_arguments(OSIMEX
            "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

    if(NOT OSIMEX_EXECUTABLES)
        set(OSIMEX_EXECUTABLES ${OSIMEX_NAME})
    endif()

    # Build the example in the build tree.
    foreach(exe ${OSIMEX_EXECUTABLES})
        add_executable(${exe} ${exe}.cpp)
        set_target_properties(${exe} PROPERTIES FOLDER "Examples")
        target_link_libraries(${exe} osimTools osimExampleComponents osimMoco)
    endforeach()
    file(COPY ${OSIMEX_RESOURCES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")

    # Install files so that users can build the example.
    # We do not install pre-built binaries of the examples.
    set(_example_install_dir
            ${OPENSIM_INSTALL_CPPEXDIR}/${OSIMEX_SUBDIR}/${OSIMEX_NAME})
    install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
            DESTINATION "${_example_install_dir}"
            PATTERN "CMakeLists.txt" EXCLUDE)

    # These next two variables are to be configured below (they are not used
    # here, but within ExampleCMakeListsToInstall.txt.in).
    set(_example_name ${OSIMEX_NAME})
    set(_example_executables ${OSIMEX_EXECUTABLES})
    file(RELATIVE_PATH _opensim_install_hint
            "${CMAKE_INSTALL_PREFIX}/${_example_install_dir}"
            "${CMAKE_INSTALL_PREFIX}")
    configure_file(
        "${CMAKE_SOURCE_DIR}/OpenSim/Examples/ExampleCMakeListsToInstall.txt.in"
        "${CMAKE_CURRENT_BINARY_DIR}/CMakeListsToInstall.txt"
        @ONLY)

    install(FILES
            "${CMAKE_CURRENT_BINARY_DIR}/CMakeListsToInstall.txt"
            DESTINATION ${_example_install_dir}
            RENAME CMakeLists.txt)
endfunction()


# Add a target to the OpenSim project for building an example containing a
# plugin library and an executable.
# The directory containing the CMakeLists.txt invoking this macro must have 3
# source files: ${NAME}.h and ${NAME}.cpp are used to create the plugin, and
# and example${NAME}.cpp is compiled into an executable that uses the plugin.
# This function also installs the example file with a CMakeLists that can find
# the OpenSim installation and build the example.
#
# If SUBDIR is provided, the example is installed into this subdirectory of the
# C++ Examples folder.
#
# This function can only be used from the source distribution of OpenSim
# (e.g., not via the UseOpenSim.cmake file in a binary distribution).
function(OpenSimAddPluginExampleCXX)
    set(options)
    set(oneValueArgs NAME SUBDIR)
    set(multiValueArgs RESOURCES)
    cmake_parse_arguments(OSIMEX
            "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

    add_library(osim${OSIMEX_NAME} SHARED
            ${OSIMEX_NAME}.h
            ${OSIMEX_NAME}.cpp
            osim${OSIMEX_NAME}DLL.h
            RegisterTypes_osim${OSIMEX_NAME}.h
            RegisterTypes_osim${OSIMEX_NAME}.cpp
            )
    set_target_properties(osim${OSIMEX_NAME} PROPERTIES
            FOLDER "Examples")
    target_link_libraries(osim${OSIMEX_NAME} osimTools osimExampleComponents
            osimMoco)

    string(TOUPPER ${OSIMEX_NAME} _example_name_upper)
    set_target_properties(osim${OSIMEX_NAME} PROPERTIES
            DEFINE_SYMBOL OSIM${_example_name_upper}_EXPORTS
            )

    add_executable(example${OSIMEX_NAME} example${OSIMEX_NAME}.cpp)
    set_target_properties(example${OSIMEX_NAME} PROPERTIES
            FOLDER "Examples")
    target_link_libraries(example${OSIMEX_NAME} osim${OSIMEX_NAME})
    file(COPY ${OSIMEX_RESOURCES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")

    set(_example_install_dir
            ${OPENSIM_INSTALL_CPPEXDIR}/${OSIMEX_SUBDIR}/Plugins/example${OSIMEX_NAME})
    install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
            DESTINATION "${_example_install_dir}"
            PATTERN "CMakeLists.txt" EXCLUDE)

    # These next two variables are to be configured below (they are not used
    # here, but within ExampleCMakeListsToInstall.txt.in).
    set(_example_name ${OSIMEX_NAME})
    file(RELATIVE_PATH _opensim_install_hint
            "${CMAKE_INSTALL_PREFIX}/${_example_install_dir}"
            "${CMAKE_INSTALL_PREFIX}")
    configure_file(
        "${CMAKE_SOURCE_DIR}/OpenSim/Examples/PluginExampleCMakeListsToInstall.txt.in"
        "${CMAKE_CURRENT_BINARY_DIR}/CMakeListsToInstall.txt"
        @ONLY)

    install(FILES
            "${CMAKE_CURRENT_BINARY_DIR}/CMakeListsToInstall.txt"
            DESTINATION ${_example_install_dir}
            RENAME CMakeLists.txt)
endfunction()


# Function to install shared libraries (any platform) from a dependency install
# directory into the OpenSim installation. One use case is to install libraries
# into the python package.
# PREFIX: A common part of the library file names (e.g., 'SimTK' or 'ezc3d').
#         This is to avoid copying unrelated files from a folder like /usr/lib.
# DEP_LIBS_DIR_WIN: Directory to search for the dependency's library, on
#         Windows.
# DEP_LIBS_DIR_UNIX: Directory to search for the dependency's library, on
#         UNIX (APPLE and Linux). Specify only the lib directory to avoid
#         searching all of /usr/local (if the dependency is installed to a
#         system location like this).
# OSIM_DESTINATION: Destination of the libraries within OpenSim's installation.
function(OpenSimInstallDependencyLibraries PREFIX DEP_LIBS_DIR_WIN
        DEP_LIBS_DIR_UNIX OSIM_DESTINATION)
    if(WIN32)
        file(GLOB_RECURSE LIBS "${DEP_LIBS_DIR_WIN}/${PREFIX}*.dll")
    else()
        if(APPLE)
            set(lib_ext "dylib")
        else()
            set(lib_ext "so*") # Trailing * for version #s.
        endif()
        file(GLOB_RECURSE LIBS "${DEP_LIBS_DIR_UNIX}/lib${PREFIX}*.${lib_ext}")
    endif()
    if(NOT LIBS)
        message(FATAL_ERROR "Zero shared libraries found in directory "
            "${DEP_INSTALL_DIR}.")
    endif()
    install(FILES ${LIBS} DESTINATION "${OSIM_DESTINATION}")
endfunction()


# Copy DLL files from a dependency's installation into the
# build and install directories. This is a Windows-specific function enabled
# only on Windows. The intention is to allow the runtime loader to find all 
# the required DLLs without editing the PATH environment variable.
# Arguments:
#   DEP_NAME: Name of the dependency (used to name a custom target)
#   DEP_BIN_DIR: The directory in the dependency containing DLLs to copy.
# This is based on a similar function in OpenSimMacros.cmake.
function(OpenSimCopyDependencyDLLsForWin)
    # On Windows, copy dlls into the OpenSim binary directory.
    set(options)
    set(oneValueArgs DEP_NAME DEP_BIN_DIR)
    set(multiValueArgs)
    cmake_parse_arguments(OSIMCOPY
            "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
    if(WIN32)
        file(GLOB DLLS ${OSIMCOPY_DEP_BIN_DIR}/*.dll)
        if(NOT DLLS)
            message(FATAL_ERROR "Zero DLLs found in directory "
                                "${OSIMCOPY_DEP_BIN_DIR}.")
        endif()
        set(DEST_DIR "${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
        foreach(DLL IN LISTS DLLS)
            get_filename_component(DLL_NAME ${DLL} NAME)
            list(APPEND DLLS_DEST "${DEST_DIR}/${DLL_NAME}")
            add_custom_command(OUTPUT "${DEST_DIR}/${DLL_NAME}"
                COMMAND ${CMAKE_COMMAND} -E make_directory ${DEST_DIR}
                COMMAND ${CMAKE_COMMAND} -E copy ${DLL} ${DEST_DIR}
                DEPENDS ${DLL}
                COMMENT "Copying ${DLL_NAME} from ${OSIMCOPY_DEP_BIN_DIR} to ${DEST_DIR}.")
        endforeach()
        add_custom_target(Copy_${OSIMCOPY_DEP_NAME}_DLLs ALL DEPENDS ${DLLS_DEST})
        set_target_properties(Copy_${OSIMCOPY_DEP_NAME}_DLLs PROPERTIES
            PROJECT_LABEL "Copy ${OSIMCOPY_DEP_NAME} DLLs")
        if(OPENSIM_COPY_DEPENDENCIES)
            install(FILES ${DLLS} DESTINATION ${CMAKE_INSTALL_BINDIR})
        endif()
    endif()
endfunction()


# Discover the file dependencies for an invocation of swig, for use with the
# DEPENDS field of an add_custom_command().
#
# OSIMSWIGDEP_RETURNVAL  is filled with a list of the dependencies.
# OSIMSWIGDEP_MODULE     is the name of the module (just for messages).
# OSIMSWIGDEP_INVOCATION is the SWIG command to use to check for dependencies.
#                        We append `-MM` to this, which asks SWIG for the
#                        dependencies.
macro(OpenSimFindSwigFileDependencies OSIMSWIGDEP_RETURNVAL
                                      OSIMSWIGDEP_MODULE
                                      OSIMSWIGDEP_INVOCATION)
    # We must use a macro instead of a function in order to return a value.

    # Assemble dependencies. This command is run during CMake's configure step.
    message(STATUS
        "Discovering dependencies for SWIG module ${OSIMSWIGDEP_MODULE}.")
    execute_process(COMMAND ${SWIG_EXECUTABLE}
            -MM # List dependencies, but omit files in SWIG library.
            ${OSIMSWIGDEP_INVOCATION}
        OUTPUT_VARIABLE _dependencies_makefile
        RESULT_VARIABLE _successfully_got_dependencies
            )
    # On Windows, _dependencies_makefile now contains something like this:
    # C:\opensim-core\Bindings\Python\swig\python_simbody_wrap.cxx: \
    #   C:\opensim-core\Bindings\Python\swig\python_simbody.i \
    #   C:\opensim-core\Bindings\Python\swig\numpy.i \
    #   ...<more header files and SWIG interface files>
    # Note: SWIG does not depend on cpp files.
    # Clean up the output, since it's in the form of a makefile
    # (and we just want a list of file paths).
    if(${_successfully_got_dependencies} EQUAL 0) # return code 0 is success.
        # '^.*cxx:' matches the first line of the makefile (the output file path).
        # '\\\\' matches a single \ (escape for CMake, and escape for regex).
        string(REGEX REPLACE "(^.*cxx:|\\\\\n)" "" ${OSIMSWIGDEP_RETURNVAL}
            ${_dependencies_makefile})
        # Replace spaces with semicolons to create a list of file paths.
        separate_arguments(${OSIMSWIGDEP_RETURNVAL})
    else()
        # In case the variable has a value for previous modules.
        unset(${OSIMSWIGDEP_RETURNVAL})
        # If someone ends up here, it's a bug in this CMakeLists.txt.
        message(AUTHOR_WARNING
            "Could not determine dependencies for SWIG module ${OSIMSWIGDEP_MODULE}.")
    endif()

    unset(_dependencies_makefile)
    unset(_successfully_got_dependencies)

endmacro()


<MSG> Merge pull request #1574 from opensim-org/python_standalone

Allow making a standalone Python package
<DFF> @@ -5,6 +5,7 @@ include(CMakeParseArguments)
 #   argument. Otherwise, omit.
 # LOWERINCLUDEDIRNAME: When installing the headers for this library, make the
 #   name of the library all lower-case (e.g., Lepton -> lepton).
+# EXCLUDEFROMPYTHON: Do not install this library into the python package.
 # KIT: Name of the library (e.g., Common).
 # AUTHORS: A string listing authors of the library.
 # LINKLIBS: List of libraries (targets) to link against.
@@ -33,7 +34,7 @@ function(OpenSimAddLibrary)
     # Parse arguments.
     # ----------------
     # http://www.cmake.org/cmake/help/v2.8.9/cmake.html#module:CMakeParseArguments
-    set(options VENDORLIB LOWERINCLUDEDIRNAME)
+    set(options VENDORLIB LOWERINCLUDEDIRNAME EXCLUDEFROMPYTHON)
     set(oneValueArgs KIT AUTHORS)
     set(multiValueArgs LINKLIBS INCLUDES SOURCES TESTDIRS INCLUDEDIRS)
     cmake_parse_arguments(
@@ -97,6 +98,16 @@ function(OpenSimAddLibrary)
         RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
         LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
         ARCHIVE DESTINATION "${OPENSIM_INSTALL_ARCHIVEDIR}")
+    if(BUILD_PYTHON_WRAPPING AND OPENSIM_PYTHON_STANDALONE
+            AND NOT OSIMADDLIB_EXCLUDEFROMPYTHON)
+        if (WIN32)
+            install(TARGETS ${OSIMADDLIB_LIBRARY_NAME}
+                RUNTIME DESTINATION "${OPENSIM_INSTALL_PYTHONDIR}/opensim")
+        else()
+            install(TARGETS ${OSIMADDLIB_LIBRARY_NAME}
+                LIBRARY DESTINATION "${OPENSIM_INSTALL_PYTHONDIR}/opensim")
+        endif()
+    endif()
 
     # Install headers.
     # ----------------
@@ -150,6 +161,8 @@ function(OpenSimAddLibrary)
         #    list(APPEND run_path_list
         #           "\@loader_path/${lib_dir_to_simbody_lib_dir}")
         #endif()
+        # It is possible that on UNIX (APPLE and Linux), we will install
+        # Simbody and BTK beside OpenSim, rather than in their own directories.
         # Use APPEND to include the BTK RPATH, set in CMAKE_INSTALL_RPATH.
         set_property(TARGET ${OSIMADDLIB_LIBRARY_NAME} APPEND PROPERTY
             INSTALL_RPATH "${run_path_list}"
@@ -304,6 +317,38 @@ function(OpenSimAddApplication)
 endfunction()
 
 
+# Function to install shared libraries (any platform) from a dependency install
+# directory into the OpenSim installation. One use case is to install libraries
+# into the python package.
+# PREFIX: A common part of the library file names (e.g., 'SimTK' or 'BTK').
+#         This is to avoid copying unrelated files from a folder like /usr/lib.
+# DEP_LIBS_DIR_WIN: Directory to search for the dependency's library, on
+#         Windows.
+# DEP_LIBS_DIR_UNIX: Directory to search for the dependency's library, on
+#         UNIX (APPLE and Linux). Specify only the lib directory to avoid
+#         searching all of /usr/local (if the dependency is installed to a
+#         system location like this).
+# OSIM_DESTINATION: Destination of the libraries within OpenSim's installation.
+function(OpenSimInstallDependencyLibraries PREFIX DEP_LIBS_DIR_WIN
+        DEP_LIBS_DIR_UNIX OSIM_DESTINATION)
+    if(WIN32)
+        file(GLOB_RECURSE LIBS "${DEP_LIBS_DIR_WIN}/${PREFIX}*.dll")
+    else()
+        if(APPLE)
+            set(lib_ext "dylib")
+        else()
+            set(lib_ext "so*") # Trailing * for version #s.
+        endif()
+        file(GLOB_RECURSE LIBS "${DEP_LIBS_DIR_UNIX}/lib${PREFIX}*.${lib_ext}")
+    endif()
+    if(NOT LIBS)
+        message(FATAL_ERROR "Zero shared libraries found in directory "
+            "${DEP_INSTALL_DIR}.")
+    endif()
+    install(FILES ${LIBS} DESTINATION "${OSIM_DESTINATION}")
+endfunction()
+
+
 # Function to copy DLL files from dependency install directory into OpenSim 
 # build and install directories. This is a Windows specific function enabled 
 # only for Windows platform. Intention is to allow runtime loader to find all 

{'commit': 'diff --git a/Bindings/Python/CMakeLists.txt b/Bindings/Python/CMakeLists.txt\nindex 7759ab208..222c4d8a9 100644\n--- a/Bindings/Python/CMakeLists.txt\n+++ b/Bindings/Python/CMakeLists.txt\n@@ -2,16 +2,6 @@\n # Find python.\n # ============\n \n-# PythonInterp is supposed to come before PythonLibs.\n-find_package(PythonInterp 2.7 REQUIRED)\n-find_package(PythonLibs 2.7 REQUIRED)\n-\n-# We may need to update the python install dir to include the python version,\n-# now that we know it. We replace the token "VERSION" with the actual python\n-# version.\n-string(REPLACE "VERSION" "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}"\n-    OPENSIM_INSTALL_PYTHONDIR "${OPENSIM_INSTALL_PYTHONDIR}")\n-\n # Location of the opensim python package in the build directory, for testing.\n if(MSVC OR XCODE)\n     # Multi-configuration generators like MSVC and XCODE use one build tree for\n@@ -160,11 +150,21 @@ macro(OpenSimAddPythonModule)\n     endif()\n     \n     if(${OPENSIM_USE_INSTALL_RPATH})\n+        # TODO @loader_path only makes sense on macOS, so we need to revisit\n+        # for Linux (use $ORIGIN).\n+        # We always set a relative RPATH but only use an absolute RPATH if the\n+        # python package is not standalone, as the libraries are not copied\n+        # into the python package.\n+        # TODO consider using a relative path from the python package directory\n+        # to the OpenSim library directory.\n+        set(run_path_list "\\@loader_path/")\n+        if(NOT OPENSIM_PYTHON_STANDALONE)\n+            list(APPEND run_path_list\n+                    "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")\n+        endif()\n         # Use APPEND to include the BTK RPATH, set in CMAKE_INSTALL_RPATH.\n-        # TODO test that NOT using APPEND causes BTK to not be found.\n         set_property(TARGET ${_libname} APPEND PROPERTY\n-            INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}"\n-            )\n+            INSTALL_RPATH "${run_path_list}")\n     endif()\n \n     # Copy files into the build tree python package.\ndiff --git a/Bindings/Python/setup.py b/Bindings/Python/setup.py\nindex cb1bb1743..431552d5f 100644\n--- a/Bindings/Python/setup.py\n+++ b/Bindings/Python/setup.py\n@@ -15,7 +15,9 @@ setup(name=\'opensim\',\n       url=\'http://opensim.stanford.edu/\',\n       license=\'Apache 2.0\',\n       packages=[\'opensim\'],\n-      package_data={\'opensim\': [\'_*.*\']},\n+      # The last 3 entries are for if OPENSIM_PYTHON_STANDALONE is ON.\n+      # The asterisk after the extension is to handle version numbers on Linux.\n+      package_data={\'opensim\': [\'_*.*\', \'*.dylib\', \'*.dll\', \'*.so*\']},\n       include_package_data=True,\n       classifiers=[\n           \'Intended Audience :: Science/Research\',\ndiff --git a/CMakeLists.txt b/CMakeLists.txt\nindex 8860e53bc..3bf1c93b8 100644\n--- a/CMakeLists.txt\n+++ b/CMakeLists.txt\n@@ -101,6 +101,20 @@ for both OpenSim and Simbody. To make a distributable installation on macOS,\n this should be set to ON to avoid using absolute paths for RPATHs to Simbody\n libraries." ON)\n \n+option(OPENSIM_PYTHON_STANDALONE "Make the Python package standalone, meaning\n+the OpenSim (and Simbody and BTK) shared libraries it depends on are copied\n+into the package. If you are building OpenSim on the same machine on which you\n+plan to use it, you can leave this OFF. If you are distributing OpenSim to\n+other computers, you should turn this ON. If macOS, this option affects how\n+RPATH is set for the SWIG-generated shared libraries. This variable has no\n+effect if BUILD_PYTHON_WRAPPING is OFF." OFF)\n+# There are many potential ways to distribute the python bindings; here\'s how\n+# you might want to set the above option for different ways of distributing:\n+#   simtk.org GUI distribution, macOS: ON (since no env. vars are set)\n+#   simtk.org GUI distrubution, Windows: OFF (PATH is set)\n+#   pypi: ON (there is no way to install the C++ libraries otherwise)\n+#   debian, homebrew, conda: OFF (can have a separate C++ library package)\n+\n option(BUILD_API_ONLY "Build/install only headers, libraries,\n wrapping, tests; not applications (opensim, ik, rra, etc.)." OFF)\n \n@@ -431,6 +445,21 @@ if(${BUILD_JAVA_WRAPPING})\n     endif()\n endif()\n \n+if(${BUILD_PYTHON_WRAPPING})\n+    # PythonInterp is supposed to come before PythonLibs.\n+    find_package(PythonInterp 2.7 REQUIRED)\n+    find_package(PythonLibs 2.7 REQUIRED)\n+\n+    # We update the python install dir to include the python version,\n+    # now that we know it. We replace the token "VERSION" with the actual python\n+    # version.\n+    string(REPLACE "VERSION" "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}"\n+        OPENSIM_INSTALL_PYTHONDIR "${OPENSIM_INSTALL_PYTHONDIR}")\n+    # This must be done before adding the OpenSim libraries, since\n+    # OPENSIM_INSTALL_PYTHONDIR is used in OpenSimAddLibrary (in\n+    # OpenSimMacros.cmake).\n+endif()\n+\n if(WIN32)\n     add_definitions(-D_CRT_SECURE_NO_DEPRECATE)\n endif()\n@@ -461,7 +490,7 @@ endif()\n \n \n ## RPATH \n-# If it is necesasry to not put RPATHS in the installed binaries, set\n+# If it is necessary to not put RPATHS in the installed binaries, set\n # set CMAKE_SKIP_INSTALL_RPATH to OFF.\n if(APPLE)\n     # CMake 2.8.12 introduced the ability to set RPATH for shared libraries\n@@ -526,6 +555,10 @@ if(WITH_BTK)\n     include(${BTK_USE_FILE})\n     add_definitions(-DWITH_BTK)\n     CopyDependencyDLLsForWin(BTK ${BTK_INSTALL_PREFIX})\n+    if(BUILD_PYTHON_WRAPPING AND OPENSIM_PYTHON_STANDALONE)\n+    OpenSimInstallDependencyLibraries(BTK "${BTK_INSTALL_PREFIX}"\n+        "${BTK_LIBRARY_DIRS}" "${OPENSIM_INSTALL_PYTHONDIR}/opensim")\n+    endif()\n     # TODO this should be handled separately between macOS and Linux.\n     set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH};${BTK_LIBRARY_DIRS}")\n endif()\n@@ -624,12 +657,11 @@ if(${OPENSIM_COPY_SIMBODY})\n     # is only needed for programmers goes in sdk/lib.\n     # TODO use SimbodyConfig.cmake variables instead of these globs.\n     if(WIN32)\n-        file(GLOB SIMBODY_BIN_FILES\n-            ${Simbody_BIN_DIR}/*.dll\n-            ${Simbody_BIN_DIR}/*.exe)\n-        file(GLOB SIMBODY_ARCHIVE_FILES\n-            ${Simbody_LIB_DIR}/*.lib)\n+        file(GLOB SIMBODY_BIN_FILES ${Simbody_BIN_DIR}/*.dll\n+                                    ${Simbody_BIN_DIR}/*.exe)\n+        file(GLOB SIMBODY_ARCHIVE_FILES ${Simbody_LIB_DIR}/*.lib)\n     else()\n+        # TODO simbody-visualizer executable probably isn\'t even there.\n         file(GLOB SIMBODY_BIN_FILES\n             ${Simbody_BIN_DIR}/simbody*) # executables only (e.g., visualizer).\n         # If the LIB_DIR is some common place for libraries (e.g., /usr/lib/),\n@@ -690,6 +722,10 @@ if(${OPENSIM_COPY_SIMBODY})\n         endforeach()\n     endif()\n endif()\n+if(BUILD_PYTHON_WRAPPING AND OPENSIM_PYTHON_STANDALONE)\n+    OpenSimInstallDependencyLibraries(SimTK "${Simbody_BIN_DIR}"\n+        "${Simbody_LIB_DIR}" "${OPENSIM_INSTALL_PYTHONDIR}/opensim")\n+endif()\n \n \n # Other than Windows we can debug without debuggable SimTK libraries\ndiff --git a/OpenSim/Utilities/simmFileWriterDLL/CMakeLists.txt b/OpenSim/Utilities/simmFileWriterDLL/CMakeLists.txt\nindex 4fe254f24..3d4c5c11d 100644\n--- a/OpenSim/Utilities/simmFileWriterDLL/CMakeLists.txt\n+++ b/OpenSim/Utilities/simmFileWriterDLL/CMakeLists.txt\n@@ -5,6 +5,7 @@ file(GLOB INCLUDES *.h)\n OpenSimAddLibrary(\n     KIT SimmFileWriter\n     AUTHORS "Peter_Loan"\n+    EXCLUDEFROMPYTHON\n     LINKLIBS osimCommon osimSimulation osimActuators ${Simbody_LIBRARIES}\n     INCLUDES ${INCLUDES}\n     SOURCES ${SOURCES}\ndiff --git a/cmake/OpenSimMacros.cmake b/cmake/OpenSimMacros.cmake\nindex a1891d23d..3434a8199 100644\n--- a/cmake/OpenSimMacros.cmake\n+++ b/cmake/OpenSimMacros.cmake\n@@ -5,6 +5,7 @@ include(CMakeParseArguments)\n #   argument. Otherwise, omit.\n # LOWERINCLUDEDIRNAME: When installing the headers for this library, make the\n #   name of the library all lower-case (e.g., Lepton -> lepton).\n+# EXCLUDEFROMPYTHON: Do not install this library into the python package.\n # KIT: Name of the library (e.g., Common).\n # AUTHORS: A string listing authors of the library.\n # LINKLIBS: List of libraries (targets) to link against.\n@@ -33,7 +34,7 @@ function(OpenSimAddLibrary)\n     # Parse arguments.\n     # ----------------\n     # http://www.cmake.org/cmake/help/v2.8.9/cmake.html#module:CMakeParseArguments\n-    set(options VENDORLIB LOWERINCLUDEDIRNAME)\n+    set(options VENDORLIB LOWERINCLUDEDIRNAME EXCLUDEFROMPYTHON)\n     set(oneValueArgs KIT AUTHORS)\n     set(multiValueArgs LINKLIBS INCLUDES SOURCES TESTDIRS INCLUDEDIRS)\n     cmake_parse_arguments(\n@@ -97,6 +98,16 @@ function(OpenSimAddLibrary)\n         RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"\n         LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"\n         ARCHIVE DESTINATION "${OPENSIM_INSTALL_ARCHIVEDIR}")\n+    if(BUILD_PYTHON_WRAPPING AND OPENSIM_PYTHON_STANDALONE\n+            AND NOT OSIMADDLIB_EXCLUDEFROMPYTHON)\n+        if (WIN32)\n+            install(TARGETS ${OSIMADDLIB_LIBRARY_NAME}\n+                RUNTIME DESTINATION "${OPENSIM_INSTALL_PYTHONDIR}/opensim")\n+        else()\n+            install(TARGETS ${OSIMADDLIB_LIBRARY_NAME}\n+                LIBRARY DESTINATION "${OPENSIM_INSTALL_PYTHONDIR}/opensim")\n+        endif()\n+    endif()\n \n     # Install headers.\n     # ----------------\n@@ -150,6 +161,8 @@ function(OpenSimAddLibrary)\n         #    list(APPEND run_path_list\n         #           "\\@loader_path/${lib_dir_to_simbody_lib_dir}")\n         #endif()\n+        # It is possible that on UNIX (APPLE and Linux), we will install\n+        # Simbody and BTK beside OpenSim, rather than in their own directories.\n         # Use APPEND to include the BTK RPATH, set in CMAKE_INSTALL_RPATH.\n         set_property(TARGET ${OSIMADDLIB_LIBRARY_NAME} APPEND PROPERTY\n             INSTALL_RPATH "${run_path_list}"\n@@ -304,6 +317,38 @@ function(OpenSimAddApplication)\n endfunction()\n \n \n+# Function to install shared libraries (any platform) from a dependency install\n+# directory into the OpenSim installation. One use case is to install libraries\n+# into the python package.\n+# PREFIX: A common part of the library file names (e.g., \'SimTK\' or \'BTK\').\n+#         This is to avoid copying unrelated files from a folder like /usr/lib.\n+# DEP_LIBS_DIR_WIN: Directory to search for the dependency\'s library, on\n+#         Windows.\n+# DEP_LIBS_DIR_UNIX: Directory to search for the dependency\'s library, on\n+#         UNIX (APPLE and Linux). Specify only the lib directory to avoid\n+#         searching all of /usr/local (if the dependency is installed to a\n+#         system location like this).\n+# OSIM_DESTINATION: Destination of the libraries within OpenSim\'s installation.\n+function(OpenSimInstallDependencyLibraries PREFIX DEP_LIBS_DIR_WIN\n+        DEP_LIBS_DIR_UNIX OSIM_DESTINATION)\n+    if(WIN32)\n+        file(GLOB_RECURSE LIBS "${DEP_LIBS_DIR_WIN}/${PREFIX}*.dll")\n+    else()\n+        if(APPLE)\n+            set(lib_ext "dylib")\n+        else()\n+            set(lib_ext "so*") # Trailing * for version #s.\n+        endif()\n+        file(GLOB_RECURSE LIBS "${DEP_LIBS_DIR_UNIX}/lib${PREFIX}*.${lib_ext}")\n+    endif()\n+    if(NOT LIBS)\n+        message(FATAL_ERROR "Zero shared libraries found in directory "\n+            "${DEP_INSTALL_DIR}.")\n+    endif()\n+    install(FILES ${LIBS} DESTINATION "${OSIM_DESTINATION}")\n+endfunction()\n+\n+\n # Function to copy DLL files from dependency install directory into OpenSim \n # build and install directories. This is a Windows specific function enabled \n # only for Windows platform. Intention is to allow runtime loader to find all \n', 'commit_subject': 'Merge pull request #1574 from opensim-org/python_standalone', 'repo_name': 'opensim-org/opensim-core', 'committer': {'name': 'GitHub', 'email': '1505422b2465e9a84f6fdfaa161078890c593f06@github.com', 'time_sec': '1490223702', 'tz_offset': '-420', 'date': {'seconds': '1490223702'}}, 'commit_tree': '1a02a57db7b63aaa48b6c9728069b9a1b392f9d2', 'commit_message': 'Merge pull request #1574 from opensim-org/python_standalone\n\nAllow making a standalone Python package', 'language_name': 'Shell', 'license': 'apache-2.0', 'hunks': '@@ -5,6 +5,7 @@ include(CMakeParseArguments)\n #   argument. Otherwise, omit.\n # LOWERINCLUDEDIRNAME: When installing the headers for this library, make the\n #   name of the library all lower-case (e.g., Lepton -> lepton).\n+# EXCLUDEFROMPYTHON: Do not install this library into the python package.\n # KIT: Name of the library (e.g., Common).\n # AUTHORS: A string listing authors of the library.\n # LINKLIBS: List of libraries (targets) to link against.\n@@ -33,7 +34,7 @@ function(OpenSimAddLibrary)\n     # Parse arguments.\n     # ----------------\n     # http://www.cmake.org/cmake/help/v2.8.9/cmake.html#module:CMakeParseArguments\n-    set(options VENDORLIB LOWERINCLUDEDIRNAME)\n+    set(options VENDORLIB LOWERINCLUDEDIRNAME EXCLUDEFROMPYTHON)\n     set(oneValueArgs KIT AUTHORS)\n     set(multiValueArgs LINKLIBS INCLUDES SOURCES TESTDIRS INCLUDEDIRS)\n     cmake_parse_arguments(\n@@ -97,6 +98,16 @@ function(OpenSimAddLibrary)\n         RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"\n         LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"\n         ARCHIVE DESTINATION "${OPENSIM_INSTALL_ARCHIVEDIR}")\n+    if(BUILD_PYTHON_WRAPPING AND OPENSIM_PYTHON_STANDALONE\n+            AND NOT OSIMADDLIB_EXCLUDEFROMPYTHON)\n+        if (WIN32)\n+            install(TARGETS ${OSIMADDLIB_LIBRARY_NAME}\n+                RUNTIME DESTINATION "${OPENSIM_INSTALL_PYTHONDIR}/opensim")\n+        else()\n+            install(TARGETS ${OSIMADDLIB_LIBRARY_NAME}\n+                LIBRARY DESTINATION "${OPENSIM_INSTALL_PYTHONDIR}/opensim")\n+        endif()\n+    endif()\n \n     # Install headers.\n     # ----------------\n@@ -150,6 +161,8 @@ function(OpenSimAddLibrary)\n         #    list(APPEND run_path_list\n         #           "\\@loader_path/${lib_dir_to_simbody_lib_dir}")\n         #endif()\n+        # It is possible that on UNIX (APPLE and Linux), we will install\n+        # Simbody and BTK beside OpenSim, rather than in their own directories.\n         # Use APPEND to include the BTK RPATH, set in CMAKE_INSTALL_RPATH.\n         set_property(TARGET ${OSIMADDLIB_LIBRARY_NAME} APPEND PROPERTY\n             INSTALL_RPATH "${run_path_list}"\n@@ -304,6 +317,38 @@ function(OpenSimAddApplication)\n endfunction()\n \n \n+# Function to install shared libraries (any platform) from a dependency install\n+# directory into the OpenSim installation. One use case is to install libraries\n+# into the python package.\n+# PREFIX: A common part of the library file names (e.g., \'SimTK\' or \'BTK\').\n+#         This is to avoid copying unrelated files from a folder like /usr/lib.\n+# DEP_LIBS_DIR_WIN: Directory to search for the dependency\'s library, on\n+#         Windows.\n+# DEP_LIBS_DIR_UNIX: Directory to search for the dependency\'s library, on\n+#         UNIX (APPLE and Linux). Specify only the lib directory to avoid\n+#         searching all of /usr/local (if the dependency is installed to a\n+#         system location like this).\n+# OSIM_DESTINATION: Destination of the libraries within OpenSim\'s installation.\n+function(OpenSimInstallDependencyLibraries PREFIX DEP_LIBS_DIR_WIN\n+        DEP_LIBS_DIR_UNIX OSIM_DESTINATION)\n+    if(WIN32)\n+        file(GLOB_RECURSE LIBS "${DEP_LIBS_DIR_WIN}/${PREFIX}*.dll")\n+    else()\n+        if(APPLE)\n+            set(lib_ext "dylib")\n+        else()\n+            set(lib_ext "so*") # Trailing * for version #s.\n+        endif()\n+        file(GLOB_RECURSE LIBS "${DEP_LIBS_DIR_UNIX}/lib${PREFIX}*.${lib_ext}")\n+    endif()\n+    if(NOT LIBS)\n+        message(FATAL_ERROR "Zero shared libraries found in directory "\n+            "${DEP_INSTALL_DIR}.")\n+    endif()\n+    install(FILES ${LIBS} DESTINATION "${OSIM_DESTINATION}")\n+endfunction()\n+\n+\n # Function to copy DLL files from dependency install directory into OpenSim \n # build and install directories. This is a Windows specific function enabled \n # only for Windows platform. Intention is to allow runtime loader to find all \n', 'addition_count': 46, 'deletion_count': 1, 'src_file': 'a/cmake/OpenSimMacros.cmake', 'tgt_file': 'b/cmake/OpenSimMacros.cmake', 'file_extension': '.cmake', 'before_file': 'include(CMakeParseArguments)\n\n# Add a relative path to the run-path of a shared library. The run-path allows\n# a library to find the libraries it depends on without the need to set the\n#   argument. Otherwise, omit.\n# LOWERINCLUDEDIRNAME: When installing the headers for this library, make the\n#   name of the library all lower-case (e.g., Lepton -> lepton).\n# KIT: Name of the library (e.g., Common).\n# AUTHORS: A string listing authors of the library.\n# LINKLIBS: List of libraries (targets) to link against.\n#   affects Mac.\n# FROM: The path (relative to the OpenSim installation root) of the\n#   executable/library that is loading a dependent library.\n# TO: The path (relative to the OpenSim installation root) where the dependent\n#   library is located.\nfunction(OpenSimAddInstallRPATH)\n    set(options EXECUTABLE LOADER)\n    set(oneValueArgs TARGET FROM TO)\n    set(multiValueArgs)\n    cmake_parse_arguments(\n        OSIMRP "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})\n    if(OSIMRP_EXECUTABLE EQUAL OSIMRP_LOADER) \n        message(AUTHOR_WARNING "Cannot specify both EXECUTABLE and LOADER.")\n    endif()\n\n    if(NOT OPENSIM_USE_INSTALL_RPATH)\n        return()\n    endif()\n\n    if(APPLE)\n        if(OSIMRP_EXECUTABLE)\n            set(rpath_macro "\\@executable_path")\n    # Parse arguments.\n    # ----------------\n    # http://www.cmake.org/cmake/help/v2.8.9/cmake.html#module:CMakeParseArguments\n    set(options VENDORLIB LOWERINCLUDEDIRNAME)\n    set(oneValueArgs KIT AUTHORS)\n    set(multiValueArgs LINKLIBS INCLUDES SOURCES TESTDIRS INCLUDEDIRS)\n    cmake_parse_arguments(\n    file(RELATIVE_PATH to_root "${CMAKE_INSTALL_PREFIX}/${OSIMRP_FROM}"\n        "${CMAKE_INSTALL_PREFIX}")\n    set_property(TARGET ${OSIMRP_TARGET} APPEND PROPERTY INSTALL_RPATH\n        "${rpath_macro}/${to_root}${OSIMRP_TO}")\nendfunction()\n\n# Similar to OpenSimAddInstallRPATH except the run-path is the same directory\n# loader (e.g., "@loader_path/"). Arguments:\n#\n# TARGET: The CMake target to which the run-path should be added.\nfunction(OpenSimAddInstallRPATHSelf)\n    set(options)\n    set(oneValueArgs TARGET)\n    set(multiValueArgs)\n    cmake_parse_arguments(\n        OSIMRP "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})\n\n    if(NOT OPENSIM_USE_INSTALL_RPATH)\n        return()\n    endif()\n\n    # By specifing "" and "" for FROM and TO, the resulting RPATH will simply\n    # be "${rpath_macro}/".\n    OpenSimAddInstallRPATH(TARGET ${OSIMRP_TARGET} LOADER FROM "" TO "")\n\nendfunction()\n\n# Similar to OpenSimAddInstallRPATH, but specifically for adding a run-path to\n# the Simbody libraries copied into the OpenSim installation. If Simbody is not\n# copied into the OpenSim installation (OPENSIM_COPY_DEPENDENCIES=OFF) or the\n# copied Simbody libraries are installed to the same folder as the OpenSim\n# libraries (OPENSIM_INSTALL_UNIX_FHS=ON), then this function does nothing.\n#\n# TARGET: The CMake target to which the run-path should be added.\n# ABSOLUTE: Add an absolute run-path to the Simbody libraries in the OpenSim\n#   installation. If you specify this argument, then you should not specify\n#   EXECTUABLE, LOADER, or FROM.\n# EXECUTABLE, LOADER: Specify one of these flags to indicate whether the\n#   run-path is relative to the executable\'s location or relative to the loader\n#   (the library/executable that attempts to load the dependent library). Only\n#   affects Mac.\n# FROM: The path (relative to the OpenSim installation root) of the\n#   executable/library that is loading a dependent Simbody library.\nfunction(OpenSimAddInstallRPATHSimbody)\n    set(options EXECUTABLE LOADER ABSOLUTE)\n    set(oneValueArgs TARGET FROM)\n    set(multiValueArgs)\n    cmake_parse_arguments(\n        OSIMRP "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})\n    if(OSIMRP_ABSOLUTE AND (OSIMRP_FROM OR OSIMRP_EXECUTABLE OR OSIMRP_LOADER))\n        message(AUTHOR_WARNING\n            "Cannot specify both ABSOLUTE and FROM, EXECUTABLE, or LOADER.")\n    endif()\n\n    if(NOT OPENSIM_USE_INSTALL_RPATH OR NOT OPENSIM_COPY_DEPENDENCIES\n            OR OPENSIM_INSTALL_UNIX_FHS)\n        return()\n        RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"\n        LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"\n        ARCHIVE DESTINATION "${OPENSIM_INSTALL_ARCHIVEDIR}")\n\n    # Install headers.\n    # ----------------\n                FROM ${OSIMRP_FROM} TO ${root_to_simbody_lib_dir})\n        endif()\n    endif()\nendfunction()\n\n# Similar to OpenSimAddInstallRPATH, but specifically for adding an absolute\n# run-path.\n#\n# TARGET: The CMake target to which the run-path should be added.\n# TO: The path (relative to the OpenSim installation root) where the dependent\n#   library is located.\nfunction(OpenSimAddInstallRPATHAbsolute)\n    set(options)\n    set(oneValueArgs TARGET TO)\n    set(multiValueArgs)\n    cmake_parse_arguments(\n        OSIMRP "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})\n\n    if(NOT OPENSIM_USE_INSTALL_RPATH)\n        return()\n    endif()\n\n    set_property(TARGET ${OSIMRP_TARGET} APPEND PROPERTY INSTALL_RPATH\n        "${CMAKE_INSTALL_PREFIX}/${OSIMRP_TO}")\nendfunction()\n\n# Create an OpenSim API library. Here are the arguments:\n# VENDORLIB: If this is a vendor library, specify "VENDORLIB" as the first\n#   argument. Otherwise, omit.\n# LOWERINCLUDEDIRNAME: When installing the headers for this library, make the\n#   name of the library all lower-case (e.g., Lepton -> lepton).\n# EXCLUDEFROMPYTHON: Do not install this library into the python package.\n# KIT: Name of the library (e.g., Common).\n# AUTHORS: A string listing authors of the library.\n# LINKLIBS: List of libraries (targets) to link against.\n# INCLUDES: List of header files for the library (obtain via file(GLOB ...)).\n# SOURCES: List of cpp files for the library (obtain via file(GLOB ...)).\n# TESTDIRS: List of subdirectories that contain tests (and a CMakeLists.txt).\n# INCLUDEDIRS (optional): Affects how header files are installed. Use this if\n#   the library directory contains subdirectories with header files. If this is\n#   the case, this variable should be a list of those subdirectories (relative\n#   paths). See OpenSim/Simulation/CMakeLists.txt for an example. If omitted,\n#   all the headers specified under INCLUDES are installed into the same\n#   directory in the installation tree.\n# INCLUDEINSTALLREL (optional): If INCLUDEDIRS is specified, remove\n#   "INCLUDEINSTALLREL" from the location of the installed headers.\n#\n        #    list(APPEND run_path_list\n        #           "\\@loader_path/${lib_dir_to_simbody_lib_dir}")\n        #endif()\n        # Use APPEND to include the BTK RPATH, set in CMAKE_INSTALL_RPATH.\n        set_property(TARGET ${OSIMADDLIB_LIBRARY_NAME} APPEND PROPERTY\n            INSTALL_RPATH "${run_path_list}"\n#       TESTDIRS "Test"\n#       )\nfunction(OpenSimAddLibrary)\n\n    # Parse arguments.\n    # ----------------\n    # http://www.cmake.org/cmake/help/v2.8.9/cmake.html#module:CMakeParseArguments\n    set(options VENDORLIB LOWERINCLUDEDIRNAME EXCLUDEFROMPYTHON)\n    set(oneValueArgs KIT AUTHORS INCLUDEINSTALLREL)\n    set(multiValueArgs LINKLIBS INCLUDES SOURCES TESTDIRS INCLUDEDIRS)\n    cmake_parse_arguments(\n        OSIMADDLIB "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})\n\n    string(TOUPPER "${OSIMADDLIB_KIT}" OSIMADDLIB_UKIT)\n\n\n    # Version stuff.\n    # --------------\n    set(OSIMADDLIB_LIBRARY_NAME osim${OSIMADDLIB_KIT})\n\n    add_definitions(\n        -DOPENSIM_${OSIMADDLIB_UKIT}_LIBRARY_NAME=${OSIMADDLIB_LIBRARY_NAME}\n        -DOPENSIM_${OSIMADDLIB_UKIT}_MAJOR_VERSION=${OPENSIM_MAJOR_VERSION}\n        -DOPENSIM_${OSIMADDLIB_UKIT}_MINOR_VERSION=${OPENSIM_MINOR_VERSION}\n        -DOPENSIM_${OSIMADDLIB_UKIT}_BUILD_VERSION=${OPENSIM_PATCH_VERSION}\n        -DOPENSIM_${OSIMADDLIB_UKIT}_COPYRIGHT_YEARS="2005-2017"\n        -DOPENSIM_${OSIMADDLIB_UKIT}_AUTHORS="${AUTHORS}"\n        -DOPENSIM_${OSIMADDLIB_UKIT}_TYPE="Shared"\n        )\n\n\n    # Add the library.\n    # ----------------\n    # These next few lines are the most important:\n\n    # Create the library using the provided source and include files.\n    add_library(${OSIMADDLIB_LIBRARY_NAME} SHARED\n        ${OSIMADDLIB_SOURCES} ${OSIMADDLIB_INCLUDES})\n\n    target_include_directories(${OSIMADDLIB_LIBRARY_NAME} \n        # Used when building this target:\n        PRIVATE "${OpenSim_SOURCE_DIR}"\n                "${OpenSim_SOURCE_DIR}/Vendors/lepton/include"\n        # Used by other targets in this project:\n        INTERFACE $<BUILD_INTERFACE:${OpenSim_SOURCE_DIR}>\n                  $<BUILD_INTERFACE:${OpenSim_SOURCE_DIR}/Vendors/lepton/include>\n        # Used by client projects using an installed OpenSim:\n        INTERFACE $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>\n                  $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/OpenSim>\n        )\n\n    # This target links to the libraries provided as arguments to this func.\n    target_link_libraries(${OSIMADDLIB_LIBRARY_NAME} ${OSIMADDLIB_LINKLIBS})\n\n    # This is for exporting classes on Windows.\n    if(OSIMADDLIB_VENDORLIB)\n\t    set(OSIMADDLIB_FOLDER "Vendor Libraries")\n    else()\n\t\tset(OSIMADDLIB_FOLDER "Libraries")\n    endif()\n    set_target_properties(${OSIMADDLIB_LIBRARY_NAME} PROPERTIES\n       DEFINE_SYMBOL OSIM${OSIMADDLIB_UKIT}_EXPORTS\n       FOLDER "${OSIMADDLIB_FOLDER}" # For Visual Studio.\n    )\n\n    # Install.\n    # --------\n    # Shared libraries are needed at runtime for applications, so we put them\n    # at the top level in OpenSim/bin/*.dll (Windows) or OpenSim/lib/*.so\n    # (Linux) or OpemSim/lib/*.dylib (Mac). Windows .lib files, and Linux/Mac\n    # .a static archives are only needed at link time so go in sdk/lib.\n    if(WIN32)\n        set(OSIMADDLIB_LIBRARY_DESTINATION sdk/lib)\n    else()\n        set(OSIMADDLIB_LIBRARY_DESTINATION lib)\n    endif()\n    install(TARGETS ${OSIMADDLIB_LIBRARY_NAME}\n        EXPORT OpenSimTargets\n        RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"\n        LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"\n        ARCHIVE DESTINATION "${OPENSIM_INSTALL_ARCHIVEDIR}")\n    if(BUILD_PYTHON_WRAPPING AND OPENSIM_PYTHON_STANDALONE\n            AND NOT OSIMADDLIB_EXCLUDEFROMPYTHON)\n        if (WIN32)\n            install(TARGETS ${OSIMADDLIB_LIBRARY_NAME}\n                RUNTIME DESTINATION "${OPENSIM_INSTALL_PYTHONDIR}/opensim")\n        else()\n            install(TARGETS ${OSIMADDLIB_LIBRARY_NAME}\n                LIBRARY DESTINATION "${OPENSIM_INSTALL_PYTHONDIR}/opensim")\n        endif()\n    endif()\n\n    # Install headers.\n    # ----------------\n    set(_INCLUDE_PREFIX "${CMAKE_INSTALL_INCLUDEDIR}/OpenSim")\n    if(OSIMADDLIB_LOWERINCLUDEDIRNAME)\n        string(TOLOWER "${OSIMADDLIB_KIT}" OSIMADDLIB_LKIT)\n        set(_INCLUDE_LIBNAME ${OSIMADDLIB_LKIT})\n    else()\n        set(_INCLUDE_LIBNAME ${OSIMADDLIB_KIT})\n    endif()\n    if(OSIMADDLIB_INCLUDEDIRS)\n        foreach(dir ${OSIMADDLIB_INCLUDEDIRS})\n            file(GLOB HEADERS ${dir}/*.h) # returns full pathnames\n            if(OSIMADDLIB_INCLUDEINSTALLREL)\n                # Remove "INCLUDEINSTALLREL" from the installed location.\n                file(RELATIVE_PATH subdir\n                    "${CMAKE_CURRENT_SOURCE_DIR}${OSIMADDLIB_INCLUDEINSTALLREL}"\n                    "${CMAKE_CURRENT_SOURCE_DIR}${dir}")\n            else()\n                set(subdir ${dir})\n            endif()\n            install(FILES ${HEADERS}\n                DESTINATION ${_INCLUDE_PREFIX}/${_INCLUDE_LIBNAME}/${subdir})\n        endforeach(dir)\n    else()\n        install(FILES ${OSIMADDLIB_INCLUDES}\n            DESTINATION ${_INCLUDE_PREFIX}/${_INCLUDE_LIBNAME})\n    endif()\n\n    # RPATH (so that libraries find library dependencies)\n    # ---------------------------------------------------\n    OpenSimAddInstallRPATHSelf(TARGET ${OSIMADDLIB_LIBRARY_NAME} LOADER)\n    OpenSimAddInstallRPATHSimbody(TARGET ${OSIMADDLIB_LIBRARY_NAME} LOADER\n        FROM "${CMAKE_INSTALL_LIBDIR}")\n\n    # Testing.\n    # --------\n    enable_testing()\n\n    if(BUILD_TESTING)\n        foreach(OSIMADDLIB_TESTDIR ${OSIMADDLIB_TESTDIRS})\n            subdirs("${OSIMADDLIB_TESTDIR}")\n        endforeach()\n    endif()\n\nendfunction()\n\n# Copy a file from the directory containing test files (model files, data,\n# etc.) to the directory in which a test will be executed. This function makes\n# it easy to re-use files that are used in tests. With an easier mechanism for\n# re-using these files, we won\'t end up version-controlling the same file in\n# multiple test directories.\n#\n# Arguments are a list of files in the test resources directory\n# (OPENSIM_SHARED_TEST_FILES_DIR) to copy.\nfunction(OpenSimCopySharedTestFiles)\n    if(BUILD_TESTING)\nendfunction()\n\n\n# Function to copy DLL files from dependency install directory into OpenSim \n# build and install directories. This is a Windows specific function enabled \n# only for Windows platform. Intention is to allow runtime loader to find all \n        if(EXECUTABLE_OUTPUT_PATH)\n            set(TEST_PATH "${EXECUTABLE_OUTPUT_PATH}")\n        else()\n            set(TEST_PATH "${CMAKE_CURRENT_BINARY_DIR}")\n        endif()\n\n        # Make test targets.\n        foreach(test_program ${OSIMADDTESTS_TESTPROGRAMS})\n            # NAME_WE stands for "name without extension"\n            get_filename_component(TEST_NAME ${test_program} NAME_WE)\n\n            add_executable(${TEST_NAME} ${test_program}\n                ${OSIMADDTESTS_SOURCES})\n            target_link_libraries(${TEST_NAME} ${OSIMADDTESTS_LINKLIBS})\n            add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME})\n            set_target_properties(${TEST_NAME} PROPERTIES\n                FOLDER "Tests"\n\t\t\t\t)\n\n        endforeach()\n\n        # Copy data files to build directory.\n        foreach(data_file ${OSIMADDTESTS_DATAFILES})\n            # This command re-copies the data files if they are modified;\n            # custom commands don\'t do this.\n            file(COPY "${data_file}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")\n        endforeach()\n\n        #if(UNIX)\n        #  add_definitions(-fprofile-arcs -ftest-coverage)\n        #  link_libraries(gcov)\n        #endif(UNIX)\n\n    endif()\n\nendfunction()\n\n\n# Create an application/executable. To be used in the Appliations directory.\n# NAME: Name of the application. Must also be the name of the source file\n#   containing main() (without the .cpp extension).\n# SOURCES: Additional header/source files to compile into this target. \n#\n# Here\'s an example:\n#   OpenSimAddApplication(NAME opensim-cmd SOURCES opensim-cmd_run-tool.h)\nfunction(OpenSimAddApplication)\n\n    # Parse arguments.\n    # ----------------\n    # http://www.cmake.org/cmake/help/v2.8.9/cmake.html#module:CMakeParseArguments\n    set(options)\n    set(oneValueArgs NAME)\n    set(multiValueArgs SOURCES)\n    cmake_parse_arguments(\n        OSIMADDAPP "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})\n    \n    # Build.\n    add_executable(${OSIMADDAPP_NAME} ${OSIMADDAPP_NAME}.cpp\n                                      ${OSIMADDAPP_SOURCES})\n    target_link_libraries(${OSIMADDAPP_NAME} osimTools)\n    set_target_properties(${OSIMADDAPP_NAME} PROPERTIES\n        FOLDER "Applications")\n\n    # Install.\n    install(TARGETS ${OSIMADDAPP_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})\n\n    # RPATH (so that the executable finds libraries without using env. vars).\n    OpenSimAddInstallRPATH(TARGET ${OSIMADDAPP_NAME} EXECUTABLE\n        FROM "${CMAKE_INSTALL_BINDIR}" TO "${CMAKE_INSTALL_LIBDIR}")\n    OpenSimAddInstallRPATHSimbody(TARGET ${OSIMADDAPP_NAME} EXECUTABLE\n        FROM "${CMAKE_INSTALL_BINDIR}")\n\nendfunction()\n\n\n# Add a target to the OpenSim project for building an example with the given\n# NAME. The example must be within a source file named ${NAME}.cpp, or could\n# contain multiple executable files, listed via the EXECUTABLES argument\n# (omitting the .cpp extension). This function also installs the example files\n# with a CMakeLists that can find the OpenSim installation and build the\n# example.\n#\n# If SUBDIR is provided, the example is installed into this subdirectory of the\n# C++ Examples folder.\n#\n# This function can only be used from the source distribution of OpenSim\n# (e.g., not via the UseOpenSim.cmake file in a binary distribution).\nfunction(OpenSimAddExampleCXX)\n    set(options)\n    set(oneValueArgs NAME SUBDIR)\n    set(multiValueArgs RESOURCES EXECUTABLES)\n    cmake_parse_arguments(OSIMEX\n            "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})\n\n    if(NOT OSIMEX_EXECUTABLES)\n        set(OSIMEX_EXECUTABLES ${OSIMEX_NAME})\n    endif()\n\n    # Build the example in the build tree.\n    foreach(exe ${OSIMEX_EXECUTABLES})\n        add_executable(${exe} ${exe}.cpp)\n        set_target_properties(${exe} PROPERTIES FOLDER "Examples")\n        target_link_libraries(${exe} osimTools osimExampleComponents osimMoco)\n    endforeach()\n    file(COPY ${OSIMEX_RESOURCES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")\n\n    # Install files so that users can build the example.\n    # We do not install pre-built binaries of the examples.\n    set(_example_install_dir\n            ${OPENSIM_INSTALL_CPPEXDIR}/${OSIMEX_SUBDIR}/${OSIMEX_NAME})\n    install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/\n            DESTINATION "${_example_install_dir}"\n            PATTERN "CMakeLists.txt" EXCLUDE)\n\n    # These next two variables are to be configured below (they are not used\n    # here, but within ExampleCMakeListsToInstall.txt.in).\n    set(_example_name ${OSIMEX_NAME})\n    set(_example_executables ${OSIMEX_EXECUTABLES})\n    file(RELATIVE_PATH _opensim_install_hint\n            "${CMAKE_INSTALL_PREFIX}/${_example_install_dir}"\n            "${CMAKE_INSTALL_PREFIX}")\n    configure_file(\n        "${CMAKE_SOURCE_DIR}/OpenSim/Examples/ExampleCMakeListsToInstall.txt.in"\n        "${CMAKE_CURRENT_BINARY_DIR}/CMakeListsToInstall.txt"\n        @ONLY)\n\n    install(FILES\n            "${CMAKE_CURRENT_BINARY_DIR}/CMakeListsToInstall.txt"\n            DESTINATION ${_example_install_dir}\n            RENAME CMakeLists.txt)\nendfunction()\n\n\n# Add a target to the OpenSim project for building an example containing a\n# plugin library and an executable.\n# The directory containing the CMakeLists.txt invoking this macro must have 3\n# source files: ${NAME}.h and ${NAME}.cpp are used to create the plugin, and\n# and example${NAME}.cpp is compiled into an executable that uses the plugin.\n# This function also installs the example file with a CMakeLists that can find\n# the OpenSim installation and build the example.\n#\n# If SUBDIR is provided, the example is installed into this subdirectory of the\n# C++ Examples folder.\n#\n# This function can only be used from the source distribution of OpenSim\n# (e.g., not via the UseOpenSim.cmake file in a binary distribution).\nfunction(OpenSimAddPluginExampleCXX)\n    set(options)\n    set(oneValueArgs NAME SUBDIR)\n    set(multiValueArgs RESOURCES)\n    cmake_parse_arguments(OSIMEX\n            "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})\n\n    add_library(osim${OSIMEX_NAME} SHARED\n            ${OSIMEX_NAME}.h\n            ${OSIMEX_NAME}.cpp\n            osim${OSIMEX_NAME}DLL.h\n            RegisterTypes_osim${OSIMEX_NAME}.h\n            RegisterTypes_osim${OSIMEX_NAME}.cpp\n            )\n    set_target_properties(osim${OSIMEX_NAME} PROPERTIES\n            FOLDER "Examples")\n    target_link_libraries(osim${OSIMEX_NAME} osimTools osimExampleComponents\n            osimMoco)\n\n    string(TOUPPER ${OSIMEX_NAME} _example_name_upper)\n    set_target_properties(osim${OSIMEX_NAME} PROPERTIES\n            DEFINE_SYMBOL OSIM${_example_name_upper}_EXPORTS\n            )\n\n    add_executable(example${OSIMEX_NAME} example${OSIMEX_NAME}.cpp)\n    set_target_properties(example${OSIMEX_NAME} PROPERTIES\n            FOLDER "Examples")\n    target_link_libraries(example${OSIMEX_NAME} osim${OSIMEX_NAME})\n    file(COPY ${OSIMEX_RESOURCES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")\n\n    set(_example_install_dir\n            ${OPENSIM_INSTALL_CPPEXDIR}/${OSIMEX_SUBDIR}/Plugins/example${OSIMEX_NAME})\n    install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/\n            DESTINATION "${_example_install_dir}"\n            PATTERN "CMakeLists.txt" EXCLUDE)\n\n    # These next two variables are to be configured below (they are not used\n    # here, but within ExampleCMakeListsToInstall.txt.in).\n    set(_example_name ${OSIMEX_NAME})\n    file(RELATIVE_PATH _opensim_install_hint\n            "${CMAKE_INSTALL_PREFIX}/${_example_install_dir}"\n            "${CMAKE_INSTALL_PREFIX}")\n    configure_file(\n        "${CMAKE_SOURCE_DIR}/OpenSim/Examples/PluginExampleCMakeListsToInstall.txt.in"\n        "${CMAKE_CURRENT_BINARY_DIR}/CMakeListsToInstall.txt"\n        @ONLY)\n\n    install(FILES\n            "${CMAKE_CURRENT_BINARY_DIR}/CMakeListsToInstall.txt"\n            DESTINATION ${_example_install_dir}\n            RENAME CMakeLists.txt)\nendfunction()\n\n\n# Function to install shared libraries (any platform) from a dependency install\n# directory into the OpenSim installation. One use case is to install libraries\n# into the python package.\n# PREFIX: A common part of the library file names (e.g., \'SimTK\' or \'ezc3d\').\n#         This is to avoid copying unrelated files from a folder like /usr/lib.\n# DEP_LIBS_DIR_WIN: Directory to search for the dependency\'s library, on\n#         Windows.\n# DEP_LIBS_DIR_UNIX: Directory to search for the dependency\'s library, on\n#         UNIX (APPLE and Linux). Specify only the lib directory to avoid\n#         searching all of /usr/local (if the dependency is installed to a\n#         system location like this).\n# OSIM_DESTINATION: Destination of the libraries within OpenSim\'s installation.\nfunction(OpenSimInstallDependencyLibraries PREFIX DEP_LIBS_DIR_WIN\n        DEP_LIBS_DIR_UNIX OSIM_DESTINATION)\n    if(WIN32)\n        file(GLOB_RECURSE LIBS "${DEP_LIBS_DIR_WIN}/${PREFIX}*.dll")\n    else()\n        if(APPLE)\n            set(lib_ext "dylib")\n        else()\n            set(lib_ext "so*") # Trailing * for version #s.\n        endif()\n        file(GLOB_RECURSE LIBS "${DEP_LIBS_DIR_UNIX}/lib${PREFIX}*.${lib_ext}")\n    endif()\n    if(NOT LIBS)\n        message(FATAL_ERROR "Zero shared libraries found in directory "\n            "${DEP_INSTALL_DIR}.")\n    endif()\n    install(FILES ${LIBS} DESTINATION "${OSIM_DESTINATION}")\nendfunction()\n\n\n# Copy DLL files from a dependency\'s installation into the\n# build and install directories. This is a Windows-specific function enabled\n# only on Windows. The intention is to allow the runtime loader to find all \n# the required DLLs without editing the PATH environment variable.\n# Arguments:\n#   DEP_NAME: Name of the dependency (used to name a custom target)\n#   DEP_BIN_DIR: The directory in the dependency containing DLLs to copy.\n# This is based on a similar function in OpenSimMacros.cmake.\nfunction(OpenSimCopyDependencyDLLsForWin)\n    # On Windows, copy dlls into the OpenSim binary directory.\n    set(options)\n    set(oneValueArgs DEP_NAME DEP_BIN_DIR)\n    set(multiValueArgs)\n    cmake_parse_arguments(OSIMCOPY\n            "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})\n    if(WIN32)\n        file(GLOB DLLS ${OSIMCOPY_DEP_BIN_DIR}/*.dll)\n        if(NOT DLLS)\n            message(FATAL_ERROR "Zero DLLs found in directory "\n                                "${OSIMCOPY_DEP_BIN_DIR}.")\n        endif()\n        set(DEST_DIR "${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}")\n        foreach(DLL IN LISTS DLLS)\n            get_filename_component(DLL_NAME ${DLL} NAME)\n            list(APPEND DLLS_DEST "${DEST_DIR}/${DLL_NAME}")\n            add_custom_command(OUTPUT "${DEST_DIR}/${DLL_NAME}"\n                COMMAND ${CMAKE_COMMAND} -E make_directory ${DEST_DIR}\n                COMMAND ${CMAKE_COMMAND} -E copy ${DLL} ${DEST_DIR}\n                DEPENDS ${DLL}\n                COMMENT "Copying ${DLL_NAME} from ${OSIMCOPY_DEP_BIN_DIR} to ${DEST_DIR}.")\n        endforeach()\n        add_custom_target(Copy_${OSIMCOPY_DEP_NAME}_DLLs ALL DEPENDS ${DLLS_DEST})\n        set_target_properties(Copy_${OSIMCOPY_DEP_NAME}_DLLs PROPERTIES\n            PROJECT_LABEL "Copy ${OSIMCOPY_DEP_NAME} DLLs")\n        if(OPENSIM_COPY_DEPENDENCIES)\n            install(FILES ${DLLS} DESTINATION ${CMAKE_INSTALL_BINDIR})\n        endif()\n    endif()\nendfunction()\n\n\n# Discover the file dependencies for an invocation of swig, for use with the\n# DEPENDS field of an add_custom_command().\n#\n# OSIMSWIGDEP_RETURNVAL  is filled with a list of the dependencies.\n# OSIMSWIGDEP_MODULE     is the name of the module (just for messages).\n# OSIMSWIGDEP_INVOCATION is the SWIG command to use to check for dependencies.\n#                        We append `-MM` to this, which asks SWIG for the\n#                        dependencies.\nmacro(OpenSimFindSwigFileDependencies OSIMSWIGDEP_RETURNVAL\n                                      OSIMSWIGDEP_MODULE\n                                      OSIMSWIGDEP_INVOCATION)\n    # We must use a macro instead of a function in order to return a value.\n\n    # Assemble dependencies. This command is run during CMake\'s configure step.\n    message(STATUS\n        "Discovering dependencies for SWIG module ${OSIMSWIGDEP_MODULE}.")\n    execute_process(COMMAND ${SWIG_EXECUTABLE}\n            -MM # List dependencies, but omit files in SWIG library.\n            ${OSIMSWIGDEP_INVOCATION}\n        OUTPUT_VARIABLE _dependencies_makefile\n        RESULT_VARIABLE _successfully_got_dependencies\n            )\n    # On Windows, _dependencies_makefile now contains something like this:\n    # C:\\opensim-core\\Bindings\\Python\\swig\\python_simbody_wrap.cxx: \\\n    #   C:\\opensim-core\\Bindings\\Python\\swig\\python_simbody.i \\\n    #   C:\\opensim-core\\Bindings\\Python\\swig\\numpy.i \\\n    #   ...<more header files and SWIG interface files>\n    # Note: SWIG does not depend on cpp files.\n    # Clean up the output, since it\'s in the form of a makefile\n    # (and we just want a list of file paths).\n    if(${_successfully_got_dependencies} EQUAL 0) # return code 0 is success.\n        # \'^.*cxx:\' matches the first line of the makefile (the output file path).\n        # \'\\\\\\\\\' matches a single \\ (escape for CMake, and escape for regex).\n        string(REGEX REPLACE "(^.*cxx:|\\\\\\\\\\n)" "" ${OSIMSWIGDEP_RETURNVAL}\n            ${_dependencies_makefile})\n        # Replace spaces with semicolons to create a list of file paths.\n        separate_arguments(${OSIMSWIGDEP_RETURNVAL})\n    else()\n        # In case the variable has a value for previous modules.\n        unset(${OSIMSWIGDEP_RETURNVAL})\n        # If someone ends up here, it\'s a bug in this CMakeLists.txt.\n        message(AUTHOR_WARNING\n            "Could not determine dependencies for SWIG module ${OSIMSWIGDEP_MODULE}.")\n    endif()\n\n    unset(_dependencies_makefile)\n    unset(_successfully_got_dependencies)\n\nendmacro()\n\n', 'message': 'Merge pull request #1574 from opensim-org/python_standalone\n\nAllow making a standalone Python package', 'author_name': 'GitHub', 'lang': 'cmake'}