From 4f4b988a8d4ae54717bc4868ccd5713ef8ebf61b Mon Sep 17 00:00:00 2001 From: Michel Schmid Date: Tue, 13 Feb 2024 18:08:20 +0100 Subject: [PATCH 1/9] build protobuf as ExternalProject if version is too new Since at least Protobuf 3.21 the version is incompatible causing various include and linker errors. Maybe the incompatibility was introduced before that, but I don't know. If that is the case the version number can just be set lower than that in the future. The approach is pretty much just copied from ER-Forces framework (https://github.com/robotics-erlangen/framework) and adapted to fit the structure of this repository. --- CMakeLists.txt | 22 ++++++- clients/qt/CMakeLists.txt | 25 +++++++- cmake/modules/BuildProtobuf.cmake | 79 +++++++++++++++++++++++++ cmake/modules/EnvHelper.cmake | 31 ++++++++++ cmake/modules/FindOrBuildProtobuf.cmake | 11 ++++ 5 files changed, 162 insertions(+), 6 deletions(-) create mode 100644 cmake/modules/BuildProtobuf.cmake create mode 100644 cmake/modules/EnvHelper.cmake create mode 100644 cmake/modules/FindOrBuildProtobuf.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 833c5cce..3c3f014d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,17 @@ include(${PROJECT_SOURCE_DIR}/cmake/Utils.cmake) standard_config() standard_paths(${PROJECT_SOURCE_DIR} bin lib) +# policy regarding how to handle generated stuff, OLD behavior would ignore generated files +# (which includes the generated protobuf cpp files) +if (POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + +# policy regarding when to rebuild stuff when external projects downloaded with URL changes +if (POLICY CMP0135) + cmake_policy(SET CMP0135 NEW) +endif() + set(app ${CMAKE_PROJECT_NAME}) # create the target before the sources list is known so that we can call # add_dependencies( external_proj) @@ -106,9 +117,14 @@ target_include_directories(${app} PRIVATE ${VARTYPES_INCLUDE_DIRS}) list(APPEND libs ${VARTYPES_LIBRARIES}) # Protobuf -find_package(Protobuf REQUIRED) -include_directories(${PROTOBUF_INCLUDE_DIRS}) -list(APPEND libs ${PROTOBUF_LIBRARIES}) +include(FindOrBuildProtobuf) + +if(TARGET protobuf_external) + add_dependencies(${app} protobuf_external) +endif() + +include_directories(${Protobuf_INCLUDE_DIRS}) +list(APPEND libs ${Protobuf_LIBRARIES}) set (Protobuf_IMPORT_DIRS ${Protobuf_INCLUDE_DIR}) protobuf_generate_cpp(PROTO_CPP PROTO_H diff --git a/clients/qt/CMakeLists.txt b/clients/qt/CMakeLists.txt index 5ea9473f..a543a721 100644 --- a/clients/qt/CMakeLists.txt +++ b/clients/qt/CMakeLists.txt @@ -4,15 +4,30 @@ set(CMAKE_AUTOMOC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) +# policy regarding how to handle generated stuff, OLD behavior would ignore generated files +# (which includes the generated protobuf cpp files) +if (POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + +# policy regarding when to rebuild stuff when external projects downloaded with URL changes +if (POLICY CMP0135) + cmake_policy(SET CMP0135 NEW) +endif() + set(libs) find_package(Qt5 COMPONENTS Core Widgets Network REQUIRED) list(APPEND libs Qt5::Core Qt5::Widgets Qt5::Network) +# if find_package was already executed and we already included BuildProtobuf find_package fails, +# so we only want to do execute find_package if protobuf was not found yet +if(NOT Protobuf_FOUND) + include(FindOrBuildProtobuf) +endif() -find_package(Protobuf REQUIRED) -include_directories(${PROTOBUF_INCLUDE_DIRS}) -list(APPEND libs ${PROTOBUF_LIBRARIES}) +include_directories(${Protobuf_INCLUDE_DIRS}) +list(APPEND libs ${Protobuf_LIBRARIES}) protobuf_generate_cpp(PROTO_CPP PROTO_H ../../src/proto/grSim_Replacement.proto @@ -30,5 +45,9 @@ add_executable(${app} MACOSX_BUNDLE mainwindow.h ) +if(TARGET protobuf_external) + add_dependencies(${app} protobuf_external) +endif() + target_link_libraries(${app} ${libs}) diff --git a/cmake/modules/BuildProtobuf.cmake b/cmake/modules/BuildProtobuf.cmake new file mode 100644 index 00000000..bced9ecc --- /dev/null +++ b/cmake/modules/BuildProtobuf.cmake @@ -0,0 +1,79 @@ +# *************************************************************************** +# * Copyright 2017 Michael Eischer * +# * Robotics Erlangen e.V. * +# * http://www.robotics-erlangen.de/ * +# * info@robotics-erlangen.de * +# * * +# * This program is free software: you can redistribute it and/or modify * +# * it under the terms of the GNU General Public License as published by * +# * the Free Software Foundation, either version 3 of the License, or * +# * any later version. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU General Public License for more details. * +# * * +# * You should have received a copy of the GNU General Public License * +# * along with this program. If not, see . * +# *************************************************************************** + +include(ExternalProject) +set(PROTOBUF_INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/protobuf_install") + +set(PROTOBUF_CMAKE_ARGS ) + +ExternalProject_Add(protobuf_external + # URL is the same as in the ER-Force framework, + # because ER-Force needs it and has an incentive to keep the link stable + URL http://www.robotics-erlangen.de/downloads/libraries/protobuf-cpp-3.6.1.tar.gz + URL_HASH SHA256=b3732e471a9bb7950f090fd0457ebd2536a9ba0891b7f3785919c654fe2a2529 + SOURCE_SUBDIR cmake + INSTALL_DIR "${PROTOBUF_INSTALL_DIR}" + CMAKE_ARGS + -DCMAKE_INSTALL_PREFIX:PATH= + -DCMAKE_TOOLCHAIN_FILE:PATH=${CMAKE_TOOLCHAIN_FILE} + -DCMAKE_C_COMPILER:PATH=${CMAKE_C_COMPILER} + -DCMAKE_CXX_COMPILER:PATH=${CMAKE_CXX_COMPILER} + -DCMAKE_MAKE_PROGRAM:PATH=${CMAKE_MAKE_PROGRAM} + # the tests fail to build :-( + -Dprotobuf_BUILD_TESTS:BOOL=OFF + STEP_TARGETS install +) + +ExternalProject_Add_Step(protobuf_external out + DEPENDEES install + BYPRODUCTS + "/${PROTOBUF_SUBPATH}" + "/${PROTOC_SUBPATH}" +) + +set(PROTOBUF_SUBPATH "${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}protobuf${CMAKE_STATIC_LIBRARY_SUFFIX}") +set(LIBPROTOC_SUBPATH "${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}protoc${CMAKE_STATIC_LIBRARY_SUFFIX}") +set(PROTOC_SUBPATH "bin/protoc${CMAKE_EXECUTABLE_SUFFIX}") + +ExternalProject_Get_Property(protobuf_external install_dir) +set_target_properties(protobuf_external PROPERTIES EXCLUDE_FROM_ALL true) + +# override all necessary variables originally set by find_package +# if FORCE is not set cmake does not allow us to override the variables, for some unknown reason +set(Protobuf_FOUND true CACHE BOOL "" FORCE) +set(Protobuf_VERSION "3.6.1" CACHE STRING "" FORCE) +set(Protobuf_INCLUDE_DIR "${install_dir}/include" CACHE PATH "" FORCE) +set(Protobuf_INCLUDE_DIRS "${Protobuf_INCLUDE_DIR}" CACHE PATH "" FORCE) +set(Protobuf_LIBRARY "${install_dir}/lib/${PROTOBUF_SUBPATH}" CACHE PATH "" FORCE) +set(Protobuf_LIBRARIES "${Protobuf_LIBRARY}" CACHE PATH "" FORCE) +set(Protobuf_LIBRARY_DEBUG "${install_dir}/lib/${PROTOBUF_SUBPATH}" CACHE PATH "" FORCE) +set(Protobuf_LIBRARY_RELEASE "${install_dir}/lib/${PROTOBUF_SUBPATH}" CACHE PATH "" FORCE) +set(Protobuf_LITE_LIBRARY_DEBUG "${install_dir}/lib/${PROTOBUF_SUBPATH}" CACHE PATH "" FORCE) +set(Protobuf_LITE_LIBRARY_RELEASE "${install_dir}/lib/${PROTOBUF_SUBPATH}" CACHE PATH "" FORCE) +set(Protobuf_PROTOC_EXECUTABLE "${install_dir}/${PROTOC_SUBPATH}" CACHE PATH "" FORCE) +set(Protobuf_PROTOC_LIBRARY_DEBUG "${install_dir}/lib/${LIBPROTOC_SUBPATH}" CACHE PATH "" FORCE) +set(Protobuf_PROTOC_LIBRARY_RELEASE "${install_dir}/lib/${LIBPROTOC_SUBPATH}" CACHE PATH "" FORCE) + +# override the protobuf::protoc path used by the protobuf_generate_cpp macro +set_target_properties(protobuf::protoc PROPERTIES + IMPORTED_LOCATION "${Protobuf_PROTOC_EXECUTABLE}" +) + +message(STATUS "Building protobuf ${Protobuf_VERSION}") diff --git a/cmake/modules/EnvHelper.cmake b/cmake/modules/EnvHelper.cmake new file mode 100644 index 00000000..f5339c5f --- /dev/null +++ b/cmake/modules/EnvHelper.cmake @@ -0,0 +1,31 @@ +# *************************************************************************** +# * Copyright 2017 Michael Eischer * +# * Robotics Erlangen e.V. * +# * http://www.robotics-erlangen.de/ * +# * info@robotics-erlangen.de * +# * * +# * This program is free software: you can redistribute it and/or modify * +# * it under the terms of the GNU General Public License as published by * +# * the Free Software Foundation, either version 3 of the License, or * +# * any later version. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU General Public License for more details. * +# * * +# * You should have received a copy of the GNU General Public License * +# * along with this program. If not, see . * +# *************************************************************************** + +macro(sanitize_env) + # remove "." from path to avoid searching the build_dir/bin folder + set(ORIG_PATH $ENV{PATH}) + set(MOD_PATH $ENV{PATH}) + list(REMOVE_ITEM MOD_PATH .) + set(ENV{PATH} ${MOD_PATH}) +endmacro() + +macro(restore_env) + set(ENV{PATH} ${ORIG_PATH}) +endmacro() diff --git a/cmake/modules/FindOrBuildProtobuf.cmake b/cmake/modules/FindOrBuildProtobuf.cmake new file mode 100644 index 00000000..940a1454 --- /dev/null +++ b/cmake/modules/FindOrBuildProtobuf.cmake @@ -0,0 +1,11 @@ +# sanitize environment before find_package, because otherwise it also looks in the directory created for the ExternalProject +include(EnvHelper) +sanitize_env() +find_package(Protobuf REQUIRED) +restore_env() + +# protobuf versions >= 3.21 are incompatible with how the project is setup and cause weird errors +# so we build protobuf ourselves +if(Protobuf_VERSION VERSION_GREATER_EQUAL 3.21) + include(BuildProtobuf) +endif() From b3a762d040628bd1a6cb9aa3e04b7774e57fb855 Mon Sep 17 00:00:00 2001 From: Michel Schmid Date: Tue, 13 Feb 2024 18:20:26 +0100 Subject: [PATCH 2/9] add option to build ODE from source On some systems the packaged ODE (e.g. the Manjaro ode package at time of writing) causes grSim to crash almost instantly. This *may* be caused by the package having been built without double precision support, but I don't know what exactly breaks. Additionally add this as a hint to INSTALL.md. --- CMakeLists.txt | 29 ++++++++++++++++++++++++++++- INSTALL.md | 6 +++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c3f014d..22651a60 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,7 +80,34 @@ find_package(Qt5 COMPONENTS Core Widgets OpenGL Network REQUIRED) list(APPEND libs Qt5::Core Qt5::Widgets Qt5::OpenGL Qt5::Network) # ODE -if(WIN32) +if(BUILD_ODE) + # build ODE, because some versions of it cause grSim to segfault somewhere + # could be because in some packages the double precision is turned off + include(ExternalProject) + + set(ODE_INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/ode_install") + + ExternalProject_Add(ode_external + GIT_REPOSITORY https://bitbucket.org/odedevs/ode.git + GIT_TAG 0.16.4 + INSTALL_DIR "${ODE_INSTALL_DIR}" + CMAKE_ARGS + -DCMAKE_INSTALL_PREFIX:PATH= + -DCMAKE_TOOLCHAIN_FILE:PATH=${CMAKE_TOOLCHAIN_FILE} + -DCMAKE_C_COMPILER:PATH=${CMAKE_C_COMPILER} + -DCMAKE_CXX_COMPILER:PATH=${CMAKE_CXX_COMPILER} + -DCMAKE_MAKE_PROGRAM:PATH=${CMAKE_MAKE_PROGRAM} + # necessary, because it does not build the static libs if this is ON + -DBUILD_SHARED_LIBS=OFF + # if this is OFF grSim just dies instantly and INSTALL.md says it should be ON + -DODE_DOUBLE_PRECISION=ON + -DCMAKE_INSTALL_PREFIX= + ) + add_dependencies(${app} ode_external) + + set(ODE_LIBRARY "${ODE_INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}ode${CMAKE_STATIC_LIBRARY_SUFFIX}") + list(APPEND libs ${ODE_LIBRARY}) +elseif(WIN32) find_package(ODE CONFIG REQUIRED) list(APPEND libs ODE::ODE) else() diff --git a/INSTALL.md b/INSTALL.md index f814175a..e7ee47f5 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -159,7 +159,11 @@ $ sudo make install grSim will be — by default — installed on the `/usr/local` directory. -if you face any problem regarding of updating the grsim version, you can try removing the `grsim.xml`. +## Troubleshooting + +If you face any problem regarding of updating the grsim version, you can try removing the `grsim.xml`. +If grSim crashes almost instantly with some ODE error the issue might by your ODE version. +Try adding -DBUILD_ODE=TRUE to build ODE from source instead of using the system dependency. ## Notes on the performance From a815ec07203278d049555ad57a699aaf3bb907b9 Mon Sep 17 00:00:00 2001 From: Michel Schmid Date: Wed, 14 Feb 2024 01:18:40 +0100 Subject: [PATCH 3/9] add protobuf built from source as dependency to protobuf_generate_cpp --- cmake/modules/BuildProtobuf.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/modules/BuildProtobuf.cmake b/cmake/modules/BuildProtobuf.cmake index bced9ecc..247d85b8 100644 --- a/cmake/modules/BuildProtobuf.cmake +++ b/cmake/modules/BuildProtobuf.cmake @@ -70,6 +70,9 @@ set(Protobuf_LITE_LIBRARY_RELEASE "${install_dir}/lib/${PROTOBUF_SUBPATH}" CACHE set(Protobuf_PROTOC_EXECUTABLE "${install_dir}/${PROTOC_SUBPATH}" CACHE PATH "" FORCE) set(Protobuf_PROTOC_LIBRARY_DEBUG "${install_dir}/lib/${LIBPROTOC_SUBPATH}" CACHE PATH "" FORCE) set(Protobuf_PROTOC_LIBRARY_RELEASE "${install_dir}/lib/${LIBPROTOC_SUBPATH}" CACHE PATH "" FORCE) +# this is a dependency for the protobuf_generate_cpp custom command +# if this is not set the generate command sometimes get executed before protoc is compiled +set(protobuf_generate_DEPENDENCIES protobuf_external CACHE TARGET "" FORCE) # override the protobuf::protoc path used by the protobuf_generate_cpp macro set_target_properties(protobuf::protoc PROPERTIES From 91402e21087d38ea7b851f6f6be4c19dcdd4e94d Mon Sep 17 00:00:00 2001 From: Michel Schmid Date: Wed, 14 Feb 2024 04:05:23 +0100 Subject: [PATCH 4/9] add missing include directories from ode built from source --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 22651a60..f588673b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -107,6 +107,7 @@ if(BUILD_ODE) set(ODE_LIBRARY "${ODE_INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}ode${CMAKE_STATIC_LIBRARY_SUFFIX}") list(APPEND libs ${ODE_LIBRARY}) + target_include_directories(${app} PRIVATE "${ODE_INSTALL_DIR}/include") elseif(WIN32) find_package(ODE CONFIG REQUIRED) list(APPEND libs ODE::ODE) From 2f304e0f79de6f24242563419a213a7ceaa6d722 Mon Sep 17 00:00:00 2001 From: Michel Schmid Date: Wed, 14 Feb 2024 04:06:53 +0100 Subject: [PATCH 5/9] fix handling of situations where protobuf is not found at all to also build protobuf correctly --- cmake/modules/BuildProtobuf.cmake | 5 +++++ cmake/modules/FindOrBuildProtobuf.cmake | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/cmake/modules/BuildProtobuf.cmake b/cmake/modules/BuildProtobuf.cmake index 247d85b8..34ded05a 100644 --- a/cmake/modules/BuildProtobuf.cmake +++ b/cmake/modules/BuildProtobuf.cmake @@ -74,6 +74,11 @@ set(Protobuf_PROTOC_LIBRARY_RELEASE "${install_dir}/lib/${LIBPROTOC_SUBPATH}" CA # if this is not set the generate command sometimes get executed before protoc is compiled set(protobuf_generate_DEPENDENCIES protobuf_external CACHE TARGET "" FORCE) +# compatibility with cmake 3.10 +if(NOT TARGET protobuf::protoc) + # avoid error if target was already created for an older version + add_executable(protobuf::protoc IMPORTED) +endif() # override the protobuf::protoc path used by the protobuf_generate_cpp macro set_target_properties(protobuf::protoc PROPERTIES IMPORTED_LOCATION "${Protobuf_PROTOC_EXECUTABLE}" diff --git a/cmake/modules/FindOrBuildProtobuf.cmake b/cmake/modules/FindOrBuildProtobuf.cmake index 940a1454..4db92e07 100644 --- a/cmake/modules/FindOrBuildProtobuf.cmake +++ b/cmake/modules/FindOrBuildProtobuf.cmake @@ -1,11 +1,11 @@ # sanitize environment before find_package, because otherwise it also looks in the directory created for the ExternalProject include(EnvHelper) sanitize_env() -find_package(Protobuf REQUIRED) +find_package(Protobuf 3.3.0) restore_env() # protobuf versions >= 3.21 are incompatible with how the project is setup and cause weird errors # so we build protobuf ourselves -if(Protobuf_VERSION VERSION_GREATER_EQUAL 3.21) +if(NOT Protobuf_FOUND OR Protobuf_VERSION VERSION_GREATER_EQUAL 3.21) include(BuildProtobuf) endif() From d372b597f5c330656eef104aabe2466a70037a48 Mon Sep 17 00:00:00 2001 From: Michel Schmid Date: Wed, 14 Feb 2024 01:20:37 +0100 Subject: [PATCH 6/9] fix github pipeline for macos and windows Also changed vcpkg dependency from qt5 to qt5-base, because that should be enough and vcpkg seems to build from source (?) and no one has time to build Qt completely. Includes some hacks to get around the fact that the macos pipeline does not set the path to the QtConfig.cmake correctly. --- .github/workflows/build.yaml | 9 ++++++--- Makefile | 4 +++- vcpkg.json | 4 ++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index a4dec060..7b2feb75 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -31,9 +31,11 @@ jobs: steps: - uses: actions/checkout@v4 - name: "Install dependencies" - run: brew tap robotology/formulae && brew install cmake pkg-config qt@5 protobuf@21 robotology/formulae/ode + run: brew tap robotology/formulae && brew install cmake pkg-config qt@5 - name: "Build" - run: make + # for some reason qt5 is not correctly in the path and this will break whenever the location of it changes + # 5.15.11 is for macos-12 and 5.15.12 is for macos-13 + run: PATH=/usr/local/Cellar/qt@5/5.15.11/lib/cmake/Qt5:/usr/local/Cellar/qt@5/5.15.12/lib/cmake/Qt5:$PATH && make BUILD_ODE=ON build-windows: runs-on: windows-latest @@ -45,7 +47,8 @@ jobs: with: vcpkgGitCommitId: 8eb57355a4ffb410a2e94c07b4dca2dffbee8e50 vcpkgDirectory: c:/vcpkg # folder must reside in c:\ otherwise qt wont install due to long path errors - + # needed to actually install the vcpkg dependencies + runVcpkgInstall: true - name: Run CMake and run vcpkg to build packages uses: lukka/run-cmake@v10 diff --git a/Makefile b/Makefile index 4486fb59..0b6ba2e0 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,8 @@ BUILDDIR=build BUILDTYPE=Release #BUILDTYPE=Debug +BUILD_ODE=OFF + .PHONY: all build mkbuilddir cmake dist package deb install clean clean-all all: build @@ -22,7 +24,7 @@ mkbuilddir: [ -d $(BUILDDIR) ] || mkdir $(BUILDDIR) cmake: CMakeLists.txt - cd $(BUILDDIR) && cmake -DCMAKE_BUILD_TYPE=$(BUILDTYPE) .. + cd $(BUILDDIR) && cmake -DCMAKE_BUILD_TYPE=$(BUILDTYPE) -DBUILD_ODE=$(BUILD_ODE) .. dist: package diff --git a/vcpkg.json b/vcpkg.json index d82168ff..89c2f3c8 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -2,8 +2,8 @@ "name": "grsim", "version-string": "0.0.1", "dependencies": [ - "qt5", + "qt5-base", "ode", "protobuf" ] -} \ No newline at end of file +} From 1c13b65db475d88c60baca436dd816e23eb60326 Mon Sep 17 00:00:00 2001 From: Michel Schmid Date: Thu, 15 Feb 2024 13:33:39 +0100 Subject: [PATCH 7/9] fix ninja build for all ExternalProjects Apparently some weird issues are caused by using the INSTALL_DIR parameter of ExternalProjects when using the Ninja generator. Makes you wonder why that is even there, but cmake works in mysterious ways, I guess. Adding the install part as a substep and explicitly telling cmake that the necessary libs and executables are produced by this step fixes this issue. --- CMakeLists.txt | 43 +++++++++++++++++++++++-------- cmake/modules/BuildProtobuf.cmake | 34 ++++++++++++------------ 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f588673b..a2a84dd7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,8 @@ if (POLICY CMP0135) cmake_policy(SET CMP0135 NEW) endif() +include(GNUInstallDirs) + set(app ${CMAKE_PROJECT_NAME}) # create the target before the sources list is known so that we can call # add_dependencies( external_proj) @@ -85,12 +87,9 @@ if(BUILD_ODE) # could be because in some packages the double precision is turned off include(ExternalProject) - set(ODE_INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/ode_install") - ExternalProject_Add(ode_external GIT_REPOSITORY https://bitbucket.org/odedevs/ode.git GIT_TAG 0.16.4 - INSTALL_DIR "${ODE_INSTALL_DIR}" CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH= -DCMAKE_TOOLCHAIN_FILE:PATH=${CMAKE_TOOLCHAIN_FILE} @@ -102,12 +101,24 @@ if(BUILD_ODE) # if this is OFF grSim just dies instantly and INSTALL.md says it should be ON -DODE_DOUBLE_PRECISION=ON -DCMAKE_INSTALL_PREFIX= + STEP_TARGETS install ) - add_dependencies(${app} ode_external) - set(ODE_LIBRARY "${ODE_INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}ode${CMAKE_STATIC_LIBRARY_SUFFIX}") + set(ODE_LIB_SUBPATH "${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}ode${CMAKE_STATIC_LIBRARY_SUFFIX}") + + # the byproducts are available after the install step + ExternalProject_Add_Step(ode_external out + DEPENDEES install + BYPRODUCTS + "/${ODE_LIB_SUBPATH}" + ) + + ExternalProject_Get_Property(ode_external install_dir) + set(ODE_LIBRARY "${install_dir}/${ODE_LIB_SUBPATH}") list(APPEND libs ${ODE_LIBRARY}) - target_include_directories(${app} PRIVATE "${ODE_INSTALL_DIR}/include") + target_include_directories(${app} PRIVATE "${install_dir}/include") + + add_dependencies(${app} ode_external) elseif(WIN32) find_package(ODE CONFIG REQUIRED) list(APPEND libs ODE::ODE) @@ -121,7 +132,6 @@ find_package(VarTypes) if(NOT VARTYPES_FOUND) include(ExternalProject) - set(VARTYPES_INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/vartypes_install") set(VARTYPES_CMAKE_ARGS "-DVARTYPES_BUILD_STATIC=ON;-DCMAKE_INSTALL_PREFIX=") if(NOT "${CMAKE_TOOLCHAIN_FILE}" STREQUAL "") @@ -131,14 +141,25 @@ if(NOT VARTYPES_FOUND) ExternalProject_Add(vartypes_external GIT_REPOSITORY https://github.com/jpfeltracco/vartypes GIT_TAG origin/jpfeltracco/build_static - INSTALL_DIR "${VARTYPES_INSTALL_DIR}" CMAKE_ARGS "${VARTYPES_CMAKE_ARGS}" + STEP_TARGETS install + ) + set(VARTYPES_LIB_SUBPATH "${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}vartypes${CMAKE_STATIC_LIBRARY_SUFFIX}") + + # the byproducts are available after the install step + ExternalProject_Add_Step(vartypes_external out + DEPENDEES install + BYPRODUCTS + "/${VARTYPES_LIB_SUBPATH}" ) + + add_dependencies(${app} vartypes_external) + + ExternalProject_Get_Property(vartypes_external install_dir) add_dependencies(${app} vartypes_external) - set(VARTYPES_INCLUDE_DIRS "${VARTYPES_INSTALL_DIR}/include") - set(VARTYPE_LIB_NAME ${CMAKE_STATIC_LIBRARY_PREFIX}vartypes${CMAKE_STATIC_LIBRARY_SUFFIX}) - set(VARTYPES_LIBRARIES "${VARTYPES_INSTALL_DIR}/lib/${VARTYPE_LIB_NAME}") + set(VARTYPES_INCLUDE_DIRS "${install_dir}/include") + set(VARTYPES_LIBRARIES "${install_dir}/${VARTYPES_LIB_SUBPATH}") endif() target_include_directories(${app} PRIVATE ${VARTYPES_INCLUDE_DIRS}) diff --git a/cmake/modules/BuildProtobuf.cmake b/cmake/modules/BuildProtobuf.cmake index 34ded05a..dcc584b3 100644 --- a/cmake/modules/BuildProtobuf.cmake +++ b/cmake/modules/BuildProtobuf.cmake @@ -19,7 +19,6 @@ # *************************************************************************** include(ExternalProject) -set(PROTOBUF_INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/protobuf_install") set(PROTOBUF_CMAKE_ARGS ) @@ -29,7 +28,6 @@ ExternalProject_Add(protobuf_external URL http://www.robotics-erlangen.de/downloads/libraries/protobuf-cpp-3.6.1.tar.gz URL_HASH SHA256=b3732e471a9bb7950f090fd0457ebd2536a9ba0891b7f3785919c654fe2a2529 SOURCE_SUBDIR cmake - INSTALL_DIR "${PROTOBUF_INSTALL_DIR}" CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH= -DCMAKE_TOOLCHAIN_FILE:PATH=${CMAKE_TOOLCHAIN_FILE} @@ -41,17 +39,19 @@ ExternalProject_Add(protobuf_external STEP_TARGETS install ) -ExternalProject_Add_Step(protobuf_external out - DEPENDEES install - BYPRODUCTS - "/${PROTOBUF_SUBPATH}" - "/${PROTOC_SUBPATH}" -) - set(PROTOBUF_SUBPATH "${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}protobuf${CMAKE_STATIC_LIBRARY_SUFFIX}") set(LIBPROTOC_SUBPATH "${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}protoc${CMAKE_STATIC_LIBRARY_SUFFIX}") set(PROTOC_SUBPATH "bin/protoc${CMAKE_EXECUTABLE_SUFFIX}") +# the byproducts are available after the install step +ExternalProject_Add_Step(protobuf_external out + DEPENDEES install + BYPRODUCTS + "/${PROTOBUF_SUBPATH}" + "/${LIBPROTOC_SUBPATH}" + "/${PROTOC_SUBPATH}" +) + ExternalProject_Get_Property(protobuf_external install_dir) set_target_properties(protobuf_external PROPERTIES EXCLUDE_FROM_ALL true) @@ -61,18 +61,18 @@ set(Protobuf_FOUND true CACHE BOOL "" FORCE) set(Protobuf_VERSION "3.6.1" CACHE STRING "" FORCE) set(Protobuf_INCLUDE_DIR "${install_dir}/include" CACHE PATH "" FORCE) set(Protobuf_INCLUDE_DIRS "${Protobuf_INCLUDE_DIR}" CACHE PATH "" FORCE) -set(Protobuf_LIBRARY "${install_dir}/lib/${PROTOBUF_SUBPATH}" CACHE PATH "" FORCE) +set(Protobuf_LIBRARY "${install_dir}/${PROTOBUF_SUBPATH}" CACHE PATH "" FORCE) set(Protobuf_LIBRARIES "${Protobuf_LIBRARY}" CACHE PATH "" FORCE) -set(Protobuf_LIBRARY_DEBUG "${install_dir}/lib/${PROTOBUF_SUBPATH}" CACHE PATH "" FORCE) -set(Protobuf_LIBRARY_RELEASE "${install_dir}/lib/${PROTOBUF_SUBPATH}" CACHE PATH "" FORCE) -set(Protobuf_LITE_LIBRARY_DEBUG "${install_dir}/lib/${PROTOBUF_SUBPATH}" CACHE PATH "" FORCE) -set(Protobuf_LITE_LIBRARY_RELEASE "${install_dir}/lib/${PROTOBUF_SUBPATH}" CACHE PATH "" FORCE) +set(Protobuf_LIBRARY_DEBUG "${install_dir}/${PROTOBUF_SUBPATH}" CACHE PATH "" FORCE) +set(Protobuf_LIBRARY_RELEASE "${install_dir}/${PROTOBUF_SUBPATH}" CACHE PATH "" FORCE) +set(Protobuf_LITE_LIBRARY_DEBUG "${install_dir}/${PROTOBUF_SUBPATH}" CACHE PATH "" FORCE) +set(Protobuf_LITE_LIBRARY_RELEASE "${install_dir}/${PROTOBUF_SUBPATH}" CACHE PATH "" FORCE) set(Protobuf_PROTOC_EXECUTABLE "${install_dir}/${PROTOC_SUBPATH}" CACHE PATH "" FORCE) -set(Protobuf_PROTOC_LIBRARY_DEBUG "${install_dir}/lib/${LIBPROTOC_SUBPATH}" CACHE PATH "" FORCE) -set(Protobuf_PROTOC_LIBRARY_RELEASE "${install_dir}/lib/${LIBPROTOC_SUBPATH}" CACHE PATH "" FORCE) +set(Protobuf_PROTOC_LIBRARY_DEBUG "${install_dir}/${LIBPROTOC_SUBPATH}" CACHE PATH "" FORCE) +set(Protobuf_PROTOC_LIBRARY_RELEASE "${install_dir}/${LIBPROTOC_SUBPATH}" CACHE PATH "" FORCE) # this is a dependency for the protobuf_generate_cpp custom command # if this is not set the generate command sometimes get executed before protoc is compiled -set(protobuf_generate_DEPENDENCIES protobuf_external CACHE TARGET "" FORCE) +set(protobuf_generate_DEPENDENCIES protobuf_external CACHE STRING "" FORCE) # compatibility with cmake 3.10 if(NOT TARGET protobuf::protoc) From 2312fb2a28fde4fbbd3a3e762fafcbe4e73e0a5b Mon Sep 17 00:00:00 2001 From: Michel Schmid Date: Wed, 14 Feb 2024 12:08:47 +0100 Subject: [PATCH 8/9] a few steps towards a working windows pipeline Windows pipeline is now doing what the samples from run-vcpkg and run-cmake suggest it should do and vcpkg claims that it should handle cmake find_package calls correctly if you use their vcpkg.cmake as the toolchain. It's not working, because for some reason the find_package call for Qt still fails with cmake claiming it can't find a Qt5config.cmake file. --- .github/workflows/build.yaml | 12 +++++++++--- CMakePresets.json | 28 +++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 7b2feb75..aa0989d3 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -47,11 +47,17 @@ jobs: with: vcpkgGitCommitId: 8eb57355a4ffb410a2e94c07b4dca2dffbee8e50 vcpkgDirectory: c:/vcpkg # folder must reside in c:\ otherwise qt wont install due to long path errors - # needed to actually install the vcpkg dependencies - runVcpkgInstall: true - name: Run CMake and run vcpkg to build packages uses: lukka/run-cmake@v10 with: - configurePreset: "windows-default" + # this preset is needed to actually install the vcpkg dependencies + configurePreset: "ninja-multi-vcpkg" + configPresetAdditionalArgs: "[-DVCPKG_TARGET_TRIPLET=x64-windows]" + buildPreset: "ninja-multi-vcpkg" buildPresetAdditionalArgs: "['--config Release']" + env: + # [OPTIONAL] Define the vcpkg's triplet you want to enforce, otherwise the default one + # for the hosting system will be automatically choosen (x64 is the default on all + # platforms, e.g. `x64-osx`). + VCPKG_DEFAULT_TRIPLET: "x64-windows" diff --git a/CMakePresets.json b/CMakePresets.json index 019632d5..de8ed6dd 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -14,6 +14,32 @@ "CMAKE_BUILD_TYPE": "Release", "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}" } + }, + { + "name": "ninja-multi-vcpkg", + "displayName": "Windows x64 Release vcpkg", + "generator": "Ninja Multi-Config", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "architecture": { + "value": "x64", + "strategy": "external" + }, + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": { + "type": "FILEPATH", + "value": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" + }, + "CMAKE_BUILD_TYPE": "Release", + "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}" + } + } + ], + "buildPresets": [ + { + "name": "ninja-multi-vcpkg", + "configurePreset": "ninja-multi-vcpkg", + "displayName": "Build ninja-multi-vcpkg", + "description": "Build ninja-multi-vcpkg Configurations" } ] -} \ No newline at end of file +} From 9789b00a1b223bc1e626f9919507c779f72c7c5d Mon Sep 17 00:00:00 2001 From: Michel Schmid Date: Thu, 15 Feb 2024 17:14:34 +0100 Subject: [PATCH 9/9] build ODE from source if the package is not found, even if flag is not set --- .github/workflows/build.yaml | 2 +- CMakeLists.txt | 56 +++++++++++------------------------- cmake/modules/BuildODE.cmake | 34 ++++++++++++++++++++++ 3 files changed, 51 insertions(+), 41 deletions(-) create mode 100644 cmake/modules/BuildODE.cmake diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index aa0989d3..74ee3643 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -35,7 +35,7 @@ jobs: - name: "Build" # for some reason qt5 is not correctly in the path and this will break whenever the location of it changes # 5.15.11 is for macos-12 and 5.15.12 is for macos-13 - run: PATH=/usr/local/Cellar/qt@5/5.15.11/lib/cmake/Qt5:/usr/local/Cellar/qt@5/5.15.12/lib/cmake/Qt5:$PATH && make BUILD_ODE=ON + run: PATH=/usr/local/Cellar/qt@5/5.15.11/lib/cmake/Qt5:/usr/local/Cellar/qt@5/5.15.12/lib/cmake/Qt5:$PATH && make build-windows: runs-on: windows-latest diff --git a/CMakeLists.txt b/CMakeLists.txt index a2a84dd7..f9ffc9e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,48 +83,24 @@ list(APPEND libs Qt5::Core Qt5::Widgets Qt5::OpenGL Qt5::Network) # ODE if(BUILD_ODE) - # build ODE, because some versions of it cause grSim to segfault somewhere - # could be because in some packages the double precision is turned off - include(ExternalProject) - - ExternalProject_Add(ode_external - GIT_REPOSITORY https://bitbucket.org/odedevs/ode.git - GIT_TAG 0.16.4 - CMAKE_ARGS - -DCMAKE_INSTALL_PREFIX:PATH= - -DCMAKE_TOOLCHAIN_FILE:PATH=${CMAKE_TOOLCHAIN_FILE} - -DCMAKE_C_COMPILER:PATH=${CMAKE_C_COMPILER} - -DCMAKE_CXX_COMPILER:PATH=${CMAKE_CXX_COMPILER} - -DCMAKE_MAKE_PROGRAM:PATH=${CMAKE_MAKE_PROGRAM} - # necessary, because it does not build the static libs if this is ON - -DBUILD_SHARED_LIBS=OFF - # if this is OFF grSim just dies instantly and INSTALL.md says it should be ON - -DODE_DOUBLE_PRECISION=ON - -DCMAKE_INSTALL_PREFIX= - STEP_TARGETS install - ) - - set(ODE_LIB_SUBPATH "${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}ode${CMAKE_STATIC_LIBRARY_SUFFIX}") - - # the byproducts are available after the install step - ExternalProject_Add_Step(ode_external out - DEPENDEES install - BYPRODUCTS - "/${ODE_LIB_SUBPATH}" - ) - - ExternalProject_Get_Property(ode_external install_dir) - set(ODE_LIBRARY "${install_dir}/${ODE_LIB_SUBPATH}") - list(APPEND libs ${ODE_LIBRARY}) - target_include_directories(${app} PRIVATE "${install_dir}/include") - + include(BuildODE) add_dependencies(${app} ode_external) -elseif(WIN32) - find_package(ODE CONFIG REQUIRED) - list(APPEND libs ODE::ODE) else() - find_package(ODE REQUIRED) - list(APPEND libs ode::ode) + if(WIN32) + find_package(ODE CONFIG) + set(ODE_LIB_NAME ODE::ODE) + else() + find_package(ODE) + set(ODE_LIB_NAME ode::ode) + endif() + + if(ODE_FOUND) + list(APPEND libs ${ODE_LIB_NAME}) + else() + # if ODE could not be found just build it + include(BuildODE) + add_dependencies(${app} ode_external) + endif() endif() # VarTypes diff --git a/cmake/modules/BuildODE.cmake b/cmake/modules/BuildODE.cmake new file mode 100644 index 00000000..41aa54f7 --- /dev/null +++ b/cmake/modules/BuildODE.cmake @@ -0,0 +1,34 @@ +# build ODE, because some versions of it cause grSim to segfault somewhere +# could be because in some packages the double precision is turned off +include(ExternalProject) + +ExternalProject_Add(ode_external + GIT_REPOSITORY https://bitbucket.org/odedevs/ode.git + GIT_TAG 0.16.4 + CMAKE_ARGS + -DCMAKE_INSTALL_PREFIX:PATH= + -DCMAKE_TOOLCHAIN_FILE:PATH=${CMAKE_TOOLCHAIN_FILE} + -DCMAKE_C_COMPILER:PATH=${CMAKE_C_COMPILER} + -DCMAKE_CXX_COMPILER:PATH=${CMAKE_CXX_COMPILER} + -DCMAKE_MAKE_PROGRAM:PATH=${CMAKE_MAKE_PROGRAM} + # necessary, because it does not build the static libs if this is ON + -DBUILD_SHARED_LIBS=OFF + # if this is OFF grSim just dies instantly and INSTALL.md says it should be ON + -DODE_DOUBLE_PRECISION=ON + -DCMAKE_INSTALL_PREFIX= + STEP_TARGETS install +) + +set(ODE_LIB_SUBPATH "${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}ode${CMAKE_STATIC_LIBRARY_SUFFIX}") + +# the byproducts are available after the install step +ExternalProject_Add_Step(ode_external out + DEPENDEES install + BYPRODUCTS + "/${ODE_LIB_SUBPATH}" +) + +ExternalProject_Get_Property(ode_external install_dir) +set(ODE_LIBRARY "${install_dir}/${ODE_LIB_SUBPATH}") +list(APPEND libs ${ODE_LIBRARY}) +target_include_directories(${app} PRIVATE "${install_dir}/include")