Configure PLplot for the Visual Studio IDE

From PLplotWiki
Revision as of 06:46, 27 September 2013 by Philrosenberg (Talk | contribs) (Rewrote the Visual Studio instructions to reflect changes for the new version)

Jump to: navigation, search

CMake allows you to generate Visual Studio solution and project files.

As of version 2.8.2 of CMake, here are a few caveats:

  • If you use Intel Fortran, the solution/project files may cause errors when building. These affect only the Fortran libraries and examples. It is due to a small bug in CMake that should be fixed with the next release.
  • For some reason you can not run the examples directly. We have not found out yet what is the matter, but there is a workaround - see below.

Workaround for examples built with Visual Studio

  • Build the PLplot libraries and examples via the ALL_BUILD project
  • Open a DOS box in the Debug directory for any one of these examples
  • Set the following environment variables:
  set path=<build>\dll\Debug;%PATH% 
  set PLPLOT_DRV_DIR=<build>\drivers    
  set PLPLOT_LIB=<source>
  where: <build> is the directory where PLplot was built
  and the directory "<source>\data" holds the .pal and .fnt files
  • In this environment you can run the sample program


Walkthrough building PLPLot with Visual Studio

Why can’t I just include all the code files in a project and press the build button?

PLplot makes every effort to be compatible with multiple different compilers on multiple OSs. It also uses third party libraries for backends/drivers. If every compiler exactly conformed to the (same) C++ and C standards and included nothing else and if every other library did the same then this would be easy. But they don’t and it isn’t. Some libraries only work on Linux or Windows and different compilers add extra features and although often the same additional features exist in different compilers they sometimes have different names or are in different header files. This all can make writing a cross platform library quite tricky.

PLplot addresses this by using a build system called CMake. This is an extra layer of code between the C/C++ code and the compiler. The CMake code is run before you try to compile the library and it attempts to detect the various platform specific differences and create (in the case of Visual Studio) .sln and .proj files and a config.h file that fits your configuration. A Walkthrough

I have spent some time trying to get CMake to work with my setup and the PLplot developers have helped with bug fixes to get this right so PLplot should now be straightforward to compile on windows. Fundamentally I want to end up with a visual studio sln file which I can use to build PLplot. It should ensure I have access to the libraries and backends/drivers that I want to use which include shapelib, wxWidgets, AGG and FreeType. Ideally it should include the examples and allow me to specify all the project properties I need so that if I update my code to the latest trunk version (which I do quite often) I don’t have to manually change lots of settings. Unfortunately there is a bit of a Linux bias to Cmake so here are some things that may catch you out, here are a few of those:

  • When specifying paths to CMAKE, capitalisation matters.
  • When CMAKE looks for additional libraries it sometimes only looks in the default Linux path so you might have to specify library locations
  • All the defaults are to build dynamically linked dynamic libraries with dynamic runtime linkage – if you want anything else then you must specify so.
  • If you need to recreate your sln files then it’s best to delete everything in your build directory and start again from scratch.

Anyhow here is a walkthrough of how I got everything working.

Backends/Drivers

PLplot could include code to write your plots to screen, memory, and the myriad of different file formats that you may want to use. However, if this was the case the developers would spend all their time looking at details of jpeg file formats or the different operating system device contexts. Instead PLplot has built in support for a few output devices and then uses other libraries referred to as drivers to output to most file types. In the walkthrough I’ll show you how to compile with just the built in outputs first, then I’ll add in shapefile support for maps using shapelib, and the wxWidgets driver with options for rendering with, AGG and Freetype.

Compiling a Basic PLplot Library

To build PLplot you will need some extra tools first. Download and install CMAKE from http://www.cmake.org/. Next if you want to use the very latest version of PLplot with the most up to date bug fixes you will need to access the Subversion repository to get the latest trunk version. To do this download tortoiseSVN from http://tortoisesvn.net/, then create a folder where you want to store the PLPlot source code (mine is D:\SourceCode\Libraries\plplot_trunk). Right click the folder and go to TortoiseSVN, Checkout. Enter the URL from http://plplot.sourceforge.net/download.php and click OK. If you ever need to update then right click the folder and click SVN Update. If you want the latest release version then you can download it from the same download link and just unzip it to a location of your choosing. If you have any doubt about whether you want the trunk version or the release version then my recommendation would be the trunk version. At the very least get the latest development release rather than the stable release as there have been a lot of updates and bug fixes since version 5.8.

Now we can start the build process. open a cmd window and run the following batch file

  C:\Program files\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat

If you installed Visual Studio elsewhere then change the path accordingly and note that on 64 bit machines the default path is in Program Files(x86). This will define environment variables that CMAKE will use so keep this cmd prompt open and do all the following commands in it.

Rather than compile PLplot ‘in place’ we’ll be building it in a separate directory, in fact we need two directories, one for release and one for debug. So create a these build directories. Mine are at D:\Sourcecode\Libraries\plplot_staticbuild_release, with another in the same location but ending debug. I think it is possible to create a release and debug version together in one .sln but i think there are potential clashes so I highly recommend creating a separate release and debug version in separate folders. In your cmd prompt navigate to the release directory.

If you wish to add any extra compiler flags do so by setting the environment variables CXXFLAGS and CFLAGS in your cmd prompt. I use this facility to set the Unicode options

  set CXXFLAGS=/DUNICODE /D_UNICODE
  set CFLAGS=/DUNICODE /D_UNICODE

Note that you almost always want CXXFLAGS and CFLAGS to be identical.

If you already have wxWidgets installed then you may wish to stop PLplot finding it for this basic build. To do so type

  %WXWIN%

and make a note of the path for later. Then enter

  set WXWIN=

Now call CMAKE as follows:

  cmake "D:/SourceCode/Libraries/plplot trunk" -G "Visual Studio 9 2008" -DPL_DOUBLE=ON -DLIB_TAG="sud" -DBUILD_TEST=ON -DCMAKE_INSTALL_PREFIX="D:\SourceCode\Libraries\plplotinstall"  -DCMAKE_CONFIGURATION_TYPES="Debug" -DBUILD_SHARED_LIBS=OFF -DSTATIC_RUNTIME=ON

A full description of the parameters can be found in the reference below. You can obviously change them to suit your needs. Hopefully after a minute or two the screen output should end with

  --Configuring done
  --Generating done
  --Build files have been written to D:/SourceCode/Libraries/plplot_staticbuild_release

If you now go to your build directory you should see a solution which you can open in Visual Studio. Just open it up, right click the INSTALL project and select build, this will build your library and put it in the install directory. I use the LIB_TAG parameter to identify this as a static (s), Unicode (u) debug (d) library. Unfortunately some of the built libraries do not get your LIB_TAG added. So go to your install directory and do this manually, this stops them getting overwritten when you build the release version. You should now be able to find the examples in the build directory and try them out. You get a choice of which built in driver you want to use. There is a memory one, a Windows one that outputs to screen and ones that output to ps, svg and xfig files. Once you have a debug version, you can repeat the process in a new directory to create a debug version, make sure you change the LIB_TAG or install directory to avoid overwriting. Well done you now have PLplot up and running.

Other Libraries and Backends

PLplot relies on a number of drivers and backends to extend its output capabilities and allow reading of certain data files. I use a few of these and will guide you through adding them. Don’t be tempted to download precompiled .lib and .dll files. If you do then they may not have been compiled with the same setting that you use and may generate hard to fix linker errors. Problem setting can include character set (Unicode, vs multibyte vs not set) and static/dynamic linking to the runtime libraries (multithreaded, multithreaded dll, multithreaded debug, multithreaded debug dll). If you don’t know what static and dynamic linking are then find out because it will be the bane of your programming life if you don’t. I tend to add u to the end of a library name to indicate Unicode and s to indicate static (not dynamic) linkage to the runtime library and d to indicate debug.

Shapelib

Shapelib allows you to read in .shp shapefileswhich contain vector map information into PLplot . PLPlot already has a coarse resolution global map included, but if you would like higher resolution then you need to add Shapelib. Global files with 10, 50 or 110 mile resolution are available from http://www.naturalearthdata.com and you can find other files online as you need. Shapelib itself is easy to compile, download it from http://shapelib.maptools.org/ create a new windows library project, add all the files and build debug and release versions as needed. There is no need to specify Unicode. To use it in PLplot add the following commands to your CMake call

  -DHAVE_SHAPELIB=ON -DSHAPELIB_INCLUDE_DIR="D:/SourceCode/Libraries/shapelib-1.3.0/include/shapelib" -DSHAPELIB_LIBRARY="D:/SourceCode/Libraries/shapelib-1.3.0/lib/shapelibsd.lib"

Of course replace the values with ones appropriate for your system and make sure you use the debug or release library appropriately. Now in calls to plmap you can replace the map name with the path to a shapefile and the lines from this file will be used to draw the map.

wxWidgets

I use wxWidgets for GUI output, it also allows output to various other graphics types like png, bmp, jpg, ps. If you wish to do the same then the best way is to install wxPack which is a fully working version of wxWidgets for Windows. It comes with a Visual Studio .sln file so saves you a lot of hassle. There are loads of instructions for compiling wxWidgets online, so I won’t repeat it all here. However you may wish to enable wxGraphicsContext (which gives anti-aliased output) and wxPostscriptDC to output to ps files. To do this, go through all the various setup.h and setup0.h and set

  #define wxUSE_GRAPHICS_CONTEXT 1
  #define wxUSE_POSTSCRIPT 1

Open the wxWidgets .sln file and if you wish to change between static and dynamic Runtime then change this in the project properties. Finally go to build, batch build and build all the versions of the library. This can take some time.

For Visual Studio 2012 Users – I have found a few problems with building wxWidgets in VS2012 so I thought I’d add them here.

  • First the Batch Build option is hidden. You can display it by going to Tools, customize, Commands and select the build menu.
  • If you get a lot of build errors talking about CL.exe then this is caused by clashes between intermediate files of different projects. To fix it select all the projects in the solution explorer then right click them and select properties. Change the configuration to All Configurations then go to Configuration properties, General and change Intermediate Directory to $(ProjectName)\$(Platform)\$(Configuration)\.
  • If you get a compilation error saying that the file pbt.h cannot be found in windows.cpp then go to the relevant line and comment it out. This header is no longer needed in wxWidgets and no longer included with Visual Studio but the #include got forgotten and left in the source.
  • Finally if you want to build a 64 bit version do not try changing the Build Target in the project properties, this causes various linker errors. Instead go to Build, Configuration Manager... and in the active solution platform select <new> then select x64. This will create 64 bit configurations for all projects. Unfortunately you cannot build 64 bit and 32 bit libraries at the same time and if you have built a 32 bit library and want to build the 64 bit version (or vice versa) then you must clean the project first. See the install-msw-2.8.12.txt file shipped with wxWidgets for more info.

Once you have wxWidgets built PLplot will automatically look for the WXWIN environmental variable which is created by wxPack, or should have been created by you if you set up wxWidgets manually. If you disabled wxWidgets above, then enter the following at the command prompt

  set WXWIN=path/you/wrote/down/earlier

If PLplot finds this environmental variable then it will include wxWidgets in the build. However, it seems that CMAKE doesn’t automatically determine if you are building with Unicode, so if you are then you must specify which wxWidgets build to use by adding the following parameter to your CMake command

  DwxWidgets_CONFIGURATION=mswud

Or for the release version use mswu, just like the suffix at the end of the wxWidgets library files.

AGG and FreeType The wxWidgets driver can use three backends. The wxDC and wxGraphicsContect are part of wxWidgets and use Windows drawing routines. This means if you port your software to Linux the code will then use Linux drawing routines which may be slightly different. This might not be a big deal, but in case it is you can also make use of the cross platform AGG library to render anti-aliased graphics and AGG can either use PLplot’s basic text or the FreeType library for Unicode fonts. If you wish to use them then download the code for these projects. Both are quite straightforward. AGG seem to pride themselves on only using ‘pure’ C so for AGG you can just download the source from http://www.antigrain.com/ and add all the files to a visual studio project and build it. If you are using FreeType then you can download the source form http://www.freetype.org/. The download includes a .sln file to build with Visual Studio.

If using both FreeType and AGG then you should copy the files from your_agg_directory\font_freetype to your_agg_directory\include\agg2. You may wish to do the same with those in font_win32_tt, but it’s not needed for PLplot at present.

Also don’t forget to ensure your character set and run time library linkage are set as you want them. To include AGG when you compile PLplot add the following parameters

  DHAVE_AGG=ON -DAGG_INCLUDE_DIR="D:/SourceCode/Libraries/agg-2.4/include" -DAGG_LIBRARIES="D:/SourceCode/Libraries/agg-2.4/VC++/AGG/lib/AGGsud.lib"

For FreeType use

  -DWITH_FREETYPE=ON -DFREETYPE_INCLUDE_DIR="D:/SourceCode/Libraries/freetype-2.4.8/include" -DFREETYPE_LIBRARY="D:/SourceCode/Libraries/freetype-2.4.8/objs/win32/vc2008/freetypesud.lib"

But of course change the paths to match your system.

Summary and reference

So just so you see the whole thing, my final CMake command for a debug build is

cmake "D:/SourceCode/Libraries/plplot_trunk" -G "Visual Studio 9 2008" -DPL_DOUBLE=ON -DLIB_TAG="su" -DBUILD_TEST=ON -DCMAKE_INSTALL_PREFIX="D:\SourceCode\Libraries\plplotinstall" -DBUILD_SHARED_LIBS=OFF -DCMAKE_CONFIGURATION_TYPES="Debug" -DSTATIC_RUNTIME=ON -DwxWidgets_CONFIGURATION=mswud -DHAVE_SHAPELIB=ON -DSHAPELIB_INCLUDE_DIR="D:/SourceCode/Libraries/shapelib-1.3.0/include/shapelib" -DSHAPELIB_LIBRARY="D:/SourceCode/Libraries/shapelib-1.3.0/lib/shapelibsd.lib"  -DHAVE_AGG=ON -DAGG_INCLUDE_DIR="D:/SourceCode/Libraries/agg-2.4/include" -DAGG_LIBRARIES="D:/SourceCode/Libraries/agg-2.4/VC++/AGG/lib/AGGsud.lib" -DWITH_FREETYPE=ON -DFREETYPE_INCLUDE_DIR="D:/SourceCode/Libraries/freetype-2.4.8/include" -DFREETYPE_LIBRARY="D:/SourceCode/Libraries/freetype-2.4.8/objs/win32/vc2008/freetypesud.lib"

For reference here is a quick rundown of each of the parameters

“D:/SourceCode/Libraries/plplot trunk”: the path to my source directory – case sensitive.

-G “Visual Studio 9 2008”: the compiler I want to generate a project/solution for.

-DPL_DOUBLE=ON: use doubles, rather than floats in PLplot. Also adds d to the library names.

-DLIB_TAG=”su”: this will append “su” to the end of the library name and is an indicator to me that I’m using static linkage with the Unicode character set. I use sud for static Unicode debug etc.

-DBUILD_TEST=ON: Indicates I want to create projects for the examples. Set to OFF to not build them.

-DCMAKE_INSTALL_PREFIX=”D:\SourceCode\Libraries\plplotinstall” The directory you want your final libraries to end up in, it will be created if it doesn’t exist. If you leave this blank it defaults to C:\Program Files\PLplot, however in Windows Vista or later UAC will stop the file being written here unless you run Visual Studio as administrator.

-DCMAKE_CONFIGURATION_TYPES=”Release”: The configuration to use in the project. You can run create multiple configurations in one solution by listing them separated by semicolons, but if using Shapelib, FreeType or AGG this causes linking problems with the examples as you can’t specify linkage against the release and debug versions separated by semicolons. It also causes issues with installing to one directory so it’s best to create on sln for each configuration. You can include Release, Debug, MinSizeRel and RelWithDebInfo.

-DSTATIC_RUNTIME=ON: This causes us to link against the static runtime (equivalent to /MT or /MTd flags). Set it to OFF if you want to link against the dynamic runtime (equivalent to /MD or /MDd).

-DBUILD_SHARED_LIBS=OFF Build a .lib rather than a .dll. If you don’t set this the default will be to build dlls.All the options above except the source directory and compiler are optional and will be set to default values if excluded.

Anything with AGG in: These point out that I want to use AGG and specifies the location of header files and the library itself. The library is only needed if –DBUILD_TEST is ON. None are needed if you are not using AGG.

Anything with FREETYPE in: As with the AGG stuff it indicates I want to use FreeType and gives the location of the headers and library. Note that the variables have slightly different names to the AGG ones. Again the library is only needed when building the examples.

Anything with SHAPELIB in: As for the FREETYPE and AGG parameters, but for shapelib.

There are also other customisable options and after you’ve run CMAKE you can examine the CMakeCache.txt file that is created in your build directory to see others (prepend -D to define them on the command line) or look at the wiki page or CMAKE documentation.









Having just been throught this process I thought I'd make sure it was available online for others. I've just compiled PLPLot 5.9.9 with wxWidgets 2.8 using Microsoft Visual Studio 2008 Express on a Windows 7 machine. It is a bit of an arduous process but it should work. My reason for wanting to do this is that I have wxWidgets compiled using Visual Studio in various differet configurations (with/without unicode, static/dynamic) and needed PLPlot with matching configurations and similar ease of changing proerties/recompiling. Here are the instructions. If you are not using wxWidgets then you can ignore the wxWidget specific instructions.

If you want to write GUI applications using wxWidgets then you probably already have a working sln file for compiling wxWidgets. If not then download one from wxPack - I found this the most reliable way to get a wxWidgets working on Windows. If you have just installed wxPack then navigate to the install folder and open the sln file. Now Go to Build->Batch Build, select all and build. I think some projects in the solution depend on others so it might take three or four attempts to get everything to compile. I never got the Universal configurations to compile, but don't use them so am not worried.

Now, to get antialiased graphics to work with wxWidgets you can use wxWidgets Built in antialiasing using the graphics context or you can use the AGG library. I seem to remember AGG was quite easy to build, so I'll leave that for you to work out. For Fonts again you have the option of wxWidgets internal or the FreeType library. Again you need to build FreeType if you want it.

If you want to use wxWidgets antialiasing you must recompile wxWidgets. In your wxWidgets directory find all instances of setup.h or setup0.h and set

  #define wxUSE_GRAPHICS_CONTEXT 1

while I was at it I also set

  #define wxUSE_POSTSCRIPT 1

This isn't needed for plplot but I thought as I was recompiling anyway I'd add it in.

Now right click the project core, and select properties. Under librarian->General->Additional dependancies or Linker->Input additional Dependancies add gdiplus.lib

Now go to Build->Batch Build and Build all. If you get errors about a manifest then go to Build-> Batch Build and ReBuild all. You may need to do repeated builds to get everything built as above. If you got the manifest error and rebuilt then do additional builds, not rebuilds until everything is built.

Download the PlPlot Source and unzip it. In this example I've chosen to unzip to D:\plplot-5.9.9. Make a new directory alongside this, I've chosen to call it D:\plplot-5.9.9_staticbuild.

Install Cmake if you don't already have it.

open a command prompt and enter

  c:\program files\microsoft visual studio 9.0\common7\tools\vsvars32.bat

This may be different if you installed visual studio elsewhere, have a different version of visual studio or I guess the 32 may be a 64 on 64 bit machines.

Then

  d:\
  cd d:\plplot-5.9.9_staticbuild

Obviously modify this if you want to build somewhere else Now you can use Cmake to generate your visual studio solution/project files. The default command is

  cmake d:/plplot-5.9.9 -G "Visual Studio 9 2008" -DPL_DOUBLE=ON -DBUILD_SHARED_LIBS=OFF

This will make your project files with plplot using double precision (in theory) to generate static libraries. There are some other options you might want to add, such as

  -DENABLE_wxwidgets=ON
  -DHAVE_AGG=ON
  -DHAVE_FREETYPE=ON
  -DLIB_TAG="s"

These are pretty self explanitory. The DLIB_TAG option adds s to the end of the project files. I use this to indicate static. You may wish to change the projects to unicode as the default for projects created with CMake is multibyte character set and the default for projects created in MSVC++ is unicode. The text type must match otherwise string related linking errors will occur. After a bit of googling the command to do this seems to be

     -DCMAKE_CXX_FLAGS="/D_UNICODE /DUNICODE"

but wen I use this option the library will not build so I suggest you change to Unicode manually using project properties after the projects have been created.

You can see CMake options for PLplot for more PLplot specific options. You can also set SHARED_LIBS to OFF to generate dynamic libraries but I haven't tried this yet.

After calling Cmake you should have a sln file in your directory and a config.h file with sensible settings. It might be worth checking your config.h file and your plconfig.h file. I had to uncomment the line

  #define PL_DOUBLE

despite using the DPL_DOUBLE option

I had to do a bit of shuffling of code to get AGG and freetype to work. I had to copy the contents of my AGG include directory and the agg_font_freetype.h file from my agg folders to d:\plplot5.9.9_staticbuild\agg2

Now open the sln file if you haven't done so already. The projects you can see in the solution do all sorts of things it seems including copying libraries, reporting errors online and building the demos. The projects needed for building the libraries are

  • plplot for the main C interface
  • plplotcxx for the c++ interface
  • plplotwxWidgets for the wxplplotstream and wxplplotwindow objects for use in wxWidget applications
  • qsatime - don't know what this does
  • csirocsa - don't know what this does either

I deleted all projects except for these ones to make life easier. You may want to include the examples or something. Instead of compiling these projects into 5 separate libraries I copied the source files from these projects into the plplot project to complile into one library. I didn't copy the plplotwxwidgets files accross because I don't intend to use these classes, but I presume you should be able to do so if you wish.

I had to make some changes to the code to make the library build. I had to add

  #ifdef __cplusplus
  extern "C" {
  #endif

to the beginning and

  #ifdef __cplusplus
  }
  #endif

to the end of csa.h and qsatime.h. You might also need to go through csa.c and add explicit typecasts to all calls to malloc.

Now you need to go through the project properties to ensure everything is as you want it, eg you are linking against the correct runtime library, the resulting libs are called the correct names and in a folder where you want them, etc.

I then went through a whole world of pain because whenever I tried to link one of my wxWidget projects to my new plplot library the code hung during wxWidgets initialisation. I've now traced this to a bug in the wxwidgets.h file. Open this file and search for a the lines

  wxAppInitializer                                                 \
  wxAppInitializer( (wxAppInitializerFunction) wxPLCreateApp );    \

and replace them with

  wxAppInitializer                                                 \
  wxAppInitializer( (wxAppInitializerFunction) (wxApp::GetInitializerFunction()==NULL ? wxPLCreateApp : wxApp::GetInitializerFunction()) );    \

You may want to create dlls as well as static libs. If so create a new folder called plplot-5.9.9_sharedlibs and start the process again from scratch using this folder. If you try to create a shared library solution in the same directory as the static library then your config files will be overwritten and your static build will stop working.

Using the latest development version

This morning (28th june 2012) I tried for the first time to build the latest development version (Trunk). This went rather smoother than when I tried version 5.9.9. Kudos to the developers for improving things and here are the instructions for using it. If you are using wxWidgets I would recommend using Trunk as there have been some bug fixes since 5.9.9.

If you wish to use wxWidgets then install it as described above.

If you wish to use AGG and/or FreeType then download and build those libraries.

Install Tortoise SVN and use this to get the PLplot source from the repository. Details are at subversion access. If you have a preffered method for accessing repositories then you can obviously use this instead.

Install CMake.

As described above, create a working directory for the library, start a cmd prompt and cd to the new directory.

Run the vsvars32.bat file as described above.

Run CMake as described above with suitable options for static linkage and use of wxWidgets/AGG/FreeType.

copy the needed AGG header files into a folder agg2 in your working directory as described above.

Open the .sln file with Visual Studio

In Visual Studio you will see a number of projects. the ones that actually create libraries are csirocsa plplotcxx plplot plplotwxwidgets qsatime You may wish to change settings in these projects. For example you may wish to change the filenames or locations of the generated libraries or the linkages or if you add the four other libraries as Additional Dependancies to plplot then they should be bundled together allowing you to include PLplot as a single library.

Right click the ALL_BUILD and select build. This project will cause the necessary libraries to be built. If any of the 5 projects above fail then build again - it might be that if you've added dependancies the build order means the needed libraries don't exist yet when a project that needs them is being built.

I have just submitted the above fix for wxwindows.h as a patch so this should be available in development version soon.