smanders / externpro

build external projects with cmake
MIT License
13 stars 12 forks source link

ceres solver issues cont'd #248

Closed smanders closed 5 years ago

smanders commented 5 years ago

related issues

this is part 2 of the "ceres solver issues" issue above because it appears to be the nearly the same issue - perhaps the fix that went in wasn't quite enough? I'd like to know if the plugin developers ever attempted to use an externpro with the fix above (externpro release 18.11.1 has the attempted fix)

From: Blake Nelson Sent: Monday, September 16, 2019 6:20 PM Subject: Re: [aimperial/SYERSPlugin] 24 bit color format first pass (#35)

...

The main problem with the version in externpro is that it adds "-std=gnu++11" to the command line. When we try to use the externpro version, we get a conflict between the "-std=c++14" flag used by our plugin and the "-std=gnu++11" added by ceres. I don't remember the details, but I imagine this wasn't an issue when you first added ceres to externpro because our plugin was probably still on C++11 only at the time, and maybe there are no conflicts between "-std=c++11" and "-std=gnu++11".

If I remember correctly, this was an artifact of cmake's compile_features functionality. Ceres is specifying some compile_feature that requires the use of C++11, and cmake interprets that to mean gnu++11 (see the following example from https://cmake.org/cmake/help/v3.8/manual/cmake-compile-features.7.html):


add_library(mylib requires_constexpr.cpp)
# cxx_constexpr is a usage-requirement
target_compile_features(mylib PUBLIC cxx_constexpr)

main.cpp will be compiled with -std=gnu++11 on GNU for cxx_constexpr.

add_executable(myexe main.cpp) target_link_libraries(myexe mylib)


>Since we added ceres to externpro, we upgraded to gcc 6 and C++14 support. I had to update ceres to support C++14, so I updated/hacked ceres in PRIMUSPro to it (https://isrhub.usurf.usu.edu/bnelson/PRIMUSPro/blob/18.07.1/patches/ceres.patch#L146-L147) and cmake no longer inserts "-std=gnu++11".
smanders commented 5 years ago

Ceres Solver http://ceres-solver.org/

externpro

PRIMUSPro

MSVC_USE_STATIC_CRT

smanders commented 5 years ago

current dev branch of externpro

cmake -DXP_DEFAULT=OFF -DXP_STEP=build -DXP_BUILD_DEBUG=OFF -DXP_PRO_CERES=ON /path/to/src
[ 77%] Performing configure step for 'ceres_Release'
-- The C compiler identification is GNU 7.4.0
-- The CXX compiler identification is GNU 7.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Detected Ceres version: 1.14.0 from /home/smanders/src/tmp/externpro/_bldx/xpbase/Source/ceres/include/ceres/version.h
-- Performing Test has_c_fPIC
-- Performing Test has_c_fPIC - Success
-- Performing Test has_c_msse3
-- Performing Test has_c_msse3 - Success
-- Performing Test has_c_StrongSP
-- Performing Test has_c_StrongSP - Success
-- Performing Test has_cxx_fPIC
-- Performing Test has_cxx_fPIC - Success
-- Performing Test has_cxx_msse3
-- Performing Test has_cxx_msse3 - Success
-- Performing Test has_cxx_StrongSP
-- Performing Test has_cxx_StrongSP - Success
-- Found Eigen: /home/smanders/src/tmp/externpro/_bldx/externpro_19.06.1-33-g9fd9625-p-gcc740-64/include/eigen_3.2.7/eigen3 (found version "3.2.7") 
-- Found Eigen version 3.2.7: /home/smanders/src/tmp/externpro/_bldx/externpro_19.06.1-33-g9fd9625-p-gcc740-64/include/eigen_3.2.7/eigen3
-- Enabling use of Eigen as a sparse linear algebra library.
-- Building without LAPACK.
-- Building without SuiteSparse.
-- Building without CXSparse.
-- Google Flags disabled; no tests or tools will be built!
-- Compiling minimal glog substitute into Ceres.
-- Using minimal glog substitute (include): internal/ceres/miniglog
-- Max log level for minimal glog substitute: 2
-- Building without OpenMP, disabling.
-- Performing Test COMPILER_HAS_CXX11_FLAG
-- Performing Test COMPILER_HAS_CXX11_FLAG - Success
-- Looking for C++ include unordered_map
-- Looking for C++ include unordered_map - found
-- Performing Test HAVE_UNORDERED_MAP_IN_STD_NAMESPACE
-- Performing Test HAVE_UNORDERED_MAP_IN_STD_NAMESPACE - Success
-- Found unordered_map/set in std namespace.
-- Looking for C++ include memory
-- Looking for C++ include memory - found
-- Performing Test HAVE_SHARED_PTR_IN_STD_NAMESPACE
-- Performing Test HAVE_SHARED_PTR_IN_STD_NAMESPACE - Success
-- Found shared_ptr in std namespace using <memory> header.
-- Performing Test CXX11_MATH_FUNCTIONS_FOUND
-- Performing Test CXX11_MATH_FUNCTIONS_FOUND - Success
   ==============================================================
   Compiling Ceres using C++11.  This will result in a version 
   of Ceres that will require the use of C++11 in client code.
   ==============================================================
-- Looking for C++ include atomic
-- Looking for C++ include atomic - found
-- Building with C++11 threads.
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE  
-- Failed to find Google benchmark library, disabling build of benchmarks.
-- Building Ceres as a static library.
-- Creating configured Ceres config.h output directory: /home/smanders/src/tmp/externpro/_bldx/xpbase/Build/ceres_Release/config/ceres/internal
-- Enabling CERES_USE_EIGEN_SPARSE in Ceres config.h
-- Enabling CERES_NO_LAPACK in Ceres config.h
-- Enabling CERES_NO_SUITESPARSE in Ceres config.h
-- Enabling CERES_NO_CXSPARSE in Ceres config.h
-- Enabling CERES_USE_CXX11 in Ceres config.h
-- Enabling CERES_USE_CXX11_THREADS in Ceres config.h
-- Enabling CERES_HAVE_PTHREAD in Ceres config.h
-- Enabling CERES_HAVE_RWLOCK in Ceres config.h
-- Enabling CERES_STD_UNORDERED_MAP in Ceres config.h
-- Do not build any example.
-- Configuring done
-- Generating done
smanders commented 5 years ago

externpro vs PRIMUSPro

smanders commented 5 years ago

making the following change, to match PRIMUSPro

diff --git a/cmake/AddCeresCXX11RequirementsToTarget.cmake b/cmake/AddCeresCXX11RequirementsToTarget.cmake
index ca2ad64..6d58ae3 100644
--- a/cmake/AddCeresCXX11RequirementsToTarget.cmake
+++ b/cmake/AddCeresCXX11RequirementsToTarget.cmake
@@ -34,7 +34,7 @@
 #    add_ceres_cxx11_requirements_to_target( [target1 [target2 [...]]] )
 function(add_ceres_cxx11_requirements_to_target)
   include(CheckCXXCompilerFlag)
-  check_cxx_compiler_flag("-std=c++11" COMPILER_HAS_CXX11_FLAG)
+  check_cxx_compiler_flag("-std=c++14" COMPILER_HAS_CXX11_FLAG)

   foreach(TARGET ${ARGN})
     if (NOT TARGET ${TARGET})
@@ -77,7 +77,7 @@ function(add_ceres_cxx11_requirements_to_target)
         # NOT compiling for C.  We check for not C, rather than C++ as
         # LINKER_LANGUAGE is often NOTFOUND and then uses the default (C++).
         target_compile_options(${TARGET} PUBLIC
-          $<$<NOT:$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,C>>:-std=c++11>)
+          $<$<NOT:$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,C>>:-std=c++14>)
       endif()
     endif()
   endforeach()

doesn't make much sense and shouldn't have any effect on the build

we are on a new enough cmake that the COMMAND target_compile_features is the conditional we would fall in (target_compile_features() existed as far back as cmake 3.3 https://cmake.org/cmake/help/v3.3/command/target_compile_features.html -- which puts us back several years as far as externpro and VANTAGE go) https://github.com/ceres-solver/ceres-solver/blob/66dd46422b01b48fb6aa2b04cba87c28ce10b90e/cmake/AddCeresCXX11RequirementsToTarget.cmake#L58-L71

so I suspect any release including externpro 18.11.1 or later (18.11.1 is where commenting out the target_compiles_features() call was made) should work the same as the PRIMUSPro version of ceres solver

smanders commented 5 years ago

From: Blake Nelson Sent: Tuesday, October 8, 2019 12:29 PM To: Scott M Anderson Cc: Andres Imperial Subject: Linking with ceres

I tried compiling with externpro 18.11.1 to see if its version of ceres worked with our plugin. I ran into one issue. When glog is not available ceres provides a different header file with the same interface and expects the target's include paths to point towards the directory with this file. On my machine this required include directory is at /opt/extern/externpro-18.11.1-gcc650-64-Linux/include/ceres_1.14.0/ceres/internal/mini glog. When I manually added this path to my project, compilation, linking, and all of my unit tests that used ceres succeeded.

I dug a little, and it seems that ceres puts this include directory into a CERES_INCLUDE_DIRS, but our usexp-ceres script is only looking for CERES_INCLUDE_DIR. However, when I tried to update the script it didn't work, so maybe there is something else going on.

smanders commented 5 years ago

externpro doesn't include the generated CeresConfig.cmake (but does include CeresTargets.cmake) https://github.com/smanders/externpro/blob/18.11.1/projects/use/usexp-ceres-config.cmake#L14-L15

# ceres installs a Targets file among other .cmake files
include(${XP_ROOTDIR}/lib/cmake${verDir}/CeresTargets.cmake)

the CeresConfig.cmake file defines a CERES_INCLUDE_DIRS variable for the "include directories for Ceres and the dependencies which appear in the Ceres public API and are thus required to use Ceres"

I opted not to make modifications to the generated CeresConfig.cmake and kept the Ceres use script (usexp-ceres-config.cmake) consistent with our other externpro project use scripts

we have other projects (for example ffmpeg) which also need access to "internal" includes -- there we simply append to the ${PRJ}_INCLUDE_DIR variable and this should work for ceres, too

diff --git a/projects/use/usexp-ceres-config.cmake b/projects/use/usexp-ceres-config.cmake
index e3b168c..f8b2892 100644
--- a/projects/use/usexp-ceres-config.cmake
+++ b/projects/use/usexp-ceres-config.cmake
@@ -11,6 +11,7 @@ set(${PRJ}_VER "@VER@ [@PROJECT_NAME@]")
 set(verDir /${prj}_@VER@)
 unset(${PRJ}_INCLUDE_DIR CACHE)
 find_path(${PRJ}_INCLUDE_DIR ceres/ceres.h PATHS ${XP_ROOTDIR}/include${verDir} NO_DEFAULT_PATH)
+list(APPEND ${PRJ}_INCLUDE_DIR ${XP_ROOTDIR}/include${verDir}/ceres/internal/miniglog)
 # ceres installs a Targets file among other .cmake files
 include(${XP_ROOTDIR}/lib/cmake${verDir}/CeresTargets.cmake)
 set(${PRJ}_LIBRARIES ceres)

looking at the CeresConfig.cmake, we may need to also append the eigen include directory... let me know if you find this is true and I'll provide the modifications to the use script to enable this, too

smanders commented 5 years ago

completed with commits to dev branch referenced above