# Mixing Static and Shared #

In this section we will show how by using the BUILD_SHARED_LIBS variable we can
control the default behavior of add_library, and allow control over how
libraries without an explicit type ( STATIC/SHARED/MODULE/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.

Next we are going to refactor MathFunctions to become a real library that
encapsulates using mysqrt or sqrt, instead of requiring the calling code
to do this logic. This will also mean that USE_MYMATH will not control building
MathFuctions, but instead will control the behavior of this library.

The first step is to update the starting section of the top level CMakeLists.txt
to look like:

  cmake_minimum_required(VERSION 3.3)
  project(Tutorial)

  # control where the static and shared libraries are built so that on windows
  # we don't need to tinker with the path to run the executable
  set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
  set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")

  set(CMAKE_CXX_STANDARD 11)
  set(CMAKE_CXX_STANDARD_REQUIRED True)

  option(BUILD_SHARED_LIBS "Build using shared libraries" ON)

  # the version number.
  set(Tutorial_VERSION_MAJOR 1)
  set(Tutorial_VERSION_MINOR 0)

  # configure a header file to pass the version number only
  configure_file(
    "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
    "${PROJECT_BINARY_DIR}/TutorialConfig.h"
    )

  # add the MathFunctions library
  add_subdirectory(MathFunctions)

  # add the executable
  add_executable(Tutorial tutorial.cxx)
  target_link_libraries(Tutorial PUBLIC MathFunctions)

Now that we have made MathFunctions always be used, we will need to update
the logic of that library. So, in MathFunctions/CMakeLists.txt we need to
create a SqrtLibrary that will conditionally be built when USE_MYMATH is
enabled. Now, since this is a tutorial, we are going to explicitly require
that SqrtLibrary is built statically.

The end result is that MathFunctions/CMakeLists.txt should look like:

  # add the library that runs
  add_library(MathFunctions MathFunctions.cxx)

  # state that anybody linking to us needs to include the current source dir
  # to find MathFunctions.h, while we don't.
  target_include_directories(MathFunctions
                             INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
                             )

  # should we use our own math functions
  option(USE_MYMATH "Use tutorial provided math implementation" ON)
  if(USE_MYMATH)

    # does this system provide the log and exp functions?
    include(CheckSymbolExists)
    set(CMAKE_REQUIRED_LIBRARIES "m")
    check_symbol_exists(log "math.h" HAVE_LOG)
    check_symbol_exists(exp "math.h" HAVE_EXP)

    # first we add the executable that generates the table
    add_executable(MakeTable MakeTable.cxx)

    # add the command to generate the source code
    add_custom_command(
      OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
      COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
      DEPENDS MakeTable
      )

    # library that just does sqrt
    add_library(SqrtLibrary STATIC
                mysqrt.cxx
                ${CMAKE_CURRENT_BINARY_DIR}/Table.h
                )

    # state that we depend on our binary dir to find Table.h
    target_include_directories(SqrtLibrary PRIVATE
                               ${CMAKE_CURRENT_BINARY_DIR}
                               )

    target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
    if(HAVE_LOG AND HAVE_EXP)
      target_compile_definitions(SqrtLibrary
                                 PRIVATE "HAVE_LOG" "HAVE_EXP")
    endif()

    target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
  endif()

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

  install(TARGETS MathFunctions DESTINATION lib)
  install(FILES MathFunctions.h DESTINATION include)

Next, update MathFunctions/mysqrt.cxx to use the mathfunctions and detail namespaces:

  #include <iostream>
  #include "MathFunctions.h"

  // include the generated table
  #include "Table.h"

  #include <cmath>

  namespace mathfunctions {
  namespace detail {
  // a hack square root calculation using simple operations
  double mysqrt(double x)
  {
    ...

    return result;
  }
  }
  }

We also need to make some changes in tutorial.cxx, so that it no longer uses USE_MYMATH:
1. Always include MathFunctions.h
2. Always use mathfunctions::sqrt

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
  #endif

  namespace mathfunctions
  {
    double DECLSPEC sqrt(double x);
  }

At this point, if you build everything, you will notice that linking fails
as we are combining a static library without position enabled code with a
library that has position enabled code. This solution to this is to explicitly
set the POSITION_INDEPENDENT_CODE target property of SqrtLibrary to be True no
matter the build type.

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

Exercise: Determine what command is enabling PIC for SqrtLibrary.
What happens if we remove said command?
