mirror of
https://github.com/opencv/opencv.git
synced 2024-12-01 23:30:06 +08:00
eceada586b
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 substitions for these paths when the afromentioned environment variables are set. In such case, since the prefix is the target one, not the sysroot one, these libraries' abolute 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 [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 Signed-off-by: Samuel Martin <s.martin49@gmail.com> --- Note: this patch properly applies on top of the master branch, though it has been written on top of the 2.4 branch.
106 lines
3.7 KiB
CMake
106 lines
3.7 KiB
CMake
# --------------------------------------------------------------------------------------------
|
|
# according to man pkg-config
|
|
# The package name specified on the pkg-config command line is defined to
|
|
# be the name of the metadata file, minus the .pc extension. If a library
|
|
# can install multiple versions simultaneously, it must give each version
|
|
# its own name (for example, GTK 1.2 might have the package name "gtk+"
|
|
# while GTK 2.0 has "gtk+-2.0").
|
|
#
|
|
# ${BIN_DIR}/unix-install/opencv.pc -> For use *with* "make install"
|
|
# -------------------------------------------------------------------------------------------
|
|
|
|
if(CMAKE_BUILD_TYPE MATCHES "Release")
|
|
set(ocv_optkind OPT)
|
|
else()
|
|
set(ocv_optkind DBG)
|
|
endif()
|
|
|
|
#build the list of opencv libs and dependencies for all modules
|
|
set(OpenCV_LIB_COMPONENTS "")
|
|
set(OpenCV_EXTRA_COMPONENTS "")
|
|
foreach(m ${OPENCV_MODULES_PUBLIC})
|
|
list(INSERT OpenCV_LIB_COMPONENTS 0 ${${m}_MODULE_DEPS_${ocv_optkind}} ${m})
|
|
if(${m}_EXTRA_DEPS_${ocv_optkind})
|
|
list(INSERT OpenCV_EXTRA_COMPONENTS 0 ${${m}_EXTRA_DEPS_${ocv_optkind}})
|
|
endif()
|
|
endforeach()
|
|
|
|
ocv_list_unique(OpenCV_LIB_COMPONENTS)
|
|
ocv_list_unique(OpenCV_EXTRA_COMPONENTS)
|
|
ocv_list_reverse(OpenCV_LIB_COMPONENTS)
|
|
ocv_list_reverse(OpenCV_EXTRA_COMPONENTS)
|
|
|
|
#build the list of components
|
|
|
|
# Note:
|
|
# when linking against static libraries, if libfoo depends on libbar, then
|
|
# libfoo must come first in the linker flags.
|
|
|
|
# world is a special target 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()
|
|
|
|
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(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}")
|
|
|
|
endforeach()
|
|
|
|
# add extra dependencies required for OpenCV
|
|
if(OpenCV_EXTRA_COMPONENTS)
|
|
foreach(extra_component ${OpenCV_EXTRA_COMPONENTS})
|
|
|
|
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(libprefix "-l")
|
|
set(libname "${extra_component}")
|
|
endif()
|
|
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()
|
|
set(OPENCV_PC_FILE_NAME opencv.pc)
|
|
endif()
|
|
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/opencv-XXX.pc.in"
|
|
"${CMAKE_BINARY_DIR}/unix-install/${OPENCV_PC_FILE_NAME}"
|
|
@ONLY)
|
|
|
|
if(UNIX AND NOT ANDROID)
|
|
install(FILES ${CMAKE_BINARY_DIR}/unix-install/${OPENCV_PC_FILE_NAME} DESTINATION ${OPENCV_LIB_INSTALL_PATH}/pkgconfig COMPONENT dev)
|
|
endif()
|