Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dependency target install paths and expanding INSTALL_RPATH #133

Merged
merged 11 commits into from
Nov 17, 2023
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
Loading