[CMake] User defined variable not propagating into subdirs

Stephen Collyer scollyer at netspinner.co.uk
Fri Nov 16 10:06:23 EST 2007


Bill Hoffman wrote:

> If you want to change all the libraries in your project to shared, you
> can use the global variable BUILD_SHARED_LIBS, and use add_library
> without specifying shared or static.
> 
> $ cmake --help-command add_library
> cmake version 2.4-patch 7
>   ADD_LIBRARY
>        Add a library to the project using the specified source files.
> 
>          ADD_LIBRARY(libname [SHARED | STATIC | MODULE]
> .....  If no keywords appear as the
>        second argument, the type defaults to the current value of
>        BUILD_SHARED_LIBS.  If this variable is not set, the type
>        defaults to STATIC.

Thanks for that. I'd read it but I misunderstood it - I didn't
realise that it meant that the SHARED/STATIC thing could be omitted.

However, I've now run into another problem. I'm trying to set up
a build system so that I can build all libraries in the source
tree either statically or shared, and link all exes statically
or shared. Under Linux, this works fine. I can run (in an
out-of-source build tree)

cmake ../..

to get a static build and:

cmake -DBUILD_SHARED_LIBS=ON ../..

to get a shared build. However in Win32, something odd happens
with VS. If I run the same "cmake -DBUILD_SHARED_LIBS=ON ..\.."
in a command line window, then fire up VS and do a build on the
ALL_BUILD target, the link of the exes fails because no .lib file
is generated for the .dll. If however, I then build the clean
target for ALL_BUILD, and then do a build, the .lib file is built
and the link of the exe succeeds.

This implies to me that for some reason, on the first pass after
I build in a command line, the appropriate \D is not being passed
to switch on my _declspec(dllexport) define appropriately.

In the top level cmake list file I have:

IF (BUILD_SHARED_LIBS)
    ADD_DEFINITIONS("-DBUILD_SHARED_LIBS")
ENDIF (BUILD_SHARED_LIBS)

and in a .h file to support the build of a library called Test,
I have:

#ifndef _TESTEXPORT
#define _TESTEXPORT

#if defined (WIN32) && defined (BUILD_SHARED_LIBS)
#pragma warning(disable: 4251)
  #if defined(Test_EXPORTS)
    #define TEST_EXPORT __declspec(dllexport)
  #else
    #define TEST_EXPORT __declspec(dllimport)
  #endif /* Test_EXPORTS */
#else    /* defined (_WIN32) && defined (BUILD_SHARED_LIBS)  */
#define TEST_EXPORT
#endif

#endif   /* _TESTEXPORT */

and something like:

class TEST_EXPORt Test { ... }

in the code for the class.

Do you have any clue why this clean/build approach is needed ?
It may be down to my misunderstanding of what is happening the
first time I'm running cmake in the command line window.

-- 
Regards

Steve Collyer
Netspinner Ltd


More information about the CMake mailing list