I've been trying to find a solution to this for a long time, but I still cannot figure out how to do this.
What I need
To be able to execute a convert
command (or equivalent in code) from within an OSX app, regardless of whether the user has ImageMagick (and its dependencies) installed.
What I've tried
Given that we have to cover (obviously) the case where the user doesn't already have ImageMagick installed, I assume we have to make it somehow self-contained...
Approach A : Pack the binary, plain and simple, within the bundle, and execute it with NSTask
.
Working? Yes, but only on my Mac where every library is pre-installed.
Approach B : Link with the static libraries.
This is the more... obvious approach. However, there are still issues.
I first tried using these precompiled IM release + Delegates. After a lot of tweaks, I got it to work.
The thing is: it include the JPEG, PNG, TIFF delegates. But not the FreeType one which I definitely need.
So... I tried re-compiling it all from scratch AND the FreeType delegate. And here come all sorts of issues (all mostly related with libraries being missing). I mean... I link the static libraries, then see a complete list of errors... add some missing library... and then a new list of errors appear. Obviously, something is wrong.
Here's what it looks like :
Undefined symbols for architecture x86_64:
"_FcConfigDestroy", referenced from:
_LoadFontConfigFonts in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-type.o)
"_FcFontList", referenced from:
_LoadFontConfigFonts in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-type.o)
"_FcFontSetDestroy", referenced from:
_LoadFontConfigFonts in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-type.o)
"_FcInitLoadConfigAndFonts", referenced from:
_LoadFontConfigFonts in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-type.o)
"_FcObjectSetBuild", referenced from:
_LoadFontConfigFonts in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-type.o)
"_FcObjectSetDestroy", referenced from:
_LoadFontConfigFonts in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-type.o)
"_FcPatternCreate", referenced from:
_LoadFontConfigFonts in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-type.o)
"_FcPatternDestroy", referenced from:
_LoadFontConfigFonts in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-type.o)
"_FcPatternGetInteger", referenced from:
_LoadFontConfigFonts in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-type.o)
"_FcPatternGetString", referenced from:
_LoadFontConfigFonts in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-type.o)
"_ImfCloseInputFile", referenced from:
_ReadEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
"_ImfCloseOutputFile", referenced from:
_WriteEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
"_ImfDeleteHeader", referenced from:
_WriteEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
"_ImfErrorMessage", referenced from:
_ReadEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
_WriteEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
"_ImfFloatToHalf", referenced from:
_WriteEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
"_ImfHalfToFloat", referenced from:
_ReadEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
"_ImfHeaderDataWindow", referenced from:
_ReadEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
"_ImfHeaderDisplayWindow", referenced from:
_ReadEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
"_ImfHeaderSetCompression", referenced from:
_WriteEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
"_ImfHeaderSetDataWindow", referenced from:
_WriteEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
"_ImfHeaderSetDisplayWindow", referenced from:
_WriteEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
"_ImfHeaderSetLineOrder", referenced from:
_WriteEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
"_ImfInputHeader", referenced from:
_ReadEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
"_ImfInputReadPixels", referenced from:
_ReadEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
"_ImfInputSetFrameBuffer", referenced from:
_ReadEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
"_ImfNewHeader", referenced from:
_WriteEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
"_ImfOpenInputFile", referenced from:
_ReadEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
"_ImfOpenOutputFile", referenced from:
_WriteEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
"_ImfOutputSetFrameBuffer", referenced from:
_WriteEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
"_ImfOutputWritePixels", referenced from:
_WriteEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
"_cmsCloseProfile", referenced from:
_ProfileImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-profile.o)
_GetImageProperty in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-property.o)
_GetMagickProperty in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-property.o)
"_cmsCreateTransformTHR", referenced from:
_ProfileImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-profile.o)
"_cmsDeleteTransform", referenced from:
_ProfileImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-profile.o)
"_cmsDoTransform", referenced from:
_ProfileImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-profile.o)
"_cmsGetColorSpace", referenced from:
_ProfileImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-profile.o)
"_cmsGetDeviceClass", referenced from:
_ProfileImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-profile.o)
"_cmsGetPCS", referenced from:
_ProfileImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-profile.o)
"_cmsGetProfileInfoASCII", referenced from:
_GetImageProperty in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-property.o)
_GetMagickProperty in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-property.o)
"_cmsOpenProfileFromMem", referenced from:
_GetImageProperty in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-property.o)
_GetMagickProperty in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-property.o)
"_cmsOpenProfileFromMemTHR", referenced from:
_ProfileImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-profile.o)
"_cmsSetLogErrorHandler", referenced from:
_ProfileImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-profile.o)
"_ddjvu_cache_set_size", referenced from:
_ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
"_ddjvu_context_create", referenced from:
_ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
"_ddjvu_context_release", referenced from:
_ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
"_ddjvu_document_create", referenced from:
_ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
"_ddjvu_document_get_pageinfo_imp", referenced from:
_ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
"_ddjvu_document_get_pagenum", referenced from:
_process_message in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
"_ddjvu_document_job", referenced from:
_process_message in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
_ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
"_ddjvu_format_create", referenced from:
_ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
"_ddjvu_format_release", referenced from:
_ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
"_ddjvu_format_set_row_order", referenced from:
_ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
"_ddjvu_format_set_y_direction", referenced from:
_ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
"_ddjvu_job_get_user_data", referenced from:
_process_message in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
"_ddjvu_job_release", referenced from:
_ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
"_ddjvu_job_set_user_data", referenced from:
_ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
"_ddjvu_job_status", referenced from:
_ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
"_ddjvu_message_peek", referenced from:
_ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
_pump_data_until_message in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
"_ddjvu_message_pop", referenced from:
_ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
"_ddjvu_message_wait", referenced from:
_ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
"_ddjvu_page_create_by_pageno", referenced from:
_ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
"_ddjvu_page_get_type", referenced from:
_ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
"_ddjvu_page_job", referenced from:
_ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
"_ddjvu_page_render", referenced from:
_ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
"_ddjvu_stream_close", referenced from:
_pump_data_until_message in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
"_ddjvu_stream_write", referenced from:
_pump_data_until_message in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
"_fftw_cleanup", referenced from:
_ForwardFourierTransformImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-fourier.o)
_InverseFourierTransformImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-fourier.o)
"_fftw_destroy_plan", referenced from:
_ForwardFourierTransformChannel in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-fourier.o)
_InverseFourierTransformChannel in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-fourier.o)
"_fftw_execute_dft_c2r", referenced from:
_InverseFourierTransformChannel in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-fourier.o)
"_fftw_execute_dft_r2c", referenced from:
_ForwardFourierTransformChannel in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-fourier.o)
"_fftw_plan_dft_c2r_2d", referenced from:
_InverseFourierTransformChannel in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-fourier.o)
"_fftw_plan_dft_r2c_2d", referenced from:
_ForwardFourierTransformChannel in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-fourier.o)
"_lzma_auto_decoder", referenced from:
_ReadMIFFImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-miff.o)
"_lzma_code", referenced from:
_ReadMIFFImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-miff.o)
_WriteMIFFImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-miff.o)
"_lzma_easy_encoder", referenced from:
_WriteMIFFImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-miff.o)
"_lzma_end", referenced from:
_ReadMIFFImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-miff.o)
_WriteMIFFImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-miff.o)
"_opj_create_compress", referenced from:
_WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_create_decompress", referenced from:
_ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_decode", referenced from:
_ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_destroy_codec", referenced from:
_ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
_WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_destroy_cstr_index", referenced from:
_ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_encode", referenced from:
_WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_end_compress", referenced from:
_WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_end_decompress", referenced from:
_ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_get_decoded_tile", referenced from:
_ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_image_create", referenced from:
_WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_image_destroy", referenced from:
_ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
_WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_read_header", referenced from:
_ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_set_decode_area", referenced from:
_ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_set_default_decoder_parameters", referenced from:
_ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_set_default_encoder_parameters", referenced from:
_WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_set_error_handler", referenced from:
_ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
_WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_set_warning_handler", referenced from:
_ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
_WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_setup_decoder", referenced from:
_ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_setup_encoder", referenced from:
_WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_start_compress", referenced from:
_WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_stream_create", referenced from:
_ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
_WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_stream_destroy", referenced from:
_ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
_WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_stream_set_read_function", referenced from:
_ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
_WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_stream_set_seek_function", referenced from:
_ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
_WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_stream_set_skip_function", referenced from:
_ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
_WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_stream_set_user_data", referenced from:
_ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
_WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_stream_set_user_data_length", referenced from:
_ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_stream_set_write_function", referenced from:
_ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
_WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
"_opj_version", referenced from:
_RegisterJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Any suggestions? Have you managed to use ImageMagick from Cocoa at all?