1

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).

2
  • Either the environments on the two machines do differ or it's a bug/insufficiency of the FindImageMagick module. Edit: Did you try to debug FindImageMagick by printing the contents of the variables set my the find module? Commented Sep 1, 2016 at 7:10
  • Yeah, I printed all the variables (see my own answer) and got identical output on both machines. Commented Sep 1, 2016 at 11:11

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

But IMAGEMAGICK_FOUND is not set anywhere in the package - Variable IMAGEMAGICK_FOUND is set by previous call to FIND_PACKAGE_HANDLE_STANDARD_ARGS. Actually, this call sets both ImageMagick_FOUND and IMAGEMAGICK_FOUND variables, so the call to set() you refer to is redudant (but it can be meaningfull for backward compatibility).
1

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.

Comments