CMake Boost linking problems - c++

I'm using Boost::Python and Boost::Asio writing my sources and next write CMakeLists.txt to create my own shared library from sources like that (a part of file):
`find_package(Boost REQUIRED COMPONENTS python system thread regex)
if (Boost_FOUND)
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
endif()
find_package(PythonLibs 3 REQUIRED)
find_package(PythonInterp 3 REQUIRED)
if (PYTHONLIBS_FOUND)
include_directories(${PYTHON_INCLUDE_DIRS})
link_directories(${PYTHON_LIBRARIES})
endif()
add_library(my_lib SHARED ${MY_SOURCES})
set_target_properties(my_lib PROPERTIES PREFIX "" SUFFIX ".pyd")
target_link_libraries(my_lib ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})`
(As Boost::Asio is header-only library I added just system thread regex since I've found out it depends on it). So CMake results look correct:
-- Boost version: 1.65.0
-- Found the following Boost libraries:
-- python
-- system
-- thread
-- regex
-- chrono
-- date_time
-- atomic
-- Configuring done
-- Generating done
(But why is it searching for chrono etc.? Additional dependencies?)
Well, when I'm running make my_lib, there are some linker errors like: In function PyInit_my_lib: undefined reference to boost::python::detail::init_module(PyModuleDef&, void (*)()) and In function boost::asio::detail::posix_thread::~posix_thread():
/usr/local/include/boost/asio/detail/impl/posix_thread.ipp:35: undefined reference to pthread_detach
, so Boost wasn't linked properly.
I've read a lot of docs and similar questions, but couldn't understand what am I doing wrong.
P.S. When I disabled -Wl,--no-undefined linker option, linking was successful, but undefined references are still there and I can't import module using python.

Finally, the solution was found by myself. The problem was indeed Boost::Python wasn't built properly. I don't know completely was it a bug or my own fault, but in my case just editing Boost Build's user-config.jam for using python3.5 wasn't enough: running build script resulted to libboost_python3.so, but internally python2.7 interpreter was used by it for reasons unknown to me.
So, what I did is launched Boost initial bootstrapping as ./bootstrap.sh --with-python=/usr/bin/python3.5m, i.e. pointed the absolute path to required interpreter. After rebuilding Boost::Python, all symbols was resolved successfully.

Related

Using new tensorflow op in a c++ library that already uses tensorflow as third party

That's my first time asking a question in stackoverflow. I will try my best to formulate my question properly.
I want to use a custom tensorflow op in in a c++ library, which already uses tensorflow as third party. But I just don't know how to use my custom operation in c++ code at all. I'm trying to learn that with the easy ZeroOut example from Tensroflow c++ tutorial. I registered the ZeroOut op for cpu as in https://github.com/MatteoRagni/tf.ZeroOut.gpu: compiling with make worked and I got a .so file in the usr-ops folder, where also the cc file was. Then I tried to add the ZeroOut.so file to my lib as shared library, but it didn't compile. However, before I added my custom op, registered with bazel as described in tensorflow new op tutorial, in the same way and my library compiled. Maybe because the .so file was created in ../bazel-bin/tensorflow/core/user_ops/ . But in this case I'm not able to use the operation as I should. And including ZeroOut.cpp or the .cpp files of my op in my c++ files didn't make any difference until now.
Here is my CMakeList.txt, which also creates the whole library I'm working with:
cmake_minimum_required(VERSION 2.8)
project(Project1)
set(CMAKE_BUILD_TYPE "Release") # Debug Release
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -std=c++14 -O3 -Wall -fopenmp")
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
#-------------path of 3rd party libraries-------------
# special libs.
find_package(Boost COMPONENTS filesystem iostreams regex)
find_package(FFTW)
find_package(NLopt)
find_package(HDF5 COMPONENTS CXX)
set(EXTERN_LIB_ROOT ${PROJECT_SOURCE_DIR}/3rd-party)
set(TENSORFLOW_ROOT /.../tensorflow)
set(TF_INCLUDE_DIRS "${TENSORFLOW_ROOT}" "${TENSORFLOW_ROOT}/bazel- genfiles" "${TENSORFLOW_ROOT}/bazel-tensorflow/external/protobuf_archive/src")
# lib dirs.
set(LUA_LIBRARIES "${EXTERN_LIB_ROOT}/lua/liblua53.so") #5.3.4
set(LINENOISE_LIBRARIES "${EXTERN_LIB_ROOT}/linenoise-ng/build/liblinenoise.so")
set(YACAS_LIBRARIES "${EXTERN_LIB_ROOT}/yacas/cyacas/libyacas/build/libyacas.so")
set(TF_LIBRARIES ${TENSORFLOW_ROOT}/bazel-bin/tensorflow/libtensorflow_cc.so
${TENSORFLOW_ROOT}/tensorflow/core/user_ops/tf.ZeroOut.gpu-master/zero_out.so
${TENSORFLOW_ROOT}/bazel-bin/tensorflow/core/user_ops/MyNewOp.so)
#-------------ssl headers-------------
include_directories(${PROJECT_SOURCE_DIR}/src
${EXTERN_LIB_ROOT}/eigen
${EXTERN_LIB_ROOT}/gnuplot-iostream
${EXTERN_LIB_ROOT}/
${EXTERN_LIB_ROOT}/linenoise-ng/include
${EXTERN_LIB_ROOT}/yacas/cyacas/libyacas/include
${EXTERN_LIB_ROOT}/lua/src
${NLOPT_INCLUDE_DIRS}
${FFTW_INCLUDES}
${TF_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
${HDF5_INCLUDE_DIRS}
${TENSORFLOW_ROOT})
option(BUILD_SHARED_LIBS "build shared library" ON)
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
#-------------ssl kernel lib-------------
file(GLOB_RECURSE _src_list
LIST_DIRECTORIES false
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${PROJECT_SOURCE_DIR}/src/*.h" "${PROJECT_SOURCE_DIR}/src/*.cpp" "")
add_library(ssl SHARED ${_src_list})
set(SSL_LIBRARIES ${TF_LIBRARIES} ${LUA_LIBRARIES} ${Boost_LIBRARIES} ${NLOPT_LIBRARIES} ${FFTW_LIBRARIES} ${LINENOISE_LIBRARIES} ${YACAS_LIBRARIES} ${HDF5_CXX_LIBRARIES}) #${TF_LIBRARIES}
target_link_libraries(ssl ${SSL_LIBRARIES} dl)
add_executable(Project1 main.cpp)
target_link_libraries(Project1 ssl)
There is a related question, but there is no clear answer. How to run custom GPU tensorflow::op from C++ code?
What am I doing wrong? I have no experience in shared library, but maybe there are other better ways to do what I'm trying to do...?
Can someone help me, Maybe giving an example of the required CMakeList.txt?
About the errors I got at runtime:
it was a very trivial one, just the function in my .so file couldn't be found if called with the right amount of parameters, if called with the wrong one it just didn't run.
In the meanwhile I found a better workaround. Since I can use my custom op in python, I will embed python in my c++ library, call a python function to make the graph,which will call my custom op to build the graph. But I didn't finish yet.
Using pkg_config it becomes very simple:
cmake_minimum_required(VERSION 3.10)
project(tf-inference)
find_package(PkgConfig)
pkg_check_modules(TensorFlow REQUIRED tensorflow)
link_directories(${TensorFlow_LIBRARY_DIRS})
include_directories(${TensorFlow_INCLUDE_DIRS})
add_compile_definitions(${TensorFlow_CFLAGS_OTHER})
add_executable(tf-inference inference.cpp)
target_link_libraries(tf-inference ${TensorFlow_LIBRARIES})
However that requires your TensorFlow install has the tensorflow.pc file included. On MacOS: brew install libtensorflow will include this file, and the above works automatically.

Run-path dependent library cannot locate its dependency during linking stage of a programme build on linux

I have written a tutorial project whilst trying to understand the use of run-path dependent libraries on macOS and Linux. simpleapp depends on libmymaths, which in turn depends on libfastmatrix. libmymaths is a run-path dependent library and you can see the structure of the project here. I am trying to use the OS specific macros (#executable_path for macOS and $ORIGIN for linux) in order to allow the binaries to be easily moved around without breaking, since their location is going to be resolved during run-time and substituted in the macros. However, although what I've programmed so far works nicely on macOS, it doesn't on Linux. Specifically, I'm getting the following error during the linking stage of simpleapp (you can reproduce simply with ./run.sh):
/usr/bin/ld: warning: libfastmatrix.so, needed by /home/thomas/Developer/rpath_tutorial/libmymaths/libmymaths.so, not found (try using -rpath or -rpath-link)
In libmymaths' CMakeLists.txt I specify the rpath where its dependency (libfastmatrix) can be found, and that's verifiable with ldd libmymaths.so once libmymaths is built.
if(APPLE)
set(TOKEN "#loader_path")
elseif(UNIX AND NOT APPLE)
set(TOKEN "$ORIGIN")
endif()
set_target_properties(${PROJECT_NAME} PROPERTIES
CXX_STANDARD 11
CXX_EXTENSIONS FALSE
BUILD_WITH_INSTALL_RPATH TRUE
INSTALL_NAME_DIR "#rpath" # Necessary prior CMP0042 introduction.
INSTALL_RPATH "${TOKEN}/../libfastmatrix"
)
I have implemented the ld's suggestions as Fix 1 and Fix 2 in simpleapp's main CMake script, which allows the project to build.
# # Fix 1, -rpath-link (linux-specific ld option)
# LINK_FLAGS "-Wl,-rpath-link,${CMAKE_CURRENT_SOURCE_DIR}/../libfastmatrix/"
# # Fix 2, additional (unecessary for macOS) rpath, overwrites line 47
# INSTALL_RPATH "${TOKEN}/../libmymaths;${CMAKE_CURRENT_SOURCE_DIR}/../libfastmatrix"
However, this is against what I'm trying to achieve - make each library responsible for its own dependencies and not contaminate other projects with dependencies of dependencies.
1) What changes do I need to make to achieve my goal on Linux as I have done on macOS?
2) In case this is not feasible because the whole approach I am taking is incorrect, can you provide some proof or sources where this is documented?
I'm using:
CMake 3.5.1
ld 2.26.1
gcc 5.4.0
Thanks.
I do this with my game project. Here are the steps I use to make it work.
cmake_minimum_required(VERSION 3.5)
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_INSTALL_RPATH "$ORIGIN/lib/:$$ORIGIN/lib/")
endif()
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
install(TARGETS SpeedBlocks DESTINATION ${PROJECT_SOURCE_DIR}/build)
endif()
Note that I'm using a higher CMAKE version, so could be a bit different from what you need to do in 2.8.
After this I need to build the project, then run make install. The built binary will not have the RPATH set properly, but when I run make install (which basically just copies the binary and applies the RPATH from what I can tell) it gets set properly.
You can check if a binary has RPATH set properly by using
objdump -x path_to_binary_or_lib | grep RPATH
should output something like
RPATH $ORIGIN/lib/:$$ORIGIN/lib/:/usr/local/lib

how to get CMake to add MagickWand library linking automatically everywhere

I want to use CMake in my software that uses MagickWand.
CMake works on my machine and generates a useful Makefile.
On another machine, I have to manually add
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lMagickWand-6.Q16 -lMagickCore-6.Q16")
otherwise the linker can't find MagickWandGenesis() and other functions.
I found that -l flags via pkg-config --cflags --libs MagickWand.
Shouldn't CMake already generate linker flags for me with TARGET_LINK_LIBRARIES?
Did I miss something obvious, or why is this not working everywhere?
I have this code in CMakeLists.txt:
FIND_PACKAGE(ImageMagick
REQUIRED
COMPONENTS MagickWand
)
[...]
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_DEPTH=16")
[...]
INCLUDE_DIRECTORIES(
${Boost_INCLUDE_DIR}
${ImageMagick_INCLUDE_DIRS}
${ImageMagick_MagickWand_INCLUDE_DIRS}
)
[...]
TARGET_LINK_LIBRARIES(application_name
[...]
${Boost_LIBRARIES}
${CURL_LIBRARIES}
${ImageMagick_LIBRARIES}
${ImageMagick_MagickWand_LIBRARY}
)
That last ${ImageMagick_MagickWand_LIBRARY} shouldn't even be necessary.
Using Magick 6.8.9.9, CMake 3.0.2 on both machines (Debian Jessie).
Short answer: the package ImageMagick is buggy.
Looking in CMake's sources, the REQUIRED mechanism is handled exclusively through the variable package-_FOUND, independently of the required components.
Looking in the package ImageMagick here, ImageMagick_FOUND is set as follows:
set(ImageMagick_FOUND ${IMAGEMAGICK_FOUND})
But IMAGEMAGICK_FOUND is not set anywhere in the package, so the call will always unset ImageMagick_FOUND, and it will always be evaluated to true (not actively set to false), wether or not the components are effectively found.
You can either debug the package (and propose a pull request) or check the component variable:
if(NOT ImageMagick_MagickWand_FOUND)
message(FATAL_ERROR "MagickWand not found")
endif()
I guess the test will fail on your second machine.
By the way, you should only use ImageMagick_INCLUDE_DIRS and ImageMagick_LIBRARIES to link to the library (the ImageMagick_MagickWand* variables are here redundant). If you choose to debug the package, you may also declare imported targets.
Figured it out, despite the output of
MESSAGE(${ImageMagick_FOUND})
MESSAGE(${ImageMagick_INCLUDE_DIRS})
MESSAGE(${ImageMagick_LIBRARIES})
MESSAGE(${ImageMagick_MagickWand_FOUND})
MESSAGE(${ImageMagick_MagickWand_INCLUDE_DIRS})
MESSAGE(${ImageMagick_MagickWand_LIBRARY})
being identical, the installed packages differed. I installed the magick-dev packages via virtual packages in aptitude, which for some reason used the graphicsmagick suite for some packages (a imagemagick fork) instead of the original imagemagick suite.
For reference, the used aptitude search one-liner was aptitude search 'magick ?installed' | sort which listed three graphicsmagick packages on the second machine where imagemagick packages were on the first machine.

where can I find the list of boost component that I can use in cmake?

I have a cmake file that adds boost like this:
if(ADD_BOOST)
#add boost library
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_STATIC_RUNTIME ON)
file(TO_CMAKE_PATH $ENV{BOOST_ROOT} BOOST_ROOT)
if (MSVC)
set(BOOST_LIBRARYDIR ${BOOST_ROOT}/lib64-msvc-12.0)
else (MSVC)
set(BOOST_LIBRARY_DIR $ENV{BOOST_ROOT})
endif (MSVC)
find_package(Boost COMPONENTS filesystem system program-options thread REQUIRED)
endif (ADD_BOOST)
I have this line:
find_package(Boost COMPONENTS filesystem system program-options thread REQUIRED)
I want to use program-option libabray from boost. what name should I add to the above list?
where can I find the list of boost library that I can use in above mentioned line in cmake?
Create a dummy CMakeLists.txt:
cmake_minimum_required(VERSION 3.0)
project(dummy)
set(Boost_DEBUG ON)
find_package(Boost COMPONENTS ALL)
Then check the output of cmake .:
[...]
-- BoostConfig: discovered components: atomic;chrono;container;context;coroutine;date_time;exception;fiber;filesystem;graph;graph_parallel;headers;iostreams;locale;log;log_setup;math_c99;math_c99f;math_c99l;math_tr1;math_tr1f;math_tr1l;mpi;mpi_python;nowide;numpy;prg_exec_monitor;program_options;python;random;regex;serialization;stacktrace_addr2line;stacktrace_backtrace;stacktrace_basic;stacktrace_noop;system;test_exec_monitor;thread;timer;type_erasure;unit_test_framework;wave;wserialization
[...]
-- BoostConfig: Boost_ALL_TARGETS: Boost::headers;Boost::atomic;Boost::chrono;Boost::container;Boost::context;Boost::coroutine;Boost::date_time;Boost::exception;Boost::fiber;Boost::filesystem;Boost::graph;Boost::graph_parallel;Boost::iostreams;Boost::locale;Boost::log;Boost::log_setup;Boost::math_c99;Boost::math_c99f;Boost::math_c99l;Boost::math_tr1;Boost::math_tr1f;Boost::math_tr1l;Boost::mpi;Boost::mpi_python;Boost::nowide;Boost::numpy;Boost::prg_exec_monitor;Boost::program_options;Boost::python;Boost::random;Boost::regex;Boost::serialization;Boost::stacktrace_addr2line;Boost::stacktrace_backtrace;Boost::stacktrace_basic;Boost::stacktrace_noop;Boost::system;Boost::test_exec_monitor;Boost::thread;Boost::timer;Boost::type_erasure;Boost::unit_test_framework;Boost::wave;Boost::wserialization
[...]
Note that this can list components only if they are installed on your system. I got the above output after installing libboost 1.74 development files on Debian 11 (e.g. apt install libboost-all-dev=1.74.0.3).
Here is a prettified version of above output for future reference:
-- BoostConfig: discovered components:
atomic
chrono
container
context
coroutine
date_time
exception
fiber
filesystem
graph
graph_parallel
headers
iostreams
locale
log
log_setup
math_c99
math_c99f
math_c99l
math_tr1
math_tr1f
math_tr1l
mpi
mpi_python
nowide
numpy
prg_exec_monitor
program_options
python
random
regex
serialization
stacktrace_addr2line
stacktrace_backtrace
stacktrace_basic
stacktrace_noop
system
test_exec_monitor
thread
timer
type_erasure
unit_test_framework
wave
wserialization
-- BoostConfig: Boost_ALL_TARGETS:
Boost::headers
Boost::atomic
Boost::chrono
Boost::container
Boost::context
Boost::coroutine
Boost::date_time
Boost::exception
Boost::fiber
Boost::filesystem
Boost::graph
Boost::graph_parallel
Boost::iostreams
Boost::locale
Boost::log
Boost::log_setup
Boost::math_c99
Boost::math_c99f
Boost::math_c99l
Boost::math_tr1
Boost::math_tr1f
Boost::math_tr1l
Boost::mpi
Boost::mpi_python
Boost::nowide
Boost::numpy
Boost::prg_exec_monitor
Boost::program_options
Boost::python
Boost::random
Boost::regex
Boost::serialization
Boost::stacktrace_addr2line
Boost::stacktrace_backtrace
Boost::stacktrace_basic
Boost::stacktrace_noop
Boost::system
Boost::test_exec_monitor
Boost::thread
Boost::timer
Boost::type_erasure
Boost::unit_test_framework
Boost::wave
Boost::wserialization
On an Ubuntu system, for example, run:
aptitude show libboost-all-dev
Take a look at its "Depends" output. It lists the names of all boost components.
I want to use program-option libabray from boost. what name should I add to the above list?
Can you please clarify what you mean?
You have already added program-options to the line:
find_package(Boost COMPONENTS filesystem system program-options thread REQUIRED)
So you don't need to add anything else to the list of components in this line.
where can I find the list of boost library that I can use in above mentioned line in cmake?
Can you please clarify what you mean?
The list of libraries is available on https://www.boost.org/doc/libs/ .
Or check the sub-directories in include/boost or include/boost_1_68/boost directory, respectively, under your $BOOST_ROOT folder.
In fact the sub-directory names can be used as component names for the find_package(Boost COMPONENTS...) command. (Exception: Boost numpy, which is included in Boost python. See here.)
But if you wanted to know how to get the list of found boost components in CMake:
You can try the undocumented _Boost_IMPORTED_TARGETS variable (which is a CMake list).
Or you can try to hack with the documented Boost_LIBRARIES variable:
foreach(boost_lib IN LISTS Boost_LIBRARIES)
string(REGEX MATCH ".+/.*boost_([^-]+)-.+\.(lib|a)" boost_lib_name ${boost_lib})
set(boost_lib_name ${CMAKE_MATCH_1})
set(boost_target Boost::${boost_lib_name})
if(TARGET ${boost_target})
message(STATUS "Boost target found: " ${boost_target})
# Process ${boost_target} according to your needs...
endif(TARGET ${boost_target})
endforeach(boost_lib)
Note 1:
I tried these tips with CMake ver. 3.12.2 and boost 1.68.0. I tested the code in Windows only. Since different boost build variants can create the same library with different file names in boost/lib, this loop can find the same library more times.
Note 2:
This whole thing is weird a little bit, since you get back the list you just passed to find_package, so other simpler approaches can be better, like storing the initial list in a variable...

Building OpenCV 2.4.8 as a static library with static Qt 5.2.0 using cmake 2.8.12.1 on Linux (64bit)

[EDIT] I have now been able to make progress and build my project with OpenCV and all its dependencies linked in statically. I have tried to answer my questions (below) as well as I could, but there are still remaining questions.
In order to be able to link OpenCV into a library I am developing (a plugin for X-Plane fligt sim) I am building it as a static library using cmake's -DBUILD_SHARED_LIBS=OFF flag.
I also need the Qt GUI backend and at first I just had Qt shared libs installed on my system. OpenCV build did recognize these, but apparently they didn't get linked into OpenCV statically because I was getting undefined symbols at runtime in my app after linking against my built OpenCV libs. Why did the app not use the shared Qt libs?
I am assuming that when I link an object in statically it will only attempt to find its dependencies statically too, it won't try and go for shared libs on the system. I would still appreciate clarification in this point.
So, I figured I need to have static Qt libs and point the OpenCV build at them. Can you confirm this is correct thinking or possibly explain why not?
I was able to link shared libs (.so) into my app so the answer is no, I don't have to use static libraries when I want to link them into my application. Also OpenCV doesn't link Qt in so when you need the OpenCV Qt support in your application, you need to link Qt in yourself.
One important thing I got bitten by is that when linking the libraries must be presented to GCC linker in the order of their dependencies - always list dependencies of an object AFTER the object itself.*
So I built Qt 5.2.0 as static libs, installed on my system and pointed the OpenCV build at these with an environment variable: CMAKE_PREFIX_PATH=/usr/local/Qt-5.2.0
This worked at least partially, because I could see the new location being used by cmake, but I started getting the following cmake error:
CMake Error at cmake/OpenCVUtils.cmake:344 (foreach):
Syntax error in cmake code at
/home/martin/Work/Hack/libs/opencv-2.4.8/cmake/OpenCVUtils.cmake:344
when parsing string
${Qt5::Core_LIB_DEPENDS}
syntax error, unexpected cal_SYMBOL, expecting } (24)
Call Stack (most recent call first):
cmake/OpenCVModule.cmake:843 (ocv_split_libs_list)
cmake/OpenCVModule.cmake:886 (__ocv_track_module_link_dependencies)
CMakeLists.txt:544 (ocv_track_build_dependencies)
Would you know what is causing this error?
I abandoned trying to build OpenCV against static Qt5, so this is no longer relevant, and I haven't found an answer. Still may be of usse to others if osmeone knew what this problem is.
Below is the relevant part of the OpenCVModule.cmake file.
get_target_property(__module_type ${the_module} TYPE)
if(__module_type STREQUAL "STATIC_LIBRARY")
#in case of static library we have to inherit its dependencies (in right order!!!)
if(NOT DEFINED ${the_module}_LIB_DEPENDS_${optkind})
vvvvvvvvvv issue on the line below vvvvvvvvvvvvvvvvvv
ocv_split_libs_list(${the_module}_LIB_DEPENDS ${the_module}_LIB_DEPENDS_DBG ${the_module}_LIB_DEPENDS_OPT)
endif()
set(__resolved_deps "")
set(__mod_depends ${${the_module}_LIB_DEPENDS_${optkind}})
set(__has_cycle FALSE)
while(__mod_depends)
list(GET __mod_depends 0 __dep)
list(REMOVE_AT __mod_depends 0)
if(__dep STREQUAL the_module)
set(__has_cycle TRUE)
else()#if("${OPENCV_MODULES_BUILD}" MATCHES "(^|;)${__dep}(;|$)")
ocv_regex_escape(__rdep "${__dep}")
if(__resolved_deps MATCHES "(^|;)${__rdep}(;|$)")
#all dependencies of this module are already resolved
list(APPEND ${the_module}_MODULE_DEPS_${optkind} "${__dep}")
else()
get_target_property(__module_type ${__dep} TYPE)
if(__module_type STREQUAL "STATIC_LIBRARY")
if(NOT DEFINED ${__dep}_LIB_DEPENDS_${optkind})
ocv_split_libs_list(${__dep}_LIB_DEPENDS ${__dep}_LIB_DEPENDS_DBG ${__dep}_LIB_DEPENDS_OPT)
endif()
list(INSERT __mod_depends 0 ${${__dep}_LIB_DEPENDS_${optkind}} ${__dep})
list(APPEND __resolved_deps "${__dep}")
elseif(NOT __module_type)
list(APPEND ${the_module}_EXTRA_DEPS_${optkind} "${__dep}")
endif()
endif()
#else()
# get_target_property(__dep_location "${__dep}" LOCATION)
endif()
endwhile()