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

rocambille
  • 15,398
  • 12
  • 50
  • 68
  • 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? – Torbjörn Sep 01 '16 at 07:10
  • Yeah, I printed all the variables (see my own answer) and got identical output on both machines. –  Sep 01 '16 at 11:11

2 Answers2

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.

rocambille
  • 15,398
  • 12
  • 50
  • 68
  • `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). – Tsyvarev Sep 01 '16 at 11:42
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.