Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gmock issue building realtime_tools on arch linux #1030

Closed
jwhendy opened this issue Sep 9, 2019 · 52 comments · Fixed by #1040 or #1105
Closed

gmock issue building realtime_tools on arch linux #1030

jwhendy opened this issue Sep 9, 2019 · 52 comments · Fixed by #1040 or #1105
Labels

Comments

@jwhendy
Copy link

jwhendy commented Sep 9, 2019

I'm trying to build ros-melodic-realtime-tools from the arch linux AUR. The PKGBUILD shows how the make commands are called.

I get the following error:

$ makepkg
==> Making package: ros-melodic-realtime-tools 1.15.0-0 (Mon 09 Sep 2019 01:57:27 AM CDT)
==> Checking runtime dependencies...
==> Checking buildtime dependencies...
==> Retrieving sources...
  -> Found ros-melodic-realtime-tools-1.15.0.tar.gz
==> Validating source files with sha256sums...
    ros-melodic-realtime-tools-1.15.0.tar.gz ... Passed
==> Extracting sources...
  -> Extracting ros-melodic-realtime-tools-1.15.0.tar.gz with bsdtar
==> Removing existing $pkgdir/ directory...
==> Starting build()...
-- Using CATKIN_DEVEL_PREFIX: /home/jwhendy/installed/build/ros-melodic-aur/ros-melodic-realtime-tools/src/build/devel
-- Using CMAKE_PREFIX_PATH: /opt/ros/melodic
-- This workspace overlays: /opt/ros/melodic
-- Using PYTHON_EXECUTABLE: /usr/bin/python3
-- Using default Python package layout
-- Using empy: /usr/lib/python3.7/site-packages/em.py
-- Using CATKIN_ENABLE_TESTING: ON
-- Skip enable_testing() when building binary package
-- Using CATKIN_TEST_RESULTS_DIR: /home/jwhendy/installed/build/ros-melodic-aur/ros-melodic-realtime-tools/src/build/test_results
-- Found gtest: gtests will be built
-- Using Python nosetests: /usr/bin/nosetests-3.7
-- catkin 0.7.17
-- BUILD_SHARED_LIBS is on
CMake Warning at /opt/ros/melodic/share/catkin/cmake/test/gtest.cmake:151 (message):
  skipping gmock 'realtime_box_tests' in project 'realtime_tools' because
  gmock was not found
Call Stack (most recent call first):
  /opt/ros/melodic/share/catkin/cmake/test/gtest.cmake:80 (_catkin_add_executable_with_google_test)
  /opt/ros/melodic/share/catkin/cmake/test/gtest.cmake:54 (_catkin_add_google_test)
  CMakeLists.txt:23 (catkin_add_gmock)


CMake Error at CMakeLists.txt:24 (target_link_libraries):
  Cannot specify link libraries for target "realtime_box_tests" which is not
  built by this project.


-- Configuring incomplete, errors occurred!
See also "/home/jwhendy/installed/build/ros-melodic-aur/ros-melodic-realtime-tools/src/build/CMakeFiles/CMakeOutput.log".
See also "/home/jwhendy/installed/build/ros-melodic-aur/ros-melodic-realtime-tools/src/build/CMakeFiles/CMakeError.log".

I made a slight edit to a function to see where it was looking.

$ cat /opt/ros/melodic/share/catkin/cmake/test/gtest.cmake
function(_catkin_add_executable_with_google_test type target)
...
  if(NOT ${type_upper}_FOUND AND NOT ${type_upper}_FROM_SOURCE_FOUND)
    message(WARNING "skipping ${type} '${target}' in project '${PROJECT_NAME}' because ${type} was not found in '${GTEST_INCLUDE_DIRS}'")

This prints out as:

skipping gmock 'realtime_box_tests' in project 'realtime_tools' because
  gmock was not found in '/usr/include'

I do have gmock/gtest installed, and the dirs are in /usr/include. For the heck of it, I tried symlinking all *.h files into /usr/include directly, but that didn't work out.

$ pacman -Qi gmock
Name            : gmock
Version         : 1.8.1-3

$ pacman -Qi gtest
Name            : gtest
Version         : 1.8.1-3

$ ls /usr/include/gmock/
internal         gmock-cardinalities.h      gmock-generated-function-mockers.h  gmock-generated-nice-strict.h  gmock-matchers.h      gmock-more-matchers.h
gmock-actions.h  gmock-generated-actions.h  gmock-generated-matchers.h          gmock.h                        gmock-more-actions.h  gmock-spec-builders.h

I think this is related to #933 and #970. I also saw #1022 and adapted ros-melodic-catkin to build from @sloretz 's fork, but this did not solve my issue. I get the same original error about gmock not being found.

Any other details that would be helpful, or debug output I could add to assist with this?

@GladOSkar
Copy link

GladOSkar commented Sep 15, 2019

Same issue on debian 10 buster

This is when building melodic-desktop-full from source

Manually installing libgmock-dev (which contains the files in /usr/include/gmock) did not resolve the issue.

I will try applying #1022 later

@GladOSkar
Copy link

Applying #1022 solved the issue for me

@jwhendy
Copy link
Author

jwhendy commented Sep 15, 2019

@GladOSkar which package from melodic-desktop-full fails for you? I will retry #1022 but as noted above, when I installed @sloretz 's fork of catkin with that change, it didn't work for me. I'll try again in case I goofed something, or perhaps the package failing for you and me (realtime_tools) is not the same?


EDIT: Another thought is that the #1022 patch fixes the issue on debian, but not arch? If the magic is adding /usr/include/gmock, that exists on arch as well. Perhaps post everything from ls /usr/include/gmock so we can compare (mine is posted above).

@GladOSkar
Copy link

@jwhendy it was realtime-tools for me as well.

Yeah I saw that #1022 didn't fix it for you, weird. An unusual thing I did is that I applied each patch line manually (didn't use his file or the patch command) because I feared conflict since their patch is for kinetic.

From how I understood their PR I don't think the issue is with /usr/include/gmock, but rather catkin's gmock detection in the cmake file is faulty for newer versions of gmock. Not entirely sure though.

@jwhendy
Copy link
Author

jwhendy commented Sep 16, 2019

Any pointers on how best to do this? This repo stops at kinetic-devel, so I don't think it's a melodic vs. kinetic thing.

If I just clone @sloretz 's fork using the gmock-from-source-buster branch, should that work? I grepped for the various googltest instances in the updated gtest.cmake and see them. It appears this is the only thing that's changed. I still fail to find gmock.

CMake Warning at /opt/ros/melodic/share/catkin/cmake/test/gtest.cmake:151 (message):
  skipping gmock 'realtime_box_tests' in project 'realtime_tools' because
  gmock was not found
Call Stack (most recent call first):
  /opt/ros/melodic/share/catkin/cmake/test/gtest.cmake:80 (_catkin_add_executable_with_google_test)
  /opt/ros/melodic/share/catkin/cmake/test/gtest.cmake:54 (_catkin_add_google_test)
  CMakeLists.txt:23 (catkin_add_gmock)

@jwhendy
Copy link
Author

jwhendy commented Sep 16, 2019

Also, do you actually have these directories, or are they really variables that get resolved?

$ grep googletest /opt/ros/melodic/share/catkin/cmake/test/gtest.cmake 
  list(APPEND _gtest_include_paths "${include_path}/googletest/googletest/include/gtest")
  list(APPEND _gtest_source_paths "${src_path}/googletest/googletest/src")
    list(INSERT _gtest_include_paths 0 "${CMAKE_SOURCE_DIR}/googletest/googletest/include/gtest")
    list(INSERT _gtest_source_paths 0 "${CMAKE_SOURCE_DIR}/googletest/googletest/src")
  list(APPEND _gmock_include_paths "${include_path}/googletest/googlemock/include/gmock")
  list(APPEND _gmock_source_paths "${src_path}/googletest/googlemock/src")
    list(INSERT _gmock_include_paths 0 "${CMAKE_SOURCE_DIR}/googletest/googlemock/include/gmock")
    list(INSERT _gmock_source_paths 0 "${CMAKE_SOURCE_DIR}/googletest/googlemock/src")

I don't have any googletest or googlemock directories.

@jwhendy
Copy link
Author

jwhendy commented Sep 16, 2019

From looking at those directories, here is arch's layout:

$ ls /usr/include/gtest/
internal            gtest-message.h     gtest-printers.h  gtest-test-part.h
gtest-death-test.h  gtest-param-test.h  gtest_prod.h      gtest-typed-test.h
gtest.h             gtest_pred_impl.h   gtest-spi.h

$ ls /usr/include/gmock/
internal                   gmock-generated-function-mockers.h  gmock-matchers.h
gmock-actions.h            gmock-generated-matchers.h          gmock-more-actions.h
gmock-cardinalities.h      gmock-generated-nice-strict.h       gmock-more-matchers.h
gmock-generated-actions.h  gmock.h

$ ls /usr/src/gtest/
cmake  src  CMakeLists.txt

$ ls /usr/src/gmock/
gmock-all.cc            gmock.cc                 gmock_main.cc      gmock-spec-builders.cc
gmock-cardinalities.cc  gmock-internal-utils.cc  gmock-matchers.cc

@GladOSkar
Copy link

Any pointers on how best to do this?

No idea TBH, i don't know a lot about these things either ¯_(ツ)_/¯

My /usr/src dirs do contain more complete source files than yours:

image

Not sure if this helps

@jwhendy
Copy link
Author

jwhendy commented Sep 16, 2019

Hmmm, that's super interesting.

$ pacman -Qi gmock
Name            : gmock
Version         : 1.8.1-3

$ pacman -Qi gtest
Name            : gtest
Version         : 1.8.1-3

Can you post the same, as well as something like (just a few, you don't need all of these)

$ pacman -Qo /usr/src/gmock/*
$ pacman -Qo /usr/src/gtest/*

I want to understand why those files are missing for me, but not you.

@jwhendy
Copy link
Author

jwhendy commented Sep 16, 2019

Oh, whoops. Bah. I'm collaborating with an Oskar on arch packages and thought you were him. Okay, I think this is a Debian vs. Arch thing, then. I definitely don't have a full src folder like that for either of these packages.

@GladOSkar
Copy link

Haha no worries :)

Good luck finding a solution!

@jwhendy
Copy link
Author

jwhendy commented Sep 16, 2019

Thanks for the post of the directories. I think that's a great start and enabled me to create an arch bug report. I'll post back when we resolve. I'm not sure where to find a de facto directory structure of what should/should not exist and where...

@dirk-thomas
Copy link
Member

@jwhendy Any update on this? Btw the referenced PRs have been merged and released in the meantime so you might want to give it another try on Arch.

@jwhendy
Copy link
Author

jwhendy commented Oct 8, 2019

@dirk-thomas I haven't done anything since I didn't hear any news here or on the Arch bug.

Btw the referenced PRs have been merged and released in the meantime so you might want to give it another try on Arch.

Are there others besides #1022? In my first post, I note that I built directly from sloretz's fork to try #1022 directly. I can certainly try again later today.

From my last comment:

I'm not sure where to find a de facto directory structure of what should/should not exist and where...

This would be super helpful. I couldn't figure out from the code what, specifically, the cmake check is not finding. Any coaching here? The posts of directory structure from @GladOSkar were potentially promising, as they show Arch doesn't have the same /lib and /src contents.

If I can nail down what catkin expects, I can also feed this to the Arch packagers to make sure things are installing properly.


As a final aside, I remembered that I did this without success.

if(CATKIN_TOPLEVEL)
    message(STATUS "gtest not found, C++ tests can not be built. Please install the gtest headers globally in your system or checkout gtest (by running 'git clone  https://github.com/google/googletest.git -b release-1.8.0' in the source space '${CMAKE_SOURCE_DIR}' of your workspace) to enable gtests")
  else()

Is there a reason this is only proposed for gtest vs. also being a workaround if gmock is not found?

@dirk-thomas
Copy link
Member

Are there others besides #1022?

I was think of #1021 which was also an issue on Buster. Though it might not be relevant here.

This would be super helpful. I couldn't figure out from the code what, specifically, the cmake check is not finding. Any coaching here?

You can either look at the directory structure on Ubuntu or use the paths which are being checked in the CMake code.

Is there a reason this is only proposed for gtest vs. also being a workaround if gmock is not found?

This corner case has never been necessary. It is extremely unlikely now that gtest and gmock are bundled together that you only have gtest but not gmock and want to provide gmock from source within the workspace.

@jwhendy
Copy link
Author

jwhendy commented Oct 8, 2019

I was think of #1021

I'll do a clean build from master tonight. Thanks!

You can either look at the directory structure on Ubuntu or use the paths which are being checked in the CMake code.

Indeed, above I tried to replicate the Ubuntu filesystem screenshot posted by @GladOSkar without success.

I've also looked at the code and it looks like the find script is looking for gmock.h and gmock.cc. Note that these exist per my post above.

Is anyone able to explain what's going wrong in plain english? So far, we haven't pinpointed what's actually going wrong. Based on the information I've provided, what looks awry? Or, what information would you need to suggest what's going wrong?

@jwhendy
Copy link
Author

jwhendy commented Oct 9, 2019

I just re-built and installed ros-melodic-catkin looking at kinetic-devel, so I should be up to date:

### from pkg build directory
$ cat src/ros-melodic-catkin/CHANGELOG.rst | head

0.7.19 (2019-10-08)
-------------------
* support for pytest 5.1+ jUnit result files (`#1033 <https://github.com/ros/catkin/issues/1033>`_)
* fix -pthread handling in Debian buster (`#1021 <https://github.com/ros/catkin/issues/1021>`_)
* gmock from source on Debian buster (`#1022 <https://github.com/ros/catkin/issues/1022>`_)
* [windows] update a typo in local_setup.bat.in (`#1029 <https://github.com/ros/catkin/issues/1029>`_)

I get the same build error with realtime_tools:

CMake Warning at /opt/ros/melodic/share/catkin/cmake/test/gtest.cmake:151 (message):
  skipping gmock 'realtime_box_tests' in project 'realtime_tools' because
  gmock was not found
Call Stack (most recent call first):
  /opt/ros/melodic/share/catkin/cmake/test/gtest.cmake:80 (_catkin_add_executable_with_google_test)
  /opt/ros/melodic/share/catkin/cmake/test/gtest.cmake:54 (_catkin_add_google_test)
  CMakeLists.txt:23 (catkin_add_gmock)


CMake Error at CMakeLists.txt:24 (target_link_libraries):
  Cannot specify link libraries for target "realtime_box_tests" which is not
  built by this project.

And here is my attempt to understand why this fails.

Here's where it looks:

_catkin_find_google_source("gmock" "${_gmock_include_paths}"
                             "${_gmock_source_paths}" _gmock_found
                             _gmock_base_dir _gmock_include_dir _gmock_lib_dir
                             _gmock_libs _gmock_main_libs)

That calls this:

function(_catkin_find_google_source type include_paths
  src_paths found base_dir include_dir lib_dir libs main_libs)
  # Find the gtest headers
  find_file(_${type}_INCLUDES "${type}.h"
            PATHS ${include_paths}
            NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)

  # Find the gtest sources
  find_file(_${type}_SOURCES "${type}.cc"
            PATHS ${src_paths}
            NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)

Thus, we look for two files from what I can tell:

find_file(_gmock__INCLUDES "gmock.h"
            PATHS ${include_paths}

find_file(_gmock__SOURCES "gmock.cc"
            PATHS ${src_paths}

At face value, do we have those files?

$ locate gmock.cc
/usr/src/gmock/gmock.cc

$ locate gmock.h
/usr/include/gmock/gmock.h

Ok, edit gtest.cmake to help us find out what it's looking for and where:

# Internal function for finding gtest or gmock sources
function(_catkin_find_google_source type include_paths
  src_paths found base_dir include_dir lib_dir libs main_libs)
  # Find the gtest headers
  message("##### _${type}_INCLUDES ${type}.h ${include_paths}")
  find_file(_${type}_INCLUDES "${type}.h"
            PATHS ${include_paths}
            NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)

  # Find the gtest sources
  message("##### _${type}_SOURCE ${type}.cc ${src_paths}")
  find_file(_${type}_SOURCES "${type}.cc"
            PATHS ${src_paths}
            NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)

What do we get?

##### _gtest_INCLUDES gtest.h /usr/include;/usr/src/gtest;/usr/include;/usr/src/googletest/googletest/include/gtest
##### _gtest_SOURCE gtest.cc /usr/src/gtest/src;/usr/src/googletest/googletest/src
##### _gmock_INCLUDES gmock.h /usr/include;/usr/src/gmock;/usr/include;/usr/src/googletest/googlemock/include/gmock
##### _gmock_SOURCE gmock.cc /usr/src/gmock/src;/usr/src/googletest/googlemock/src

So, it looks like it's looking or /usr/include/{gtest,gmock}.h and /usr/src/{gtest, gmock}/src/{gtest, gmock}.cc On arch linux, three were not in the right place according to these paths, but I fixed that with symlinks.

$ ls -l /usr/include/gtest.h 
lrwxrwxrwx 1 root root 26 Oct  8 21:30 /usr/include/gtest.h -> /usr/include/gtest/gtest.h
$ ls -l /usr/include/gmock.h
lrwxrwxrwx 1 root root 26 Oct  8 21:28 /usr/include/gmock.h -> /usr/include/gmock/gmock.h

$ ls -l /usr/src/gmock/src/gmock.cc 
lrwxrwxrwx 1 root root 23 Oct  8 21:34 /usr/src/gmock/src/gmock.cc -> /usr/src/gmock/gmock.cc

### gtest gets installed here by default, no need to symlink
$ ls -l /usr/src/gtest/src/gtest.cc 
-rw-r--r-- 1 root root 217839 Oct  1  2018 /usr/src/gtest/src/gtest.cc

Ah! Interesting. No error. I didn't expect that, and was pretty sure I did this up above. That said, printing out the includes from that function did leave me puzzled. Note lines 258-259:

set(_gmock_include_paths "${include_path}/gmock")
set(_gmock_source_paths "${src_path}/gmock/src")
# ...
_catkin_find_google_source("gmock" "${_gmock_include_paths}"
                             "${_gmock_source_paths}" _gmock_found
                             _gmock_base_dir _gmock_include_dir _gmock_lib_dir
                             _gmock_libs _gmock_main_libs)

In my message() call above from within function(_catkin_find_google_source type include_paths...), it looks to have been passed include_paths=${_gmock_include_paths}, which looks to include ${include_path}/gmock. But only /usr/include was printed out. So, this issue looks like two issues:

  • arch linux needs to add /usr/src/gmock/src/{gmock-all.cc, gmock.cc, gmock_main.cc} to their package.
  • I think /usr/include/{gmock, gtest}/{gmock, gtest}.h seems like a reasonable location for these files. What about a PR to add those to the include paths in catkin?
  • I also think it's odd to have /usr/src/gmock in _gmock_include_paths (if it was in _gmock_source_paths, arch's default gmock location would work), and /usr/include is in there twice (should one have been /usr/include/gmock?). How about a bonus PR to clean that up, if possible?

@dirk-thomas
Copy link
Member

I think /usr/include/{gmock, gtest}/{gmock, gtest}.h seems like a reasonable location for these files. What about a PR to add those to the include paths in catkin?

These are the exact paths used by the Debian package googletest: see https://packages.ubuntu.com/bionic/amd64/googletest/filelist As far as I can see the headers are already being found in those locations so I don't understand what your PR would contain?

I also think it's odd to have /usr/src/gmock in _gmock_include_paths

Maybe that was necessary for versions of googletest which ship only the sources? If you want to remove something like this it would need to be thoroughly tested that it doesn't break any use case (on Ubuntu, on Debian, different version of googletest, from-source, etc.)

and /usr/include is in there twice (should one have been /usr/include/gmock?)

Please use references to exact lines of code otherwise I am unable to follow your argument.

How about a bonus PR to clean that up, if possible?

Please feel free to propose any kind of PR. Only when seeing the actual proposed diff I can give you concrete feedback.

[As mentioned above please make sure to do thorough testing of any changes - often it is hard to justify the necessary testing effort for "just cleaning up something".]

@jwhendy
Copy link
Author

jwhendy commented Oct 9, 2019

As far as I can see the headers are already being found in those locations so I don't understand what your PR would contain?

Well, something is awry, as even after fixing the *.cc files, I indeed had the .h files in the respective /usr/include/{gmock, gtest}/{gmock, gtest}.h locations and they were not found. I can't explain the results on debian.

Maybe that was necessary for versions of googletest which ship only the sources?

Maybe, but I think it could be an accident based on findings below.

Please use references to exact lines of code otherwise I am unable to follow your argument.

I thought I did? The bullet you're commenting on was a closing summary based on the code and output I'd already laid out, including both linked lines and copy/pasted chunks. To summarize again: my observation was that printing out the include_paths argument passed to catkin_find_google_source() (here) didn't show /usr/include/gmock, but that is what _gmock_include_paths appears to be set to (here) when it's passed (here).

I did make a potential breakthrough while writing this. Here was an experiment on this function just to make sure the passed path was really what I thought:

#Find GMock
  set(_gmock_include_paths "${include_path}/gmock/whammy") ### I changed this line
  set(_gmock_source_paths "${src_path}/gmock/src")
  # ...
  _catkin_find_google_source("gmock" ${_gmock_include_paths}"
                             "${_gmock_source_paths}" _gmock_found
                             _gmock_base_dir _gmock_include_dir _gmock_lib_dir
                             _gmock_libs _gmock_main_libs)

I then added output to the function called:

# Internal function for finding gtest or gmock sources
function(_catkin_find_google_source type include_paths
  # ...
  message("### ${include_paths}")
  message("### ${src_paths}")

Output:

### /usr/include;/usr/src/gmock/whammy
### /usr/src/gmock/src

How is /usr/src/gmock/whammy getting in there vs. the expected /usr/include/gmock/whammy?

I tracked it down to this:

if(NOT GMOCK_FOUND OR NOT GTEST_FOUND)
  # ...
    set(_include_paths "/usr/include" "/usr/src")
    set(_source_paths "/usr/src")

Removing the /usr/src allowed me to git rid of /usr/include/{gtest, gmock}.h and build successfully. I assume this is a mistake, either to have /usr/src there at all, or not using whatever cmake mechanism is necessary to set this as a list.

I now get this as the only relevant build output:

-- Forcing gtest/gmock from source, though one was otherwise available.
-- Found gtest sources under '/usr/src/gmock': gtests will be built
-- Found gmock sources under '/usr/src/gmock': gmock will be built

Now that I had a culprit, it explains the behavior I commented on above as well. By default, these are the paths passed to _catkin_find_google_source():

### /usr/include;/usr/src/gtest;/usr/include;/usr/src/googletest/googletest/include/gtest
### /usr/src/gtest/src;/usr/src/googletest/googletest/src
### /usr/include;/usr/src/gmock;/usr/include;/usr/src/googletest/googlemock/include/gmock
### /usr/src/gmock/src;/usr/src/googletest/googlemock/src

As observed in a previous comment, /usr/include/ is in there twice, which doesn't make any sense. Removing the trailing /usr/src entry here results in:

### /usr/include/gtest;/usr/include/googletest/googletest/include/gtest
### /usr/src/gtest/src;/usr/src/googletest/googletest/src
### /usr/include/gmock;/usr/include/googletest/googlemock/include/gmock
### /usr/src/gmock/src;/usr/src/googletest/googlemock/src

Thoughts based on this?

For the src issues, I could see having arch to match debian, but could also see adding the path here. Is there a preference?

#Find GTest
  set(_gtest_include_paths "${include_path}/gtest")
  set(_gtest_source_paths "${src_path}/gtest/src")
  list(APPEND _gtest_include_paths "${include_path}/googletest/googletest/include/gtest")
  list(APPEND _gtest_source_paths "${src_path}/googletest/googletest/src")
  ### add this, and analog for gmock
  list(APPEND _gtest_source_paths "${src_path}/gtest")  

For the include issues, I don't know cmake well enough to understand why /usr/src was in the include_path. The change came with #1022 where it went from /usr/include/ to both paths

I'd propose either removing it or using list(APPEND) instead of set(foo bar).


Aside: is there a list of distros you ROS requires testing on before merging a PR? You stressed testing a couple times above, but in this case #1022 looks to have complicated things. In the end, it was probably that arch doesn't have /usr/src/gmock/src/*.cc and I only replicated /usr/src/gmock/*, not /usr/src/gmock/src/* in my previous attempt. Trying since #1022 brought about the path issue, so now there were two issues to debug.

I plan to hunt down the full story of what happened since 0.7.18 and now, then can post back with PR proposals.

@dirk-thomas
Copy link
Member

The change came with #1022 where it went from /usr/include/ to both paths

Maybe @sloretz can comment on that who authored that change.

@dirk-thomas
Copy link
Member

is there a list of distros you ROS requires testing on before merging a PR?

Since catkin is the most low level package in ROS 1 the list of platforms a change can break is basically any platform someone might be building ROS on. That is why any change needs to be really clear why it is necessary and we need to be convinced that it doesn't break any potential use case.

@jwhendy
Copy link
Author

jwhendy commented Oct 9, 2019

Maybe @sloretz can comment on that who authored that change.

It looks like he did, and then you merged it. I don't see any discussion of testing at all, nor does it look to refer to any issues so I'm not sure what specific issues prompted this.

I'm digging through internals more and am a bit out of my league to know what, exactly, needs fixing. I undid all my system changes, so I am back to the default file locations for gmock and gtest on arch linux.

My intuition was to change _include_paths to a list and append /usr/src vs. setting them at the same time. So, I started by changing this line from this:

    set(_include_paths "/usr/include" "/usr/src")

... to this:

    set(_include_paths "/usr/include")
    list(APPEND _include_paths "/usr/src")

I'm not sure what the desired outcome was, but /usr/include/{gmock,gtest} seems like it should be included, but the package-specific dir here is only appended to the last path.

Doing some output testing by modifying the code here:

    set(_include_paths "/usr/include" "/usr/src")
    set(_gmock_include_paths "${_include_paths}/gmock")
    message("### _gmock_include_paths: ${_gmock_include_paths}")
    ### _gmock_include_paths: /usr/include;/usr/src/gmock

Now, when I fix that to point at /usr/include/gmock, I get another error:

CMake Error at /home/jwhendy/catkin_ws/src/catkin/cmake/test/gtest.cmake:344 (add_subdirectory):
  The source directory

    /usr/src

  does not contain a CMakeLists.txt file.
Call Stack (most recent call first):
  cmake/all.cmake:164 (include)
  CMakeLists.txt:8 (include)


CMake Error at /home/jwhendy/catkin_ws/src/catkin/cmake/test/gtest.cmake:346 (set_target_properties):
  set_target_properties Can not find target to add properties to: gtest
Call Stack (most recent call first):
  cmake/all.cmake:164 (include)
  CMakeLists.txt:8 (include)


CMake Error at /home/jwhendy/catkin_ws/src/catkin/cmake/test/gtest.cmake:349 (set_target_properties):
  set_target_properties Can not find target to add properties to: gmock
Call Stack (most recent call first):
  cmake/all.cmake:164 (include)
  CMakeLists.txt:8 (include)


make: *** [Makefile:390: cmake_check_build_system] Error 1

Starting with the first, it's this line. Printing out the directories:

    message("### ${base_dir} ${gtest_lib_dir}")
    ### /usr/src /home/jwhendy/catkin_ws/build/catkin/gtest

I would not expect CMakeLists.txt in /usr/src either. If I manually change it to /usr/src/gtest, it goes away. Then I get an error at this line.

CMake Error at /home/jwhendy/catkin_ws/src/catkin/cmake/test/gtest.cmake:349 (set_target_properties):
  set_target_properties Can not find target to add properties to: gmock

Adding some messages yields:

    message("### ${gtest_libs} ${gtest_main_libs}")
    message("### ${gmock_libs} ${gmock_main_libs}")
    ### gtest gtest_main
    ### gmock gmock_main

So, we're back to the filesystem woes:

# all good for gtest, hence no error
$ ls /usr/src/gtest/src/
gtest-all.cc  gtest.cc  gtest-death-test.cc  gtest-filepath.cc  gtest-internal-inl.h  gtest_main.cc  gtest-port.cc  gtest-printers.cc  gtest-test-part.cc  gtest-typed-test.cc

# booo
$ ls /usr/src/gmock/src
ls: cannot access '/usr/src/gmock/src': No such file or directory

So, I think one could make the case that arch should align these two packages to have the same src location.

I still think something is off, though. If I change this line to this:

set(_gmock_source_paths "${src_path}/gmock")

That error still exists, even though that's where the files are. I then copied *.cc to /usr/src/gmock/src but am still getting the same error:

### gmock gmock_main
CMake Error at /home/jwhendy/catkin_ws/src/catkin/cmake/test/gtest.cmake:348 (set_target_properties):
  set_target_properties Can not find target to add properties to: gmock

That's where I'll leave it for now. I feel extremely inefficient in tracking this down and there appears to be at least a couple independent sets of paths maintained depending on what goes hunting for gtest/gmock. This might make sense to someone, but I'm pretty confused on what ultimately needs to be found, which paths match up to what and for what purpose, and what's now breaking. This isn't the behavior I got yesterday and now I don't seem to be able to replicate my eventual success! Out of time for the day...

@dirk-thomas
Copy link
Member

started by changing this line from this:

    set(_include_paths "/usr/include" "/usr/src")

... to this:

    set(_include_paths "/usr/include")
    list(APPEND _include_paths "/usr/src")

Both code snippets are producing the very same result in CMake. Your code change is a no op. The variable was before and is afterwards a list with two paths.

@sloretz
Copy link
Contributor

sloretz commented Oct 10, 2019

@jwhendy I'm unable to reproduce using this Dockerfile, but I'm not familiar with arch so I probably I made a mistake. Mind showing me what the correct steps are?

FROM archlinux/base

RUN pacman -Sy --noconfirm base-devel

# Add a user to build stuff
RUN useradd ros --create-home

# give user passwordless sudo access
RUN echo "ros ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers

# Get yay
RUN pacman -Sy --noconfirm git go \
 && cd /tmp \
 && sudo -u ros git clone https://aur.archlinux.org/yay.git \
 && cd yay \
 && sudo -u ros makepkg -si --noconfirm

# Install ros-melodic-catkin with modifications to use 0.7.19
RUN sudo -u ros yay --useask -S --noconfirm gmock gtest python python-catkin_pkg python-empy python-nose ros-build-tools-py3 cmake \
 && cd /tmp \
 && sudo -u ros git clone https://github.com/ros-melodic-arch/ros-melodic-catkin.git \
 && cd ros-melodic-catkin \
 && sed -i.bak 's/0.7.18/0.7.19/g' .SRCINFO \
 && sed -i.bak 's/0.7.18/0.7.19/g' PKGBUILD \
 && sed -i.bak 's/b6a7428944911a011b0c3b0e465f2db04d219ce5f72cf3e2f76194dd055f1f49/b83d66640df99f72bc37160e8b60a76df6c87ff8dcbb9ab096911c44f08d13e1/' .SRCINFO \
 && sed -i.bak 's/b6a7428944911a011b0c3b0e465f2db04d219ce5f72cf3e2f76194dd055f1f49/b83d66640df99f72bc37160e8b60a76df6c87ff8dcbb9ab096911c44f08d13e1/' PKGBUILD \
 && sudo -u ros makepkg -si --noconfirm

# Try to build realtime tools
RUN sudo -u ros yay --useask -S --noconfirm ros-build-tools-py3 ros-melodic-realtime-tools

I guess this being at the end of the output means it succeeded?

Packages (1) ros-melodic-realtime-tools-1.13.1-0

Total Installed Size:  0.19 MiB

:: Proceed with installation? [Y/n] 
checking keyring...
checking package integrity...
loading package files...
checking for file conflicts...
checking available disk space...
:: Processing package changes...
installing ros-melodic-realtime-tools...
:: Running post-transaction hooks...
(1/1) Cleaning up package cache...

The package seems to exist

[root@62545e10fc86 /]# . /opt/ros/melodic/setup.bash
[root@62545e10fc86 /]# rospack find realtime_tools
/opt/ros/melodic/share/realtime_tools

@jwhendy
Copy link
Author

jwhendy commented Nov 15, 2019

@dirk-thomas follow-up on the src warnings. As mentioned above, this line in the default gmock CMakeLists.txt does not work:

# A directory to find Google Test sources.
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/gtest/CMakeLists.txt")
  set(gtest_dir gtest)
else()
  set(gtest_dir ../googletest)
endif()

With this default, I get:

Starting  >>> catkin                                                                                                                                                                     
_________________________________________________________________________________________________________________________________________________________________________________________
Errors     << catkin:check /home/jwhendy/catkin_ws/logs/catkin/build.check.002.log                                                                                                       
CMake Warning at /usr/src/gmock/CMakeLists.txt:37 (project):
  VERSION keyword not followed by a value or was followed by a value that
  expanded to nothing.


CMake Error at /usr/src/gmock/CMakeLists.txt:47 (add_subdirectory):
  add_subdirectory given source "../googletest" which is not an existing
  directory.


CMake Error at /usr/src/gmock/CMakeLists.txt:59 (config_compiler_and_linker):
  Unknown CMake command "config_compiler_and_linker".


make: *** [Makefile:446: cmake_check_build_system] Error 1

I didn't know what to make this, so I guessed ../gtest instead. That does build, but leads to a warning for every package like this:

Starting  >>> catkin                                                                                                                                                                     
_________________________________________________________________________________________________________________________________________________________________________________________
Warnings   << catkin:check /home/jwhendy/catkin_ws/logs/catkin/build.check.003.log                                                                                                       
CMake Warning at /usr/src/gmock/CMakeLists.txt:37 (project):
  VERSION keyword not followed by a value or was followed by a value that
  expanded to nothing.


CMake Warning (dev) at /usr/src/gmock/CMakeLists.txt:47 (add_subdirectory):
  Policy CMP0013 is not set: Duplicate binary directories are not allowed.
  Run "cmake --help-policy CMP0013" for policy details.  Use the cmake_policy
  command to set the policy and suppress this warning.

  The binary directory

    /home/jwhendy/catkin_ws/build/catkin/gtest

  is already used to build a source directory.  This command uses it to build
  source directory

    /usr/src/gtest

  which can generate conflicting build files.  CMake does not support this
  use case but it used to work accidentally and is being allowed for
  compatibility.
This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Warning at /usr/src/gtest/CMakeLists.txt:47 (project):
  VERSION keyword not followed by a value or was followed by a value that
  expanded to nothing.

I'm guessing the proposal would be to take this up with googletest and arch?

Edit: for clarification, arch doesn't ship with a /usr/src/gmock/CMakeLists.txt for whatever reason. So, it will break using the default package, then also break of you google around for what to do about this missing file (i.e. download it), and give warnings when I do the above.

@sloretz
Copy link
Contributor

sloretz commented Nov 16, 2019

I don't understand all of the gtest/gmock logic, but I had a look through it. Hopefully this is useful. IIUC catkin first tries to decide whether to find_package() GTest/GMock, or build it from source. If it decides the latter, then it tries to build from source in the same project.

#1022 is supposed to just refactor the logic that makes the decision (catkin was choosing to use GTest from the find module when it should have built gtest/gmock from source), but as reported by @mikepurvis it seems to have broken the code that builds gtest/gmock on Xenial. #1040 doesn't touch the decision logic, but instead fixes the finding of gtest/gmock sources on Jessie/Xenial.

Neither #1022 or #1040 address Arch (this ticket). I don't know if it's the decision logic or the code that finds gtest/gmock sources that needs to be fixed for Arch, but I suspect it's the latter based on @jwhendy's note:

Edit: for clarification, arch doesn't ship with a /usr/src/gmock/CMakeLists.txt for whatever reason.

If it got that far then there weren't find modules for both GTest and GMock, so it tried to build from source. The logic to build gtest/gmock assumes there is a CMakeLists.txt and calls add_subdirectory() to make the build of gtest/gmock happen. I'm not sure about using add_subdirectory() as the tool for building gtest/gmock, but it seems to be recommended by googletest. For that to succeed, there must a directory containing a CMakeLists.txt for gtest and and another directory containing a CMakeLists.txt for gmock.

IIUC catkin_find_google_test_source() is supposed to find a directory containing a CMakeLists.txt for gtest or gmock. It does this by looking for source code, and then assumes a directory above that will have a CMakeLists.txt, which is returned as base_dir and given to add_subdirectory(). I don't know why it doesn't look for CMakeLists.txt directly. I don't know why it looks for the header files and sets GTEST/GMOCK_INCLUDE_DIRS directly. I would think header file locations could be retrieved from targets or variables after the call to add_subdirectory().

IIUC the locations catkin_find_google_test_source() should come up with for base_dir are these directories:

gtest CMakeList.txt:

gmock CMakeList.txt:

@sloretz
Copy link
Contributor

sloretz commented Nov 16, 2019

Actually, it looks even more complicated. It looks like catkin_find_google_test_source() returns only a single base directory for both gtest and gmock depending on what sources are found. For stretch/bionic/buster it looks like this is /usr/src/googletest/CMakeLists.txt. For jessie/xenial, I'm not sure. It looks like it uses the gmock CMakeLists.txt? Is there an assumption that gmock provides gtest too?

@sloretz
Copy link
Contributor

sloretz commented Nov 16, 2019

Reopening since I don't think #1040 is expected to resolve the issue on Arch.

@sloretz sloretz reopened this Nov 16, 2019
@jwhendy
Copy link
Author

jwhendy commented Nov 16, 2019

Thanks for the analysis @sloretz ! I think at this point, the catkin related things are solved and this is on me to take up with arch. That said, I still feel out of my league so any pointers on what might be awry on arch would still be highly appreciated (even though this could probably be closed as unrelated now).

Thus far:

  • for sure we need /usr/src/gmock/src/*.cc to exist (hope to accomplish via this bug request)
  • ideally, include a functioning CMakeLists.txt with the gmock package

For arch's files,

  • gtest: usr/src/gtest/CMakeLists.txt
  • none shipped with gmock

I tried this file from Ubuntu Trusty and no longer get the errors. It points to a ../gtest directory, but bionic points to ../googletest. Diffing vs. the default file from google has quite a bit of differences. I'm not sure how custom these files are to the distribution or what.

@liborw
Copy link

liborw commented Dec 2, 2019

Hi, here is a PKGBUILD for the googletest that I have used to install both gtest and gmock version 1.8.1, which hopefully provides all the necessary files in order to be found by catkin. The realtime-tools then compile without problems.

There is just small problem that there is no VERSION in the CMakeLists and catkin is complaining.

@mikepurvis
Copy link
Member

@liborw Can you try again as of #1052, and see if the VERSION-related warning is now silenced?

@acxz
Copy link
Contributor

acxz commented Feb 25, 2020

Should be resolved with the merge of this PR: anthraxx/arch-pkgbuilds#33. Since no change needs to be made in this codebase, feel free to close this issue.

@dirk-thomas
Copy link
Member

Since no change needs to be made in this codebase, feel free to close this issue.

Sounds good to me. Please feel free to comment on the closed ticket and it can be reopened if necessary.

@acxz
Copy link
Contributor

acxz commented Feb 26, 2020

Did some more thorough testing and even though catkin now builds on Arch with the above linked PR, realtime-tools still does not. Sorry for the haste, request to reopen this issue.

@dirk-thomas dirk-thomas reopened this Feb 26, 2020
@jwhendy
Copy link
Author

jwhendy commented Feb 26, 2020

@acxz any notable error messages you could post?

@acxz
Copy link
Contributor

acxz commented Feb 26, 2020

The error message is the exact same as in the OP. When I install catkin it identifies gmock and gtest but when I want to use those catkin cmake functions it chokes. Sadly I don’t have time to spend on this further. One thing I want to try once I do get some time or if someone wants to PR, is change how gtest/gmock is installed on Arch to exactly match the ubuntu package hierarchy. If that doesn’t fix it, I’ll admit defeat.

@jwhendy
Copy link
Author

jwhendy commented Feb 26, 2020

Ok, just trying to understand and I can look into this later this week/weekend.

For reference, can you?

ls /usr/src/gmock/src

@acxz
Copy link
Contributor

acxz commented Feb 26, 2020

acxz@archard ~ (git)-[master] % ls /usr/src/gmock/src
gmock.cc      gmock-cardinalities.cc   gmock-matchers.cc       gmock_main.cc
gmock-all.cc  gmock-internal-utils.cc  gmock-spec-builders.cc

@jjaaseon
Copy link

jjaaseon commented Mar 6, 2020

I recently encountered the same problem on Manjaro.

I manually compiled ros-melodic-realtime-tools and found that the problem was GMOCK_MAIN_LIBRARIES . CATKIN_ENABLE_TESTING is "ON" while GMOCK_MAIN_LIBRARIES was empty. Then I checked the CMake Module and found that FindGTest is already shipped with CMake but not FindGMock.

Here is my solution:

  • Take the FindGMock.cmake script from the net (e.g.,FindGMock.cmake) and copy that script into my project.
  • Then add the following in the PKGBUILD of the ros-melodic-realtime-tools
    -DCMAKE_MODULE_PATH=/FindGMock.cmake/Modules/Path
  • Then use makepkg to compile manually, and finally succeeded!

Hope it would help.

@acxz
Copy link
Contributor

acxz commented Mar 15, 2020

@liborw you mentioned that your PKGBUILD solves building realtime-tools, but I tested it out and it did not work for me.

@acxz
Copy link
Contributor

acxz commented Mar 15, 2020

I recreated the Ubuntu installation of gtest and gmock as shown here. You can see my attempts here at the AUR gtest-py3/gmock-py3 package.
However, I was still unsuccessful.

@acxz
Copy link
Contributor

acxz commented Mar 15, 2020

@jiaaseon mentioned something important that the GMOCK_MAIN_LIBRARIES variable is empty. Based on that advice I am patching the AUR package for realtime-tools to not test if that variable is empty. ros-melodic-arch/ros-melodic-realtime-tools#5

Also submitted a PR to realtime-tools with the patch: ros-controls/realtime_tools#55

@acxz
Copy link
Contributor

acxz commented Jul 9, 2020

Finally got around to resolving this. Submitted a patch to the Arch Linux repos to get gtest updated to 1.10.0 and restructure the installed files based on upstream recommendations. Just need to add one more path for the googletest sources see above linked PR in catkin's gtest.cmake and we good to go.

@SomePersonSomeWhereInTheWorld
Copy link

SomePersonSomeWhereInTheWorld commented Sep 4, 2020

I'm seeing this on Fedora 32 with ROS Noetic as well. Which fix works?

rpm -qa|grep gtest
gtest-1.10.0-1.fc32.x86_64
gtest-devel-1.10.0-1.fc32.x86_64
-- ==> add_subdirectory(realtime_tools)
CMake Warning at /root/ros_catkin_ws/install_isolated/share/catkin/cmake/test/gtest.cmake:160 (message):
  skipping gmock 'realtime_box_tests' in project 'realtime_tools' because
  gmock was not found
Call Stack (most recent call first):
  /root/ros_catkin_ws/install_isolated/share/catkin/cmake/test/gtest.cmake:89 (_catkin_add_executable_with_google_test)
  /root/ros_catkin_ws/install_isolated/share/catkin/cmake/test/gtest.cmake:63 (_catkin_add_google_test)
  realtime_tools/CMakeLists.txt:23 (catkin_add_gmock)

CMake Error at realtime_tools/CMakeLists.txt:24 (target_link_libraries):
  Cannot specify link libraries for target "realtime_box_tests" which is not
  built by this project.

-- Configuring incomplete, errors occurred!
See also "/root/catkin_ws/build/CMakeFiles/CMakeOutput.log".
See also "/root/catkin_ws/build/CMakeFiles/CMakeError.log".
make: *** [Makefile:284: cmake_check_build_system] Error 1
Invoking "make cmake_check_build_system" failed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants