0

I am new to CMake. I was trying to use ImageMagick's c++ api Magick++ in my code.

This is my whole directory structure:

enter image description here

external/image_magick just contains the result of cloning the image magick library using: git submodule add https://github.com/ImageMagick/ImageMagick.git external/image_magick.

This is the top-level CMakeLists.txt ( the one in the pic above):

cmake_minimum_required (VERSION 3.22.1)
project(DEMO)
add_executable(${PROJECT_NAME} main.cpp)

This is main.cpp (it just crops the image magick image and saves it, just for the demo):

#include <iostream>

#include <Magick++.h>

using namespace std;

using namespace Magick;

int main()
{
    cout << "Hello World!" << endl;

    // Construct the image object. Seperating image construction from the
    // the read operation ensures that a failure to read the image file
    // doesn't render the image object useless.
    Image image;
    try
    {
        // Read a file into image object
        image.read("logo:");

        // Crop the image to specified size (width, height, xOffset, yOffset)
        image.crop(Geometry(100, 100, 100, 100));

        // Write the image to a file
        image.write("logo.png");
        printf("Image written to logo.png");
    }
    catch (Exception &error_)
    {
        cout << "Caught exception: " << error_.what() << endl;
        printf("Error: %s", error_.what());
        return 1;
    }

    return 0;
}

If I compile and run the app like this (as per image magick docs):

c++ main.cpp -o main.out `Magick++-config --cppflags --cxxflags --ldflags --libs`
./main.out

Then all is good and image is generated.

But I can't use the CMakeLists.txt to build and run like this:

cmake -S . -B out/build
cd out/build; make
cd out/build
./DEMO

Because the external/image_magick directory I cloned does not contain CMakeLists.txt. I tried searching inside that directory for the library file (something like libmagic++??) to use it like below in my top level CMakeLists.txt but I didn't know how to do it:

add_subdirectory(external/image_magick/Magick++)

target_include_directories(${PROJECT_NAME} 
    PUBLIC external/image_magick/
)
target_link_directories(${PROJECT_NAME} 
PRIVATE external/image_magick/Magick++
)
target_link_libraries(${PROJECT_NAME} 
    PUBLIC ${PROJECT_SOURCE_DIR}/Magick++
)
# DOES NOT WORK

So how to properly add this library to my app while keeping using CMAke?

HII
  • 3,420
  • 1
  • 14
  • 35
  • 1
    So you have cloned [ImageMagick sources](https://github.com/ImageMagick/ImageMagick). They do not contain the library, you need to build them first. CMake provides module [ExternalProject](https://cmake.org/cmake/help/latest/module/ExternalProject.html) for building external projects during the building of your one. There are many questions on Stack Overflow about using External Project functionality in CMake. See e.g. that one: https://stackoverflow.com/questions/6351609/cmake-linking-to-library-downloaded-from-externalproject-add – Tsyvarev Sep 23 '22 at 15:21

2 Answers2

0

I have had a similar problem, and it was solved by instead of using link_libraries, using the set command like this:

set(CMAKE_CXX_FLAGS "-LlibraryPath -lMagick++ ${CMAKE_CXX_FLAGS}")

I understand this is not the intended use for this, but this was the way I got my project building.

Also, expect many problems with libraries with C/C++, as everyone has many, many, MANY questions that need asking.

cs1349459
  • 911
  • 9
  • 27
  • Setting `-l` options in CMAKE_CXX_FLAGS will never work with gcc, which is sensitive to the order of libraries in the command line. Resulting command line for the linker will firstly has all options from `CMAKE_CXX_FLAGS` variable and only then all object files. So when the linker will process those object files the libraries from `-l` options will already be forgotten. – Tsyvarev Sep 23 '22 at 16:44
  • didn't work, I am still getting the same error: `fatal error: Magick++.h: No such file or directory 3 | #include | ^~~~~~~~~~~~ compilation terminated.` So do you suggest to use something else instead? – HII Sep 23 '22 at 18:13
  • Sorry, I misunderstood the question, my bad. You should include the ImageMagick++ include directory using the `include_directories` command. You can learn more here: https://cmake.org/cmake/help/latest/command/include_directories.html – cs1349459 Sep 23 '22 at 18:20
  • @cs1349459 I already tried this,but here is the problem, if you look at the ImageMagick library repo at github, you can see they don't have an include directory ,they have an `Include.h` file inside the `Magick++` folder, but no `include/` directory. – HII Sep 23 '22 at 18:36
0

According to this answer, the solution was to add the following to CMakeLists.txt:

#ImageMagick
add_definitions( -DMAGICKCORE_QUANTUM_DEPTH=16 )
add_definitions( -DMAGICKCORE_HDRI_ENABLE=0 )
find_package(ImageMagick COMPONENTS Magick++)
include_directories(${ImageMagick_INCLUDE_DIRS})
target_link_libraries(demo ${ImageMagick_LIBRARIES})
HII
  • 3,420
  • 1
  • 14
  • 35