3

I'm running into a CMake issue that I am a little stumped by. It involves a CMake project that builds dependencies for an application I develop at work. I now have to add a new dependency, libnest2d, which itself also has three dependencies, of which some are also new.

To get libnest2d to build I have this ExternalProject_Add call:

ExternalProject_Add(libnest2d
    GIT_REPOSITORY https://github.com/tamasmeszaros/libnest2d.git
    GIT_TAG da4782500da4eb8cb6e38e5e3f10164ec5a59778
    CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
               -DCMAKE_PREFIX_PATH=${CMAKE_INSTALL_PREFIX}
               -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
    DEPENDS BoostHeaders nlopt Clipper
)

This project depends on the Boost Headers, NLopt and Clipper. Those Boost headers and Clipper are fine, but it somehow complains about NLopt with the following errors:

CMake Error at /usr/share/cmake-3.16/Modules/ExternalProject.cmake:2962 (get_property):
  get_property could not find TARGET nlopt.  Perhaps it has not yet been
  created.
Call Stack (most recent call first):
  /usr/share/cmake-3.16/Modules/ExternalProject.cmake:3239 (_ep_add_configure_command)
  projects/libnest2d.cmake:5 (ExternalProject_Add)
  CMakeLists.txt:61 (include)


CMake Error at /usr/share/cmake-3.16/Modules/ExternalProject.cmake:2964 (get_property):
  get_property could not find TARGET nlopt.  Perhaps it has not yet been
  created.
Call Stack (most recent call first):
  /usr/share/cmake-3.16/Modules/ExternalProject.cmake:3239 (_ep_add_configure_command)
  projects/libnest2d.cmake:5 (ExternalProject_Add)
  CMakeLists.txt:61 (include)


CMake Error at /usr/share/cmake-3.16/Modules/ExternalProject.cmake:1783 (get_property):
  get_property could not find TARGET nlopt.  Perhaps it has not yet been
  created.
Call Stack (most recent call first):
  /usr/share/cmake-3.16/Modules/ExternalProject.cmake:2064 (ExternalProject_Get_Property)
  /usr/share/cmake-3.16/Modules/ExternalProject.cmake:2966 (_ep_get_step_stampfile)
  /usr/share/cmake-3.16/Modules/ExternalProject.cmake:3239 (_ep_add_configure_command)
  projects/libnest2d.cmake:5 (ExternalProject_Add)
  CMakeLists.txt:61 (include)


CMake Error at /usr/share/cmake-3.16/Modules/ExternalProject.cmake:1785 (message):
  External project "nlopt" has no stamp_dir
Call Stack (most recent call first):
  /usr/share/cmake-3.16/Modules/ExternalProject.cmake:2064 (ExternalProject_Get_Property)
  /usr/share/cmake-3.16/Modules/ExternalProject.cmake:2966 (_ep_get_step_stampfile)
  /usr/share/cmake-3.16/Modules/ExternalProject.cmake:3239 (_ep_add_configure_command)
  projects/libnest2d.cmake:5 (ExternalProject_Add)
  CMakeLists.txt:61 (include)

So it states that the nlopt target is not defined. However that target is defined using another ExternalProject_Add call, the same as the other two dependencies:

ExternalProject_Add(nlopt
    GIT_REPOSITORY https://github.com/stevengj/nlopt.git
    GIT_TAG v2.6.2
    CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
               -DCMAKE_PREFIX_PATH=${CMAKE_INSTALL_PREFIX}
               -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
)

ExternalProject_Add(BoostHeaders
    URL http://sourceforge.net/projects/boost/files/boost/1.67.0/boost_1_67_0.tar.bz2
    URL_HASH SHA1=694ae3f4f899d1a80eb7a3b31b33be73c423c1ae
    CONFIGURE_COMMAND ""
    BUILD_COMMAND ""
    INSTALL_COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_CURRENT_BINARY_DIR}/BoostHeaders-prefix/src/BoostHeaders/boost" "${CMAKE_INSTALL_PREFIX}/include/boost"
)

ExternalProject_Add(Clipper
    URL https://sourceforge.net/projects/polyclipping/files/clipper_ver6.4.2.zip
    URL_HASH SHA1=b05c1f454c22576f867fc633b11337d053e9ea33
    SOURCE_SUBDIR cpp
    CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
               -DCMAKE_PREFIX_PATH=${CMAKE_INSTALL_PREFIX}
               -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
)

Without the NLopt dependency, libnest2d builds fine (since I still have the dependency installed on my local system), but there is no guarantee that NLopt is built and installed before starting on libnest2d, and indeed this goes wrong if I execute this build in a VM with multiple threads.

If I temporarily remove the nlopt dependency and call cmake .. && make help then I see that nlopt is one of the available targets. I can also call make nlopt and it starts building NLopt as expected.

You can view my entire source code here: https://github.com/Ultimaker/cura-build-environment/tree/CURA-7259_pynest2d . As of this writing I'm on commit 39298d203d115b60d7093f0a801be1bad0ba7842.

Other problems I've found have not been the same and don't provide a solution for me:

  • This related question has the same error but it seems to be caused by a tool that OP was using, which I'm not using.
  • This question and this bug report were a problem with a target that was disabled by a build option, which is not the case for me. The target clearly exists and I made no option to disable it.
  • There was an old bug that caused this but it was fixed in CMake 2.8. I'm using CMake 3.16.3.

So to summarize, how can I cause the libnest2d external project to depend on NLopt? Why are two dependencies accepted, but one isn't?

Ghostkeeper
  • 2,830
  • 1
  • 15
  • 27
  • "Perhaps it has not yet been created." - It seems you create `nlopt` target **after** `libnest2d` one. So, when call for `ExternalProject_Add` for `libnest2d` is parsed `nlopt` target is not created. Actually, I am not sure whether `file(GLOB _projects projects/*.cmake)` provides a specific order in the globbed files. – Tsyvarev Sep 28 '20 at 18:50
  • BTW, finding the above reason **requires** looking into the repo. This is not how Stack Overflow is expected to work: all important information should be in the question itself, not linked. I would suggest to read about [mcve] and next time prepare a question in that format. – Tsyvarev Sep 28 '20 at 18:54
  • I tried putting the list of .cmake files in the variable manually with nlopt before libnest2d, but it doesn't make a difference. Indeed the way in which CMake works is that it reads through all definitions first before resolving these dependencies, so the GLOB order doesn't matter. – Ghostkeeper Sep 28 '20 at 22:13
  • I attempted to give a minimum reproducible example but there's a difference between the three dependencies; Boost and Clipper work but NLopt doesn't. This is as small as I could make it while giving the information necessary to see that something is up with this library specifically. So I still included the other two dependencies; it's important to the story. – Ghostkeeper Sep 28 '20 at 22:16
  • "So I still included the other two dependencies; it's important to the story." - Have you tried to remove building of Boost and Clipper and reproduce your problem? If the problem remains without them, then they should be removed from the minimal example. Following the "story" has a little sense when prepare a minimal example. Look, you could just take 3 `CMakeLists.txt` files: main one with just two `include()` calls and ones in subdirectories which just performs `ExternalProject_Add` call. And that 3 `CMakeLists.txt` would perfectly fit into the question post. – Tsyvarev Sep 28 '20 at 23:45
  • I'll adjust the question to better reflect what I'd like to know then. Thanks for the feedback. – Ghostkeeper Sep 28 '20 at 23:56
  • You forgot to show top-level `CMakeLists.txt` which includes the ones you provide. Also, please update the error message for the code shown (that code reproduces the problem, doesn't it?) – Tsyvarev Sep 29 '20 at 00:15

0 Answers0