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

refactor(cmake): asset uses library helper #12433

Merged
merged 2 commits into from
Aug 21, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
14 changes: 14 additions & 0 deletions cmake/GoogleCloudCppLibrary.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,21 @@
# * library: the short name of the library, e.g. `kms`.
# * display_name: the display name of the library, e.g. "Cloud Key Management
# Service (KMS) API"
#
# Additionally, we must set the following **variable** in the parent scope. We
Copy link
Contributor

Choose a reason for hiding this comment

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

For a separate PR, maybe we should have a SERVICE_DIRS list parameter and a boolean parameter that adds "" to it, something like WITH_LOCAL_SERVICE_DIR or WITH_FORWARDING_HEADERS

Copy link
Member Author

Choose a reason for hiding this comment

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

Eh. I think that would add unnecessary complexity. What we have works and I am not trying to get cmake readability.

Copy link
Contributor

Choose a reason for hiding this comment

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

Passing values through global variables in CMake is bad for the same reason that passing values in global variables is bad in all languages. This is not a good habit to get into.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ack.

# cannot use a `cmake_parse_arguments()` keyword because it will skip the empty
# string when provided in a list. We often need to use the empty string.
#
# * GOOGLE_CLOUD_CPP_SERVICE_DIRS: a list of service directories within the
# library.
#
# The following **keywords** can be optionally supplied to handle edge cases:
#
# * ADDITIONAL_PROTO_LISTS: a list of proto files that may be used indirectly.
# `asset` sets this.
#
function (google_cloud_cpp_add_ga_grpc_library library display_name)
cmake_parse_arguments(_opt "" "" "ADDITIONAL_PROTO_LISTS" ${ARGN})
set(library_target "google_cloud_cpp_${library}")
set(mocks_target "google_cloud_cpp_${library}_mocks")
set(protos_target "google_cloud_cpp_${library}_protos")
Expand Down Expand Up @@ -58,6 +69,9 @@ function (google_cloud_cpp_add_ga_grpc_library library display_name)
google_cloud_cpp_load_protolist(
proto_list
"${PROJECT_SOURCE_DIR}/external/googleapis/protolists/${library}.list")
if (_opt_ADDITIONAL_PROTO_LISTS)
list(APPEND proto_list "${_opt_ADDITIONAL_PROTO_LISTS}")
endif ()
google_cloud_cpp_load_protodeps(
proto_deps
"${PROJECT_SOURCE_DIR}/external/googleapis/protodeps/${library}.deps")
Expand Down
178 changes: 10 additions & 168 deletions google/cloud/asset/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,109 +14,22 @@
# limitations under the License.
# ~~~

include(GoogleapisConfig)
set(DOXYGEN_PROJECT_NAME "Cloud Asset API C++ Client")
set(DOXYGEN_PROJECT_BRIEF "A C++ Client Library for the Cloud Asset API")
set(DOXYGEN_PROJECT_NUMBER "${PROJECT_VERSION}")
set(DOXYGEN_EXCLUDE_SYMBOLS "internal")
set(DOXYGEN_EXAMPLE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/quickstart")
include(GoogleCloudCppLibrary)

unset(mocks_globs)
unset(source_globs)
set(service_dirs "" "v1/")
foreach (dir IN LISTS service_dirs)
string(REPLACE "/" "_" ns "${dir}")
list(APPEND source_globs "${dir}*.h" "${dir}*.cc" "${dir}internal/*")
list(APPEND mocks_globs "${dir}mocks/*.h")
list(APPEND DOXYGEN_EXCLUDE_SYMBOLS "asset_${ns}internal")
if (NOT dir STREQUAL "")
list(APPEND DOXYGEN_EXAMPLE_PATH
"${CMAKE_CURRENT_SOURCE_DIR}/${dir}samples")
endif ()
endforeach ()
set(GOOGLE_CLOUD_CPP_SERVICE_DIRS "" "v1/")

include(GoogleCloudCppDoxygen)
set(GOOGLE_CLOUD_CPP_DOXYGEN_EXTRA_INCLUDES
"${PROJECT_BINARY_DIR}/google/cloud/accesscontextmanager"
"${PROJECT_BINARY_DIR}/google/cloud/osconfig")
google_cloud_cpp_doxygen_targets("asset" DEPENDS cloud-docs
google-cloud-cpp::asset_protos)

include(GoogleCloudCppCommon)

include(CompileProtos)
google_cloud_cpp_find_proto_include_dir(PROTO_INCLUDE_DIR)
google_cloud_cpp_load_protolist(
proto_list
"${PROJECT_SOURCE_DIR}/external/googleapis/protolists/asset.list")
# orgpolicy/v**1** is used *indirectly* by google/cloud/asset, therefore it does
# not appear in protolists/asset.list. In addition, it is not compiled by any
# other library. So, added manually.
list(APPEND proto_list
"${EXTERNAL_GOOGLEAPIS_SOURCE}/google/cloud/orgpolicy/v1/orgpolicy.proto")
google_cloud_cpp_load_protodeps(
proto_deps "${PROJECT_SOURCE_DIR}/external/googleapis/protodeps/asset.deps")
google_cloud_cpp_grpcpp_library(
google_cloud_cpp_asset_protos # cmake-format: sort
${proto_list} PROTO_PATH_DIRECTORIES "${EXTERNAL_GOOGLEAPIS_SOURCE}"
"${PROTO_INCLUDE_DIR}")
external_googleapis_set_version_and_alias(asset_protos)
target_link_libraries(google_cloud_cpp_asset_protos PUBLIC ${proto_deps})

file(
GLOB source_files
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
${source_globs})
list(SORT source_files)
add_library(google_cloud_cpp_asset ${source_files})
target_include_directories(
google_cloud_cpp_asset
PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>
$<INSTALL_INTERFACE:include>)
target_link_libraries(
google_cloud_cpp_asset
PUBLIC google-cloud-cpp::grpc_utils google-cloud-cpp::common
google-cloud-cpp::asset_protos)
google_cloud_cpp_add_common_options(google_cloud_cpp_asset)
set_target_properties(
google_cloud_cpp_asset
PROPERTIES EXPORT_NAME google-cloud-cpp::asset
VERSION "${PROJECT_VERSION}"
SOVERSION "${PROJECT_VERSION_MAJOR}")
target_compile_options(google_cloud_cpp_asset
PUBLIC ${GOOGLE_CLOUD_CPP_EXCEPTIONS_FLAG})

add_library(google-cloud-cpp::asset ALIAS google_cloud_cpp_asset)

# Create a header-only library for the mocks. We use a CMake `INTERFACE` library
# for these, a regular library would not work on macOS (where the library needs
# at least one .o file). Unfortunately INTERFACE libraries are a bit weird in
# that they need absolute paths for their sources.
file(
GLOB relative_mock_files
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
${mocks_globs})
list(SORT relative_mock_files)
set(mock_files)
foreach (file IN LISTS relative_mock_files)
list(APPEND mock_files "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
endforeach ()
add_library(google_cloud_cpp_asset_mocks INTERFACE)
target_sources(google_cloud_cpp_asset_mocks INTERFACE ${mock_files})
target_link_libraries(
google_cloud_cpp_asset_mocks
INTERFACE google-cloud-cpp::asset GTest::gmock_main GTest::gmock
GTest::gtest)
set_target_properties(google_cloud_cpp_asset_mocks
PROPERTIES EXPORT_NAME google-cloud-cpp::asset_mocks)
target_include_directories(
google_cloud_cpp_asset_mocks
INTERFACE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>
$<INSTALL_INTERFACE:include>)
target_compile_options(google_cloud_cpp_asset_mocks
INTERFACE ${GOOGLE_CLOUD_CPP_EXCEPTIONS_FLAG})
google_cloud_cpp_add_ga_grpc_library(
asset
"Cloud Asset API"
# orgpolicy/v**1** is used *indirectly* by google/cloud/asset, therefore it
# does not appear in protolists/asset.list. In addition, it is not compiled
# by any other library. So, added manually.
ADDITIONAL_PROTO_LISTS
"${EXTERNAL_GOOGLEAPIS_SOURCE}/google/cloud/orgpolicy/v1/orgpolicy.proto")

if (BUILD_TESTING AND GOOGLE_CLOUD_CPP_ENABLE_CXX_EXCEPTIONS)
add_executable(asset_quickstart "quickstart/quickstart.cc")
Expand All @@ -129,74 +42,3 @@ if (BUILD_TESTING AND GOOGLE_CLOUD_CPP_ENABLE_CXX_EXCEPTIONS)
set_tests_properties(asset_quickstart
PROPERTIES LABELS "integration-test;quickstart")
endif ()

# Get the destination directories based on the GNU recommendations.
include(GNUInstallDirs)

# Export the CMake targets to make it easy to create configuration files.
install(
EXPORT google_cloud_cpp_asset-targets
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/google_cloud_cpp_asset"
COMPONENT google_cloud_cpp_development)

# Install the libraries and headers in the locations determined by
# GNUInstallDirs
install(
TARGETS google_cloud_cpp_asset google_cloud_cpp_asset_protos
EXPORT google_cloud_cpp_asset-targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
COMPONENT google_cloud_cpp_runtime
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT google_cloud_cpp_runtime
NAMELINK_SKIP
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT google_cloud_cpp_development)
# With CMake-3.12 and higher we could avoid this separate command (and the
# duplication).
install(
TARGETS google_cloud_cpp_asset google_cloud_cpp_asset_protos
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT google_cloud_cpp_development
NAMELINK_ONLY
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT google_cloud_cpp_development)

google_cloud_cpp_install_proto_library_protos("google_cloud_cpp_asset_protos"
"${EXTERNAL_GOOGLEAPIS_SOURCE}")
google_cloud_cpp_install_proto_library_headers("google_cloud_cpp_asset_protos")
google_cloud_cpp_install_headers("google_cloud_cpp_asset"
"include/google/cloud/asset")
google_cloud_cpp_install_headers("google_cloud_cpp_asset_mocks"
"include/google/cloud/asset")

google_cloud_cpp_add_pkgconfig(
asset
"The Cloud Asset API C++ Client Library"
"Provides C++ APIs to use the Cloud Asset API."
"google_cloud_cpp_grpc_utils"
"google_cloud_cpp_common"
"google_cloud_cpp_asset_protos")

# Create and install the CMake configuration files.
include(CMakePackageConfigHelpers)
configure_file("config.cmake.in" "google_cloud_cpp_asset-config.cmake" @ONLY)
write_basic_package_version_file(
"google_cloud_cpp_asset-config-version.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY ExactVersion)

install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/google_cloud_cpp_asset-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/google_cloud_cpp_asset-config-version.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/google_cloud_cpp_asset"
COMPONENT google_cloud_cpp_development)

external_googleapis_install_pc("google_cloud_cpp_asset_protos")

# google-cloud-cpp::asset must be defined before we can add the samples.
foreach (dir IN LISTS service_dirs)
if (BUILD_TESTING AND GOOGLE_CLOUD_CPP_ENABLE_CXX_EXCEPTIONS)
google_cloud_cpp_add_samples_relative("asset" "${dir}samples/")
endif ()
endforeach ()