c/cmake_modules/GoUtils.cmake (224 lines of code) (raw):

# Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you 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. find_program(GO_BIN "go" REQUIRED) message(STATUS "Detecting Go executable: Found ${GO_BIN}") function(add_go_lib GO_MOD_DIR GO_LIBNAME) set(options) set(one_value_args BUILD_TAGS SHARED_LINK_FLAGS CMAKE_PACKAGE_NAME PKG_CONFIG_NAME BUILD_STATIC BUILD_SHARED) set(multi_value_args SOURCES OUTPUTS) cmake_parse_arguments(ARG "${options}" "${one_value_args}" "${multi_value_args}" ${ARGN}) if(ARG_UNPARSED_ARGUMENTS) message(SEND_ERROR "Error: unrecognized arguments: ${ARG_UNPARSED_ARGUMENTS}") endif() if(ARG_OUTPUTS) set(${ARG_OUTPUTS}) endif() # Allow overriding ADBC_BUILD_SHARED and ADBC_BUILD_STATIC if(DEFINED ARG_BUILD_SHARED) set(BUILD_SHARED ${ARG_BUILD_SHARED}) else() set(BUILD_SHARED ${ADBC_BUILD_SHARED}) endif() if(DEFINED ARG_BUILD_STATIC) set(BUILD_STATIC ${ARG_BUILD_STATIC}) else() set(BUILD_STATIC ${ADBC_BUILD_STATIC}) endif() set(BUILD_TAGS) if(DEFINED ARG_BUILD_TAGS) set(BUILD_TAGS "${ARG_BUILD_TAGS}") endif() if(NOT "${ADBC_GO_BUILD_TAGS}" STREQUAL "") if(NOT "${BUILD_TAGS}" STREQUAL "") set(BUILD_TAGS "${BUILD_TAGS},") endif() set(BUILD_TAGS "${BUILD_TAGS}${ADBC_GO_BUILD_TAGS}") endif() if(NOT "${BUILD_TAGS}" STREQUAL "") set(GO_BUILD_TAGS "-tags=${BUILD_TAGS}") endif() list(TRANSFORM ARG_SOURCES PREPEND "${GO_MOD_DIR}/") # go asan only works on linux/amd64 and linux/arm64 if(ADBC_USE_ASAN) if(CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64") if(NOT APPLE AND NOT MSVC_TOOLCHAIN) set(GO_BUILD_FLAGS "-asan") endif() endif() endif() # Go gcflags for disabling optimizations and inlining if debug separate_arguments(GO_BUILD_FLAGS NATIVE_COMMAND "${GO_BUILD_FLAGS} $<$<CONFIG:DEBUG>:-gcflags=\"-N -l\">") # if we're building debug mode then change the default CGO_CFLAGS and CGO_CXXFLAGS from "-g O2" to "-g3" set(GO_ENV_VARS "CGO_ENABLED=1 $<$<CONFIG:DEBUG>:CGO_CFLAGS=-g3> $<$<CONFIG:DEBUG>:CGO_CXXFLAGS=-g3>" ) separate_arguments(GO_ENV_VARS NATIVE_COMMAND "${GO_ENV_VARS}") if(BUILD_SHARED) set(LIB_NAME_SHARED "${CMAKE_SHARED_LIBRARY_PREFIX}${GO_LIBNAME}${CMAKE_SHARED_LIBRARY_SUFFIX}") set(ADBC_VERSION_SCRIPT_LINK_FLAG "-Wl,--version-script=${REPOSITORY_ROOT}/c/symbols.map") check_linker_flag(CXX ${ADBC_VERSION_SCRIPT_LINK_FLAG} CXX_LINKER_SUPPORTS_VERSION_SCRIPT) if(CXX_LINKER_SUPPORTS_VERSION_SCRIPT) set(EXTLDFLAGS ",--version-script=${REPOSITORY_ROOT}/c/symbols.map") endif() if(NOT APPLE) set(EXTLDFLAGS "${EXTLDFLAGS},-soname,${LIB_NAME_SHARED}.${ADBC_SO_VERSION}") endif() if(DEFINED EXTLDFLAGS) set(EXTLDFLAGS "'-extldflags=-Wl${EXTLDFLAGS}'") endif() if(DEFINED ARG_SHARED_LINK_FLAGS) separate_arguments(ARG_SHARED_LINK_FLAGS NATIVE_COMMAND "${ARG_SHARED_LINK_FLAGS}") endif() set(GO_LDFLAGS "-ldflags;\"${ARG_SHARED_LINK_FLAGS};-a;${EXTLDFLAGS}\"") set(LIBOUT_SHARED "${CMAKE_CURRENT_BINARY_DIR}/${LIB_NAME_SHARED}") if(CMAKE_OSX_ARCHITECTURES STREQUAL "x86_64") list(APPEND GO_ENV_VARS "GOARCH=amd64") elseif(CMAKE_OSX_ARCHITECTURES STREQUAL "arm64") list(APPEND GO_ENV_VARS "GOARCH=arm64") endif() add_custom_command(OUTPUT "${LIBOUT_SHARED}.${ADBC_FULL_SO_VERSION}" WORKING_DIRECTORY ${GO_MOD_DIR} DEPENDS ${ARG_SOURCES} COMMAND ${CMAKE_COMMAND} -E env ${GO_ENV_VARS} ${GO_BIN} build ${GO_BUILD_TAGS} "${GO_BUILD_FLAGS}" -o ${LIBOUT_SHARED}.${ADBC_FULL_SO_VERSION} -buildmode=c-shared ${GO_LDFLAGS} . COMMAND ${CMAKE_COMMAND} -E remove -f "${LIBOUT_SHARED}.${ADBC_SO_VERSION}.0.h" COMMENT "Building Go Shared lib ${GO_LIBNAME}" COMMAND_EXPAND_LISTS) add_custom_command(OUTPUT "${LIBOUT_SHARED}.${ADBC_SO_VERSION}" "${LIBOUT_SHARED}" DEPENDS "${LIBOUT_SHARED}.${ADBC_FULL_SO_VERSION}" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E create_symlink "${LIB_NAME_SHARED}.${ADBC_FULL_SO_VERSION}" "${LIB_NAME_SHARED}.${ADBC_SO_VERSION}" COMMAND ${CMAKE_COMMAND} -E create_symlink "${LIB_NAME_SHARED}.${ADBC_SO_VERSION}" "${LIB_NAME_SHARED}") add_custom_target(${GO_LIBNAME}_target ALL DEPENDS "${LIBOUT_SHARED}.${ADBC_FULL_SO_VERSION}" "${LIBOUT_SHARED}.${ADBC_SO_VERSION}" "${LIBOUT_SHARED}") add_library(${GO_LIBNAME}_shared SHARED IMPORTED) set_target_properties(${GO_LIBNAME}_shared PROPERTIES IMPORTED_LOCATION "${LIBOUT_SHARED}.${ADBC_FULL_SO_VERSION}" IMPORTED_SONAME "${LIB_NAME_SHARED}") add_dependencies(${GO_LIBNAME}_shared ${GO_LIBNAME}_target) if(ARG_OUTPUTS) list(APPEND ${ARG_OUTPUTS} ${GO_LIBNAME}_shared) endif() if(ADBC_RPATH_ORIGIN) if(APPLE) set(_lib_install_rpath "@loader_path") else() set(_lib_install_rpath "\$ORIGIN") endif() set_target_properties(${GO_LIBNAME}_shared PROPERTIES INSTALL_RPATH ${_lib_install_rpath}) endif() if(APPLE) if(ADBC_INSTALL_NAME_RPATH) set(_lib_install_name "@rpath") else() set(_lib_install_name "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") endif() set_target_properties(${GO_LIBNAME}_shared PROPERTIES INSTALL_NAME_DIR "${_lib_install_name}") endif() if(CMAKE_VERSION VERSION_LESS "3.21") if(WIN32) install(PROGRAMS $<TARGET_FILE:${GO_LIBNAME}_shared> ${INSTALL_IS_OPTIONAL} DESTINATION ${RUNTIME_INSTALL_DIR}) else() install(PROGRAMS $<TARGET_FILE:${GO_LIBNAME}_shared> ${INSTALL_IS_OPTIONAL} TYPE LIB) endif() else() install(IMPORTED_RUNTIME_ARTIFACTS ${GO_LIBNAME}_shared ${INSTALL_IS_OPTIONAL} RUNTIME DESTINATION ${RUNTIME_INSTALL_DIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() if(WIN32) # This symlink doesn't get installed install(FILES "${LIBOUT_SHARED}.${ADBC_SO_VERSION}" TYPE BIN) else() install(FILES "${LIBOUT_SHARED}" "${LIBOUT_SHARED}.${ADBC_SO_VERSION}" TYPE LIB) endif() endif() if(BUILD_STATIC) set(LIBNAME_STATIC "${CMAKE_STATIC_LIBRARY_PREFIX}${GO_LIBNAME}${CMAKE_STATIC_LIBRARY_SUFFIX}") set(LIBOUT_STATIC "${CMAKE_CURRENT_BINARY_DIR}/${LIBNAME_STATIC}") if(CMAKE_VERSION VERSION_LESS "3.20") string(REGEX REPLACE "\\..+$" ".h" LIBOUT_HEADER "${LIBOUT_STATIC}") else() cmake_path(REPLACE_EXTENSION LIBOUT_STATIC ".h" OUTPUT_VARIABLE LIBOUT_HEADER) endif() add_custom_command(OUTPUT "${LIBOUT_STATIC}" WORKING_DIRECTORY ${GO_MOD_DIR} DEPENDS ${ARG_SOURCES} COMMAND ${CMAKE_COMMAND} -E env "${GO_ENV_VARS}" ${GO_BIN} build "${GO_BUILD_TAGS}" -o "${LIBOUT_STATIC}" -buildmode=c-archive "${GO_BUILD_FLAGS}" . COMMAND ${CMAKE_COMMAND} -E remove -f "${LIBOUT_HEADER}" COMMENT "Building Go Static lib ${GO_LIBNAME}" COMMAND_EXPAND_LISTS) add_custom_target(${GO_LIBNAME}_static_target ALL DEPENDS "${LIBOUT_STATIC}") add_library(${GO_LIBNAME}_static STATIC IMPORTED) set_target_properties(${GO_LIBNAME}_static PROPERTIES IMPORTED_LOCATION "${LIBOUT_STATIC}") add_dependencies(${GO_LIBNAME}_static ${GO_LIBNAME}_static_target) if(ARG_OUTPUTS) list(APPEND ${ARG_OUTPUTS} ${GO_LIBNAME}_static) endif() install(FILES "${LIBOUT_STATIC}" TYPE LIB) endif() if(ARG_PKG_CONFIG_NAME) arrow_add_pkg_config("${ARG_PKG_CONFIG_NAME}") endif() # Modify variable in calling scope if(ARG_OUTPUTS) set(${ARG_OUTPUTS} ${${ARG_OUTPUTS}} PARENT_SCOPE) endif() endfunction()