[CMake] Help using CMake & Expat in Windows

Michael Jackson mike.jackson at bluequartz.net
Sat Jul 31 11:17:45 EDT 2010


Not sure if your issues are expat specific or just finding libraries
in general but here is what I did.

I created my own fork of Expat
(http://gitorious.bluequartz.net/support-libraries/expat) which I
build and install. I then set the "EXPAT_INSTALL" environment variable
in my system.

 Then in my project I use a custom FindExpat.cmake
(http://gitorious.bluequartz.net/mxa/mxadatamodel/trees/master/Resources/CMake/Modules)
in order to locate the Expat library. This will also set some cmake
variables like EXPAT_INCLUDE_DIRS and EXPAT_LIBRARIES.

 In my projects CMakeLists.txt file I have the following:

include_directories( ${EXPAT_INCLUDE_DIRS} )

Does any of that help?
_________________________________________________________
Mike Jackson                  mike.jackson at bluequartz.net

On Sat, Jul 31, 2010 at 10:24 AM, Clark Taylor <clark.n.taylor at gmail.com> wrote:
> Please ignore my last e-mail.  For some reason, my e-mail ate Stefan's
> earlier response, but I just saw it in the digest I receive.  I'll try his
> suggestions out and see if it works.
> Clark
>
> On Sat, Jul 31, 2010 at 10:21 AM, Clark Taylor <clark.n.taylor at gmail.com>
> wrote:
>>
>> This is very helpful.  Thank you!
>> My other question though is how can I get Cmake to add the correct
>> information into the visual studio solution.  Even though I have put in the
>> directory names in the cmake gui, I then have to add the same directories
>> manually to the solution.  Did I miss something simple.  To me the advantage
>> of cmake is that it automatically sets everything up for you in the Visual
>> Studio solutions, which is great.  However, even when I manually put in the
>> directories in the cmake-gui, it doesn't seem to add the information to the
>> solution.  With that information in there, I can definitely have it copy the
>> .dll to the correct location.
>> Thanks again for all your help.
>> Clark
>>
>> On Sat, Jul 31, 2010 at 9:44 AM, Michael Jackson
>> <mike.jackson at bluequartz.net> wrote:
>>>
>>> On Fri, Jul 30, 2010 at 7:15 PM, John Drescher <drescherjm at gmail.com>
>>> wrote:
>>> >> I have created a very simple CMake file (I am a newbie) that works
>>> >> wonderfully in Linux, but am having problems in Windows.  The
>>> >> CMakeLists.txt
>>> >> is below
>>> >>
>>> >> #I think 2.6 is required for some of things I do below, but I am not
>>> >> sure
>>> >> CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
>>> >>
>>> >> # This is the CMake file for my application.  This
>>> >> # will be my first CMake file of decent size, so please excuse
>>> >> # any particularly bad syntax :)
>>> >> PROJECT(MyApp)
>>> >> FIND_PACKAGE(wxWidgets REQUIRED)
>>> >> FIND_PACKAGE(OpenCV REQUIRED)
>>> >> FIND_PACKAGE(EXPAT REQUIRED)
>>> >> INCLUDE (${wxWidgets_USE_FILE} ${OpenCV_USE_FILE}
>>> >> ${EXPAT_INCLUDE_DIRS})
>>> >>
>>> >> SET(Headers myApp.h myAppGUI.h myAppGUImpl.h
>>> >> Coordinates/Coordinates.h)
>>> >> SET(Src myApp.cpp myAppGUI.cpp myAppGUImpl.cpp
>>> >> Coordinates/Coordinates.cpp)
>>> >> ADD_EXECUTABLE(myApp ${Headers} ${Src})
>>> >> TARGET_LINK_LIBRARIES(myApp ${wxWidgets_LIBRARIES} ${OpenCV_LIBS}
>>> >> ${EXPAT_LIBRARIES})
>>> >>
>>> >> #End of code
>>> >>
>>> >> Everything works great in Linux, but when I try to use this in
>>> >> Windows, I
>>> >> have series of problems, all inter-related.
>>> >>
>>> >> Problem #1.  While wxWidgets and OpenCV work seamlessly, Cmake can't
>>> >> find
>>> >> the expat libraries.  (They are installed.  I installed the
>>> >> expat libraries
>>> >> using the basic windows download and install package).
>>> >
>>> > CMake rarely finds libraries on windows. The main reason is there is
>>> > no OS standard path for libraries or header files. For me its even
>>> > less likely to find stuff since I build on X: and not the same drive
>>> > as the OS. To fix this normally you run cmake-gui and it tells me it
>>> > can not find a package set the projectname_dir variable. After setting
>>> > this variable in cmake-gui all is well.
>>> >
>>> >>
>>> >> Problem #2.  While I can overcome problem #1 by hardcoding in where
>>> >> the
>>> >> expat include directory and library files are (setting the values in
>>> >> the
>>> >> CMake GUI), when I then open up the resulting solution in Visual
>>> >> Studio 2008
>>> >> Express and compile my code, the compiler gives the error "can't find
>>> >> expat.h"
>>> >>
>>> >
>>> > That is normally the correct solution.
>>> >
>>> >>
>>> >> Problem #3.  I can fix that problem as well by directly modifying the
>>> >> solution properties, but then when I run the project, it dies because
>>> >> it
>>> >> can't find libexpat.dll.
>>> >>
>>> > In your CMakeLists.txt have it copy the libexpat.dll to your debug,
>>> > release .. folder. Do that as a custom build step or an install step.
>>> >
>>> > Here are two ways I do this for Qt libraries (modify this for
>>> > libexpat):
>>> >
>>> > The first uses an install.
>>> >
>>> > IF (WIN32)
>>> > IF (GET_RUNTIME)
>>> > INSTALL(FILES
>>> >                "${QT_BINARY_DIR}/QtCored${QT_VERSION_MAJOR}.dll"
>>> >                "${QT_BINARY_DIR}/QtXmld${QT_VERSION_MAJOR}.dll"
>>> >                "${QT_BINARY_DIR}/QtTestd${QT_VERSION_MAJOR}.dll"
>>> >                "${QT_BINARY_DIR}/QtGuid${QT_VERSION_MAJOR}.dll"
>>> >                "${QT_BINARY_DIR}/QtNetworkd${QT_VERSION_MAJOR}.dll"
>>> >                "${QT_BINARY_DIR}/QtScriptd${QT_VERSION_MAJOR}.dll"
>>> >                DESTINATION ${EXECUTABLE_OUTPUT_PATH}/Debug
>>> > )
>>> > INSTALL(FILES
>>> >                "${QT_BINARY_DIR}/QtCore${QT_VERSION_MAJOR}.dll"
>>> >                "${QT_BINARY_DIR}/QtXml${QT_VERSION_MAJOR}.dll"
>>> >                "${QT_BINARY_DIR}/QtTest${QT_VERSION_MAJOR}.dll"
>>> >                "${QT_BINARY_DIR}/QtGui${QT_VERSION_MAJOR}.dll"
>>> >                "${QT_BINARY_DIR}/QtNetwork${QT_VERSION_MAJOR}.dll"
>>> >                "${QT_BINARY_DIR}/QtScript${QT_VERSION_MAJOR}.dll"
>>> >                DESTINATION ${EXECUTABLE_OUTPUT_PATH}/RelWithDebInfo
>>> > )
>>> > ENDIF(GET_RUNTIME)
>>> > ENDIF(WIN32)
>>> >
>>> > The second uses a custom build step:
>>> >
>>> > # Copy the needed Qt libraries into the Build directory. Also add
>>> > installation
>>> > # and CPack code to support installer generation.
>>> > # this is a complete hack for Visual Studio to copy the Qt libraries.
>>> > if ( NOT Q_WS_MAC)
>>> >   if (DEFINED QT_QMAKE_EXECUTABLE)
>>> >       SET (QTLIBLIST QtCore QtGui)
>>> >
>>> >       IF (MSVC)
>>> >           set(TYPE "d")
>>> >           FOREACH(qtlib ${QTLIBLIST})
>>> >             IF (WIN32)
>>> >               GET_FILENAME_COMPONENT(QT_DLL_PATH_tmp
>>> > ${QT_QMAKE_EXECUTABLE} PATH)
>>> >               file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/Debug)
>>> >               file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/Release)
>>> >               file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/MinSizeRel)
>>> >               file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/RelWithDebInfo)
>>> >               INSTALL(FILES ${QT_DLL_PATH_tmp}/${qtlib}${type}d4.dll
>>> >                   DESTINATION ./
>>> >                   CONFIGURATIONS Debug
>>> >                   COMPONENT Applications)
>>> >               INSTALL(FILES ${QT_DLL_PATH_tmp}/${qtlib}4.dll
>>> >                   DESTINATION ./
>>> >                   CONFIGURATIONS Release
>>> >                   COMPONENT Applications)
>>> >               add_custom_target(ZZ_${qtlib}-Debug-Copy ALL
>>> >                           COMMAND ${CMAKE_COMMAND} -E
>>> >
>>> >  copy_if_different ${QT_DLL_PATH_tmp}/${qtlib}${TYPE}4.dll
>>> >                           ${PROJECT_BINARY_DIR}/Debug/
>>> >                           COMMENT "Copying ${qtlib}${TYPE}4.dll to
>>> > ${PROJECT_BINARY_DIR}/Debug/")
>>> >               add_custom_target(ZZ_${qtlib}-Release-Copy ALL
>>> >                           COMMAND ${CMAKE_COMMAND} -E
>>> >                                                   copy_if_different
>>> > ${QT_DLL_PATH_tmp}/${qtlib}4.dll
>>> >                           ${PROJECT_BINARY_DIR}/Release/
>>> >                           COMMENT "Copying ${qtlib}4.dll to
>>> > ${PROJECT_BINARY_DIR}/Release/")
>>> >             ENDIF (WIN32)
>>> >           ENDFOREACH(qtlib)
>>> >
>>> >       endif(MSVC)
>>> >   endif(DEFINED QT_QMAKE_EXECUTABLE)
>>> > endif(NOT Q_WS_MAC)
>>> >
>>> >
>>> >>
>>> >> So, in summary, I think cmake is completely ignoring libexpat, even
>>> >> when I
>>> >> explicitly tell it (in the gui) where the include and library files
>>> >> are.
>>> >>
>>> >> Any ideas?
>>> >>
>>> > Follow the advice by Stefan. I too believe that is the reason why the
>>> > include did not work.
>>> >
>>> > John
>>>
>>> Here is a slightly improved version of the above:
>>>
>>>
>>> # --------------------------------------------------------------------
>>> # Copy the needed Qt libraries into the Build directory. Also add
>>> installation
>>> # and CPack code to support installer generation.
>>> # --------------------------------------------------------------------
>>> if ( NOT Q_WS_MAC AND MSVC AND DEFINED QT_QMAKE_EXECUTABLE)
>>>
>>>    SET (QTLIBLIST QtCore QtGui)
>>>    SET (QTPLUGINLIST qgif qjpeg qtiff)
>>>    set (BUILD_TYPES "Debug;Release")
>>>
>>>    foreach (btype ${BUILD_TYPES})
>>>        string(TOUPPER ${btype} BTYPE)
>>>        file(MAKE_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${btype})
>>>        foreach(qtlib ${QTLIBLIST})
>>>
>>>            string(TOUPPER ${qtlib} QTLIB)
>>>           # message(STATUS "QT_${QTLIB}_LIBRARY_${BTYPE}:
>>> ${QT_${QTLIB}_LIBRARY_${BTYPE}}")
>>>            GET_FILENAME_COMPONENT(DLL_NAME
>>> ${QT_${QTLIB}_LIBRARY_${BTYPE}} NAME_WE)
>>>           # message(STATUS "DLL_NAME: ${DLL_NAME}")
>>>            GET_FILENAME_COMPONENT(QT_BIN_PATH ${QT_QMAKE_EXECUTABLE}
>>> PATH)
>>>           # message(STATUS "QT_BIN_PATH: ${QT_BIN_PATH}")
>>>
>>>            INSTALL(FILES ${QT_BIN_PATH}/${DLL_NAME}.dll
>>>                DESTINATION ./
>>>                CONFIGURATIONS ${btype}
>>>                COMPONENT Applications)
>>>
>>>            add_custom_target(Z_${qtlib}-${BTYPE}-Copy ALL
>>>                        COMMAND ${CMAKE_COMMAND} -E copy_if_different
>>> ${QT_BIN_PATH}/${DLL_NAME}.dll
>>>                        ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${btype}/
>>>                        COMMENT "Copying
>>> ${QT_BIN_PATH}/${DLL_NAME}.dll to
>>> ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${btype}/")
>>>
>>>        endforeach()
>>>
>>>    # For this project we also need to copy the imageformat Qt plugins
>>> which should have already been defined
>>>    # in the cmake variables QTPLUGINS_DEBUG, QTPLUGINS_RELEASE and
>>> QTPLUGINS
>>>        file(MAKE_DIRECTORY
>>> ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${btype}/plugins/imageformats)
>>>        foreach(plugin ${QTPLUGINLIST})
>>>            string(TOUPPER ${plugin} PLUGIN)
>>>           # message(STATUS "QT_${QTLIB}_LIBRARY_${BTYPE}:
>>> ${QT_${QTLIB}_LIBRARY_${BTYPE}}")
>>>            GET_FILENAME_COMPONENT(DLL_NAME
>>> ${QT_${PLUGIN}_PLUGIN_${BTYPE}} NAME_WE)
>>>           # message(STATUS "DLL_NAME: ${DLL_NAME}")
>>>           # GET_FILENAME_COMPONENT(QT_BIN_PATH ${QT_QMAKE_EXECUTABLE}
>>> PATH)
>>>           # message(STATUS "QT_BIN_PATH: ${QT_BIN_PATH}")
>>>
>>>            INSTALL(FILES ${QT_PLUGINS_DIR}/imageformats/${DLL_NAME}.dll
>>>                DESTINATION ./plugins/imageformats
>>>                CONFIGURATIONS ${btype}
>>>                COMPONENT Applications)
>>>
>>>            add_custom_target(Z_${plugin}-${BTYPE}-Copy ALL
>>>                        COMMAND ${CMAKE_COMMAND} -E copy_if_different
>>> ${QT_PLUGINS_DIR}/imageformats/${DLL_NAME}.dll
>>>
>>> ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${btype}/plugins/imageformats/
>>>                        COMMENT "Copying
>>> ${QT_PLUGINS_DIR}/imageformats/${DLL_NAME}.dll to
>>> ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${btype}/plugins/imageformats")
>>>
>>>        endforeach(plugin ${QTPLUGINS_${BTYPE}})
>>>
>>>                #write a qt.conf file into the application directory and
>>> install it
>>>                file(WRITE
>>> ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${btype}/qt.conf "")
>>>                INSTALL(FILES
>>> ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${btype}/qt.conf
>>>                                DESTINATION .
>>>                                CONFIGURATIONS ${btype}
>>>                                COMPONENT Applications )
>>>
>>>    endforeach()
>>> endif()
>>>
>>> Mike Jackson
>>
>>
>>
>> --
>> Clark
>
>


More information about the CMake mailing list