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

113 #138

Merged
merged 20 commits into from
Dec 11, 2023
Merged

113 #138

Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/scripts/build_api_docs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ mkdir -p build

# Build the API docs with CMinx
cminx "cmake/cmaize" -o "build/api_docs/cmaize" -r -p cmaize
cminx "cmake/cpp" -o "build/api_docs/cpp" -r -p cpp

# Move the api docs to the documentation directory
mv build/api_docs docs/src/api/developer
535 changes: 28 additions & 507 deletions cmake/cmaize/package_managers/cmake/cmake_package_manager.cmake

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Copyright 2023 CMakePP
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

include_guard()

macro(_cpm_ctor_impl self)
# Issue #109, w/o this we get a warning if no languages are enabled
get_property(_cpm_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
if(NOT "${_cpm_languages}" EQUAL "NONE")
include(GNUInstallDirs)
endif()

PackageManager(SET "${self}" type "CMake")

# Establish default paths
if(CMAKE_INSTALL_LIBDIR)
CMakePackageManager(
SET "${self}" library_prefix "${CMAKE_INSTALL_LIBDIR}"
)
else()
CMakePackageManager(SET "${self}" library_prefix "lib")
endif()

if(CMAKE_INSTALL_BINDIR)
CMakePackageManager(
SET "${self}" binary_prefix "${CMAKE_INSTALL_BINDIR}"
)
else()
CMakePackageManager(SET "${self}" binary_prefix "bin")
endif()

CMakePackageManager(add_paths "${self}" ${CMAKE_PREFIX_PATH})

# TODO: Add paths from Dependency(_search_paths if there are any
# generalizable ones

# Initialize the dependency map
cpp_map(CTOR _ctor_dep_map)
CMakePackageManager(SET "${self}" dependencies "${_ctor_dep_map}")
endmacro()
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# Copyright 2023 CMakePP
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

include_guard()

macro(
_cpm_generate_package_config_impl
self
__gpc_output_file
__gpc_pkg_name
)


set(__gpc_targets ${ARGN})

_cmaize_generated_by_cmaize(__gpc_file_contents)
string(APPEND __gpc_file_contents "\n\n")

string(APPEND
__gpc_file_contents
"include(CMakeFindDependencyMacro)\n\n"
)

# Get the current CMaize project
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}"
)
BuildTarget(GET "${__gpc_tgt_obj}" __gpc_tgt_deps depends)

list(LENGTH __gpc_tgt_deps __gpc_tgt_deps_len)

# Appends the 'external/' directory to the CMAKE_PREFIX_PATH
# if there are dependencies that were built under the package
if(__gpc_tgt_deps_len GREATER 0)
string(APPEND
__gpc_file_contents
"set(\n"
" CMAKE_PREFIX_PATH\n"
" \"\${CMAKE_PREFIX_PATH}\" \"\${CMAKE_CURRENT_LIST_DIR}/../external\"\n"
" CACHE STRING \"\" FORCE\n"
")\n\n"
)
endif()

foreach(__gpc_tgt_deps_i ${__gpc_tgt_deps})
message(DEBUG "Processing dependency: ${__gpc_tgt_deps_i}")

# Skip dependency processing if this is not a target managed
# by the CMaize project
CMaizeProject(check_target
"${__gpc_proj}"
__gpc_is_cmaize_tgt
"${__gpc_tgt_deps_i}"
ALL
)
if(NOT __gpc_is_cmaize_tgt)
message(
DEBUG
"Skipping ${__gpc_tgt_deps_i}. It is not target "
"managed by CMaize."
)
continue()
endif()

# Skip dependency processing if it is a target defined as a
# part of this package
cpp_contains(_gpc_dep_is_proj_tgt "${__gpc_tgt_deps_i}" "${__gpc_targets}")
if(_gpc_dep_is_proj_tgt)
message(
DEBUG
"Skipping ${__gpc_tgt_deps_i}. It is a target defined "
"by this project."
)
continue()
endif()

# Check if it is a dependency to be built and redirect the
# installation to the ``external`` directory
CMaizeProject(get_target
"${__gpc_proj}" __gpc_tgt_deps_i_obj "${__gpc_tgt_deps_i}"
)

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

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
"find_dependency(${__gpc_tgt_deps_i})\n"
)
else()
string(APPEND
__gpc_file_contents
"find_dependency(${__gpc_tgt_deps_i} COMPONENTS ${__gpc_dep_build_tgt_name})\n"
)
endif()
endforeach()
endforeach()

# Add a space between the dependency imports and component imports
string(APPEND __gpc_file_contents "\n" )

# Start to generate full list of components if no specific components
# are given
string(APPEND
__gpc_file_contents
"list(LENGTH @PROJECT_NAME@_FIND_COMPONENTS "
"@PROJECT_NAME@_FIND_COMPONENTS_len)\n"
"if(@PROJECT_NAME@_FIND_COMPONENTS_len LESS_EQUAL 0)\n"
)

# Append all target names to the component list
foreach(__gpc_targets_i ${__gpc_targets})

string(APPEND
__gpc_file_contents
" list(APPEND @PROJECT_NAME@_FIND_COMPONENTS "
"${__gpc_targets_i})\n"
)
endforeach()

# End handling no components given
string(APPEND __gpc_file_contents "endif()\n\n")

# Write the loop that includes all specified components
string(APPEND
__gpc_file_contents
"foreach(component \${@PROJECT_NAME@_FIND_COMPONENTS})\n"
" include(\${CMAKE_CURRENT_LIST_DIR}/\${component}-target.cmake)\n"
"endforeach()\n\n"
)

# Potentially add an additional check for imported target names
# From: https://gist.github.com/mbinna/c61dbb39bca0e4fb7d1f73b0d66a4fd1?permalink_comment_id=3200539#gistcomment-3200539
# pkg_check_modules(libname REQUIRED IMPORTED_TARGET libname)

string(APPEND "check_required_components(${__gpc_pkg_name})\n")

# Write to a file to be configured
file(WRITE
"${CMAKE_CURRENT_BINARY_DIR}/${__gpc_pkg_name}Config.cmake.in"
"${__gpc_file_contents}"
)

set(
"${__gpc_output_file}"
"${CMAKE_CURRENT_BINARY_DIR}/${__gpc_pkg_name}Config.cmake.in"
)

cpp_return("${__gpc_output_file}")

endmacro()
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# Copyright 2023 CMakePP
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

include_guard()

macro(_cpm_generate_target_config_impl
self
__gtc_tgt_obj
__gtc_target_name
__gtc_namespace
__gtc_config_file
__gtc_install_dest
)

_cmaize_generated_by_cmaize(__gtc_file_contents)
string(APPEND __gtc_file_contents "\n")

string(APPEND
__gtc_file_contents
"
if(TARGET ${__gtc_namespace}${__gtc_target_name})
return()
endif()")
string(APPEND __gtc_file_contents "\n\n")

string(APPEND
__gtc_file_contents
"get_filename_component(PACKAGE_PREFIX_DIR "
"\"\${CMAKE_CURRENT_LIST_DIR}/../../..\" ABSOLUTE)\n"
)

BuildTarget(GET "${__gtc_tgt_obj}" __gtc_dep_list depends)
CXXTarget(GET "${__gtc_tgt_obj}" __gtc_cxx_std cxx_standard)
CMaizeTarget(get_property "${__gtc_tgt_obj}" __gtc_version VERSION)
CMaizeTarget(get_property "${__gtc_tgt_obj}" __gtc_so_version SOVERSION)

string(APPEND
__gtc_file_contents
"
# Create imported target ${__gtc_namespace}${__gtc_target_name}
add_library(${__gtc_namespace}${__gtc_target_name} SHARED IMPORTED)

set_target_properties(${__gtc_namespace}${__gtc_target_name} PROPERTIES
INTERFACE_COMPILE_FEATURES \"cxx_std_${__gtc_cxx_std}\"
INTERFACE_INCLUDE_DIRECTORIES \"\${PACKAGE_PREFIX_DIR}/include\"
INTERFACE_LINK_LIBRARIES "
)

set(__gtc_interface_link_libraries)
foreach(__gtc_dep_i ${__gtc_dep_list})
CMakePackageManager(GET "${self}" __gtc_dep_map dependencies)
cpp_map(KEYS "${__gtc_dep_map}" __gtc_keys)
cpp_map(GET "${__gtc_dep_map}" __gtc_dep_obj "${__gtc_dep_i}")

if("${__gtc_dep_obj}" STREQUAL "")
continue()
endif()

Dependency(GET
"${__gtc_dep_obj}" __gtc_dep_find_tgt_name find_target
)
list(APPEND __gtc_interface_link_libraries ${__gtc_dep_find_tgt_name})
endforeach()

string(APPEND
__gtc_file_contents
"\"${__gtc_interface_link_libraries}\"
)\n"
)

# Based on the shared library suffix, generate the correct versioned
# library name and soname that CMake will install
if ("${CMAKE_SHARED_LIBRARY_SUFFIX}" STREQUAL ".so")
set(__gtc_libname_w_version
"lib${__gtc_target_name}.so.${__gtc_version}"
)
set(__gtc_soname "lib${__gtc_target_name}.so.${__gtc_so_version}")
elseif("${CMAKE_SHARED_LIBRARY_SUFFIX}" STREQUAL ".dylib")
set(__gtc_libname_w_version
"lib${__gtc_target_name}.${__gtc_version}.dylib"
)
set(__gtc_soname
"lib${__gtc_target_name}.${__gtc_so_version}.dylib"
)
else()
string(APPEND __gtc_msg "Shared libraries with the")
string(APPEND __gtc_msg "${CMAKE_SHARED_LIBRARY_SUFFIX} suffix")
string(APPEND __gtc_msg "are not supported yet.")
cpp_raise(
UnsupportedLibraryType
"${__gtc_msg}"
)
endif()

CMakePackageManager(GET "${self}" __gtc_lib_prefix library_prefix)
string(APPEND
__gtc_file_contents
"
set(_CMAIZE_IMPORT_LOCATION \"\${PACKAGE_PREFIX_DIR}/${__gtc_lib_prefix}/${__gtc_target_name}/${__gtc_libname_w_version}\")

# Import target \"${__gtc_namespace}${__gtc_target_name}\" for configuration \"???\"
Comment on lines +111 to +112
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Import target \"${__gtc_namespace}${__gtc_target_name}\" for configuration \"???\"
# TODO: Handle different configurations (Release, Debug, etc.)
# Import target \"${__gtc_namespace}${__gtc_target_name}\" for configuration \"???\"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I missed this, but I'll put it into my next PR.

set_property(TARGET ${__gtc_namespace}${__gtc_target_name} APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(${__gtc_namespace}${__gtc_target_name} PROPERTIES
IMPORTED_LOCATION_RELEASE \"\${_CMAIZE_IMPORT_LOCATION}\"
IMPORTED_SONAME_RELEASE \"${__gtc_soname}\"
)\n"
)

string(APPEND
__gtc_file_contents
"
# Unset variables used
set(PACKAGE_PREFIX_DIR)
set(_CMAIZE_IMPORT_LOCATION)"
)

# Write the config file *.in variant
set(__gtc_config_file_in "${__gtc_config_file}.in")
file(WRITE "${__gtc_config_file_in}" "${__gtc_file_contents}")

# Configure the file so it is ready for installation
configure_package_config_file(
"${__gtc_config_file_in}"
"${__gtc_config_file}"
INSTALL_DESTINATION
"${__gtc_install_dest}"
)

# Install config file
install(
FILES "${__gtc_config_file}"
DESTINATION "${__gtc_install_dest}"
)

endmacro()
Loading
Loading