Monday, March 4, 2013

How to build 64-bit versions of libgeotiff for Windows

I could not find 64-bit binaries of the open-source libGeotiff library so I decided to download the most recent source code from http://trac.osgeo.org/geotiff/ so that I could use Microsoft Visual Studio 2010 to compile make my own. Other libraries are also required so I downloaded the latest source code for libTiff from http://download.osgeo.org/libtiff/ and Proj4 from http://trac.osgeo.org/proj/. I have no problems compiling libTiff and Proj4 as is but I had to modify the libGeotiff's makefile.vc file to make it compile successfully. Note that successful compilation does not necessarily mean the 64 bit executables will run successfully.



Compile 64 bit version of Proj4
  1. Extract the Proj4 source code into a folder e.g. C:\Work\src\proj-4.8.0\
  2. Select Start | All Programs | Microsoft Visual Studio 2010 | Visual Studio Tools | Visual Studio x64 Win64 Command Prompt.

    The Win64 Command Prompt appears.
  3. In the Command Prompt, type in and enter the following:

    C:\> cd \Work\src\proj-4.8.0
  4. Run the nmake build command in the Command Prompt:

    C:\> nmake /f makefile.vc

    The 64 bit version of Proj4 is created.
Compile 64 bit version of libTiff
  1. Extract the libTiff source code into a folder e.g. C:\Work\src\tiff-4.0.3\.
  2. Open up the Win64 Command Prompt if it is not  already on the screen.
  3. In the Command Prompt, type in the following command.

    C:\> cd \Work\src\tiff-4.0.3\
  4. Run the nmake build command in the Command Prompt.

    C:\> nmake /f makefile.vc

    The 64 bit version of libTiff is created.
Compile 64-bit version of libGeotiff
  1. Extract the libGeotiff source code into a folder e.g. C:\Work\src\libgeotiff-1.4.0\.
  2. Use a text editor to open up the header file geo_config.h. Add in the line #define BUILD_AS_DLL 1 as shown in red below.

    /* geo_config.h.  Generated from geo_config.h.in by configure.  */
    #ifndef GEO_CONFIG_H
    #define GEO_CONFIG_H
    
    #define BUILD_AS_DLL 1
    
    /* Define if you have the ANSI C header files.  */
    #define STDC_HEADERS 1
    
    /* Define if you have the <stdlib.h> header file.  */
    #define HAVE_STDLIB_H 1
    
    /* Define if you have the <string.h> header file.  */
    #define HAVE_STRING_H 1
    
    /* Define if you have the <strings.h> header file.  */
    #define HAVE_STRINGS_H 1
    
    #define HAVE_LIBPROJ 1
    /* #undef HAVE_PROJECTS_H */
    
    #endif /* ndef GEO_CONFIG_H */
    

  3. Use a text editor to open up the libGeotiff's makefile.vc file.
  4. Replace the contents of makefile.vc with the contents below.

    Note: the parts that were modified are colored in red.

    #
    # Typically the only thing that needs to be changed are the paths to the
    # TIFF tree.  Note that we expect an existing build tree, in part because we
    # need private include files from libtiff, but also we need access to getopt.h.
    # in the ports directory.
    #
    # You may want to add optimization options to the CFLAGS macro as well. 
    #
    
    TIFF = C:\Work\src\tiff-4.0.3
    PROJ4 = C:\Work\proj-4.8.0
    
    TIFF_INC = -I$(TIFF)\libtiff
    TIFF_LIB = $(TIFF)\libtiff\libtiff.lib
    TIFF_LIB_DLL = $(TIFF)\libtiff\libtiff_i.lib
    PROJ4_INC = -I$(PROJ4)\src
    PROJ_LIB = $(PROJ4)\src\proj.lib
    PROJ4_LIB_DLL = $(PROJ4)\src\proj_i.lib
    
    # Installation locations (with install, or devinstall targets)
    PREFIX =    release    
    BINDIR =    $(PREFIX)\bin
    LIBDIR =    $(PREFIX)\lib
    INCDIR =    $(PREFIX)\include
    DATADIR =    $(PREFIX)\share\epsg_csv
    
    #
    CC      = cl
    INCL    = -I. -Ilibxtiff $(TIFF_INC) $(PROJ4_INC)
    
    
    # Pick the first LIBS definition for a static libtiff.lib or the second
    # to link against the libtiff DLL.
    
    #LIBS    = geotiff.lib $(TIFF_LIB) $(PROJ4_LIB)
    LIBS    = geotiff_i.lib $(TIFF_LIB_DLL) $(PROJ4_LIB_DLL)
    
    DLLNAME = geotiff.dll
    
    # Set optimization or debug flags here.
    CFLAGS  = $(INCL) /MD /Ox /nologo
    #CFLAGS  = $(INCL) /MD /Zi /nologo
    
    #
    OBJS    = \
        xtiff.obj \
        geo_free.obj \
        geo_get.obj \
        geo_names.obj \
        geo_new.obj \
        geo_print.obj \
        geo_set.obj \
        geo_tiffp.obj \
        geo_write.obj \
        geo_extra.obj \
        geo_trans.obj \
        geo_normalize.obj \
        geotiff_proj4.obj \
        geo_simpletags.obj \
        cpl_csv.obj \
        cpl_serv.obj
    
    all:    geo_config.h geotiff.lib $(DLLNAME) listgeo.exe geotifcp.exe
    
    listgeo.exe:    bin\listgeo.c geotiff.lib
        $(CC) $(CFLAGS) bin\listgeo.c $(LIBS)
        
    geotifcp.exe:    bin\geotifcp.c geotiff.lib
        $(CC) $(CFLAGS) bin\geotifcp.c bin\getopt.c $(LIBS)
        
    gt_update.exe:    bin\gt_update.c geotiff.lib
        $(CC) $(CFLAGS) bin\gt_update.c bin\getopt.c geotiff.lib $(LIBS)
        
    geotiff.lib:    $(OBJS)
        lib /out:geotiff.lib $(OBJS)
    
    #
    $(DLLNAME):    $(OBJS)
        link /dll /out:$(DLLNAME) /implib:geotiff_i.lib $(OBJS) $(TIFF_LIB_DLL) $(PROJ4_LIB_DLL)
        if exist $(DLLNAME).manifest mt -manifest $(DLLNAME).manifest -outputresource:$(DLLNAME);2
    
    geo_config.h:    geo_config.h.vc
        copy geo_config.h.vc geo_config.h
    
    xtiff.obj: libxtiff\xtiff.c
        $(CC) -c $(CFLAGS) libxtiff\xtiff.c
    
    geo_free.obj: geo_free.c
        $(CC) -c $(CFLAGS) geo_free.c
    
    geo_get.obj: geo_get.c
        $(CC) -c $(CFLAGS) geo_get.c
    
    geo_names.obj: geo_names.c
        $(CC) -c $(CFLAGS) geo_names.c
    
    geo_new.obj: geo_new.c
        $(CC) -c $(CFLAGS) geo_new.c
    
    geo_print.obj: geo_print.c
        $(CC) -c $(CFLAGS) geo_print.c
    
    geo_set.obj: geo_set.c
        $(CC) -c $(CFLAGS) geo_set.c
    
    geo_tiffp.obj: geo_tiffp.c
        $(CC) -c $(CFLAGS) geo_tiffp.c
    
    geo_write.obj: geo_write.c
        $(CC) -c $(CFLAGS) geo_write.c
    
    geo_trans.obj: geo_trans.c
        $(CC) -c $(CFLAGS) geo_trans.c
    
    geo_extra.obj: geo_extra.c
        $(CC) -c $(CFLAGS) geo_extra.c
    
    geo_normalize.obj: geo_normalize.c
        $(CC) -c $(CFLAGS) geo_normalize.c
    
    geotiff_proj4.obj: geotiff_proj4.c
        $(CC) -c $(CFLAGS) geotiff_proj4.c
    
    cpl_csv.obj: cpl_csv.c
        $(CC) -c $(CFLAGS) cpl_csv.c
    
    cpl_serv.obj: cpl_serv.c
        $(CC) -c $(CFLAGS) cpl_serv.c
    
    clean:
        -del *.obj
        -del *.exe
        -del *.lib
        -del *.dll
        -del *.manifest
    
    install:    all
        -mkdir $(PREFIX)
        -mkdir $(BINDIR)
        -mkdir $(DATADIR)
        copy *.dll $(BINDIR)
        copy *.exe $(BINDIR)
        -copy csv\*.csv $(DATADIR)    
    
    devinstall:    install
        -mkdir $(INCDIR)
        -mkdir $(LIBDIR)
        copy *.lib $(LIBDIR)
        copy *.h $(INCDIR)
        copy libxtiff\*.h $(INCDIR)
        copy *.inc $(INCDIR)
        
    

  5. Save and close the text editor.

  6. Open up the Win64 Command Prompt if it is not on the screen.
  7. In the Command Prompt, type in the following.

    C:\> cd \Work\src\libgeotiff-1.4.0\
  8. Run the nmake build command in the Command Prompt.

    C:\> nmake /f makefile.vc
    The 64 bit libgeotiff files are created.

8 comments:

  1. When tried to compile libgeotiff folowing your instructions, I got the following error:

    Creating library geotiff_i.lib and object geotiff_i.exp
    geotiff_proj4.obj : error LNK2019: unresolved external symbol pj_fwd referenced
    in function GTIFProj4FromLatLong
    geotiff_proj4.obj : error LNK2019: unresolved external symbol pj_inv referenced
    in function GTIFProj4ToLatLong
    geotiff_proj4.obj : error LNK2019: unresolved external symbol pj_free referenced
    in function GTIFProj4ToLatLong
    geotiff_proj4.obj : error LNK2019: unresolved external symbol pj_init referenced
    in function GTIFProj4ToLatLong
    geotiff.dll : fatal error LNK1120: 4 unresolved externals
    NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 11.0
    \VC\BIN\x86_amd64\link.EXE"' : return code '0x460'
    Stop.

    Could you give me some advice? Thank you very much!

    ReplyDelete
  2. Hi Valeria,
    the messages say that the linker cannot find the Proj.4 functions. Can you make sure that your makefile.vc variables are pointing to the right Proj.4 include and library directories?

    HTH

    rg

    ReplyDelete
  3. Hi dominoc,
    I have the same problem with Valeria.
    I already made sure proj4 path is correct.
    But it is still running error.
    Could you give me more advice?

    ReplyDelete
  4. Valeria, 楊金融,
    makefile.vc
    $(DLLNAME): $(OBJS)
    link /dll /out:$(DLLNAME) /implib:geotiff_i.lib $(OBJS) $(TIFF_LIB_DLL) $(PROJ4_LIB_DLL)

    $(PROJ4_LIB_DLL) is not Red in post

    ReplyDelete
  5. Valeria, 楊金融,
    in makefile.vc this line
    $(DLLNAME): $(OBJS)
    link /dll /out:$(DLLNAME) /implib:geotiff_i.lib $(OBJS) $(TIFF_LIB_DLL) $(PROJ4_LIB_DLL)

    $(PROJ4_LIB_DLL) is not Red in post

    ReplyDelete
  6. First, thank you for your website it is very well documented :)

    I did the same architecture than you and did a copied/paste of your makefile.vc of libgeotiff and yet i have the following errors ..

    cl -c -I. -Ilibxtiff -IC:\Work\src\tiff-4.0.3\libtiff -IC:\Work\proj-4.8.0\src /MD /Ox /nologo libxtiff\xtiff.c
    xtiff.c
    cl -c -I. -Ilibxtiff -IC:\Work\src\tiff-4.0.3\libtiff -IC:\Work\proj-4.8.0\src /MD /Ox /nologo geo_free.c
    geo_free.c
    cl -c -I. -Ilibxtiff -IC:\Work\src\tiff-4.0.3\libtiff -IC:\Work\proj-4.8.0\src /MD /Ox /nologo geo_get.c
    geo_get.c
    cl -c -I. -Ilibxtiff -IC:\Work\src\tiff-4.0.3\libtiff -IC:\Work\proj-4.8.0\src /MD /Ox /nologo geo_names.c
    geo_names.c
    cl -c -I. -Ilibxtiff -IC:\Work\src\tiff-4.0.3\libtiff -IC:\Work\proj-4.8.0\src /MD /Ox /nologo geo_new.c
    geo_new.c
    cl -c -I. -Ilibxtiff -IC:\Work\src\tiff-4.0.3\libtiff -IC:\Work\proj-4.8.0\src /MD /Ox /nologo geo_print.c
    geo_print.c
    cl -c -I. -Ilibxtiff -IC:\Work\src\tiff-4.0.3\libtiff -IC:\Work\proj-4.8.0\src /MD /Ox /nologo geo_set.c
    geo_set.c
    cl -c -I. -Ilibxtiff -IC:\Work\src\tiff-4.0.3\libtiff -IC:\Work\proj-4.8.0\src /MD /Ox /nologo geo_tiffp.c
    geo_tiffp.c
    cl -c -I. -Ilibxtiff -IC:\Work\src\tiff-4.0.3\libtiff -IC:\Work\proj-4.8.0\src /MD /Ox /nologo geo_write.c
    geo_write.c
    cl -c -I. -Ilibxtiff -IC:\Work\src\tiff-4.0.3\libtiff -IC:\Work\proj-4.8.0\src /MD /Ox /nologo geo_extra.c
    geo_extra.c
    cl -c -I. -Ilibxtiff -IC:\Work\src\tiff-4.0.3\libtiff -IC:\Work\proj-4.8.0\src /MD /Ox /nologo geo_trans.c
    geo_trans.c
    cl -c -I. -Ilibxtiff -IC:\Work\src\tiff-4.0.3\libtiff -IC:\Work\proj-4.8.0\src /MD /Ox /nologo geo_normalize.c
    geo_normalize.c
    cl -c -I. -Ilibxtiff -IC:\Work\src\tiff-4.0.3\libtiff -IC:\Work\proj-4.8.0\src /MD /Ox /nologo geotiff_proj4.c
    geotiff_proj4.c
    geotiff_proj4.c(1333) : fatal error C1083: Cannot open include file: 'proj_api.h': No such file or directory
    NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\BIN\amd64\cl.EXE"' : return code '0x2'
    Stop.

    Tell me if you have an idea, bye

    ReplyDelete
  7. @Unknown, that was 5 years ago. It is simpler now with the latest versions. All you have to do is to do the following (from the libgeotiff README.WIN file:

    ...snip....
    o Edit makefile.vc, updating the TIFF_DIR (or TIFF_LIB and TIFF_INC) variable
    to point to the location of the tiff build tree.

    o Build using the command ``nmake -f makefile.vc''
    ---snip...

    ReplyDelete
  8. you could try to cmake and link the library as following:
    cmake -DTIFF_INCLUDE_DIR=C:\tiff-4.1.0\libtiff -DTIFF_LIBRARY=C:\tiff-4.1.0\libtiff\libtiff.lib ..
    note that cmake should be the latest version accordingt to my experiment

    ReplyDelete