├── .github └── workflows │ └── conda-forge-ci.yml ├── .gitignore ├── CHANGELOG.md ├── CMakeLists.txt ├── LICENSE ├── README.md ├── RelocCPPGenerate.cmake ├── reloc-cpp-config.cmake.in └── tests ├── CMakeLists.txt └── reloc_cpp_test.cpp /.github/workflows/conda-forge-ci.yml: -------------------------------------------------------------------------------- 1 | name: C++ CI Workflow with conda-forge dependencies 2 | 3 | on: 4 | push: 5 | pull_request: 6 | schedule: 7 | # * is a special character in YAML so you have to quote this string 8 | # Execute a "weekly" build at 2 AM UTC on Sunday 9 | - cron: '0 2 * * 0' 10 | 11 | jobs: 12 | build: 13 | name: '[${{ matrix.os }}@${{ matrix.build_type }}@conda]' 14 | runs-on: ${{ matrix.os }} 15 | strategy: 16 | matrix: 17 | build_type: [Release] 18 | os: [ubuntu-latest, windows-2019, macOS-latest] 19 | fail-fast: false 20 | 21 | steps: 22 | - uses: actions/checkout@v2 23 | 24 | - uses: conda-incubator/setup-miniconda@v3 25 | with: 26 | miniforge-version: latest 27 | channels: conda-forge,defaults 28 | channel-priority: true 29 | 30 | - name: Dependencies 31 | shell: bash -l {0} 32 | run: | 33 | conda install cmake compilers make ninja pkg-config ycm-cmake-modules 34 | 35 | - name: Additional Dependencies [Windows] 36 | if: contains(matrix.os, 'windows') 37 | shell: bash -l {0} 38 | run: | 39 | conda install vs2019_win-64 40 | 41 | 42 | - name: Configure&Build&Test&Install [Linux&macOS] 43 | if: contains(matrix.os, 'macos') || contains(matrix.os, 'ubuntu') 44 | shell: bash -l {0} 45 | run: | 46 | mkdir -p build 47 | cd build 48 | cmake -GNinja -DBUILD_TESTING:BOOL=ON -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_INSTALL_PREFIX=./install .. 49 | cmake --build . --config ${{ matrix.build_type }} 50 | ctest --output-on-failure -C ${{ matrix.build_type }} 51 | cmake --install . --config ${{ matrix.build_type }} 52 | 53 | - name: Configure&Build&Test&Install [Windows] 54 | if: contains(matrix.os, 'windows') 55 | shell: cmd /C CALL {0} 56 | run: | 57 | mkdir build 58 | cd build 59 | cmake -GNinja -DBUILD_TESTING:BOOL=ON -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_INSTALL_PREFIX=./install .. 60 | cmake --build . --config ${{ matrix.build_type }} 61 | ctest --output-on-failure -C ${{ matrix.build_type }} 62 | cmake --install . --config ${{ matrix.build_type }} 63 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). 6 | 7 | ## [Unreleased] 8 | 9 | ## [0.1.0] - 2022-11-14 10 | 11 | ### Added 12 | 13 | - First version of the library (https://github.com/ami-iit/reloc-cpp/pull/1). 14 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Fondazione Istituto Italiano di Tecnologia (IIT) 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | cmake_minimum_required(VERSION 3.16) 5 | 6 | project(reloc-cpp 7 | LANGUAGES CXX C 8 | VERSION 0.1.0) 9 | 10 | include(GNUInstallDirs) 11 | 12 | # Make reloc_cpp_generate available 13 | include(${CMAKE_CURRENT_SOURCE_DIR}/RelocCPPGenerate.cmake) 14 | 15 | if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) 16 | set(RELOC_CPP_STANDALONE ON) 17 | endif() 18 | 19 | option(RELOC_CPP_INSTALL "Enable installation of reloc-cpp" ${RELOC_CPP_STANDALONE}) 20 | 21 | # Build test related commands? 22 | option(BUILD_TESTING "Create tests using CMake" ${RELOC_CPP_STANDALONE}) 23 | if(BUILD_TESTING) 24 | enable_testing() 25 | endif() 26 | 27 | if(RELOC_CPP_INSTALL) 28 | set(RELOC_CPP_INSTALL_MODULE_DIR "${CMAKE_INSTALL_DATADIR}/reloc-cpp") 29 | set(RELOC_CPP_INSTALL_CMAKE_DIR "${CMAKE_INSTALL_DATADIR}/reloc-cpp/cmake") 30 | 31 | install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/RelocCPPGenerate.cmake 32 | DESTINATION "${CMAKE_INSTALL_DATADIR}/reloc-cpp") 33 | 34 | find_package(YCM REQUIRED) 35 | include(InstallBasicPackageFiles) 36 | install_basic_package_files(${PROJECT_NAME} 37 | VERSION ${${PROJECT_NAME}_VERSION} 38 | COMPATIBILITY AnyNewerVersion 39 | VARS_PREFIX ${PROJECT_NAME} 40 | NO_CHECK_REQUIRED_COMPONENTS_MACRO 41 | ARCH_INDEPENDENT 42 | NO_EXPORT) 43 | include(AddUninstallTarget) 44 | endif() 45 | 46 | # Add integration tests (unit tests for each library should be in each sublibrary directory). 47 | if(BUILD_TESTING) 48 | add_subdirectory(tests) 49 | endif() 50 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2022, Artificial and Mechanical Intelligence 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # reloc-cpp 2 | 3 | CMake/C++ library to get the installation prefix of a shared library in a relocatable way. 4 | 5 | In a nutshell, it permits to avoid the need to hardcode the location of `CMAKE_INSTALL_PREFIX` in a shared library if you need it to localize other resources installed with the package. This permits to easily move the installation prefix in a location different from `CMAKE_INSTALL_PREFIX` after the installation (i.e. making it a *relocatable* installation), as long as the library is compiled as shared. This is useful when the C++ shared library is packaged in package managers that create the package with a given `CMAKE_INSTALL_PREFIX` and install it with a different prefix, such as [conda](https://docs.conda.io), [vcpkg](https://vcpkg.io) or [conan](https://conan.io/). 6 | 7 | In the case that the library is compiled as static, `reloc-cpp` will fall back to hardcode `CMAKE_INSTALL_PREFIX` in the library. 8 | 9 | `reloc-cpp` requires the use of C++ 17 or any later version. 10 | 11 | ## Installation 12 | 13 | ### FetchContent 14 | 15 | ~~~cmake 16 | include(FetchContent) 17 | FetchContent_Declare( 18 | reloc-cpp 19 | GIT_REPOSITORY https://github.com/ami-iit/reloc-cpp.git 20 | GIT_TAG v0.1.0 21 | ) 22 | 23 | FetchContent_MakeAvailable(reloc-cpp) 24 | ~~~ 25 | 26 | ## Usage 27 | 28 | In your CMake build system you can use `reloc-cpp` as: 29 | 30 | ```cmake 31 | add_library(yourLibrary) 32 | 33 | # ... 34 | 35 | reloc_cpp_generate(yourLibrary 36 | GENERATED_HEADER ${CMAKE_CURRENT_BINARY_DIR}/yourLibrary_getInstallPrefix.h 37 | GENERATED_FUNCTION yourLibrary::getInstallPrefix) 38 | ``` 39 | 40 | then, you can use it in C++ as: 41 | 42 | ~~~cpp 43 | #include 44 | 45 | // This return the value corresponding to CMAKE_INSTALL_PREFIX 46 | std::string installPrefix = yourLibrary::getInstallPrefix().value(); 47 | ~~~ 48 | 49 | 50 | ## Contributing 51 | 52 | Pull requests are welcome. For major changes, please open an issue first 53 | to discuss what you would like to change. 54 | 55 | ## References 56 | 57 | References that were useful as inspiration when developing reloc-cpp: 58 | * ["Helping C/C++ Packages be Relocatable" presentation](https://indico.cern.ch/event/848215/contributions/3591953/attachments/1923018/3181752/HSFPackagingRelocation.pdf) 59 | * [Resourceful: Techniques for installing and accessing resource files using C++ and Python.](https://github.com/drbenmorgan/Resourceful) 60 | * ["Qt is relocatable" blog post](https://www.qt.io/blog/qt-is-relocatable) 61 | * [binreloc: Library for creating relocatable software](https://github.com/limbahq/binreloc) 62 | 63 | Resources that could be useful as an alternative to reloc-cpp: 64 | * [cmrc: A Resource Compiler in a Single CMake Script ](https://github.com/vector-of-bool/cmrc) 65 | 66 | ## License 67 | 68 | [BSD-3-Clause](https://choosealicense.com/licenses/bsd-3-clause/) 69 | -------------------------------------------------------------------------------- /RelocCPPGenerate.cmake: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Fondazione Istituto Italiano di Tecnologia (IIT) 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | # reloc_cpp_generate( 5 | # GENERATED_HEADER 6 | # GENERATED_FUNCTION 7 | # DISABLE_RELOCATABLE 8 | # EXPORT_MACRO_INCLUDE 9 | # EXPORT_MACRO_NAME 10 | # VERBOSE ) 11 | # 12 | function(RELOC_CPP_GENERATE _library) 13 | set(_options) 14 | set(_oneValueArgs 15 | GENERATED_HEADER 16 | GENERATED_FUNCTION 17 | DISABLE_RELOCATABLE 18 | EXPORT_MACRO_INCLUDE 19 | EXPORT_MACRO_NAME 20 | VERBOSE 21 | ) 22 | set(_multiValueArgs ) 23 | cmake_parse_arguments(RCG "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN} ) 24 | 25 | if(NOT DEFINED RCG_GENERATED_HEADER) 26 | message(FATAL_ERROR "reloc_cpp_generate: missing parameter GENERATED_HEADER") 27 | endif() 28 | 29 | if(NOT DEFINED RCG_GENERATED_FUNCTION) 30 | message(FATAL_ERROR "reloc_cpp_generate: missing parameter GENERATED_FUNCTION") 31 | endif() 32 | 33 | if(DEFINED RCG_EXPORT_MACRO_INCLUDE) 34 | set(RCG_EXPORT_MACRO_INCLUDE_LINE "#include <${RCG_EXPORT_MACRO_INCLUDE}>") 35 | else() 36 | set(RCG_EXPORT_MACRO_INCLUDE_LINE "") 37 | endif() 38 | 39 | if(DEFINED RCG_EXPORT_MACRO_NAME) 40 | set(RCG_EXPORT_MACRO_NAME "") 41 | endif() 42 | 43 | if(DEFINED RCG_EXPORT_MACRO_NAME) 44 | set(RCG_EXPORT_MACRO_NAME_WITH_SPACE "${RCG_EXPORT_MACRO_NAME} ") 45 | else() 46 | set(RCG_EXPORT_MACRO_NAME_WITH_SPACE "${RCG_EXPORT_MACRO_NAME}") 47 | endif() 48 | 49 | if(NOT TARGET ${_library}) 50 | message(FATAL_ERROR "reloc_cpp_generate: library ${_library} does not exist") 51 | endif() 52 | 53 | if(NOT TARGET ${_library}) 54 | message(FATAL_ERROR "reloc_cpp_generate: library ${_library} does not exist") 55 | endif() 56 | 57 | get_target_property(target_type ${_library} TYPE) 58 | if(NOT (target_type STREQUAL "STATIC_LIBRARY" OR target_type STREQUAL "MODULE_LIBRARY" OR target_type STREQUAL "SHARED_LIBRARY")) 59 | message(FATAL_ERROR "reloc_cpp_generate: library ${_library} is of unsupported type ${target_type}") 60 | endif() 61 | 62 | # Get generated .cpp name 63 | get_filename_component(RCG_GENERATED_HEADER_DIRECTORY ${RCG_GENERATED_HEADER} DIRECTORY) 64 | get_filename_component(RCG_GENERATED_HEADER_NAME_WE ${RCG_GENERATED_HEADER} NAME_WE) 65 | get_filename_component(RCG_GENERATED_HEADER_NAME ${RCG_GENERATED_HEADER} NAME) 66 | set(RCG_GENERATED_CPP ${RCG_GENERATED_HEADER_DIRECTORY}/${RCG_GENERATED_HEADER_NAME_WE}.cpp) 67 | 68 | if (DEFINED RCG_VERBOSE AND RCG_VERBOSE) 69 | message(STATUS "reloc_cpp_generate: RCG_GENERATED_CPP=${RCG_GENERATED_CPP}") 70 | endif() 71 | 72 | # Decompose scoped function name in unscoped name and namespaces 73 | string(REPLACE "::" ";" RCG_GENERATED_FUNCTION_NAMESPACES ${RCG_GENERATED_FUNCTION}) 74 | list(POP_BACK RCG_GENERATED_FUNCTION_NAMESPACES RCG_GENERATED_FUNCTION_UNSCOPED) 75 | 76 | # Generate namespace-related lines 77 | set(RCG_HEADER_OPEN_NAMESPACES "") 78 | set(RCG_HEADER_CLOSE_NAMESPACES "") 79 | 80 | foreach(RCG_NAMESPACE IN ITEMS ${RCG_GENERATED_FUNCTION_NAMESPACES}) 81 | string(APPEND RCG_HEADER_OPEN_NAMESPACES "namespace ${RCG_NAMESPACE} {\n") 82 | string(APPEND RCG_HEADER_CLOSE_NAMESPACES "}\n") 83 | endforeach() 84 | 85 | # Write header 86 | file(GENERATE OUTPUT "${RCG_GENERATED_HEADER}" 87 | CONTENT 88 | "// This file is automatically generated reloc_cpp_generate CMake function. 89 | #pragma once 90 | 91 | #include 92 | #include 93 | 94 | ${RCG_EXPORT_MACRO_INCLUDE_LINE} 95 | 96 | ${RCG_HEADER_OPEN_NAMESPACES} 97 | 98 | ${RCG_EXPORT_MACRO_NAME_WITH_SPACE}std::optional ${RCG_GENERATED_FUNCTION_UNSCOPED}(); 99 | 100 | ${RCG_HEADER_CLOSE_NAMESPACES} 101 | ") 102 | 103 | # Write cpp for shared or module library type 104 | if (target_type STREQUAL "MODULE_LIBRARY" OR target_type STREQUAL "SHARED_LIBRARY" AND NOT RCG_DISABLE_RELOCATABLE) 105 | # We can't query the LOCATION property of the target due to https://cmake.org/cmake/help/v3.25/policy/CMP0026.html 106 | # We can only access the directory of the library at generation time via $ 107 | 108 | file(GENERATE OUTPUT "${RCG_GENERATED_CPP}" 109 | CONTENT 110 | "// This file is automatically generated reloc_cpp_generate CMake function. 111 | #include \"${RCG_GENERATED_HEADER_NAME}\" 112 | 113 | #include 114 | 115 | #ifdef _WIN32 116 | #include 117 | #else 118 | #include 119 | #endif 120 | 121 | #include 122 | 123 | std::optional ${RCG_GENERATED_FUNCTION}() 124 | { 125 | std::error_code fs_error; 126 | 127 | // Get location of the library 128 | std::filesystem::path library_location; 129 | #ifndef _WIN32 130 | Dl_info address_info; 131 | int res_val = dladdr(reinterpret_cast(&${RCG_GENERATED_FUNCTION}), &address_info); 132 | if (address_info.dli_fname && res_val > 0) 133 | { 134 | library_location = address_info.dli_fname; 135 | } 136 | else 137 | { 138 | return {}; 139 | } 140 | #else 141 | // See 142 | char module_path[MAX_PATH]; 143 | HMODULE hm = NULL; 144 | 145 | if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | 146 | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, 147 | (LPCSTR) &${RCG_GENERATED_FUNCTION}, &hm) == 0) 148 | { 149 | return {}; 150 | } 151 | if (GetModuleFileNameA(hm, module_path, sizeof(module_path)) == 0) 152 | { 153 | return {}; 154 | } 155 | 156 | library_location = std::string(module_path); 157 | #endif 158 | 159 | const std::filesystem::path library_directory = library_location.parent_path(); 160 | 161 | // Given the library_directory, return the install prefix via the relative path 162 | #ifndef _WIN32 163 | const std::filesystem::path rel_path_from_install_prefix_to_lib = std::string(\"${CMAKE_INSTALL_LIBDIR}\"); 164 | #else 165 | const std::filesystem::path rel_path_from_install_prefix_to_lib = std::string(\"${CMAKE_INSTALL_BINDIR}\"); 166 | #endif 167 | const std::filesystem::path rel_path_from_lib_to_install_prefix = 168 | std::filesystem::relative(std::filesystem::current_path(), std::filesystem::current_path() / rel_path_from_install_prefix_to_lib, fs_error); 169 | // TODO(traversaro): handle fs_error errors 170 | const std::filesystem::path install_prefix = library_directory / rel_path_from_lib_to_install_prefix; 171 | const std::filesystem::path install_prefix_canonical = std::filesystem::canonical(install_prefix, fs_error); 172 | // TODO(traversaro): handle fs_error errors 173 | 174 | // Return install prefix 175 | return install_prefix_canonical.string(); 176 | } 177 | ") 178 | else() 179 | # For static library, fallback to just provide return CMAKE_INSTALL_PREFIX 180 | file(GENERATE OUTPUT "${RCG_GENERATED_CPP}" 181 | CONTENT 182 | "// This file is automatically generated reloc_cpp_generate CMake function. 183 | 184 | #include \"${RCG_GENERATED_HEADER_NAME}\" 185 | 186 | std::optional ${RCG_GENERATED_FUNCTION}() 187 | { 188 | return \"${CMAKE_INSTALL_PREFIX}\"; 189 | } 190 | ") 191 | endif() 192 | 193 | # Add cpp to library 194 | target_sources(${_library} PRIVATE ${RCG_GENERATED_CPP}) 195 | 196 | # Specify that we need C++17 features 197 | target_compile_features(${_library} PUBLIC cxx_std_17) 198 | 199 | # Link dl due to the use of dladdr 200 | if(NOT WIN32) 201 | target_link_libraries(${_library} PRIVATE ${CMAKE_DL_LIBS}) 202 | endif() 203 | 204 | endfunction() 205 | -------------------------------------------------------------------------------- /reloc-cpp-config.cmake.in: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Istituto Italiano di Tecnologia (IIT) 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | @PACKAGE_INIT@ 5 | 6 | set_and_check(RELOC_CPP_MODULE_DIR "@PACKAGE_RELOC_CPP_INSTALL_MODULE_DIR@") 7 | include(${RELOC_CPP_MODULE_DIR}/RelocCPPGenerate.cmake) 8 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Fondazione Istituto Italiano di Tecnologia (IIT) 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | # For the tests, we make sure that the relative path in the build location is the same 5 | # of the install, and we make sure that the value returned by the shared library is ${CMAKE_BINARY_DIR} 6 | # while for the static library we make sure that the value returned is ${CMAKE_INSTALL_PREFIX} 7 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}") 8 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}") 9 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}") 10 | 11 | # shared test 12 | add_library(reloc-cpp-test-shared SHARED) 13 | 14 | reloc_cpp_generate(reloc-cpp-test-shared 15 | GENERATED_HEADER ${CMAKE_CURRENT_BINARY_DIR}/reloc_cpp_test_shared.h 16 | GENERATED_FUNCTION RelocCPP::test::sharedlib::getInstallPrefix) 17 | set_target_properties(reloc-cpp-test-shared PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) 18 | 19 | # static test 20 | add_library(reloc-cpp-test-static STATIC) 21 | 22 | reloc_cpp_generate(reloc-cpp-test-static 23 | GENERATED_HEADER ${CMAKE_CURRENT_BINARY_DIR}/reloc_cpp_test_static.h 24 | GENERATED_FUNCTION RelocCPP::test::staticlib::getInstallPrefix) 25 | 26 | # shared-relocatable-disabled 27 | # In this case, we test the use of several options: 28 | # * DISABLE_RELOCATABLE 29 | # Use of function without namespace 30 | add_library(reloc-cpp-test-shared-relocatable-disabled SHARED) 31 | 32 | reloc_cpp_generate(reloc-cpp-test-shared-relocatable-disabled 33 | GENERATED_HEADER ${CMAKE_CURRENT_BINARY_DIR}/reloc_cpp_test_shared_relocatable_disabled.h 34 | GENERATED_FUNCTION getInstallPrefixSharedRelocatableDisabled 35 | DISABLE_RELOCATABLE ON) 36 | set_target_properties(reloc-cpp-test-shared-relocatable-disabled PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) 37 | 38 | # Write header with CMake variables to check 39 | file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/reloc_cpp_test_cmake_variables.h 40 | "#pragma once 41 | 42 | #define CMAKE_INSTALL_PREFIX \"${CMAKE_INSTALL_PREFIX}\" 43 | #define CMAKE_BINARY_DIR \"${CMAKE_BINARY_DIR}\" 44 | 45 | ") 46 | 47 | # Add test executable 48 | add_executable(reloc-cpp-test reloc_cpp_test.cpp) 49 | target_include_directories(reloc-cpp-test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) 50 | target_link_libraries(reloc-cpp-test PRIVATE reloc-cpp-test-shared reloc-cpp-test-static reloc-cpp-test-shared-relocatable-disabled) 51 | add_test(NAME reloc-cpp-test COMMAND reloc-cpp-test) 52 | -------------------------------------------------------------------------------- /tests/reloc_cpp_test.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Fondazione Istituto Italiano di Tecnologia (IIT) 2 | // SPDX-License-Identifier: BSD-3-Clause 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | std::string toCanonical(const std::string input_path) 14 | { 15 | return std::filesystem::weakly_canonical(std::filesystem::path(input_path)).string(); 16 | } 17 | 18 | int main() 19 | { 20 | std::string sharedInstallPrefix = RelocCPP::test::sharedlib::getInstallPrefix().value(); 21 | std::string staticInstallPrefix = RelocCPP::test::staticlib::getInstallPrefix().value();; 22 | std::string sharedRelocatableDisabledInstallPrefix = getInstallPrefixSharedRelocatableDisabled().value(); 23 | 24 | std::cerr << "reloc-cpp test:" << std::endl; 25 | std::cerr << "sharedInstallPrefix: " << sharedInstallPrefix << std::endl; 26 | std::cerr << "CMAKE_BINARY_DIR: " << CMAKE_BINARY_DIR << std::endl; 27 | std::cerr << "staticInstallPrefix: " << staticInstallPrefix << std::endl; 28 | std::cerr << "CMAKE_INSTALL_PREFIX: " << CMAKE_INSTALL_PREFIX << std::endl; 29 | std::cerr << "sharedRelocatableDisabledInstallPrefix: " << sharedRelocatableDisabledInstallPrefix << std::endl; 30 | 31 | 32 | if (toCanonical(sharedInstallPrefix) != toCanonical(CMAKE_BINARY_DIR)) 33 | { 34 | std::cerr << "getInstallPrefixShared returned unexpected value, test is failing." << std::endl; 35 | return EXIT_FAILURE; 36 | } 37 | 38 | if (toCanonical(staticInstallPrefix) != toCanonical(CMAKE_INSTALL_PREFIX)) 39 | { 40 | std::cerr << "getInstallPrefixStatic returned unexpected value, test is failing." << std::endl; 41 | return EXIT_FAILURE; 42 | } 43 | 44 | if (toCanonical(sharedRelocatableDisabledInstallPrefix) != toCanonical(CMAKE_INSTALL_PREFIX)) 45 | { 46 | std::cerr << "getInstallPrefixSharedRelocatableDisabled returned unexpected value, test is failing." << std::endl; 47 | return EXIT_FAILURE; 48 | } 49 | 50 | return EXIT_SUCCESS; 51 | } 52 | --------------------------------------------------------------------------------