Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'cmake' command fails when Exiv2 built as static #1230

Closed
SPlesskin opened this issue Jun 6, 2020 · 12 comments
Closed

'cmake' command fails when Exiv2 built as static #1230

SPlesskin opened this issue Jun 6, 2020 · 12 comments
Assignees
Milestone

Comments

@SPlesskin
Copy link

I'm developing a Qt 5.7 application on Linux Debian 9 and which uses Exiv2 0.27.2. When I run the cmake command to generate the makefile, I get the following error(s):

CMake Error at src/CMakeLists.txt:30 (add_library):
Target "simphoniz-api" links to target "Iconv::Iconv" but the target was
not found. Perhaps a find_package() call is missing for an IMPORTED
target, or an ALIAS target is missing?

When I successfully compiled Exiv2 as a static library, I get the following messages:

-- The CXX compiler identification is GNU 6.3.0
-- The C compiler identification is GNU 6.3.0
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE
-- Performing Test Iconv_IS_BUILT_IN
-- Performing Test Iconv_IS_BUILT_IN - Success
-- Found Iconv: /usr/lib/x86_64-linux-gnu/libc.so
-- ICONV_INCLUDE_DIR :
-- ICONV_LIBRARIES : /usr/lib/x86_64-linux-gnu/libc.so
-- Looking for gmtime_r
-- Looking for gmtime_r - found
-- Looking for mmap
-- Looking for mmap - found
-- Looking for munmap
-- Looking for munmap - found
-- Looking for strerror_r
-- Looking for strerror_r - found
-- Performing Test EXV_STRERROR_R_CHAR_P
-- Performing Test EXV_STRERROR_R_CHAR_P - Success
-- Looking for C++ include memory.h
-- Looking for C++ include memory.h - found
-- Looking for C++ include process.h
-- Looking for C++ include process.h - not found
-- Looking for C++ include stdbool.h
-- Looking for C++ include stdbool.h - found
-- Looking for C++ include stdint.h
-- Looking for C++ include stdint.h - found
-- Looking for C++ include strings.h
-- Looking for C++ include strings.h - found
-- Looking for C++ include sys/stat.h
-- Looking for C++ include sys/stat.h - found
-- Looking for C++ include sys/types.h
-- Looking for C++ include sys/types.h - found
-- Looking for C++ include inttypes.h
-- Looking for C++ include inttypes.h - found
-- Looking for C++ include unistd.h
-- Looking for C++ include unistd.h - found
-- Looking for C++ include sys/mman.h
-- Looking for C++ include sys/mman.h - found
-- Looking for C++ include regex.h
-- Looking for C++ include regex.h - found
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY - Success
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY - Success
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR - Success
-- Install prefix: /home/erwan/git/simphoniz/external/build/external
...
-- Compiler info: GNU (/usr/bin/c++) ; version: 6.3.0
-- Building shared library: NO
-- Building PNG support: NO
-- XMP metadata support: NO
-- Native language support: NO
-- Conversion of Windows XP tags: YES
-- Nikon lens database: YES
-- Building video support: NO
-- Building webready support: NO
-- Building exiv2 command: YES
-- Building samples: NO
-- Building PO files: NO
-- Building unit tests: NO
-- Building doc: NO
-- Building with coverage flags: NO
-- Using ccache: NO

It seems that the problem comes from the libiconv library but I don't see why... Please, can you tell me what can be wrong with my configuration ? Thank you very much for your help.

@SPlesskin SPlesskin added the bug label Jun 6, 2020
@clanmills
Copy link
Collaborator

I'll look at this when I get up in the morning. From the transcript, it appears that libiconv is built into libc on your platform. Can you clarify if you are building a static or shared library?

@clanmills clanmills self-assigned this Jun 7, 2020
@clanmills clanmills removed the bug label Jun 7, 2020
@clanmills
Copy link
Collaborator

I've loaded a nice new debian 9.3 VM on my MacMini and can build both static and shared with 0.27.2 with GCC 6.3.0

rmills@rmillsmm-debian:~/gnu/github/exiv2/exiv2/static_build$ uname -a
Linux rmillsmm-debian 4.9.0-4-amd64 #1 SMP Debian 4.9.65-3 (2017-12-03) x86_64 GNU/Linux
rmills@rmillsmm-debian:~/gnu/github/exiv2/exiv2/static_build$ gcc --version
gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516

I installed all the dependencies as documented in README.md:

sudo apt install --yes build-essential git clang ccache python3 libxml2-utils cmake python3 libexpat1-dev libz-dev zlib1g-dev libssh-dev libcurl4-openssl-dev libgtest-dev google-mock

The reason I asked for clarification is because you said:

When I successfully compiled Exiv2 as a static library, I get the following messages:

Here's my history. Everything build normally. Nothing unusual.

   39  git clone https://github.com/exiv2/exiv2 --branch 0.27-maintenance --depth 1 0.27-maintenance
   40  cd 0.27-maintenance/
   41  git pull --unshallow
   42  git checkout v0.27.2
   43  git status
   44  mkdir build
   45  cd build
   46  cmake .. -DBUILD_SHARED_LIBS=Off
   47  make
   48  make tests
   49  ls -l bin lib

@clanmills
Copy link
Collaborator

Oh, something I forgot to ask:

CMake Error at src/CMakeLists.txt:30 (add_library):
Target "simphoniz-api" links to target "Iconv::Iconv" but the target was
not found. Perhaps a find_package() call is missing for an IMPORTED
target, or an ALIAS target is missing?

I think that's something in your src/CMakeLists.txt. Exiv2 has:

rmills@rmillsmm-debian:~$ cd ~/gnu/github/exiv2/0.27-maintenance/src
rmills@rmillsmm-debian:~/gnu/github/exiv2/0.27-maintenance/src$ nl -b a CMakeLists.txt 
     1	# CMakeLists.txt for exiv2 library and command-line program
     2	
     3	# Note that this is a hack for testing the internals of the library. If EXIV2_BUILD_UNIT_TESTS==OFF
     4	# Then we only export the symbols that are explicitly exported
     5	if( EXIV2_BUILD_UNIT_TESTS )
     6	    set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) # Requires CMake 3.3.3
     7	endif()
     8	
     9	include(CMakePackageConfigHelpers)
    10	
    11	include_directories(${CMAKE_CURRENT_BINARY_DIR})
    12	
    13	
    14	add_library( exiv2lib_int OBJECT
    15	    canonmn_int.cpp         canonmn_int.hpp
    16	    casiomn_int.cpp         casiomn_int.hpp
    17	    cr2header_int.cpp       cr2header_int.hpp
    18	    crwimage_int.cpp        crwimage_int.hpp
    19	    fujimn_int.cpp          fujimn_int.hpp
    20	    helper_functions.cpp    helper_functions.hpp
    21	    image_int.cpp           image_int.hpp
    22	    makernote_int.cpp       makernote_int.hpp
    23	    minoltamn_int.cpp       minoltamn_int.hpp
    24	    nikonmn_int.cpp         nikonmn_int.hpp
    25	    olympusmn_int.cpp       olympusmn_int.hpp
    26	    orfimage_int.cpp        orfimage_int.hpp
    27	    panasonicmn_int.cpp     panasonicmn_int.hpp
    28	    pentaxmn_int.cpp        pentaxmn_int.hpp
    29	    rw2image_int.cpp        rw2image_int.hpp
    30	    safe_op.hpp
    31	    samsungmn_int.cpp       samsungmn_int.hpp
    32	    sigmamn_int.cpp         sigmamn_int.hpp
    33	    sonymn_int.cpp          sonymn_int.hpp
    34	    tags_int.cpp            tags_int.hpp
    35	    tiffcomposite_int.cpp   tiffcomposite_int.hpp
    36	    tiffimage_int.cpp       tiffimage_int.hpp
    37	    tiffvisitor_int.cpp     tiffvisitor_int.hpp
    38	    tifffwd_int.hpp
    39	    timegm.h
    40	    unused.h
    41	)

My suspicion is that you have something in your src/CMakeLists.txt file that's linking Iconv and expecting it to be in an external package. On the debian platform, it's in libc. I'm not an expert on CMake, however we have the code:

if( ICONV_FOUND )
    target_link_libraries( exiv2lib PRIVATE Iconv::Iconv )
endif()

Unless you are using Iconv directly in your code, you don't need to think about Iconv as it will be linked into libexiv2 on your behalf. In the case of the static library, it'll be 100% invisible inside libexiv2.a:

rmills@rmillsmm-debian:~/gnu/github/exiv2/0.27-maintenance/build/lib$ ls -lh 
total 13M
-rw-r--r-- 1 rmills rmills  11M Jun  7 00:43 libexiv2.a
-rw-r--r-- 1 rmills rmills 1.9M Jun  7 00:42 libexiv2-xmp.a
rmills@rmillsmm-debian:~/gnu/github/exiv2/0.27-maintenance/build/lib$ 

@SPlesskin
Copy link
Author

Thank you for your help. FYI, I'm building a static library (i.e., libsimphoniz-api.a). The Exiv2 library is statically linked into it. And it seems to be a problem since Iconv is linked into Exiv2 as PRIVATE. I found this explanation here:

"If, however, A is a static library, the situation changes. Static libraries do not carry
information about other libraries they depend on. For this reason, when A
links in B as PRIVATE and another target C links in A, CMake will still add
B to the list of libraries to be linked for C because parts of B are needed
by A, but A itself doesn't have that dependency encoded into it. So even
though B is an internal implementation detail of A, C still needs B added
to the linker command, which CMake conveniently handles for you."

So, I should probably also link Iconv into my static library in addition to Exiv2.

@SPlesskin
Copy link
Author

Ok, so I called the command find_package(Iconv) in my CMakeLists.txt file and I linked the target Iconv::Iconv along with exiv2lib and now, I've no problem generating the Makefile with CMake. I don't need to do that when Exiv2 is compiled as a shared library. Maybe something needs to be added to the Exiv2 project to solve this kind of issue... Whatever, this issue can be closed.

@clanmills
Copy link
Collaborator

@SPlesskin Thank You for updating this issue. I'm pleased that this issue can be closed. I'm going to ask @piponazo to comment as he is the Team Exiv2 CMake Magician!

I personally don't like static libraries. DLLs/shared objects are a much more "democratic" as the libraries and executables dance together.

@piponazo
Copy link
Collaborator

piponazo commented Jun 8, 2020

Hi @SPlesskin , and thanks for reporting this.

The link from where you extracted the explanation about static libraries is correct. I had to do the same thing (include the call to find_package()) in other projects where I was using static libraries. But it is important to note that this is not needed when working with shared ones.

Luckily CMake identifies the situation and the warning which is throwing you is quite clear:

CMake Error at src/CMakeLists.txt:30 (add_library):
Target "simphoniz-api" links to target "Iconv::Iconv" but the target was
not found. Perhaps a find_package() call is missing for an IMPORTED
target, or an ALIAS target is missing?

If there is a clan way to prevent this situation I would be happy to include it in our CMake code. However, I think there is not such approach and it is something that needs to be handled by the projects consuming exvi2 statically.

@clanmills
Copy link
Collaborator

Thanks for looking into this, @piponazo. If you think I should add something in README.md about this, could you reopen the issue and set the milestone to v0.27.3.

I think we'll need a new section in README.md. Currently, building shared and static is mentioned in 2.3 Build Options. I think we add a new section 2.18 Building Shared and Static Libraries. I might need a little help to explain this, however if we go down this road, you can review my PR with the changes to README.md

@piponazo
Copy link
Collaborator

piponazo commented Jun 8, 2020

Sure @clanmills, You can create a branch a give the structure to the README.md you have in your mind and I can add the CMake details later there ;)

@piponazo piponazo reopened this Jun 8, 2020
@piponazo piponazo added this to the v0.27.3 milestone Jun 8, 2020
@clanmills
Copy link
Collaborator

Yes. Thank You @piponazo. I will add submit a PR tomorrow. I'm happy for this to go into 0.27.3 GM as it's only a change to the documentation.

@clanmills
Copy link
Collaborator

@SPlesskin Thanks for bring up this topic. We've updated README.md in branch 0.27-maintenance with a new section concerning static and shared libraries. This issue report is referenced in the modified documentation. #1232.

Exiv2 v0.27.3 is on-track to ship on 2020-06-30 and will include the modified README.md. I'm going to close this issue. If you wish further discussion about this matter, please update this issue and it'll be re-opened.

@Ryanf55
Copy link
Contributor

Ryanf55 commented Jul 5, 2023

I also get errors with XMP and inih.

CMake Error at /usr/local/lib/cmake/exiv2/exiv2Config.cmake:61 (set_target_properties):
  The link interface of target "exiv2-xmp" contains:

    EXPAT::EXPAT
  but the target was not found.  Possible reasons include:

    * There is a typo in the target name.
    * A find_package call is missing for an IMPORTED target.
    * An ALIAS target is missing.

CMake Error at /usr/local/lib/cmake/exiv2/exiv2Config.cmake:61 (set_target_properties):
  The link interface of target "exiv2lib" contains:

    inih::libinih

  but the target was not found.  Possible reasons include:

Should I file a new issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants