community: [Freetype] Link error when used from a thirdparty

Description of Problem, Request, or Question

It seems like the dependencies of freetype are not linked when freetype is builded from a thirparty.

Package Details (Include if Applicable)

  • Package Name/Version: freetype/2.9.0
  • Operating System: Windows
  • Compiler+version: Visual Studio 15 2017

Steps to reproduce (Include if Applicable)

We are trying to use Freetype as a thirdparty of a project (https://github.com/Tulip-Dev/tulip). So in our conanfile.py we did put freetype as requirement, but we have errors when building tulip (actually ftgl-tulip):

freetype.lib(sfnt.obj) : error LNK2019: symbole externe non résolu png_create_read_struct référencé dans la fonction Load_SBit_Png

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 37 (29 by maintainers)

Most upvoted comments

@uilianries great job! Thanks @lucienboillod for your feedback and support!

Alright, many thanks for the explanations ! I understand the problem now.

I’ll try your way asap and let you know

It is handled by conan. When you depend on conan packages, you will get defined the ${CONAN_LIBS} variable with an ordered list of libraries you need to link with, if you are using old-style cmake with global configuration. Or you can use CONAN_PKG::freetype target if using modern cmake style. Conan provides both ways to do so.

But if you have in your CMakeLists.txt:

TARGET_LINK_LIBRARIES(${FTGLLibrary} ${OPENGL_gl_LIBRARY} ${FREETYPE_LIBRARY} ${Tess2Library} ${GLEW_LIBRARY})

And the ${FREETYPE_LIBRARY} comes from a find_package that is not managed by conan, there is nothing conan can do. (Btw: conan will never mess with your build system, it declares things to be used, but the consumer needs to explicitly use them). The conan package knows that it has a transitive dependency to libpng, and it will add it to CONAN_LIBS or CONAN_PKG::freetype, but it seems the cmake find_package for freetype is not aware of this transitivity.

Maybe you could try to set ${FREETYPE_LIBRARY} to point to CONAN_PKG::freetype, instead of using the one provided by find_package

@lucienboillod I updated the package, please run it again.

@uilianries

I would suggest trying to do an explicit find of png in the find_package, something in the line:

find_library(PNG_LIBRARY NAMES ${CONAN_LIBS_PNG} PATHS ${CONAN_LIB_DIRS_PNG} NO_CMAKE_FIND_ROOT_PATH)
set(FREETYPE_LIBRARY ${FREETYPE_LIBRARY} ${PNG_LIBRARY})

That is true. The PR looked good to me initially, but it is true that iterating over CONAN_LIBS on the consumer cmake space, will iterate over all dependencies, not only the freetype one.

For me, this is one of the big inconveniences of find_package: transitivity is quite difficult, even at small scale (just 1 level of transitive dependencies). With many nested dependencies it becomes unmanageable.

I found a solution, the key is change FindFreetype.cmake provided by conan-freetype:

# FindFreetype.cmake
cmake_minimum_required(VERSION 2.8)

foreach(libname ${CONAN_LIBS})
    find_library(${libname}_LIBRARY NAMES ${libname} PATHS ${CONAN_LIB_DIRS} NO_CMAKE_FIND_ROOT_PATH)
    set(FREETYPE_LIBRARY ${FREETYPE_LIBRARY} ${${libname}_LIBRARY})
endforeach(libname ${CONAN_LIBS})

set(FREETYPE_INCLUDE_DIRS ${CONAN_INCLUDE_DIRS})
set(FREETYPE_INCLUDE_DIR ${CONAN_INCLUDE_DIRS_FREETYPE})
set(FREETYPE_LIBRARIES ${CONAN_LIBS})

MESSAGE("** FREETYPE ALREADY FOUND BY CONAN!")
SET(FREETYPE_FOUND TRUE)
MESSAGE("** FOUND FREETYPE:  ${FREETYPE_LIBRARY}")
MESSAGE("** FOUND FREETYPE INCLUDE:  ${FREETYPE_INCLUDE_DIR}")

mark_as_advanced(FREETYPE_LIBRARY FREETYPE_INCLUDE_DIR)

set(FREETYPE_MAJOR_VERSION "2")
set(FREETYPE_MINOR_VERSION "9")
set(FREETYPE_PATCH_VERSION "0")

As we can see, I listed each library involving freetype and pushed into FREETYPE_LIBRARY. Other variables are collected from conanbuildinfo.cmake

I’m going to update the testing branch.

@memsharded @lucienboillod WDYT?

I just updated my example to have the same behavior.

https://github.com/uilianries/freetype-png-example

Log: https://gist.github.com/uilianries/1001863bf450c613c02c13b3e2895b4f

Now I’m able to see the same error. Well, looks like my FindFreetype is not solving libpng and all other dependencies.

I think that I need to check some variable from conanbuildinfo.cmake to fill ${FREETYPE_LIBRARIES}

It is working fine ! thanks a lot

A last question, for now I’m setting the CONAN_LIBS variable directly from the CMakeLists, is there a way to set from the conan side and not touch the Cmake part ?

I just managed to have a reproductible example, but you will need a least Qt5 (you can put the path at the dedicated line in the conanfile).

You should be able to get the link errors by doing:

conan source .
mkcd build & conan install .. 
conan build ..

https://github.com/lucienboillod/conan-tulip

Please tellme if you need anything,

Many Thanks!

I have been having a look, but I cannot make if fail. I’d need some code that uses freetype-png, but I can’t find any online, and it is difficult to reproduce with ftgl, because it is not isolated, it has other dependencies (${Tess2Library} ${GLEW_LIBRARY})

Could you please @lucienboillod try to provide some reference (an actual main() would be excellent) of some code using freetype with png support to make it fail? Or maybe detailed instructions how to reproduce while building ftgl. I cannot find a branch with the ongoing work using freetype from the bincrafters repo.

Many thanks!

The full log:

freetype.lib(sfnt.obj) : error LNK2019: symbole externe non résolu png_create_read_struct référencé dans la fonction Load_SBit_Png
freetype.lib(sfnt.obj) : error LNK2019: symbole externe non résolu png_set_longjmp_fn référencé dans la fonction Load_SBit_Png
freetype.lib(sfnt.obj) : error LNK2019: symbole externe non résolu png_create_info_struct référencé dans la fonction Load_SBit_Png
freetype.lib(sfnt.obj) : error LNK2019: symbole externe non résolu png_read_info référencé dans la fonction Load_SBit_Png
freetype.lib(sfnt.obj) : error LNK2019: symbole externe non résolu png_set_expand_gray_1_2_4_to_8 référencé dans la fonction Load_SBit_Png
freetype.lib(sfnt.obj) : error LNK2019: symbole externe non résolu png_set_palette_to_rgb référencé dans la fonction Load_SBit_Png
freetype.lib(sfnt.obj) : error LNK2019: symbole externe non résolu png_set_tRNS_to_alpha référencé dans la fonction Load_SBit_Png
freetype.lib(sfnt.obj) : error LNK2019: symbole externe non résolu png_set_gray_to_rgb référencé dans la fonction Load_SBit_Png
freetype.lib(sfnt.obj) : error LNK2019: symbole externe non résolu png_set_filler référencé dans la fonction Load_SBit_Png
freetype.lib(sfnt.obj) : error LNK2019: symbole externe non résolu png_set_packing référencé dans la fonction Load_SBit_Png
freetype.lib(sfnt.obj) : error LNK2019: symbole externe non résolu png_set_interlace_handling référencé dans la fonction Load_SBit_Png
freetype.lib(sfnt.obj) : error LNK2019: symbole externe non résolu png_set_strip_16 référencé dans la fonction Load_SBit_Png
freetype.lib(sfnt.obj) : error LNK2019: symbole externe non résolu png_read_update_info référencé dans la fonction Load_SBit_Png
freetype.lib(sfnt.obj) : error LNK2019: symbole externe non résolu png_read_image référencé dans la fonction Load_SBit_Png
freetype.lib(sfnt.obj) : error LNK2019: symbole externe non résolu png_read_end référencé dans la fonction Load_SBit_Png
freetype.lib(sfnt.obj) : error LNK2019: symbole externe non résolu png_destroy_read_struct référencé dans la fonction Load_SBit_Png
freetype.lib(sfnt.obj) : error LNK2019: symbole externe non résolu png_get_error_ptr référencé dans la fonction error_callback
freetype.lib(sfnt.obj) : error LNK2019: symbole externe non résolu png_set_read_fn référencé dans la fonction Load_SBit_Png
freetype.lib(sfnt.obj) : error LNK2019: symbole externe non résolu png_get_io_ptr référencé dans la fonction read_data_from_FT_Stream
freetype.lib(sfnt.obj) : error LNK2019: symbole externe non résolu png_set_read_user_transform_fn référencé dans la fonction Load_SBit_Png
freetype.lib(sfnt.obj) : error LNK2019: symbole externe non résolu png_error référencé dans la fonction read_data_from_FT_Stream
freetype.lib(sfnt.obj) : error LNK2019: symbole externe non résolu png_get_valid référencé dans la fonction Load_SBit_Png
freetype.lib(sfnt.obj) : error LNK2019: symbole externe non résolu png_get_IHDR référencé dans la fonction Load_SBit_Png
freetype.lib(ftgzip.obj) : error LNK2019: symbole externe non résolu inflate référencé dans la fonction FT_Gzip_Uncompress
freetype.lib(ftgzip.obj) : error LNK2019: symbole externe non résolu inflateEnd référencé dans la fonction FT_Gzip_Uncompress
freetype.lib(ftgzip.obj) : error LNK2019: symbole externe non résolu inflateReset référencé dans la fonction ft_gzip_file_io
freetype.lib(ftgzip.obj) : error LNK2019: symbole externe non résolu inflateInit2_ référencé dans la fonction FT_Gzip_Uncompress
freetype.lib(ftbzip2.obj) : error LNK2019: symbole externe non résolu BZ2_bzDecompressInit référencé dans la fonction FT_Stream_OpenBzip2
freetype.lib(ftbzip2.obj) : error LNK2019: symbole externe non résolu BZ2_bzDecompress référencé dans la fonction ft_bzip2_file_fill_output
freetype.lib(ftbzip2.obj) : error LNK2019: symbole externe non résolu BZ2_bzDecompressEnd référencé dans la fonction ft_bzip2_stream_close
C:\Users\lboillod\conan-tulip\build\tulip\thirdparty\ftgl\ftgl-tulip-5_2.dll : fatal error LNK1120: 30 externes non résolus

@uilianries the defaults ones, with is “with_png=True” for the case of libpng