Skip to content

Commit

Permalink
Dependency target install paths and expanding INSTALL_RPATH (#133)
Browse files Browse the repository at this point in the history
* Add install and build target attributes

* Add dependency target install paths to package target's rpath information

* Ignore some local files [skip ci]

* Remove unused line [skip ci]

* Remove external/tmp directory [skip ci]

* Use top project for all target adding and acces (might revert later) [skip ci]

* Gather dependency rpaths and add rpath guesses during find or build dependency call

* Bump minimum CMake version from 3.14.7 to 3.19.7

* Remove extra install of libraries to external/tmp
  • Loading branch information
zachcran authored Nov 17, 2023
1 parent c7629d3 commit 3cef972
Show file tree
Hide file tree
Showing 12 changed files with 154 additions and 26 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/integration_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
cmake: [3.14.7, latestrc]
cmake: [3.19.7, latestrc]

env:
cmake_version: ${{ matrix.cmake }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/unit_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
cmake: [3.14.7, 3.15.5, 3.16.3, 3.22.4, 3.23.1]
cmake: [3.19.7, 3.22.4, 3.23.1]

env:
cmake_version: ${{ matrix.cmake }}
Expand Down
18 changes: 17 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,27 @@

# Build directories
**/*build*/

## API documentation build directory
docs/src/api/developer/

# Install directories
**/*install*/

# Python virtual environments
**/*venv*/
**/*venv*/

# Build logs
**/*logs*/

# Scratch files
**/scratch/

# Local build scripts
*build*.sh

# Integration test artifacts
tests/scripts/catch2_install
tests/scripts/install
tests/scripts/logs
tests/scripts/src
2 changes: 1 addition & 1 deletion cmake/cmaize/cmaize.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
# set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
# endif("${isSystemDir}" STREQUAL "-1")

list(APPEND CMAKE_INSTALL_RPATH "$ORIGIN" "$ORIGIN/external/tmp")
list(APPEND CMAKE_INSTALL_RPATH "$ORIGIN")
107 changes: 91 additions & 16 deletions cmake/cmaize/package_managers/cmake/cmake_package_manager.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ cpp_class(CMakePackageManager PackageManager)
# Set VERSION and SOVERSION properties on the targets
foreach(_ip_TARGETS_i ${_ip_TARGETS})
CMaizeProject(get_target
"${_ip_proj}" _ip_tgt_obj_i "${_ip_TARGETS_i}"
"${_ip_top_proj}" _ip_tgt_obj_i "${_ip_TARGETS_i}"
)

# Set package version
Expand All @@ -342,7 +342,7 @@ cpp_class(CMakePackageManager PackageManager)
# Generate individual <target>Config.cmake components for
# find_package(package COMPONENT target)
foreach(_ip_TARGETS_i ${_ip_TARGETS})
CMaizeProject(get_target "${_ip_proj}" _ip_tgt_obj_i "${_ip_TARGETS_i}")
CMaizeProject(get_target "${_ip_top_proj}" _ip_tgt_obj_i "${_ip_TARGETS_i}")

set(
_ip_tgt_config
Expand All @@ -366,6 +366,36 @@ cpp_class(CMakePackageManager PackageManager)
# "${_ip_destination_prefix}/${CMAKE_INSTALL_INCLUDEDIR}/${_ip_pkg_name}"
)

# Set each package target's installation path(s). Currently this
# sets both the bin and lib directories but realistically only
# one or the other would actually contain the target binary
set(_ip_destination_prefix_tmp "${_ip_destination_prefix}")
if(NOT "${_ip_proj_name}" STREQUAL "${_ip_top_proj_name}")
# We store a temporary destination prefix since it is only
# going to be used to determine install paths and we don't
# want to affect the _ip_destination_prefix used elsewhere
set(
_ip_destination_prefix_tmp
"${_ip_destination_prefix}/${CMAKE_INSTALL_LIBDIR}/${_ip_top_proj_name}/external"
)
endif()

# Get the absolute path of the temporary destination prefix
file(REAL_PATH
"${_ip_destination_prefix_tmp}"
_ip_destination_prefix_abs_path
BASE_DIRECTORY "${CMAKE_INSTALL_PREFIX}"
)

# Generate the install paths
set(
_ip_install_paths
"${_ip_destination_prefix_abs_path}/${CMAKE_INSTALL_BINDIR}/${_ip_pkg_name}"
"${_ip_destination_prefix_abs_path}/${CMAKE_INSTALL_LIBDIR}/${_ip_pkg_name}"
)
CMaizeTarget(SET "${_ip_tgt_obj_i}" install_path "${_ip_install_paths}")
CMaizeTarget(SET_PROPERTY "${_ip_tgt_obj_i}" INSTALL_PATH "${_ip_install_paths}")

# Writes config file to build directory
CMakePackageManager(_generate_target_config
"${self}"
Expand All @@ -389,6 +419,61 @@ cpp_class(CMakePackageManager PackageManager)
endforeach()
endforeach()

# Set INSTALL_RPATH to install paths of dependencies to ensure they
# can be found
foreach(_ip_TARGETS_i ${_ip_TARGETS})
CMaizeProject(get_target
"${_ip_top_proj}" _ip_tgt_obj_i "${_ip_TARGETS_i}"
)

# Loop over each dependency. This is currently done by looking
# up the dependencies by name from the CMaizeProject, but later
# we should make each CMaize target hold references to its
# dependencies
BuildTarget(GET "${_ip_tgt_obj_i}" _dep_list depends)
foreach(dependency ${_dep_list})
# Fetch the dependency's target object
CMaizeProject(get_target
"${_ip_top_proj}" _dep_tgt_obj "${dependency}"
)

# Skip the dependency if it is not managed by CMaize, since
# those won't have install path information
if("${_dep_tgt_obj}" STREQUAL "")
continue()
endif()

# Get the install path for the dependency
CMaizeTarget(GET "${_dep_tgt_obj}" _dep_install_path install_path)

# Turn the dependency paths into absolute paths
file(REAL_PATH
"${_ip_destination_prefix}/${CMAKE_INSTALL_LIBDIR}/${_ip_pkg_name}"
_ip_lib_path
BASE_DIRECTORY "${CMAKE_INSTALL_PREFIX}"
)
# Replace install prefix with $ORIGIN
# We currently don't do this since we couldn't get it to work
# string(REPLACE "${_ip_lib_path}" "$ORIGIN" _dep_install_path "${_dep_install_path}")

# While not a great way to do it, this will check if the dependency
# has any INSTALL_RPATH data. If it does, we add that data to the
# current target as well. In theory, each target should manage its
# own INSTALL_RPATH set, but for now that does not seem to be working.
CMaizeTarget(has_property "${_dep_tgt_obj}" _dep_has_install_rpath INSTALL_RPATH)
if(_dep_has_install_rpath)
CMaizeTarget(get_property "${_dep_tgt_obj}" _dep_install_rpath INSTALL_RPATH)
endif()

# Actually append the aggregated paths to the current target's
# INSTALL_RPATH
CMaizeTarget(get_property "${_ip_tgt_obj_i}" _install_rpath INSTALL_RPATH)
list(APPEND _install_rpath ${_dep_install_path})
list(APPEND _install_rpath ${_dep_install_rpath})
CMaizeTarget(set_property "${_ip_tgt_obj_i}" INSTALL_RPATH "${_install_rpath}")
endforeach()
endforeach()

# Writes config file to build directory
CMakePackageManager(_generate_package_config
"${self}" _ip_pkg_config_in "${_ip_pkg_name}" ${_ip_TARGETS}
Expand Down Expand Up @@ -448,7 +533,7 @@ cpp_class(CMakePackageManager PackageManager)
)

# Get the current CMaize project
cpp_get_global(__gpc_proj CMAIZE_PROJECT_${PROJECT_NAME})
cpp_get_global(__gpc_proj CMAIZE_TOP_PROJECT)
foreach(__gpc_targets_i ${__gpc_targets})
CMaizeProject(get_target
"${__gpc_proj}" __gpc_tgt_obj "${__gpc_targets_i}"
Expand Down Expand Up @@ -510,24 +595,14 @@ cpp_class(CMakePackageManager PackageManager)

CMakePackageManager(GET "${self}" __gpc_dependencies dependencies)
cpp_map(GET "${__gpc_dependencies}" __gpc_dep_obj "${__gpc_tgt_deps_i}")

cpp_type_of(__gpc_dep_type "${__gpc_tgt_deps_i_obj}")
if("${__gpc_dep_type}" STREQUAL "buildtarget")
Dependency(GET
"${__gpc_dep_obj}" __gpc_dep_build_tgt_name build_target
)

install(
TARGETS "${__gpc_dep_build_tgt_name}"
RUNTIME DESTINATION "tmp"
LIBRARY DESTINATION "tmp"
)
endif()

Dependency(GET
"${__gpc_dep_obj}" __gpc_dep_build_tgt_name build_target
)

# This determines how the find_dependency call in the config
# file should be formatted, based on whether the dependency is
# a component of a package or not
if("${__gpc_tgt_deps_i}" STREQUAL "${__gpc_dep_build_tgt_name}")
string(APPEND
__gpc_file_contents
Expand Down
7 changes: 7 additions & 0 deletions cmake/cmaize/targets/build_target.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ include(cmaize/targets/cmaize_target)
#]]
cpp_class(BuildTarget CMaizeTarget)

#[[[
# :type: path
#
# Directory where the target binary will appear after being built.
#]]
cpp_attr(CMaizeTarget build_path)

#[[[
# :type: List[path]
#
Expand Down
7 changes: 7 additions & 0 deletions cmake/cmaize/targets/cmaize_target.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ include(cmakepp_lang/cmakepp_lang)
#]]
cpp_class(CMaizeTarget)

#[[[
# :type: path
#
# Directory where the target binary will be installed.
#]]
cpp_attr(CMaizeTarget install_path)

#[[[
# Creates a ``CMaizeTarget`` object to manage a target of the given name.
#
Expand Down
2 changes: 1 addition & 1 deletion cmake/cmaize/user_api/add_executable.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ function(cmaize_add_executable _cae_tgt_name)
)
endif()

cpp_get_global(_cae_project CMAIZE_PROJECT_${PROJECT_NAME})
cpp_get_global(_cae_project CMAIZE_TOP_PROJECT)

CMaizeProject(add_target
"${_cae_project}" "${_cae_tgt_name}" "${_cae_tgt_obj}"
Expand Down
2 changes: 1 addition & 1 deletion cmake/cmaize/user_api/add_library.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ function(cmaize_add_library _cal_tgt_name)
)
endif()

cpp_get_global(_cal_project CMAIZE_PROJECT_${PROJECT_NAME})
cpp_get_global(_cal_project CMAIZE_TOP_PROJECT)

CMaizeProject(add_target
"${_cal_project}" "${_cal_tgt_name}" "${_cal_tgt_obj}"
Expand Down
2 changes: 1 addition & 1 deletion cmake/cmaize/user_api/add_package.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ endfunction()
function(cmaize_add_package_cmake _capc_pkg_name)

# Get the CMaize project
cpp_get_global(_capc_proj CMAIZE_PROJECT_${PROJECT_NAME})
cpp_get_global(_capc_proj CMAIZE_TOP_PROJECT)

# Get the correct package manager
CMaizeProject(get_package_manager
Expand Down
27 changes: 25 additions & 2 deletions cmake/cmaize/user_api/find_or_build_dependency.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ function(cmaize_find_or_build_dependency _fobd_name)

# Decide which language we are building for
string(TOLOWER "${_fobd_PACKAGE_MANAGER}" _fobd_PACKAGE_MANAGER_lower)
set(pm_obj "")
if("${_fobd_PACKAGE_MANAGER_lower}" STREQUAL "cmake")
cmaize_find_or_build_dependency_cmake(
"${_fobd_name}"
Expand Down Expand Up @@ -106,7 +105,7 @@ function(cmaize_find_or_build_dependency_cmake _fobdc_name)
set(_fobdc_one_value_args VERSION)
cmake_parse_arguments(_fobdc "" "${_fobdc_one_value_args}" "" ${ARGN})

cpp_get_global(_fobdc_project CMAIZE_PROJECT_${PROJECT_NAME})
cpp_get_global(_fobdc_project CMAIZE_TOP_PROJECT)

# Create the package specification
PackageSpecification(ctor _fobdc_package_specs)
Expand Down Expand Up @@ -152,6 +151,30 @@ function(cmaize_find_or_build_dependency_cmake _fobdc_name)
CMaizeProject(add_target
"${_fobdc_project}" "${_fobdc_name}" "${_fobdc_tgt}"
)

# This creates the suspected install prefix for this dependency
cpp_get_global(_fobdc_top_proj CMAIZE_TOP_PROJECT)
CMaizeProject(GET "${_fobdc_top_proj}" _fobdc_top_proj_name name)
file(REAL_PATH
"${CMAKE_INSTALL_LIBDIR}/${_fobdc_top_proj_name}/external"
_fobdc_external_prefix
BASE_DIRECTORY "${CMAKE_INSTALL_PREFIX}"
)

# Get the build target name for the dependency, since it is not
# necessarily the same as the name of the CMaize target
CMaizeTarget(target "${_fobdc_tgt}" _fobdc_build_tgt)

# Create some possible paths where the dependency library will be
# installed
set(
_fobdc_install_paths
"${_fobdc_external_prefix}/lib"
"${_fobdc_external_prefix}/lib/${_fobdc_name}"
"${_fobdc_external_prefix}/lib/${_fobdc_build_tgt}"
)
list(REMOVE_DUPLICATES _fobdc_install_paths)
CMaizeTarget(SET "${_fobdc_tgt}" install_path "${_fobdc_install_paths}")
endif()

# The command above will throw build errors from inside FetchContent
Expand Down
2 changes: 1 addition & 1 deletion cmake/cmaize/utilities/replace_project_targets.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function(cmaize_replace_project_targets _rpt_result)
cpp_return("${_rpt_result}")
endif()

cpp_get_global(_rpt_project CMAIZE_PROJECT_${PROJECT_NAME})
cpp_get_global(_rpt_project CMAIZE_TOP_PROJECT)

# Check if each dependency listed is a CMaizeTarget
foreach(_rpt_targets_i ${_rpt_targets})
Expand Down

0 comments on commit 3cef972

Please sign in to comment.