#------------------------------------------------------------------------------- # Simbody # # This is the master CMake file that coordinates # the build of Simbody. There are four steps: # (1) Get files needed for particular platform # (2) Build SimTKcommon library # (3) Build SimTKmath library # (4) Build SimTKsimbody library # (5) Build examples # #------------------------------------------------------------------------------- cmake_minimum_required(VERSION 3.21) # Needed for install(RUNTIME_DEPENDENCY_SET ...) project(Simbody VERSION 3.8.0) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") ## List of Simbody build configuration options: #------------------------------------------------------------------------------- ### Major build options: #-------------------------------- # SIMBODY_BUILD_SHARED_LIBS # BUILD_VISUALIZER # BUILD_EXAMPLES # BUILD_TESTING # INSTALL_DOCS # CMake doesn't initialize BUILD_SHARED_LIBS and add_library calls without a library type # default to STATIC if BUILD_SHARED_LIBS isn't defined. BUT, we don't want to pollute/affect # the global cache, so we define a project-prefixed variable (which defaults to the cache'd # BUILD_SHARED_LIBS if defined), and then set BUILD_SHARED_LIBS before each target definition. set(shared_lib_default ON) if(DEFINED BUILD_SHARED_LIBS) set(shared_lib_default ${BUILD_SHARED_LIBS}) endif() option(SIMBODY_BUILD_SHARED_LIBS "Build dynamic (shared) Simbody libraries. Defaults to ON or the value of BUILD_SHARED_LIBS if defined." ${shared_lib_default}) # TODO: Remove after this version cycle? option(BUILD_DYNAMIC_LIBRARIES "[DEPRECATED] Build dynamic (shared) Simbody libraries." OFF) mark_as_advanced(BUILD_DYNAMIC_LIBRARIES) if(BUILD_DYNAMIC_LIBRARIES) message(DEPRECATION "The BUILD_DYNAMIC_LIBRARIES build option is deprecated and will be \ ignored in future versions of Simbody. Please set SIMBODY_BUILD_SHARED_LIBS=ON instead.") if(NOT SIMBODY_BUILD_SHARED_LIBS) set(SIMBODY_BUILD_SHARED_LIBS ON CACHE BOOL "" FORCE) unset(BUILD_DYNAMIC_LIBRARIES CACHE) endif() endif() # TODO: Remove after this version cycle? option(BUILD_STATIC_LIBRARIES "[DEPRECATED] Build static Simbody libraries." OFF) mark_as_advanced(BUILD_STATIC_LIBRARIES) if(BUILD_STATIC_LIBRARIES) message(DEPRECATION "The BUILD_STATIC_LIBRARIES build option is deprecated and will be \ ignored in future versions of Simbody. Please set SIMBODY_BUILD_SHARED_LIBS=OFF instead.") if(SIMBODY_BUILD_SHARED_LIBS) set(SIMBODY_BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) unset(BUILD_STATIC_LIBRARIES CACHE) endif() endif() if(BUILD_DYNAMIC_LIBRARIES AND BUILD_STATIC_LIBRARIES) message(FATAL_ERROR "Simultaneous static and shared library builds are no longer supported. \ Please see the README for instructions to produce similar builds.") endif() option(BUILD_VISUALIZER "Build and install the Simbody visualizer." ON) option(BUILD_EXAMPLES "Build and install Simbody examples." ON) # Caution: this variable is automatically created by the CMake # enable_testing() command, but we'll take it over here for # our own purposes too. set(BUILD_TESTING ON CACHE BOOL "Build tests for Simbody libraries.") option(INSTALL_DOCS "Build and install Simbody documentation." ON) ### Library name related options: #-------------------------------- # BUILD_USING_NAMESPACE # BUILD_VERSIONED_LIBRARIES # SIMBODY_STATIC_LIBRARIES_POSTFIX set(BUILD_USING_NAMESPACE "" CACHE STRING "Add a prefix to library filenames. (e.g. `BUILD_USING_NAMESPACE=ns_` would produce \ libraries like 'libns_SimTKmath.so' on Unix).") mark_as_advanced(BUILD_USING_NAMESPACE) option(BUILD_VERSIONED_LIBRARIES "Add a version suffix to Simbody libraries (e.g. library names like 'libSimTKMath_3.8.so')" OFF) mark_as_advanced(BUILD_VERSIONED_LIBRARIES) # TODO: Remove after this version cycle? option(BUILD_UNVERSIONED_LIBRARIES "[DEPRECATED] Opposite of BUILD_VERSIONED_LIBRARIES. Will be ignored in future versions of Simbody" OFF) mark_as_advanced(BUILD_UNVERSIONED_LIBRARIES) if(BUILD_UNVERSIONED_LIBRARIES) message(DEPRECATION "The BUILD_UNVERSIONED_LIBRARIES build option is deprecated and will be \ ignored in future versions of Simbody. Please set BUILD_VERSIONED_LIBRARIES=OFF instead.") set(BUILD_VERSIONED_LIBRARIES OFF CACHE BOOL "" FORCE) unset(BUILD_UNVERSIONED_LIBRARIES CACHE) endif() if(BUILD_VERSIONED_LIBRARIES AND BUILD_UNVERSIONED_LIBRARIES) message(FATAL_ERROR "Simultaneous versioned and unversioned library builds are no longer supported. \ Please see the README for instructions to produce similar builds.") endif() set(SIMBODY_STATIC_LIBRARIES_POSTFIX "" CACHE STRING "Add a postfix to static Simbody libraries (e.g. library names like 'libSimTKMath_static.dll'). \ Typically only useful to distinguish static/dynamic libaries on DLL platforms") mark_as_advanced(SIMBODY_STATIC_LIBRARIES_POSTFIX) ### Advanced dev options: #------------------------ option(SIMBODY_COVERAGE "Generate code coverage files to assess test coverage (ignored for MSVC compilers)" OFF) mark_as_advanced(SIMBODY_COVERAGE) option(WINDOWS_USE_EXTERNAL_LIBS "Link against system BLAS/LAPACK on Windows. When set to OFF/FALSE (default), Simbody \ will use vendored BLAS/LAPACK libraries." OFF) mark_as_advanced(WINDOWS_USE_EXTERNAL_LIBS) # Ultimately, BUILD_USING_OTHER_LAPACK is given to target_link_libraries; # see https://cmake.org/cmake/help/latest/command/target_link_libraries.html#overview # for a more complete description of different valid incantations for BUILD_USING_OTHER_LAPACK set(BUILD_USING_OTHER_LAPACK "" CACHE STRING "Use non-default BLAS/LAPACK libraries. List library names (no extensions) \ separated by semicolons (full paths or paths that are on the (DY)LD_LIBRARY_PATH \ (UNIX) or PATH (Windows)). (e.g. BUILD_USING_OTHER_LAPACK='mkl_intel_c_dll;\ mkl_sequential_dll;mkl_core_dll' to use Intel MKL on Windows).") mark_as_advanced(BUILD_USING_OTHER_LAPACK) ### Deprecated and ignored build options: #---------------------------------------- if(DEFINED BUILD_TESTS_AND_EXAMPLES_STATIC) message(DEPRECATION "The BUILD_TESTS_AND_EXAMPLES_STATIC is deprecated. Only one set \ of Simbody libraries are built now (shared or static is set by SIMBODY_BUILD_SHARED_LIBS), \ and examples and tests are linked against these libraries.") unset(BUILD_TESTS_AND_EXAMPLES_STATIC CACHE) endif() if(DEFINED BUILD_TESTS_AND_EXAMPLES_SHARED) message(DEPRECATION "The BUILD_TESTS_AND_EXAMPLES_SHARED is deprecated. Only one set \ of Simbody libraries are built now (shared or static is set by SIMBODY_BUILD_SHARED_LIBS), \ and examples and tests are linked against these libraries.") unset(BUILD_TESTS_AND_EXAMPLES_SHARED CACHE) endif() #------------------------------------------------------------------------------- # Check compiler version if(MSVC) if(MSVC_VERSION LESS 1800 OR MSVC_VERSION EQUAL 1800) message(FATAL_ERROR "\nMSVC does not support C++ 2011 features, for " "example 'constexpr'. Update to at least MSVC 2015 " "or use a MinGW version on Windows.\nLook at the " "README.md for more information.\nIf you have the" " 'Visual C++ Compiler Nov 2013 CTP (CTP_Nov2013)'" " comment this test and configure normally.") endif() if(SIMBODY_COVERAGE) message(FATAL_ERROR "Code coverage is not possible with MSVC.") endif() elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "GNU") set(SIMBODY_REQUIRED_GCC_VERSION 4.9.0) if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${SIMBODY_REQUIRED_GCC_VERSION}) message(FATAL_ERROR "GNU GCC/G++ version is too old to compile Simbody.\n" "Simbody requires at least version : " "${SIMBODY_REQUIRED_GCC_VERSION}") endif() elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") set(SIMBODY_REQUIRED_CLANG_VERSION 3.4) if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${SIMBODY_REQUIRED_CLANG_VERSION}) message(FATAL_ERROR "Clang version is too old to compile Simbody.\n" "Simbody requires at least version : " "${SIMBODY_REQUIRED_CLANG_VERSION}") endif() endif() if((${CMAKE_CXX_COMPILER_ID} MATCHES "GNU" OR ${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") AND SIMBODY_COVERAGE) find_package(codecov) endif() set(SIMBODY_SONAME_VERSION "${Simbody_VERSION_MAJOR}.${Simbody_VERSION_MINOR}" CACHE INTERNAL "Soname version; appended to names of shared libs" ) # At this point CMake will have set CMAKE_INSTALL_PREFIX to /usr/local on Linux # or appropriate ProgramFiles directory on Windows, for example # C:/Program Files/Simbody, C:/Program Files (x86)/Simbody, or the local # language equivalent. if(WIN32) set(CMAKE_INSTALL_DOCDIR doc CACHE PATH "documentation root (DATAROOTDIR/doc/PROJECT_NAME)") else() # Redefine DOCDIR to use the project name in lowercase to avoid # problems with some platforms: NTFS on Win, XFS or JFS variants set(CMAKE_INSTALL_DOCDIR share/doc/simbody CACHE PATH "documentation root (DATAROOTDIR/doc/PROJECT_NAME)") endif() # Include GNUInstallDirs to get canonical paths include(GNUInstallDirs) # Put executables and libraries (shared and static) in the Simbody project binary folder. # This is most (only?) relevant on Windows, where libraries need to be in the same folder as the .exe set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) # Ensure that debug libraries have "_d" appended to their names. set(CMAKE_DEBUG_POSTFIX "_d") set(NS) if(BUILD_USING_NAMESPACE) set(NS "${BUILD_USING_NAMESPACE}_") endif() set(VN) if(BUILD_VERSIONED_LIBRARIES) # This is the suffix if we're building and depending on versioned libraries. set(VN "_${Simbody_VERSION}") endif() # # These are the output names of all the libraries we may generate. # set(SimTKSIMBODY_LIBRARY_NAME ${NS}SimTKsimbody${VN} CACHE INTERNAL "Base name of the SimTKsimbody library" ) set(SimTKMATH_LIBRARY_NAME ${NS}SimTKmath${VN} CACHE INTERNAL "Base name of the SimTKmath library" ) set(SimTKCOMMON_LIBRARY_NAME ${NS}SimTKcommon${VN} CACHE INTERNAL "Base name of the SimTKcommon library" ) # In addition to the platform name we need to know the Application Binary # Interface (ABI) we're building for. Currently that is either x86, meaning # 32 bit Intel instruction set, or x64 for 64 bit Intel instruction set. if("${CMAKE_SIZEOF_VOID_P}" EQUAL 8) set(PLATFORM_ABI x64) else() set(PLATFORM_ABI x86) endif() if(NOT MSVC AND NOT XCODE AND NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Debug, RelWithDebInfo (recommended), or Release build" FORCE) endif() # RPATH # ----- set(SIMBODY_USE_INSTALL_RPATH FALSE) if(APPLE) # CMake 2.8.12 introduced the ability to set RPATH for shared libraries on # OSX. This helps executables find the libraries they depend on without # having to set the DYLD_LIBRARY_PATH environment variable. # Consider a library libfoo.dyld and an executable bar. # On OSX, libraries have an "install name" that, when linking, is copied # into the target (e.g., bar). The "install name" can be the full path to # libfoo.dylib, in which case bar will have no trouble finding libfoo.dylib # at runtime (since it has the full path to it). This doesn't work if you # want to be able to relocate your project. Therefore, it's possible to use # special tokens in the "install name" that are evaluated separately. The # token "@exectuable_path" is evaluated (at run time) to the full path of # the exectuable (e.g., bar) that is trying to load libfoo.dylib. An even # more flexible token is "@rpath", which is evaluated to a path (called # RPATH) that can be baked into the executable just after compiling or any # time before running the executable (using the executable # "install_name_tool"). The RPATH stored in executables can also contain # "@executable_path", etc. On Linux, rather than "@executable_path", we # must use "$ORIGIN" to find the location of the executable. if(APPLE) # This variable gets used when configuring the Info.plist for # simbody-visualizer.app; see cmake/MacOSXBundleInfo.plist.in. set(MACOSX_BUNDLE_HIGH_RESOLUTION_CAPABLE "false") # Set the install name of libraries to contain "@rpath". # This allows clients of our libraries to point to them however they wish. set(CMAKE_MACOSX_RPATH ON) endif() # We only need to set RPATH in executables if the libraries are installed # into directories that are not already searched by the linker. list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" isSystemDir) # CMake sets isSystemDir to -1 if the lib dir is NOT a system lib dir. if("${isSystemDir}" STREQUAL "-1") # This variable is used later on to toggle if RPATH should be set for # specific targets. set(SIMBODY_USE_INSTALL_RPATH TRUE) endif() endif() ## This can be set to a different value by the person running CMake. set(BUILD_INST_SET "" CACHE STRING "CPU instruction level compiler is permitted to use (default: let compiler decide).") mark_as_advanced( BUILD_INST_SET ) ## Choose the maximum level of x86 instruction set that the compiler is ## allowed to use. if(BUILD_INST_SET) set(inst_set_to_use ${BUILD_INST_SET}) else() set(inst_set_to_use) endif() ## When building in any of the Release modes, tell gcc/clang to use ## not-quite most agressive optimization. Here we ## are specifying *all* of the Release flags, overriding CMake's defaults. ## Watch out for optimizer bugs in particular gcc versions! if(${CMAKE_CXX_COMPILER_ID} MATCHES "GNU" OR ${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") if(inst_set_to_use) string(TOLOWER ${inst_set_to_use} GCC_INST_SET) set(GCC_INST_SET "-m${GCC_INST_SET}") else() set(GCC_INST_SET) endif() # Unrolling fixed-count loops was a useful optimization for Simmatrix # in earlier gcc versions. # Doesn't have a big effect for current compiler crop and may be # pushing our luck with optimizer bugs. So let the compilers decide # how to handle loops instead. ##set(GCC_OPT_ENABLE "-funroll-loops") # If you know of optimization bugs that affect Simbody in particular # gcc versions, this is the place to turn off those optimizations. set(GCC_OPT_DISABLE) # C++ set(BUILD_CXX_FLAGS_DEBUG "-g ${GCC_INST_SET}") set(BUILD_CXX_FLAGS_RELEASE "-DNDEBUG -O2 ${GCC_OPT_ENABLE} ${GCC_OPT_DISABLE} ${GCC_INST_SET}") set(BUILD_CXX_FLAGS_RELWITHDEBINFO "-DNDEBUG -O2 -g ${GCC_OPT_ENABLE} ${GCC_OPT_DISABLE} ${GCC_INST_SET}") set(BUILD_CXX_FLAGS_MINSIZEREL "-DNDEBUG -Os ${GCC_INST_SET}") # C set(BUILD_C_FLAGS_DEBUG "-g ${GCC_INST_SET}") set(BUILD_C_FLAGS_RELEASE "-DNDEBUG -O2 ${GCC_OPT_ENABLE} ${GCC_OPT_DISABLE} ${GCC_INST_SET}") set(BUILD_C_FLAGS_RELWITHDEBINFO "-DNDEBUG -O2 -g ${GCC_OPT_ENABLE} ${GCC_OPT_DISABLE} ${GCC_INST_SET}") set(BUILD_C_FLAGS_MINSIZEREL "-DNDEBUG -Os ${GCC_INST_SET}") # C++ set(CMAKE_CXX_FLAGS_DEBUG ${BUILD_CXX_FLAGS_DEBUG} CACHE STRING "Control using BUILD_CXX" FORCE) set(CMAKE_CXX_FLAGS_RELEASE ${BUILD_CXX_FLAGS_RELEASE} CACHE STRING "Control using BUILD_CXX" FORCE) set(CMAKE_CXX_FLAGS_RELWITHDEBINFO ${BUILD_CXX_FLAGS_RELWITHDEBINFO} CACHE STRING "Control using BUILD_CXX" FORCE) set(CMAKE_CXX_FLAGS_MINSIZEREL ${BUILD_CXX_FLAGS_MINSIZEREL} CACHE STRING "Control using BUILD_CXX" FORCE) # C set(CMAKE_C_FLAGS_DEBUG ${BUILD_C_FLAGS_DEBUG} CACHE STRING "Control using BUILD_CXX" FORCE) set(CMAKE_C_FLAGS_RELEASE ${BUILD_C_FLAGS_RELEASE} CACHE STRING "Control using BUILD_CXX" FORCE) set(CMAKE_C_FLAGS_RELWITHDEBINFO ${BUILD_C_FLAGS_RELWITHDEBINFO} CACHE STRING "Control using BUILD_CXX" FORCE) set(CMAKE_C_FLAGS_MINSIZEREL ${BUILD_C_FLAGS_MINSIZEREL} CACHE STRING "Control using BUILD_CXX" FORCE) elseif(MSVC) ## When building in any of the Release modes, tell VC++ cl compiler to use ## intrinsics (i.e. sqrt instruction rather than sqrt subroutine) with ## flag /Oi. if(inst_set_to_use) string(TOUPPER ${inst_set_to_use} CL_INST_SET) set(CL_INST_SET "/arch:${CL_INST_SET}") else() set(CL_INST_SET) endif() ## C++ set(BUILD_CXX_FLAGS_DEBUG "/D _DEBUG /MDd /Od /Ob0 /RTC1 /Zi /GS- ${CL_INST_SET}") set(BUILD_CXX_FLAGS_RELEASE "/D NDEBUG /MD /O2 /Ob2 /Oi /GS- ${CL_INST_SET}") set(BUILD_CXX_FLAGS_RELWITHDEBINFO "/D NDEBUG /MD /O2 /Ob2 /Oi /Zi /GS- ${CL_INST_SET}") set(BUILD_CXX_FLAGS_MINSIZEREL "/D NDEBUG /MD /O1 /Ob1 /Oi /GS- ${CL_INST_SET}") ## C set(BUILD_C_FLAGS_DEBUG "/D _DEBUG /MDd /Od /Ob0 /RTC1 /Zi /GS- ${CL_INST_SET}") set(BUILD_C_FLAGS_RELEASE "/D NDEBUG /MD /O2 /Ob2 /Oi /GS- ${CL_INST_SET}") set(BUILD_C_FLAGS_RELWITHDEBINFO "/D NDEBUG /MD /O2 /Ob2 /Oi /Zi /GS- ${CL_INST_SET}") set(BUILD_C_FLAGS_MINSIZEREL "/D NDEBUG /MD /O1 /Ob1 /Oi /GS- ${CL_INST_SET}") ## C++ set(CMAKE_CXX_FLAGS_DEBUG "${BUILD_CXX_FLAGS_DEBUG} ${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING "Control using BUILD_CXX" FORCE) set(CMAKE_CXX_FLAGS_RELEASE "${BUILD_CXX_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS_RELEASE}" CACHE STRING "Control using BUILD_CXX" FORCE) set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${BUILD_CXX_FLAGS_RELWITHDEBINFO} ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}" CACHE STRING "Control using BUILD_CXX" FORCE) set(CMAKE_CXX_FLAGS_MINSIZEREL "${BUILD_CXX_FLAGS_MINSIZEREL} ${CMAKE_CXX_FLAGS_MINSIZEREL}" CACHE STRING "Control using BUILD_CXX" FORCE) ## C set(CMAKE_C_FLAGS_DEBUG "${BUILD_C_FLAGS_DEBUG} ${CMAKE_C_FLAGS_DEBUG}" CACHE STRING "Control using BUILD_CXX" FORCE) set(CMAKE_C_FLAGS_RELEASE "${BUILD_C_FLAGS_RELEASE} ${CMAKE_C_FLAGS_RELEASE}" CACHE STRING "Control using BUILD_CXX" FORCE) set(CMAKE_C_FLAGS_RELWITHDEBINFO "${BUILD_C_FLAGS_RELWITHDEBINFO} ${CMAKE_C_FLAGS_RELWITHDEBINFO}" CACHE STRING "Control using BUILD_CXX" FORCE) set(CMAKE_C_FLAGS_MINSIZEREL "${BUILD_C_FLAGS_MINSIZEREL} ${CMAKE_C_FLAGS_MINSIZEREL}" CACHE STRING "Control using BUILD_CXX" FORCE) endif() # # Allow automated build and dashboard. # if(BUILD_TESTING) include(CTest) # automatically calls enable_testing() ## When in Debug mode and running valgrind, some of the test ## cases take longer than the default 1500 seconds. set(CTEST_TESTING_TIMEOUT 7200) endif() # These are used in Doxyfile.in and SimbodyConfig.cmake.in. set(SIMBODY_INSTALL_DOXYGENDIR "${CMAKE_INSTALL_DOCDIR}/api") set(SIMBODY_DOXYGEN_TAGFILE_NAME "SimbodyDoxygenTagfile") if( INSTALL_DOCS ) add_subdirectory(doc) endif() # Specify where visualizer should be installed. This needs to be in the # root CMakeLists.txt so the cmake config file can see this value. # # Also specify where include files are installed. if(WIN32) # Install visualizer to bin, since it needs to be co-located with dll's set(SIMBODY_VISUALIZER_REL_INSTALL_DIR ${CMAKE_INSTALL_BINDIR}) # Install include files into base include folder since it's a sandbox set(SIMBODY_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}) else() # Visualizer is not intended to be a user executable. Proper place is # inside the lib directory set(SIMBODY_VISUALIZER_REL_INSTALL_DIR ${CMAKE_INSTALL_LIBEXECDIR}/simbody) # Install include files in simbody subfolder to avoid polluting the # global build folder set(SIMBODY_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}/simbody) endif() set(SIMBODY_VISUALIZER_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/${SIMBODY_VISUALIZER_REL_INSTALL_DIR}) add_subdirectory( Platform ) # PLATFORM_INCLUDE_DIRECTORIES now set; 'blas' and 'lapack' targets defined on Windows if(BUILD_USING_OTHER_LAPACK) set(LAPACK_BEING_USED ${BUILD_USING_OTHER_LAPACK} CACHE INTERNAL "The BLAS/LAPACK libraries that will be linked against by the Simbody libraries.") message(CHECK_START "Trying to compile with requested BLAS/LAPACK libraries") else() # Determine which math libraries to use for this platform. # Intel MKL: mkl_intel_c_dll;mkl_sequential_dll;mkl_core_dll set(BUILD_USING_OTHER_LAPACK "" CACHE STRING "If you have your own Lapack and Blas, put libraries here, separated by semicolons (full paths or paths that are on the (DY)LD_LIBRARY_PATH (UNIX) or PATH (Windows)). See LAPACK_BEING_USED to see what's actually being used.") if(WIN32 AND NOT WINDOWS_USE_EXTERNAL_LIBS) set(LAPACK_PLATFORM_DEFAULT lapack;blas) else() find_package(BLAS) # defines IMPORTED target BLAS::BLAS find_package(LAPACK) # defines IMPORTED target LAPACK::LAPACK if(BLAS_FOUND AND LAPACK_FOUND) set(LAPACK_PLATFORM_DEFAULT BLAS::BLAS LAPACK::LAPACK) else() message(WARNING "Could not find blas/lapack") endif() endif() set(LAPACK_BEING_USED ${LAPACK_PLATFORM_DEFAULT} CACHE INTERNAL "The BLAS/LAPACK libraries that will be linked against by the Simbody libraries.") message(CHECK_START "Trying to compile with system BLAS/LAPACK libraries") endif() # Try to link against the requested BLAS/LAPACK libraries set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE) file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/lapack_test.c "\ #include \"SimTKlapack.h\" int main () { int n = 2; int stride = 1; float x[] = {1.0, 1.0}; float y[] = {2.0, 3.0}; float d = sdot_(&n, x, &stride, y, &stride); return !(d == 5.0); // return zero if sdot_ worked } ") try_compile(OTHER_LAPACK_FUNCTIONAL ${CMAKE_CURRENT_BINARY_DIR} SOURCES ${CMAKE_CURRENT_BINARY_DIR}/lapack_test.c CMAKE_FLAGS -DINCLUDE_DIRECTORIES=${CMAKE_CURRENT_SOURCE_DIR}/SimTKcommon/include OUTPUT_VARIABLE BLAS_TRYCOMPILE_LOG LINK_LIBRARIES ${LAPACK_BEING_USED}) if(OTHER_LAPACK_FUNCTIONAL) message(CHECK_PASS "success.") message(STATUS "Using BLAS/LAPACK libraries ${LAPACK_BEING_USED}") else() message(CHECK_FAIL "failed.") message(AUTHOR_WARNING ${BLAS_TRYCOMPILE_LOG}) message(FATAL_ERROR "Failed to compile using the BLAS/LAPACK libraries ${LAPACK_BEING_USED}. If BUILD_USING_OTHER_LAPACK was given; check that it was set correctly.") endif() if(UNIX) if(NOT APPLE) set(REALTIME_LIB rt) # We do not use pthreads directly anymore, but on Linux, C++11 threads # are implemented with pthreads, and we must link to it. set(PTHREAD_LIB pthread) endif() set(MATH_LIBRARY m) set(DL_LIBRARY dl) endif() set(MATH_LIBS_TO_USE ${LAPACK_BEING_USED} ${PTHREAD_LIB} ${REALTIME_LIB} ${DL_LIBRARY} ${MATH_LIBRARY}) set(MATH_LIBS_TO_USE_VN ${MATH_LIBS_TO_USE}) add_subdirectory( SimTKcommon ) add_subdirectory( SimTKmath ) add_subdirectory( Simbody ) export(EXPORT SimbodyTargets FILE "${CMAKE_CURRENT_BINARY_DIR}/SimbodyTargets.cmake" ) if( BUILD_EXAMPLES ) add_subdirectory( examples ) endif() if( INSTALL_DOCS ) file(GLOB TOPLEVEL_DOCS doc/*.pdf doc/*.md) install(FILES LICENSE.txt README.md CHANGELOG.md CONTRIBUTING.md ${TOPLEVEL_DOCS} DESTINATION ${CMAKE_INSTALL_DOCDIR}) endif() # Add uninstall target configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake" IMMEDIATE @ONLY) add_custom_target(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake") # Make the cmake config files set(PKG_NAME ${PROJECT_NAME}) set(PKG_LIBRARIES SimTKsimbody SimTKmath SimTKcommon) if(WIN32) set(SIMBODY_CMAKE_DIR cmake) elseif(UNIX) set(SIMBODY_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/simbody/) endif() # Configure SimbodyConfig.cmake in a way that allows the installation to be # relocatable. include(CMakePackageConfigHelpers) configure_package_config_file( ${CMAKE_SOURCE_DIR}/cmake/SimbodyConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/cmake/SimbodyConfigForInstall.cmake INSTALL_DESTINATION "${SIMBODY_CMAKE_DIR}" PATH_VARS # Variables to edit in the SimbodyConfig.cmake.in. CMAKE_INSTALL_PREFIX SIMBODY_INCLUDE_INSTALL_DIR CMAKE_INSTALL_LIBDIR CMAKE_INSTALL_BINDIR SIMBODY_VISUALIZER_INSTALL_DIR SIMBODY_INSTALL_DOXYGENDIR ) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cmake/SimbodyConfigForInstall.cmake DESTINATION ${SIMBODY_CMAKE_DIR} RENAME SimbodyConfig.cmake) # Create a file that allows clients to Simbody to ensure they have the version # of Simbody they want. include(CMakePackageConfigHelpers) write_basic_package_version_file( ${CMAKE_CURRENT_BINARY_DIR}/cmake/SimbodyConfigVersion.cmake VERSION "${SIMBODY_VERSION}" COMPATIBILITY SameMajorVersion) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cmake/SimbodyConfigVersion.cmake DESTINATION ${SIMBODY_CMAKE_DIR}) install(EXPORT SimbodyTargets DESTINATION "${SIMBODY_CMAKE_DIR}") #optionally: COMPONENT dev # Install a sample CMakeLists.txt that uses SimbodyConfig.cmake. install(FILES ${CMAKE_SOURCE_DIR}/cmake/SampleCMakeLists.txt DESTINATION ${SIMBODY_CMAKE_DIR}) # Make the pkgconfig file: select the proper flags depending on the platform if(WIN32) set(PKGCONFIG_PLATFORM_LIBS "-lliblapack -llibblas") elseif(APPLE) set(PKGCONFIG_PLATFORM_LIBS "-llapack -lblas -ldl") else() set(PKGCONFIG_PLATFORM_LIBS "-llapack -lblas -lpthread -lrt -ldl -lm") endif() configure_file(${CMAKE_SOURCE_DIR}/cmake/pkgconfig/simbody.pc.in ${CMAKE_CURRENT_BINARY_DIR}/cmake/pkgconfig/simbody.pc @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cmake/pkgconfig/simbody.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig/)