提交 671a630f 编写于 作者: S Samuel Martin 提交者: Maksim Shabunin

cmake/OpenCVGenPkgconfig.cmake: rework opencv.pc generation

Using absolute path to locate the components in the "Libs:" field of the
*.pc can badly break cross-compilation, especially when building
statically linked objects.

Indeed, pkg-config automatically replaces the '-I...' and '-L...' paths
when the PKG_CONFIG_SYSROOT_DIR and PKG_CONFIG_LIBDIR environment
variables are set [1]. This feature is very helpful and common in
cross-compilation framework like Buildroot [2,3].

When there are absolute paths in the *.pc files, pkg-config won't be
able to do the path substitutions for these paths when the
aforementioned environment variables are set.
In such case, since the prefix is the target one, not the sysroot one,
these libraries' absolute paths will point to:
- in the best case: a non-existing file (i.e. these files do not exists
  on the host system;
- at worst: the host system's libraries. This will make the linking
  failed because these host system's libraries will most likely not be
  build for the target architecture [4].

So, this patch replace the components' absolute paths by the form:
  -L<libdir> -l<libname>

This way, the linker will be able to resolve each dependency path,
whatever the kind of objects/build (shared object or static build) it
is dealing with.

Note that for static link, the library order does matter [5]. The order
of the opencv components has been carefully chosen to comply with this
requirement.

Fixes #3931

This patch is a port of [6] on the master branch.

[1] http://linux.die.net/man/1/pkg-config
[2] http://buildroot.org/
[3] http://git.buildroot.net/buildroot/tree/package/pkgconf/pkg-config.in
[4] http://autobuild.buildroot.net/results/e8a/e8a859276db34aff87ef181b0cce98916b0afc90/build-end.log
[5] http://stackoverflow.com/questions/45135/linker-order-gcc
[6] https://github.com/Itseez/opencv/commit/eceada586bbf18fc267e437522ec4f1f23ddc656Signed-off-by: NSamuel Martin <s.martin49@gmail.com>
上级 ef8182e1
......@@ -8,10 +8,6 @@
#
# ${BIN_DIR}/unix-install/opencv.pc -> For use *with* "make install"
# -------------------------------------------------------------------------------------------
set(prefix "${CMAKE_INSTALL_PREFIX}")
set(exec_prefix "\${prefix}")
set(libdir "") #TODO: need link paths for OpenCV_EXTRA_COMPONENTS
set(includedir "\${prefix}/${OPENCV_INCLUDE_INSTALL_PATH}")
if(CMAKE_BUILD_TYPE MATCHES "Release")
set(ocv_optkind OPT)
......@@ -35,44 +31,71 @@ ocv_list_reverse(OpenCV_LIB_COMPONENTS)
ocv_list_reverse(OpenCV_EXTRA_COMPONENTS)
#build the list of components
set(OpenCV_LIB_COMPONENTS_ "")
foreach(CVLib ${OpenCV_LIB_COMPONENTS})
if (TARGET ${CVLib})
get_target_property(libpath ${CVLib} LOCATION_${CMAKE_BUILD_TYPE})
get_filename_component(libname "${libpath}" NAME)
if(INSTALL_TO_MANGLED_PATHS)
set(libname "${libname}.${OPENCV_VERSION}")
endif()
# Note:
# when linking against static libraries, if libfoo depends on libbar, then
# libfoo must come first in the linker flags.
#need better solution....
if(libpath MATCHES "3rdparty")
set(installDir "share/OpenCV/3rdparty/${OPENCV_LIB_INSTALL_PATH}")
# world and contrib_world are special targets whose library should come first,
# especially for static link.
if(OpenCV_LIB_COMPONENTS MATCHES "opencv_world")
list(REMOVE_ITEM OpenCV_LIB_COMPONENTS "opencv_world")
list(INSERT OpenCV_LIB_COMPONENTS 0 "opencv_world")
endif()
if(OpenCV_LIB_COMPONENTS MATCHES "opencv_contrib_world")
list(REMOVE_ITEM OpenCV_LIB_COMPONENTS "opencv_contrib_world")
list(INSERT OpenCV_LIB_COMPONENTS 0 "opencv_contrib_world")
endif()
set(OpenCV_LIB_COMPONENTS_)
foreach(CVLib ${OpenCV_LIB_COMPONENTS})
get_target_property(libloc ${CVLib} LOCATION_${CMAKE_BUILD_TYPE})
if(libloc MATCHES "3rdparty")
set(libpath "\${exec_prefix}/share/OpenCV/3rdparty/${OPENCV_LIB_INSTALL_PATH}")
else()
set(installDir "${OPENCV_LIB_INSTALL_PATH}")
set(libpath "\${exec_prefix}/${OPENCV_LIB_INSTALL_PATH}")
endif()
list(APPEND OpenCV_LIB_COMPONENTS_ "-L${libpath}")
get_filename_component(libname ${CVLib} NAME_WE)
string(REGEX REPLACE "^lib" "" libname "${libname}")
list(APPEND OpenCV_LIB_COMPONENTS_ "-l${libname}")
set(OpenCV_LIB_COMPONENTS_ "${OpenCV_LIB_COMPONENTS_} \${exec_prefix}/${installDir}/${libname}")
endif()
endforeach()
# add extra dependencies required for OpenCV
set(OpenCV_LIB_COMPONENTS ${OpenCV_LIB_COMPONENTS_})
if(OpenCV_EXTRA_COMPONENTS)
foreach(extra_component ${OpenCV_EXTRA_COMPONENTS})
if(extra_component MATCHES "^-[lL]" OR extra_component MATCHES "[\\/]")
set(maybe_l_prefix "")
if(extra_component MATCHES "^-[lL]")
set(libprefix "")
set(libname "${extra_component}")
elseif(extra_component MATCHES "[\\/]")
get_filename_component(libdir "${extra_component}" PATH)
list(APPEND OpenCV_LIB_COMPONENTS_ "-L${libdir}")
get_filename_component(libname "${extra_component}" NAME_WE)
string(REGEX REPLACE "^lib" "" libname "${libname}")
set(libprefix "-l")
else()
set(maybe_l_prefix "-l")
set(libprefix "-l")
set(libname "${extra_component}")
endif()
set(OpenCV_LIB_COMPONENTS "${OpenCV_LIB_COMPONENTS} ${maybe_l_prefix}${extra_component}")
list(APPEND OpenCV_LIB_COMPONENTS_ "${libprefix}${libname}")
endforeach()
endif()
list(REMOVE_DUPLICATES OpenCV_LIB_COMPONENTS_)
string(REPLACE ";" " " OpenCV_LIB_COMPONENTS "${OpenCV_LIB_COMPONENTS_}")
#generate the .pc file
set(prefix "${CMAKE_INSTALL_PREFIX}")
set(exec_prefix "\${prefix}")
set(libdir "\${exec_prefix}/${OPENCV_LIB_INSTALL_PATH}")
set(includedir "\${prefix}/${OPENCV_INCLUDE_INSTALL_PATH}")
if(INSTALL_TO_MANGLED_PATHS)
set(OPENCV_PC_FILE_NAME "opencv-${OPENCV_VERSION}.pc")
else()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册