From c94601cb28d602420153007b1068c9986db996b2 Mon Sep 17 00:00:00 2001 From: carmichaelong Date: Mon, 25 Apr 2022 23:02:39 -0700 Subject: [PATCH 1/5] update dependencies: add superbuild for mac+arm64. add mechanism to use pre-installed ipopt --- dependencies/CMakeLists.txt | 152 ++++++++++++++++++++++++++---------- dependencies/ipopt.patch | 10 +++ 2 files changed, 122 insertions(+), 40 deletions(-) create mode 100644 dependencies/ipopt.patch diff --git a/dependencies/CMakeLists.txt b/dependencies/CMakeLists.txt index c765cf9a25..f332f334aa 100644 --- a/dependencies/CMakeLists.txt +++ b/dependencies/CMakeLists.txt @@ -210,26 +210,33 @@ option(OPENSIM_WITH_TROPTER if(OPENSIM_WITH_TROPTER OR OPENSIM_WITH_CASADI) -AddDependency(NAME eigen - DEFAULT ON - URL https://gitlab.com/libeigen/eigen/-/archive/3.3.7/eigen-3.3.7.zip) - -mark_as_advanced(SUPERBUILD_eigen) - -AddDependency(NAME colpack - DEFAULT ON - GIT_URL https://github.com/opensim-org/colpack.git - GIT_TAG 72f691e91d59e8eb2123f258e67a4ddc72d105ee - CMAKE_ARGS -DCMAKE_DEBUG_POSTFIX:STRING=_d - -DENABLE_EXAMPLES:BOOL=OFF - -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON) - -mark_as_advanced(SUPERBUILD_colpack) + AddDependency(NAME eigen + DEFAULT ON + URL https://gitlab.com/libeigen/eigen/-/archive/3.3.7/eigen-3.3.7.zip) + + mark_as_advanced(SUPERBUILD_eigen) + + AddDependency(NAME colpack + DEFAULT ON + GIT_URL https://github.com/opensim-org/colpack.git + GIT_TAG 72f691e91d59e8eb2123f258e67a4ddc72d105ee + CMAKE_ARGS -DCMAKE_DEBUG_POSTFIX:STRING=_d + -DENABLE_EXAMPLES:BOOL=OFF + -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON) + + mark_as_advanced(SUPERBUILD_colpack) + + CMAKE_DEPENDENT_OPTION(SUPERBUILD_adolc "Automatically download, configure, build and install adolc" ON + "OPENSIM_WITH_TROPTER" OFF) + CMAKE_DEPENDENT_OPTION(SUPERBUILD_ipopt "Automatically download, configure, build and install ipopt" ON + "OPENSIM_WITH_TROPTER OR OPENSIM_WITH_CASADI" OFF) + CMAKE_DEPENDENT_OPTION(USE_IPOPT_INSTALL "Use an ipopt install folder instead of using the superbuild option." OFF + "OPENSIM_WITH_TROPTER OR OPENSIM_WITH_CASADI" OFF) + set(IPOPT_INSTALL_DIR "" CACHE STRING "Path to the ipopt install folder when USE_IPOPT_INSTALL is ON") +endif() -CMAKE_DEPENDENT_OPTION(SUPERBUILD_adolc "Automatically download, configure, build and install adolc" ON - "OPENSIM_WITH_TROPTER" OFF) -CMAKE_DEPENDENT_OPTION(SUPERBUILD_ipopt "Automatically download, configure, build and install ipopt" ON - "OPENSIM_WITH_TROPTER OR OPENSIM_WITH_CASADI" OFF) +if (SUPERBUILD_ipopt AND USE_IPOPT_INSTALL) + message(FATAL_ERROR "SUPERBUILD_ipopt and USE_IPOPT_INSTALL cannot both be ON") endif() if (OPENSIM_WITH_CASADI) @@ -319,34 +326,99 @@ else() --with-colpack=${CMAKE_INSTALL_PREFIX}/colpack --with-boost=no BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} ${BUILD_FLAGS} - INSTALL_COMMAND ${CMAKE_MAKE_PROGRAM} install) + INSTALL_COMMAND ${CMAKE_MAKE_PROGRAM} install + ) endif() if(SUPERBUILD_ipopt) - # TODO --enable-debug if building in Debug. - # TODO must have gfortran for MUMPS (brew install gcc). - # TODO CMake documentation says "Whether the current working directory - # is preserved between commands is not defined. Behavior of shell - # operators like && is not defined." - # Patch the scripts that download Metis and MUMPS to use our - # Sourceforge mirror. The original links are not reliable. - ExternalProject_Add(ipopt - URL https://www.coin-or.org/download/source/Ipopt/Ipopt-3.12.8.zip - INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/ipopt" - PATCH_COMMAND cd /ThirdParty/Metis && patch < ${CMAKE_SOURCE_DIR}/get.Metis.patch - COMMAND cd /ThirdParty/Metis && ./get.Metis - COMMAND cd /ThirdParty/Mumps && patch < ${CMAKE_SOURCE_DIR}/get.Mumps.patch - COMMAND cd /ThirdParty/Mumps && ./get.Mumps - # GCC 10 generates a warning when compling MUMPS that we must suppress using - # -fallow-argument-mismatch. - # Suppress warnings treated as errors in Clang/LLVM with -Wno-error=implicit-function-declaration - CONFIGURE_COMMAND /configure --prefix= ADD_FFLAGS=-fallow-argument-mismatch ADD_CFLAGS=-Wno-error=implicit-function-declaration - BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} ${BUILD_FLAGS} - INSTALL_COMMAND ${CMAKE_MAKE_PROGRAM} install) + + # Check for arm64 architecture + execute_process( + COMMAND uname -m + OUTPUT_VARIABLE MACHINE_ARCH + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + # For ARM-based Macs, use different version of METIS and MUMPS than + # those automatically pulled from IPOPT's ThirdParty submodules. + if(APPLE AND MACHINE_ARCH STREQUAL "arm64") + + # Homebrew dir is /opt/homebrew for arm64 (/usr/local for x86_64). + # Use METIS from Homebrew, which is currently 5.1.0 (IPOPT 3.12.8 + # automatically pulls 4.10.0, which had some segfault issues) + set(HOMEBREW_DIR "/opt/homebrew") + set(METIS_INSTALL_DIR "${HOMEBREW_DIR}/opt/metis") + + # For MUMPS, use a tag from stable/2.1 branch instead of what + # IPOPT 3.12.8 automatically pulls (stable/1.6). Both branches + # use MUMPS 4.10.0. This avoid some linker issues with Homebrew METIS. + set(MUMPS_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/mumps") + ExternalProject_Add(mumps + GIT_REPOSITORY https://github.com/coin-or-tools/ThirdParty-Mumps.git + GIT_TAG f4ad789112161f73b2a3daf1c586f7de85cd7043 #from stable/2.1 branch + INSTALL_DIR ${MUMPS_INSTALL_DIR} + PATCH_COMMAND cd && ./get.Mumps + CONFIGURE_COMMAND /configure --prefix= ADD_FFLAGS=-fallow-argument-mismatch ADD_CFLAGS=-Wno-error=implicit-function-declaration + --with-metis-cflags=-I${METIS_INSTALL_DIR}/include + "--with-metis-lflags=-L${METIS_INSTALL_DIR}/lib -lmetis" + BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} ${BUILD_FLAGS} + INSTALL_COMMAND ${CMAKE_MAKE_PROGRAM} install + ) + + # Can still use IPOPT 3.12.8, with a small patch. + set(IPOPT_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/ipopt") + ExternalProject_Add(ipopt + DEPENDS mumps + URL https://www.coin-or.org/download/source/Ipopt/Ipopt-3.12.8.zip + INSTALL_DIR ${IPOPT_INSTALL_DIR} + # For Ipopt 3.12, patch a file so that it can find the proper MUMPS flags/variables. + PATCH_COMMAND cd && patch -p0 < ${CMAKE_SOURCE_DIR}/ipopt.patch + CONFIGURE_COMMAND /configure --prefix= + --with-mumps-incdir=${MUMPS_INSTALL_DIR}/include/coin-or/mumps + "--with-mumps-lib=-L${MUMPS_INSTALL_DIR}/lib -lcoinmumps" + BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} ${BUILD_FLAGS} + INSTALL_COMMAND ${CMAKE_MAKE_PROGRAM} install + ) + + else() + # TODO --enable-debug if building in Debug. + # TODO must have gfortran for MUMPS (brew install gcc). + # TODO CMake documentation says "Whether the current working directory + # is preserved between commands is not defined. Behavior of shell + # operators like && is not defined." + # Patch the scripts that download Metis and MUMPS to use our + # Sourceforge mirror. The original links are not reliable. + ExternalProject_Add(ipopt + URL https://www.coin-or.org/download/source/Ipopt/Ipopt-3.12.8.zip + INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/ipopt" + PATCH_COMMAND cd /ThirdParty/Metis && patch < ${CMAKE_SOURCE_DIR}/get.Metis.patch + COMMAND cd /ThirdParty/Metis && ./get.Metis + COMMAND cd /ThirdParty/Mumps && patch < ${CMAKE_SOURCE_DIR}/get.Mumps.patch + COMMAND cd /ThirdParty/Mumps && ./get.Mumps + # GCC 10 generates a warning when compling MUMPS that we must suppress using + # -fallow-argument-mismatch. + # Suppress warnings treated as errors in Clang/LLVM with -Wno-error=implicit-function-declaration + CONFIGURE_COMMAND /configure --prefix= ADD_FFLAGS=-fallow-argument-mismatch ADD_CFLAGS=-Wno-error=implicit-function-declaration + BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} ${BUILD_FLAGS} + INSTALL_COMMAND ${CMAKE_MAKE_PROGRAM} install) + endif() endif() endif() +# Use a pre-built IPOPT installation folder instead of using the superbuild. +if (USE_IPOPT_INSTALL) + set(IPOPT_INSTALL_CMD "${CMAKE_COMMAND}" -E copy_directory + "${IPOPT_INSTALL_DIR}" + "${CMAKE_INSTALL_PREFIX}/ipopt") + ExternalProject_Add(ipopt + DOWNLOAD_COMMAND "" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND ${IPOPT_INSTALL_CMD} + ) +endif() + if(SUPERBUILD_casadi) AddDependency(NAME casadi DEFAULT ON diff --git a/dependencies/ipopt.patch b/dependencies/ipopt.patch new file mode 100644 index 0000000000..d2ad8badf9 --- /dev/null +++ b/dependencies/ipopt.patch @@ -0,0 +1,10 @@ +--- Ipopt/src/Algorithm/LinearSolvers/IpMumpsSolverInterface.cpp 2022-04-13 11:59:52.000000000 -0700 ++++ Ipopt/src/Algorithm/LinearSolvers/IpMumpsSolverInterface.cpp 2022-04-13 11:59:37.000000000 -0700 +@@ -16,6 +16,7 @@ + // The first header to include is the one for MPI. + // In newer ThirdParty/Mumps, mpi.h is renamed to mumps_mpi.h. + // We get informed about this by having COIN_USE_MUMPS_MPI_H defined. ++#include "mumps_compat.h" + #ifdef COIN_USE_MUMPS_MPI_H + #include "mumps_mpi.h" + #else From cf78acdf27a17660756ce27dec2609e366ccfefe Mon Sep 17 00:00:00 2001 From: carmichaelong Date: Fri, 13 May 2022 15:02:20 -0700 Subject: [PATCH 2/5] mark USE_IPOPT_INSTALL and IPOPT_INSTALL_DIR as advanced --- dependencies/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dependencies/CMakeLists.txt b/dependencies/CMakeLists.txt index f332f334aa..1dcec6ce2f 100644 --- a/dependencies/CMakeLists.txt +++ b/dependencies/CMakeLists.txt @@ -233,6 +233,9 @@ if(OPENSIM_WITH_TROPTER OR OPENSIM_WITH_CASADI) CMAKE_DEPENDENT_OPTION(USE_IPOPT_INSTALL "Use an ipopt install folder instead of using the superbuild option." OFF "OPENSIM_WITH_TROPTER OR OPENSIM_WITH_CASADI" OFF) set(IPOPT_INSTALL_DIR "" CACHE STRING "Path to the ipopt install folder when USE_IPOPT_INSTALL is ON") + + mark_as_advanced(USE_IPOPT_INSTALL) + mark_as_advanced(IPOPT_INSTALL_DIR) endif() if (SUPERBUILD_ipopt AND USE_IPOPT_INSTALL) From d68607a6403b66583c1f15f3679e5f207b8c52dd Mon Sep 17 00:00:00 2001 From: carmichaelong Date: Fri, 1 Jul 2022 11:30:08 -0700 Subject: [PATCH 3/5] explicitly avoid using asl or hsl libraries. don't copy mumps and metis libraries for apple during install --- Vendors/tropter/cmake/CMakeLists.txt | 12 ++++++------ dependencies/CMakeLists.txt | 10 ++++++---- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Vendors/tropter/cmake/CMakeLists.txt b/Vendors/tropter/cmake/CMakeLists.txt index be14adef42..ade850c6d8 100644 --- a/Vendors/tropter/cmake/CMakeLists.txt +++ b/Vendors/tropter/cmake/CMakeLists.txt @@ -13,12 +13,12 @@ if(TROPTER_COPY_DEPENDENCIES AND APPLE) ${IPOPT_LIBDIR}/libipopt.1.10.8.dylib ${IPOPT_LIBDIR}/libipopt.1.dylib ${IPOPT_LIBDIR}/libipopt.dylib - ${IPOPT_LIBDIR}/libcoinmumps.1.6.0.dylib - ${IPOPT_LIBDIR}/libcoinmumps.1.dylib - ${IPOPT_LIBDIR}/libcoinmumps.dylib - ${IPOPT_LIBDIR}/libcoinmetis.1.3.5.dylib - ${IPOPT_LIBDIR}/libcoinmetis.1.dylib - ${IPOPT_LIBDIR}/libcoinmetis.dylib + #${IPOPT_LIBDIR}/libcoinmumps.1.6.0.dylib + #${IPOPT_LIBDIR}/libcoinmumps.1.dylib + #${IPOPT_LIBDIR}/libcoinmumps.dylib + #${IPOPT_LIBDIR}/libcoinmetis.1.3.5.dylib + #${IPOPT_LIBDIR}/libcoinmetis.1.dylib + #${IPOPT_LIBDIR}/libcoinmetis.dylib ${gfortran} ${quadmath} diff --git a/dependencies/CMakeLists.txt b/dependencies/CMakeLists.txt index 1dcec6ce2f..94f451d706 100644 --- a/dependencies/CMakeLists.txt +++ b/dependencies/CMakeLists.txt @@ -362,8 +362,8 @@ else() INSTALL_DIR ${MUMPS_INSTALL_DIR} PATCH_COMMAND cd && ./get.Mumps CONFIGURE_COMMAND /configure --prefix= ADD_FFLAGS=-fallow-argument-mismatch ADD_CFLAGS=-Wno-error=implicit-function-declaration - --with-metis-cflags=-I${METIS_INSTALL_DIR}/include - "--with-metis-lflags=-L${METIS_INSTALL_DIR}/lib -lmetis" + --with-metis-cflags=-I${METIS_INSTALL_DIR}/include + "--with-metis-lflags=-L${METIS_INSTALL_DIR}/lib -lmetis" BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} ${BUILD_FLAGS} INSTALL_COMMAND ${CMAKE_MAKE_PROGRAM} install ) @@ -377,8 +377,10 @@ else() # For Ipopt 3.12, patch a file so that it can find the proper MUMPS flags/variables. PATCH_COMMAND cd && patch -p0 < ${CMAKE_SOURCE_DIR}/ipopt.patch CONFIGURE_COMMAND /configure --prefix= - --with-mumps-incdir=${MUMPS_INSTALL_DIR}/include/coin-or/mumps - "--with-mumps-lib=-L${MUMPS_INSTALL_DIR}/lib -lcoinmumps" + --with-mumps-incdir=${MUMPS_INSTALL_DIR}/include/coin-or/mumps + "--with-mumps-lib=-L${MUMPS_INSTALL_DIR}/lib -lcoinmumps" + --without-hsl --without-hsl-lib --without-hsl-incdir + --without-asl --without-asl-lib --without-asl-incdir BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} ${BUILD_FLAGS} INSTALL_COMMAND ${CMAKE_MAKE_PROGRAM} install ) From 4db0ec110b41fe5bac2cad474dc2b0576ebbe9ae Mon Sep 17 00:00:00 2001 From: carmichaelong Date: Fri, 1 Jul 2022 16:31:55 -0700 Subject: [PATCH 4/5] include a different set of install files for arm based macs --- Vendors/tropter/cmake/CMakeLists.txt | 66 +++++++++++++++++++--------- 1 file changed, 46 insertions(+), 20 deletions(-) diff --git a/Vendors/tropter/cmake/CMakeLists.txt b/Vendors/tropter/cmake/CMakeLists.txt index ade850c6d8..0ca8d3c5ec 100644 --- a/Vendors/tropter/cmake/CMakeLists.txt +++ b/Vendors/tropter/cmake/CMakeLists.txt @@ -5,26 +5,52 @@ if(TROPTER_COPY_DEPENDENCIES AND APPLE) file(GLOB gfortran "${gcc_libdir}/libgfortran*.dylib") file(GLOB quadmath "${gcc_libdir}/libquadmath*.dylib") - install(FILES - ${ADOLC_DIR}/lib64/libadolc.2.dylib - ${ADOLC_DIR}/lib64/libadolc.dylib - # /usr/local/opt/boost/lib/libboost_system.dylib - ${ColPack_ROOT_DIR}/lib/libColPack.0.dylib - ${IPOPT_LIBDIR}/libipopt.1.10.8.dylib - ${IPOPT_LIBDIR}/libipopt.1.dylib - ${IPOPT_LIBDIR}/libipopt.dylib - #${IPOPT_LIBDIR}/libcoinmumps.1.6.0.dylib - #${IPOPT_LIBDIR}/libcoinmumps.1.dylib - #${IPOPT_LIBDIR}/libcoinmumps.dylib - #${IPOPT_LIBDIR}/libcoinmetis.1.3.5.dylib - #${IPOPT_LIBDIR}/libcoinmetis.1.dylib - #${IPOPT_LIBDIR}/libcoinmetis.dylib - - ${gfortran} - ${quadmath} - ${gcc_libdir}/libgcc_s.1.dylib - - DESTINATION ${CMAKE_INSTALL_LIBDIR}) + # Check for arm64 architecture + execute_process( + COMMAND uname -m + OUTPUT_VARIABLE MACHINE_ARCH + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + # For ARM-based Macs, install a different set of libraries (without mumps + # and metis) because of the different way dependencies are built. + if(MACHINE_ARCH STREQUAL "arm64") + install(FILES + ${ADOLC_DIR}/lib64/libadolc.2.dylib + ${ADOLC_DIR}/lib64/libadolc.dylib + ${ColPack_ROOT_DIR}/lib/libColPack.0.dylib + ${IPOPT_LIBDIR}/libipopt.1.10.8.dylib + ${IPOPT_LIBDIR}/libipopt.1.dylib + ${IPOPT_LIBDIR}/libipopt.dylib + + ${gfortran} + ${quadmath} + ${gcc_libdir}/libgcc_s.1.dylib + + DESTINATION ${CMAKE_INSTALL_LIBDIR}) + + # For x64 Macs, make sure to also include mumps and metis libraries. + else() + install(FILES + ${ADOLC_DIR}/lib64/libadolc.2.dylib + ${ADOLC_DIR}/lib64/libadolc.dylib + # /usr/local/opt/boost/lib/libboost_system.dylib + ${ColPack_ROOT_DIR}/lib/libColPack.0.dylib + ${IPOPT_LIBDIR}/libipopt.1.10.8.dylib + ${IPOPT_LIBDIR}/libipopt.1.dylib + ${IPOPT_LIBDIR}/libipopt.dylib + ${IPOPT_LIBDIR}/libcoinmumps.1.6.0.dylib + ${IPOPT_LIBDIR}/libcoinmumps.1.dylib + ${IPOPT_LIBDIR}/libcoinmumps.dylib + ${IPOPT_LIBDIR}/libcoinmetis.1.3.5.dylib + ${IPOPT_LIBDIR}/libcoinmetis.1.dylib + ${IPOPT_LIBDIR}/libcoinmetis.dylib + + ${gfortran} + ${quadmath} + ${gcc_libdir}/libgcc_s.1.dylib + + DESTINATION ${CMAKE_INSTALL_LIBDIR}) # This command must be invoked from the cmake subdirectory so that the # editing of libtropter's link libraries is done after libtropter.dylib From 806102b893bd8919683315a912b656debb1a5b6e Mon Sep 17 00:00:00 2001 From: carmichaelong Date: Sat, 2 Jul 2022 00:03:30 -0700 Subject: [PATCH 5/5] missing endif() --- Vendors/tropter/cmake/CMakeLists.txt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Vendors/tropter/cmake/CMakeLists.txt b/Vendors/tropter/cmake/CMakeLists.txt index 0ca8d3c5ec..264c78b1a4 100644 --- a/Vendors/tropter/cmake/CMakeLists.txt +++ b/Vendors/tropter/cmake/CMakeLists.txt @@ -6,11 +6,11 @@ if(TROPTER_COPY_DEPENDENCIES AND APPLE) file(GLOB quadmath "${gcc_libdir}/libquadmath*.dylib") # Check for arm64 architecture - execute_process( - COMMAND uname -m - OUTPUT_VARIABLE MACHINE_ARCH - OUTPUT_STRIP_TRAILING_WHITESPACE - ) + execute_process( + COMMAND uname -m + OUTPUT_VARIABLE MACHINE_ARCH + OUTPUT_STRIP_TRAILING_WHITESPACE + ) # For ARM-based Macs, install a different set of libraries (without mumps # and metis) because of the different way dependencies are built. @@ -51,6 +51,7 @@ if(TROPTER_COPY_DEPENDENCIES AND APPLE) ${gcc_libdir}/libgcc_s.1.dylib DESTINATION ${CMAKE_INSTALL_LIBDIR}) + endif() # This command must be invoked from the cmake subdirectory so that the # editing of libtropter's link libraries is done after libtropter.dylib