Step 10: Selecting Static or Shared Libraries

In this section we will show how the BUILD_SHARED_LIBS variable can be used to control the default behavior of add_library(), and allow control over how libraries without an explicit type (STATIC, SHARED, MODULE or OBJECT) are built.

To accomplish this we need to add BUILD_SHARED_LIBS to the top-level CMakeLists.txt. We use the option() command as it allows users to optionally select if the value should be ON or OFF.

option(BUILD_SHARED_LIBS "Build using shared libraries" ON)

Next, we need to specify output directories for our static and shared libraries.


option(BUILD_SHARED_LIBS "Build using shared libraries" ON)

Finally, update MathFunctions/MathFunctions.h to use dll export defines:

#if defined(_WIN32)
#  if defined(EXPORTING_MYMATH)
#    define DECLSPEC __declspec(dllexport)
#  else
#    define DECLSPEC __declspec(dllimport)
#  endif
#else // non windows
#  define DECLSPEC

namespace mathfunctions {
double DECLSPEC sqrt(double x);

At this point, if you build everything, you may notice that linking fails as we are combining a static library without position independent code with a library that has position independent code. The solution to this is to explicitly set the POSITION_INDEPENDENT_CODE target property of SqrtLibrary to be True when building shared libraries.

  # state that SqrtLibrary need PIC when the default is shared libraries
  set_target_properties(SqrtLibrary PROPERTIES

Define EXPORTING_MYMATH stating we are using declspec(dllexport) when building on Windows.

# define the symbol stating we are using the declspec(dllexport) when
# building on windows
target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")

Exercise: We modified MathFunctions.h to use dll export defines. Using CMake documentation can you find a helper module to simplify this?