Skip to content

Commit

Permalink
Continue making it a proper library
Browse files Browse the repository at this point in the history
  • Loading branch information
drdanz committed Jun 25, 2018
1 parent e874077 commit 84afb1a
Show file tree
Hide file tree
Showing 13 changed files with 1,120 additions and 84 deletions.
62 changes: 58 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,71 @@ project(shlibpp
DESCRIPTION "Tiny cross-platform plug-in system (dll, so, dylib)"
LANGUAGES CXX)

set(BUILD_SHARED_LIBS 1)
# For now keep YCM as a soft dependency
find_package(YCM 0.8.1 QUIET)
if(NOT YCM_FOUND)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
endif()

# Set output directories for targets
include(GNUInstallDirs)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")

# Set postfix for debug builds on MSVC
if(MSVC)
set(CMAKE_DEBUG_POSTFIX "d")
endif()

# Encourage user to specify a build type (e.g. Release, Debug, etc.), otherwise set it to Release.
if(NOT CMAKE_CONFIGURATION_TYPES)
if(NOT CMAKE_BUILD_TYPE)
message(STATUS "Setting build type to 'Release' as none was specified.")
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY VALUE "Release")
endif()
endif()

# Shared/Dynamic or Static library?
option(BUILD_SHARED_LIBS "Build libraries as shared as opposed to static" ON)

# Enable RPATH?
option(SHLIBPP_ENABLE_RPATH "Enable RPATH for this library" ON)
mark_as_advanced(SHLIBPP_ENABLE_RPATH)
include(AddInstallRPATHSupport)
add_install_rpath_support(BIN_DIRS "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}"
LIB_DIRS "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}"
INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}"
DEPENDS SHLIBPP_ENABLE_RPATH
USE_LINK_PATH)

# Build in pure c++11
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Build position independent code
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
if(MSVC)
set(CMAKE_DEBUG_POSTFIX "d")
endif()

# Hide all symbols by default
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)

add_subdirectory(src)

# Install CMake config files for the library
include(InstallBasicPackageFiles)
install_basic_package_files(shlibpp
VERSION ${shlibpp_VERSION}
COMPATIBILITY AnyNewerVersion
EXPORT shlibpp
NO_CHECK_REQUIRED_COMPONENTS_MACRO)

# Add uninstall target
include(AddUninstallTarget)



# Create examples
option(BUILD_EXAMPLES "Build examples" ON)
if(BUILD_EXAMPLES)
Expand Down
169 changes: 169 additions & 0 deletions cmake/AddInstallRPATHSupport.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
#.rst:
# AddInstallRPATHSupport
# ----------------------
#
# Add support to RPATH during installation to your project::
#
# add_install_rpath_support([BIN_DIRS dir [dir]]
# [LIB_DIRS dir [dir]]
# [INSTALL_NAME_DIR [dir]]
# [DEPENDS condition [condition]]
# [USE_LINK_PATH])
#
# Normally (depending on the platform) when you install a shared
# library you can either specify its absolute path as the install name,
# or leave just the library name itself. In the former case the library
# will be correctly linked during run time by all executables and other
# shared libraries, but it must not change its install location. This
# is often the case for libraries installed in the system default
# library directory (e.g. ``/usr/lib``).
# In the latter case, instead, the library can be moved anywhere in the
# file system but at run time the dynamic linker must be able to find
# it. This is often accomplished by setting environmental variables
# (i.e. ``LD_LIBRARY_PATH`` on Linux).
# This procedure is usually not desirable for two main reasons:
#
# - by setting the variable you are changing the default behaviour
# of the dynamic linker thus potentially breaking executables (not as
# destructive as ``LD_PRELOAD``)
# - the variable will be used only by applications spawned by the shell
# and not by other processes.
#
# RPATH aims in solving the issues introduced by the second
# installation method. Using run-path dependent libraries you can
# create a directory structure containing executables and dependent
# libraries that users can relocate without breaking it.
# A run-path dependent library is a dependent library whose complete
# install name is not known when the library is created.
# Instead, the library specifies that the dynamic loader must resolve
# the library’s install name when it loads the executable that depends
# on the library. The executable or the other shared library will
# hardcode in the binary itself the additional search directories
# to be passed to the dynamic linker. This works great in conjunction
# with relative paths.
# This command will enable support to RPATH to your project.
# It will enable the following things:
#
# - If the project builds shared libraries it will generate a run-path
# enabled shared library, i.e. its install name will be resolved
# only at run time.
# - In all cases (building executables and/or shared libraries)
# dependent shared libraries with RPATH support will have their name
# resolved only at run time, by embedding the search path directly
# into the built binary.
#
# The command has the following parameters:
#
# Options:
# - ``USE_LINK_PATH``: if passed the command will automatically adds to
# the RPATH the path to all the dependent libraries.
#
# Arguments:
# - ``BIN_DIRS`` list of directories when the targets (executable and
# plugins) will be installed.
# - ``LIB_DIRS`` list of directories to be added to the RPATH. These
# directories will be added "relative" w.r.t. the ``BIN_DIRS`` and
# ``LIB_DIRS``.
# - ``INSTALL_NAME_DIR`` directory where the libraries will be installed.
# This variable will be used only if ``CMAKE_SKIP_RPATH`` or
# ``CMAKE_SKIP_INSTALL_RPATH`` is set to ``TRUE`` as it will set the
# ``INSTALL_NAME_DIR`` on all targets
# - ``DEPENDS`` list of conditions that should be ``TRUE`` to enable
# RPATH, for example ``FOO; NOT BAR``.
#
# Note: see https://gitlab.kitware.com/cmake/cmake/issues/16589 for further
# details.

#=======================================================================
# Copyright 2014 Istituto Italiano di Tecnologia (IIT)
# @author Francesco Romano <[email protected]>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=======================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)


include(CMakeParseArguments)


function(ADD_INSTALL_RPATH_SUPPORT)

set(_options USE_LINK_PATH)
set(_oneValueArgs INSTALL_NAME_DIR)
set(_multiValueArgs BIN_DIRS
LIB_DIRS
DEPENDS)

cmake_parse_arguments(_ARS "${_options}"
"${_oneValueArgs}"
"${_multiValueArgs}"
"${ARGN}")

# if either RPATH or INSTALL_RPATH is disabled
# and the INSTALL_NAME_DIR variable is set, then hardcode the install name
if(CMAKE_SKIP_RPATH OR CMAKE_SKIP_INSTALL_RPATH)
if(DEFINED _ARS_INSTALL_NAME_DIR)
set(CMAKE_INSTALL_NAME_DIR ${_ARS_INSTALL_NAME_DIR} PARENT_SCOPE)
endif()
endif()

if (CMAKE_SKIP_RPATH OR (CMAKE_SKIP_INSTALL_RPATH AND CMAKE_SKIP_BUILD_RPATH))
return()
endif()


set(_rpath_available 1)
if(DEFINED _ARS_DEPENDS)
foreach(_dep ${_ARS_DEPENDS})
string(REGEX REPLACE " +" ";" _dep "${_dep}")
if(NOT (${_dep}))
set(_rpath_available 0)
endif()
endforeach()
endif()

if(_rpath_available)

# Enable RPATH on OSX.
set(CMAKE_MACOSX_RPATH TRUE PARENT_SCOPE)

# Find system implicit lib directories
set(_system_lib_dirs ${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES})
if(EXISTS "/etc/debian_version") # is this a debian system ?
if(CMAKE_LIBRARY_ARCHITECTURE)
list(APPEND _system_lib_dirs "/lib/${CMAKE_LIBRARY_ARCHITECTURE}"
"/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}")
endif()
endif()
# This is relative RPATH for libraries built in the same project
foreach(lib_dir ${_ARS_LIB_DIRS})
list(FIND _system_lib_dirs "${lib_dir}" isSystemDir)
if("${isSystemDir}" STREQUAL "-1")
foreach(bin_dir ${_ARS_LIB_DIRS} ${_ARS_BIN_DIRS})
file(RELATIVE_PATH _rel_path ${bin_dir} ${lib_dir})
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
list(APPEND CMAKE_INSTALL_RPATH "@loader_path/${_rel_path}")
else()
list(APPEND CMAKE_INSTALL_RPATH "\$ORIGIN/${_rel_path}")
endif()
endforeach()
endif()
endforeach()
if(NOT "${CMAKE_INSTALL_RPATH}" STREQUAL "")
list(REMOVE_DUPLICATES CMAKE_INSTALL_RPATH)
endif()
set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_RPATH} PARENT_SCOPE)

# add the automatically determined parts of the RPATH
# which point to directories outside the build tree to the install RPATH
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH ${_ARS_USE_LINK_PATH} PARENT_SCOPE)

endif()

endfunction()
70 changes: 70 additions & 0 deletions cmake/AddUninstallTarget.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#.rst:
# AddUninstallTarget
# ------------------
#
# Add the "uninstall" target for your project::
#
# include(AddUninstallTarget)
#
#
# will create a file cmake_uninstall.cmake in the build directory and add a
# custom target uninstall that will remove the files installed by your package
# (using install_manifest.txt)

#=============================================================================
# Copyright 2008-2013 Kitware, Inc.
# Copyright 2013 Istituto Italiano di Tecnologia (IIT)
# Authors: Daniele E. Domenichelli <[email protected]>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)


if(DEFINED __ADD_UNINSTALL_TARGET_INCLUDED)
return()
endif()
set(__ADD_UNINSTALL_TARGET_INCLUDED TRUE)


set(_filename ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)

file(WRITE ${_filename}
"if(NOT EXISTS \"${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt\")
message(WARNING \"Cannot find install manifest: \\\"${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt\\\"\")
return()
endif()
file(READ \"${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt\" files)
string(STRIP \"\${files}\" files)
string(REGEX REPLACE \"\\n\" \";\" files \"\${files}\")
list(REVERSE files)
foreach(file \${files})
message(STATUS \"Uninstalling: \$ENV{DESTDIR}\${file}\")
if(EXISTS \"\$ENV{DESTDIR}\${file}\")
execute_process(
COMMAND \${CMAKE_COMMAND} -E remove \"\$ENV{DESTDIR}\${file}\"
OUTPUT_VARIABLE rm_out
RESULT_VARIABLE rm_retval)
if(NOT \"\${rm_retval}\" EQUAL 0)
message(FATAL_ERROR \"Problem when removing \\\"\$ENV{DESTDIR}\${file}\\\"\")
endif()
else()
message(STATUS \"File \\\"\$ENV{DESTDIR}\${file}\\\" does not exist.\")
endif()
endforeach(file)
")

if("${CMAKE_GENERATOR}" MATCHES "^(Visual Studio|Xcode)")
set(_uninstall "UNINSTALL")
else()
set(_uninstall "uninstall")
endif()
add_custom_target(${_uninstall} COMMAND "${CMAKE_COMMAND}" -P "${_filename}")
set_property(TARGET ${_uninstall} PROPERTY FOLDER "CMakePredefinedTargets")
Loading

0 comments on commit 84afb1a

Please sign in to comment.