• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

How to build an Illustrator C++-Plugin with CMake?

Explorer ,
May 12, 2023 May 12, 2023

Copy link to clipboard

Copied

Hi
I'm currently developing a plugin for Illustrator. Because our ecosystem demands it (and for portability reasons) I have to do this on CMake.
I was successful to build a plugin for Mac with CMake, but now I'm struggeling with Windows.
For using an easy plugin, I took the MenuPlay-example from the samples delivered together with the SDK and build it in Visual Studio -> This Plugin was detected by the Illustrator
I then tried to port it to CMake. The build was successful, but Illustrator does not detect the plugin. What am I missing?
This is the CMake-Script:

 

cmake_minimum_required(VERSION 3.14)

project(MenuPlay)

add_compile_definitions(WIN_ENV=1)

set(CMAKE_AUTOMOC ON)

add_library(${PROJECT_NAME})
add_library(${PROJECT_NAME}::${PROJECT_NAME}  ALIAS ${PROJECT_NAME})

set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".aip")

target_sources(${PROJECT_NAME} PRIVATE
	"Source/MenuPlayID.h"
	"Source/MenuPlayPlugin.h"	
        "Source/MenuPlayPlugin.cpp"
        "Source/MenuPlaySuites.h"
        "Source/MenuPlaySuites.cpp"
	"../common/source/Main.cpp"
	"../common/source/Plugin.cpp"
	"../common/source/SDKAboutPluginsHelper.cpp"
	"../common/source/Suites.cpp"	
	"Resources/Win/MenuPlay.rc"
    	
)

target_include_directories(${PROJECT_NAME} PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>)
target_include_directories(${PROJECT_NAME} PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/Source>)

target_include_directories(${PROJECT_NAME} PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/../common/includes>)
target_include_directories(${PROJECT_NAME} PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/../common/win>)
target_include_directories(${PROJECT_NAME} PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/../../illustratorapi/pica_sp>)
target_include_directories(${PROJECT_NAME} PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/../../illustratorapi/illustrator>)
target_include_directories(${PROJECT_NAME} PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/../../illustratorapi/ate>)


foreach(LANG  C CXX RC)
    set(CMAKE_${LANG}_STANDARD_INCLUDE_DIRECTORIES ${CUSTOM_INCLUDE_DIRECTORIES})
endforeach()

 

There is no step for building the plugin.pipl-file, I use the one which was generated via the VS-project.

I put this small sample under github:
https://github.com/Voronwe-the-guide/IllustratorPluginCmake
(The illustratorapi itself is not the, because I was unsure whether it is allowed by Adobe to publish it there. If it is ok, I can also upload it

TOPICS
How-to , SDK , Third party plugins

Views

2.7K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Explorer , May 19, 2023 May 19, 2023

😄😄😄

I was finally able to get my plugin running on Windows with cmake.
I found out the following:

 

The following has to be set in CMake:

 

set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)

 

Also, it has to be explicitly set as a Shared library, because when setting nothing, my CMake build it as a Static Library: 

 

add_library(${PROJECT_NAME} SHARED)

 

 I will keep the github open, so if somebody fall in the same problem, there is an example how to do it (If I have time, I will maybe also include the handling f

...

Votes

Translate

Translate
Adobe
Explorer ,
May 12, 2023 May 12, 2023

Copy link to clipboard

Copied

Addition (Because I do not see an edit-button):
the plugin.pipl was build with the following call:

c:\Python27\python2.exe ..\..\tools\pipl\create_pipl.py -input "[{\"name\":\"MenuPlay\"}]"  

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
May 12, 2023 May 12, 2023

Copy link to clipboard

Copied

This usually happens because it's missing the PIPL. You can check if it's in there by opening the AIP file in Visual Studio in the Resource editor. File > Open as usual. Make sure you pick the AIP but don't click Open yet. Now you can click on the Open's arrow button and pick "Open with...". Choose 'Resource Editor' (last entry). You should see something like this:

 

APatterson_0-1683894766943.png

 

If you don't, your PIPL isn't being included, and Illustrator will ignore your AIP.

 

P.S. You don't need:

set(CMAKE_AUTOMOC ON)

 That's for Qt (unless you are going to add Qt later, we do!)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
May 12, 2023 May 12, 2023

Copy link to clipboard

Copied

@A. Patterson Thanks for pointing that out.
however, when I try to open that file, I got a message "Can not load any resources from this file". It seems that some step is missing, but I can not find out which. The MenuPlay.rc is called, because when I change the plugin.pipl inside there to another name, I will get a compile error.

------

Indeed you are correct that the real plugin will use Qt. But for this demo I wanted to make it as simple as possible. Just a question for the laster steps (as it seems that you have some experience there): Do I see it correct that later the dll's should be put into the same folder as the .aip?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
May 12, 2023 May 12, 2023

Copy link to clipboard

Copied

So then it's definitely not including the resources at all. Odd, because I checked how we added our .rc file and it looks the same. We switched to CMake earlier this year, so I should be well situated to help here.

 

I use nested CMakeLists.txt files and here's the one for our .rc file:

 

cmake_minimum_required(VERSION 3.21)

target_sources(MAPublisher
  PRIVATE
    MAPublisher_cmake.rc
    resource.h
)

 

I don't see any real difference. If you're not already generating an MSVC project, I'd do that and see if the .rc file is included properly. I suspect it's not. That makes this less an AI thing and more a CMake thing -- there should be lots of help for that problem on StackOverflow. If you can get resources into the AIP and it's still not working, then we're back in AI SDK territory!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
May 15, 2023 May 15, 2023

Copy link to clipboard

Copied

I worked further on that this today and found out the CMake was building a static library - I do not know why. When trying to build a dynamic one with CMake, I got a lot of linker-error.
But I was able to build a dynamic library from the same sources which I allready use for Mac (my whole Plugin so far is working perfectly with CMake on the Mac).

But Illustrator is still not able to load it
This is the .rc-File:

//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#include "../../Source/IllustratorPluginID.h"


#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winnt.h"
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32

#define kMySDKPluginName "MyIllustratorPlugin"
#define PIPL_PLUGIN_NAME kMySDKPluginName

/////////////////////////////////////////////////////////////////////////////
// VersionInfo
//

#include "VersionInfo.rc"

/////////////////////////////////////////////////////////////////////////////
//
// PIPL
//
//pipl is one folder deeper
plugin pipl "Output/plugin.pipl"

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE DISCARDABLE 
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE DISCARDABLE 
BEGIN
    "#include ""winuser.h""\r\n"
    "#include ""winnt.h""\r\n"
    "#include ""IllustratorPluginID.h""\0"
END

3 TEXTINCLUDE DISCARDABLE 
BEGIN
    "\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED

/////////////////////////////////////////////////////////////////////////////
//
// Parameter Dialog
//

kMyPluginPromptDialogID DIALOG DISCARDABLE  0, 0, 240, 75
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION kMyPluginPromptDialogName
FONT 8, "MS Sans Serif"
BEGIN
   DEFPUSHBUTTON	"OK",kDlgOKButton,185,5,50,14
   PUSHBUTTON		"Cancel",kDlgCancelButton,185,25,50,14
   LTEXT			"Prompt: ",kMyPluginParameterPromptItemID,5,5,170,14
   EDITTEXT			kMyPluginParameterValueItemID,5,25,170,14,ES_AUTOHSCROLL
   CONTROL			"",kMyPluginParameterChoiceItemID,"ADM Popup List Type",WS_TABSTOP,5,25,170,14
   LTEXT			"Type: ",kMyPluginParameterTypeItemID,5,55,170,14
END

/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE 
BEGIN
    kMyPluginPanelDialogID, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 142
        TOPMARGIN, 7
        BOTTOMMARGIN, 70
    END
END
#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// String Table
//

STRINGTABLE DISCARDABLE 
BEGIN
    16000                   "<First Mac index is 1>"
    16001                   "My"
    16002                   "My Illustrator Plugin..."
END

#endif    // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//


/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED

 

I get from this the following resources in my aip-file:

ResourceAIP.png

 

 

 

 

 

 

 

 

But when I start Illustrator, it is still not detected. Is this because something is wrong inside this one, or is it because Illustrator can not find the other dlls I need (especially the one for Qt). All the dlls are in the Folder of the .aip

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
May 15, 2023 May 15, 2023

Copy link to clipboard

Copied

Illustrator will not look in the plugins folder for DLLs. Try moving all your required support DLLs into the folder with Illustrator.exe (Support Files/Windows, something like that). 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
May 16, 2023 May 16, 2023

Copy link to clipboard

Copied

quote

Illustrator will not look in the plugins folder for DLLs. Try moving all your required support DLLs into the folder with Illustrator.exe (Support Files/Windows, something like that). 



 So it is the same issue as with Photoshop 😞 
However, I tries this and put all the dlls to

c:\Program Files\Adobe\Adobe Illustrator 2023\Support Files\Contents\Windows\

The Plugin seems to be detected, but still has problems:

IllustratorIssue.png

 Is there a way to get more details what the problem is? Trying to run the plugin from Command line does not give printouts.
BTW: Thanks for your help so far



 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
May 16, 2023 May 16, 2023

Copy link to clipboard

Copied

Figuring out why your plugin isn't being loaded is a time-honoured tradition in AI plugin development 😛 The first thing I always do is put a breakpoint in the shell.cpp or whatever the entry point source file is. If you hit that, everything else I'm about to tell you is unnecessary. But assuming you don't hit the breakpoint, it can only be either (i) your PIPL is missing/bad or it can't find a dependency. The tool I use to debug the latter kind of problem is DependencyWalker.

 

Basically, you open the AIP file and it will show you its depenencies. It's fairly slow so be patient as it loads (it might look like it's hung for two or three minutes, but it is working). It will initially show most everything as missing, but you can add a path for it to consider: namely, the Illustrator.exe location where you put your DLLs.

 

APatterson_1-1684240953333.png

Once it loads, you press the explorer button at (1). Then you click the Browse button on the dialog that pops up (2) and pick the Illustrator folder (as you see I've done). Then you click the 'Add Directory' button at (3). Hit OK and you will be prompted to refresh the current file. Say 'Yes' and you will have to wait that two or three minutes again, but now it will be accurate. You can right-click and ask it to collapse everything, which will again take a minute or so but is probably worth it. That will leave you with your AIP as the only item, which you can expand see your immediate dependencies. Expanding them in turn will show their dependencies. You likely won't need to go more than one or two levels deep.

 

The icon you're looking for is a yellow circle with a ? in it. You can ignore system ones, they'll work fine. You're interested in seeing DLLs you expect to be loaded, like Qt6Core.DLL or something that you know should be found. It will also flag them as x64 (if not shown, it's 32-bit) in case you've accidentally mixed your binaries. You shouldn't need anything that isn't in the tree in the upper left window.

 

If everything looks good, then take a second look at the PIPL. If you have any questions about the tool, post them here with a screenshot and I might be able to help clarify.


Good luck!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
May 16, 2023 May 16, 2023

Copy link to clipboard

Copied

I just found out that someone has done a rewrite of that tool, which you can find here. I just tried it out and it's about 1000x faster and seems to work more or less the same. So if you find the other tool too slow, give it a try. Their version of that dialog I mentioned is "Options" > "Customize Search Folders"

 

Minor note: your run DependenciesGui.exe not Dependencies.exe in the unzipped folder. I'll hang on to this and I suspect I'll be advocating for it in the future instead.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
May 17, 2023 May 17, 2023

Copy link to clipboard

Copied

Heureka!
I was able to build and run my example aip.
This line was missing in CMake:

set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)

This will provide a .lib for the .dll, which seems that this is neede for Windows.
Source how to do:

https://stackoverflow.com/questions/7614286/how-do-i-get-cmake-to-create-a-dll-and-its-matching-lib-...

Now next step would be to work with libraries. But at least one first step is made.
I will keep you updated

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
May 19, 2023 May 19, 2023

Copy link to clipboard

Copied

😄😄😄

I was finally able to get my plugin running on Windows with cmake.
I found out the following:

 

The following has to be set in CMake:

 

set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)

 

Also, it has to be explicitly set as a Shared library, because when setting nothing, my CMake build it as a Static Library: 

 

add_library(${PROJECT_NAME} SHARED)

 

 I will keep the github open, so if somebody fall in the same problem, there is an example how to do it (If I have time, I will maybe also include the handling for Mac):
https://github.com/Voronwe-the-guide/IllustratorPluginCmake

On other thing I found out this morning:

I had the main.cpp, which includes the function 

extern "C" ASAPI ASErr PluginMain(char* caller, char* selector, void* message)

in a static library (I made a static library as a wrapper of all the Adobe-API). This works well on Mac, but not on Windows. Here, the main.cpp must be a part of the .aip-Build.

One good thing I found out: Illustrator checks for dlls which are in the same folder as the Plugin

 That means, it is not needed to mess up c:\Program Files\Adobe\Adobe Illustrator 2023\Support Files\Contents\Windows\. with dlls. 

Just put the aip and it's dlls somewhere, and make a symbolic Link to that folder in c:\Program Files\Adobe\Adobe Illustrator 2023\Plug-ins\


Thanks a lot for all the help, it put me at least on the right track

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
May 20, 2023 May 20, 2023

Copy link to clipboard

Copied

LATEST

Interesting thread, even though I'm usually working directly with the IDEs and more so targeting InDesign.

Have you come across the stackoverflow question Exporting specific symbols using cmake? As far I understand AIP your PluginMain would be the only required export. You'd do that twice, for both the static library and the final aip-dll.

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines