CMake: Introduce a public qt_add_library function
Internally it uses a new _qt_internal_add_library function (similar how we have qt_add_executable and _qt_internal_add_executable) as well as finalizer code line the executable case. _qt_internal_add_library forwards arguments to add_library with some Qt specific adjustments to the selected default target type (based on whether Qt is configured as static or shared). The new _qt_internal_add_library is now used in qt_add_plugin as well as some internal library creating functions like qt_internal_add_module. This reduces some duplication of file name adjustments across functions and creates a central point for creation of Qt-like libraries (for some definition of Qt-like). Change-Id: Id9a31fe6bf278c8c3bb1e61e00a9febf7f1a2664 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
parent
5e96c64afb
commit
1bd408d6f7
@ -1,52 +1,96 @@
|
||||
# Wrapper function to create a regular cmake target and forward all the
|
||||
# arguments collected by the conversion script.
|
||||
function(qt_internal_add_cmake_library target)
|
||||
# Process arguments:
|
||||
qt_parse_all_arguments(arg "qt_add_cmake_library"
|
||||
"SHARED;MODULE;STATIC;INTERFACE"
|
||||
"OUTPUT_DIRECTORY;ARCHIVE_INSTALL_DIRECTORY;INSTALL_DIRECTORY"
|
||||
"${__default_private_args};${__default_public_args}"
|
||||
macro(qt_internal_get_add_library_option_args option_args)
|
||||
set(${option_args}
|
||||
SHARED
|
||||
STATIC
|
||||
MODULE
|
||||
INTERFACE
|
||||
)
|
||||
endmacro()
|
||||
|
||||
# Helper to create a library using the public _qt_internal_add_library function.
|
||||
#
|
||||
# The difference to _qt_internal_add_library is that MODULE is replaced with STATIC in a static
|
||||
# Qt build.
|
||||
# Everything else is just prepation for option validating.
|
||||
function(qt_internal_add_common_qt_library_helper target)
|
||||
qt_internal_get_add_library_option_args(option_args)
|
||||
qt_parse_all_arguments(arg "qt_internal_add_common_qt_library_helper"
|
||||
"${option_args}"
|
||||
""
|
||||
""
|
||||
${ARGN}
|
||||
)
|
||||
|
||||
set(is_static_lib 0)
|
||||
|
||||
### Define Targets:
|
||||
if(${arg_INTERFACE})
|
||||
add_library("${target}" INTERFACE)
|
||||
elseif(${arg_STATIC} OR (${arg_MODULE} AND NOT BUILD_SHARED_LIBS))
|
||||
add_library("${target}" STATIC)
|
||||
set(is_static_lib 1)
|
||||
elseif(${arg_SHARED})
|
||||
add_library("${target}" SHARED)
|
||||
_qt_internal_apply_win_prefix_and_suffix("${target}")
|
||||
elseif(${arg_MODULE})
|
||||
add_library("${target}" MODULE)
|
||||
set_property(TARGET ${name} PROPERTY C_VISIBILITY_PRESET default)
|
||||
set_property(TARGET ${name} PROPERTY CXX_VISIBILITY_PRESET default)
|
||||
set_property(TARGET ${name} PROPERTY OBJC_VISIBILITY_PRESET default)
|
||||
set_property(TARGET ${name} PROPERTY OBJCXX_VISIBILITY_PRESET default)
|
||||
|
||||
if(APPLE)
|
||||
# CMake defaults to using .so extensions for loadable modules, aka plugins,
|
||||
# but Qt plugins are actually suffixed with .dylib.
|
||||
set_property(TARGET "${target}" PROPERTY SUFFIX ".dylib")
|
||||
endif()
|
||||
_qt_internal_apply_win_prefix_and_suffix("${target}")
|
||||
if(arg_SHARED)
|
||||
set(arg_SHARED SHARED)
|
||||
else()
|
||||
add_library("${target}")
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
set(is_static_lib 1)
|
||||
endif()
|
||||
set(arg_SHARED "")
|
||||
endif()
|
||||
|
||||
if(arg_MODULE)
|
||||
set(arg_MODULE MODULE)
|
||||
else()
|
||||
set(arg_MODULE "")
|
||||
endif()
|
||||
|
||||
if(arg_STATIC)
|
||||
set(arg_STATIC STATIC)
|
||||
else()
|
||||
set(arg_STATIC "")
|
||||
endif()
|
||||
|
||||
if(arg_INTERFACE)
|
||||
set(arg_INTERFACE INTERFACE)
|
||||
else()
|
||||
set(arg_INTERFACE "")
|
||||
endif()
|
||||
|
||||
if(arg_MODULE AND NOT BUILD_SHARED_LIBS)
|
||||
set(arg_MODULE STATIC)
|
||||
endif()
|
||||
|
||||
_qt_internal_add_library(${target} ${arg_STATIC} ${arg_SHARED} ${arg_MODULE} ${arg_INTERFACE})
|
||||
endfunction()
|
||||
|
||||
# Wrapper function to create a regular cmake target and forward all the
|
||||
# arguments collected by the conversion script.
|
||||
function(qt_internal_add_cmake_library target)
|
||||
qt_internal_get_add_library_option_args(option_args)
|
||||
set(single_args
|
||||
OUTPUT_DIRECTORY
|
||||
ARCHIVE_INSTALL_DIRECTORY
|
||||
INSTALL_DIRECTORY
|
||||
)
|
||||
set(multi_args
|
||||
${__default_private_args}
|
||||
${__default_public_args}
|
||||
)
|
||||
|
||||
qt_parse_all_arguments(arg "qt_add_cmake_library"
|
||||
"${option_args}"
|
||||
"${single_args}"
|
||||
"${multi_args}"
|
||||
${ARGN}
|
||||
)
|
||||
|
||||
qt_remove_args(library_helper_args
|
||||
ARGS_TO_REMOVE
|
||||
${single_args}
|
||||
${multi_args}
|
||||
ALL_ARGS
|
||||
${option_args}
|
||||
${single_args}
|
||||
${multi_args}
|
||||
ARGS
|
||||
${ARGN}
|
||||
)
|
||||
|
||||
qt_internal_add_common_qt_library_helper(${target} ${library_helper_args})
|
||||
|
||||
if (NOT arg_ARCHIVE_INSTALL_DIRECTORY AND arg_INSTALL_DIRECTORY)
|
||||
set(arg_ARCHIVE_INSTALL_DIRECTORY "${arg_INSTALL_DIRECTORY}")
|
||||
endif()
|
||||
|
||||
if (ANDROID)
|
||||
qt_android_apply_arch_suffix("${target}")
|
||||
endif()
|
||||
qt_skip_warnings_are_errors_when_repo_unclean("${target}")
|
||||
|
||||
if (arg_INSTALL_DIRECTORY)
|
||||
@ -91,42 +135,43 @@ endfunction()
|
||||
# compile 3rdparty libraries as part of the build.
|
||||
#
|
||||
function(qt_internal_add_3rdparty_library target)
|
||||
# Process arguments:
|
||||
qt_parse_all_arguments(arg "qt_add_3rdparty_library"
|
||||
"SHARED;MODULE;STATIC;INTERFACE;EXCEPTIONS;INSTALL;SKIP_AUTOMOC"
|
||||
"OUTPUT_DIRECTORY;QMAKE_LIB_NAME"
|
||||
"${__default_private_args};${__default_public_args}"
|
||||
qt_internal_get_add_library_option_args(library_option_args)
|
||||
set(option_args
|
||||
EXCEPTIONS
|
||||
INSTALL
|
||||
SKIP_AUTOMOC
|
||||
)
|
||||
set(single_args
|
||||
OUTPUT_DIRECTORY
|
||||
QMAKE_LIB_NAME
|
||||
)
|
||||
set(multi_args
|
||||
${__default_private_args}
|
||||
${__default_public_args}
|
||||
)
|
||||
|
||||
qt_parse_all_arguments(arg "qt_internal_add_3rdparty_library"
|
||||
"${library_option_args};${option_args}"
|
||||
"${single_args}"
|
||||
"${multi_args}"
|
||||
${ARGN}
|
||||
)
|
||||
|
||||
set(is_static_lib 0)
|
||||
qt_remove_args(library_helper_args
|
||||
ARGS_TO_REMOVE
|
||||
${option_args}
|
||||
${single_args}
|
||||
${multi_args}
|
||||
ALL_ARGS
|
||||
${library_option_args}
|
||||
${option_args}
|
||||
${single_args}
|
||||
${multi_args}
|
||||
ARGS
|
||||
${ARGN}
|
||||
)
|
||||
|
||||
### Define Targets:
|
||||
if(${arg_INTERFACE})
|
||||
add_library("${target}" INTERFACE)
|
||||
elseif(${arg_STATIC} OR (${arg_MODULE} AND NOT BUILD_SHARED_LIBS))
|
||||
add_library("${target}" STATIC)
|
||||
set(is_static_lib 1)
|
||||
elseif(${arg_SHARED})
|
||||
add_library("${target}" SHARED)
|
||||
elseif(${arg_MODULE})
|
||||
add_library("${target}" MODULE)
|
||||
set_property(TARGET ${name} PROPERTY C_VISIBILITY_PRESET default)
|
||||
set_property(TARGET ${name} PROPERTY CXX_VISIBILITY_PRESET default)
|
||||
set_property(TARGET ${name} PROPERTY OBJC_VISIBILITY_PRESET default)
|
||||
set_property(TARGET ${name} PROPERTY OBJCXX_VISIBILITY_PRESET default)
|
||||
|
||||
if(APPLE)
|
||||
# CMake defaults to using .so extensions for loadable modules, aka plugins,
|
||||
# but Qt plugins are actually suffixed with .dylib.
|
||||
set_property(TARGET "${target}" PROPERTY SUFFIX ".dylib")
|
||||
endif()
|
||||
else()
|
||||
add_library("${target}")
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
set(is_static_lib 1)
|
||||
endif()
|
||||
endif()
|
||||
qt_internal_add_common_qt_library_helper(${target} ${library_helper_args})
|
||||
|
||||
if(NOT arg_INTERFACE)
|
||||
qt_set_common_target_properties(${target})
|
||||
@ -143,10 +188,6 @@ function(qt_internal_add_3rdparty_library target)
|
||||
qt_internal_add_target_aliases(${target})
|
||||
_qt_internal_apply_strict_cpp(${target})
|
||||
|
||||
if (ANDROID)
|
||||
qt_android_apply_arch_suffix("${target}")
|
||||
endif()
|
||||
|
||||
qt_skip_warnings_are_errors_when_repo_unclean("${target}")
|
||||
|
||||
set_target_properties(${target} PROPERTIES
|
||||
|
@ -93,21 +93,30 @@ function(qt_internal_add_module target)
|
||||
endif()
|
||||
|
||||
### Define Targets:
|
||||
if(arg_HEADER_MODULE)
|
||||
set(type_to_create INTERFACE)
|
||||
elseif(arg_STATIC)
|
||||
set(type_to_create STATIC)
|
||||
else()
|
||||
# Use default depending on Qt configuration.
|
||||
set(type_to_create "")
|
||||
endif()
|
||||
|
||||
_qt_internal_add_library("${target}" ${type_to_create})
|
||||
|
||||
get_target_property(target_type ${target} TYPE)
|
||||
|
||||
set(is_interface_lib 0)
|
||||
set(is_shared_lib 0)
|
||||
set(is_static_lib 0)
|
||||
if(${arg_HEADER_MODULE})
|
||||
add_library("${target}" INTERFACE)
|
||||
if(target_type STREQUAL "INTERFACE_LIBRARY")
|
||||
set(is_interface_lib 1)
|
||||
elseif(${arg_STATIC})
|
||||
add_library("${target}" STATIC)
|
||||
elseif(target_type STREQUAL "STATIC_LIBRARY")
|
||||
set(is_static_lib 1)
|
||||
elseif(${QT_BUILD_SHARED_LIBS})
|
||||
add_library("${target}" SHARED)
|
||||
elseif(target_type STREQUAL "SHARED_LIBRARY")
|
||||
set(is_shared_lib 1)
|
||||
else()
|
||||
add_library("${target}" STATIC)
|
||||
set(is_static_lib 1)
|
||||
message(FATAL_ERROR "Invalid target type '${target_type}' for Qt module '${target}'")
|
||||
endif()
|
||||
|
||||
set_target_properties(${target} PROPERTIES
|
||||
@ -171,9 +180,6 @@ function(qt_internal_add_module target)
|
||||
target_compile_options(${target} PRIVATE -ffat-lto-objects)
|
||||
endif()
|
||||
|
||||
if (ANDROID)
|
||||
qt_android_apply_arch_suffix("${target}")
|
||||
endif()
|
||||
qt_internal_add_target_aliases("${target}")
|
||||
qt_skip_warnings_are_errors_when_repo_unclean("${target}")
|
||||
_qt_internal_apply_strict_cpp("${target}")
|
||||
@ -248,8 +254,6 @@ function(qt_internal_add_module target)
|
||||
)
|
||||
endif()
|
||||
|
||||
_qt_internal_apply_win_prefix_and_suffix("${target}")
|
||||
|
||||
if (WIN32 AND BUILD_SHARED_LIBS)
|
||||
_qt_internal_generate_win32_rc_file(${target})
|
||||
endif()
|
||||
@ -582,7 +586,6 @@ set(QT_CMAKE_EXPORT_NAMESPACE ${QT_CMAKE_EXPORT_NAMESPACE})")
|
||||
message(WARNING "GENERATE_METATYPES is on by default for Qt modules. Please remove the manual specification.")
|
||||
endif()
|
||||
if (NOT ${arg_NO_GENERATE_METATYPES})
|
||||
get_target_property(target_type ${target} TYPE)
|
||||
if (NOT target_type STREQUAL "INTERFACE_LIBRARY")
|
||||
set(metatypes_install_dir ${INSTALL_LIBDIR}/metatypes)
|
||||
set(args)
|
||||
|
@ -1731,31 +1731,33 @@ function(qt6_add_plugin target)
|
||||
)
|
||||
endif()
|
||||
|
||||
# If no explicit STATIC/SHARED option is set, default to the flavor of the Qt build.
|
||||
if(QT6_IS_SHARED_LIBS_BUILD)
|
||||
set(create_static_plugin FALSE)
|
||||
else()
|
||||
set(create_static_plugin TRUE)
|
||||
endif()
|
||||
|
||||
# Explicit option takes priority over the computed default.
|
||||
if(arg_STATIC)
|
||||
set(create_static_plugin TRUE)
|
||||
elseif(arg_SHARED)
|
||||
set(create_static_plugin FALSE)
|
||||
else()
|
||||
# If no explicit STATIC/SHARED option is set, default to the flavor of the Qt build.
|
||||
if(QT6_IS_SHARED_LIBS_BUILD)
|
||||
set(create_static_plugin FALSE)
|
||||
else()
|
||||
set(create_static_plugin TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (create_static_plugin)
|
||||
add_library(${target} STATIC)
|
||||
target_compile_definitions(${target} PRIVATE QT_STATICPLUGIN)
|
||||
# The default of _qt_internal_add_library creates SHARED in a shared Qt build, so we need to
|
||||
# be explicit about the MODULE.
|
||||
if(create_static_plugin)
|
||||
set(type_to_create STATIC)
|
||||
else()
|
||||
add_library(${target} MODULE)
|
||||
if(APPLE)
|
||||
# CMake defaults to using .so extensions for loadable modules, aka plugins,
|
||||
# but Qt plugins are actually suffixed with .dylib.
|
||||
set_property(TARGET "${target}" PROPERTY SUFFIX ".dylib")
|
||||
endif()
|
||||
_qt_internal_apply_win_prefix_and_suffix(${target})
|
||||
set(type_to_create MODULE)
|
||||
endif()
|
||||
|
||||
_qt_internal_add_library(${target} ${type_to_create})
|
||||
|
||||
get_target_property(target_type "${target}" TYPE)
|
||||
if (target_type STREQUAL "STATIC_LIBRARY")
|
||||
target_compile_definitions(${target} PRIVATE QT_STATICPLUGIN)
|
||||
endif()
|
||||
|
||||
set(output_name ${target})
|
||||
@ -1765,7 +1767,6 @@ function(qt6_add_plugin target)
|
||||
set_property(TARGET "${target}" PROPERTY OUTPUT_NAME "${output_name}")
|
||||
|
||||
if (ANDROID)
|
||||
qt6_android_apply_arch_suffix("${target}")
|
||||
set_target_properties(${target}
|
||||
PROPERTIES
|
||||
LIBRARY_OUTPUT_NAME "plugins_${arg_TYPE}_${output_name}"
|
||||
@ -1796,6 +1797,105 @@ if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
|
||||
endfunction()
|
||||
endif()
|
||||
|
||||
# Creates a library by forwarding arguments to add_library, applies some Qt naming file name naming
|
||||
# conventions and ensures the execution of Qt specific finalizers.
|
||||
function(qt6_add_library target)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "MANUAL_FINALIZATION" "" "")
|
||||
|
||||
_qt_internal_add_library("${target}" ${arg_UNPARSED_ARGUMENTS})
|
||||
|
||||
if(arg_MANUAL_FINALIZATION)
|
||||
# Caller says they will call qt6_finalize_target() themselves later
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Defer the finalization if we can. When the caller's project requires
|
||||
# CMake 3.19 or later, this makes the calls to this function concise while
|
||||
# still allowing target property modification before finalization.
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.19)
|
||||
# Need to wrap in an EVAL CODE or else ${target} won't be evaluated
|
||||
# due to special behavior of cmake_language() argument handling
|
||||
cmake_language(EVAL CODE "cmake_language(DEFER CALL qt6_finalize_target ${target})")
|
||||
else()
|
||||
set_target_properties("${target}" PROPERTIES _qt_is_immediately_finalized TRUE)
|
||||
qt6_finalize_target("${target}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Creates a library target by forwarding the arguments to add_library.
|
||||
#
|
||||
# Applies some Qt specific behaviors:
|
||||
# - If no type option is specified, rather than defaulting to STATIC it defaults to STATIC or SHARED
|
||||
# depending on the Qt configuration.
|
||||
# - Applies Qt specific prefixes and suffixes to file names depending on platform.
|
||||
function(_qt_internal_add_library target)
|
||||
set(opt_args
|
||||
STATIC
|
||||
SHARED
|
||||
MODULE
|
||||
INTERFACE
|
||||
OBJECT
|
||||
)
|
||||
set(single_args "")
|
||||
set(multi_args "")
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
|
||||
set(option_type_count 0)
|
||||
if(arg_STATIC)
|
||||
set(type_to_create STATIC)
|
||||
math(EXPR option_type_count "${option_type_count}+1")
|
||||
elseif(arg_SHARED)
|
||||
set(type_to_create SHARED)
|
||||
math(EXPR option_type_count "${option_type_count}+1")
|
||||
elseif(arg_MODULE)
|
||||
set(type_to_create MODULE)
|
||||
math(EXPR option_type_count "${option_type_count}+1")
|
||||
elseif(arg_INTERFACE)
|
||||
set(type_to_create INTERFACE)
|
||||
math(EXPR option_type_count "${option_type_count}+1")
|
||||
elseif(arg_OBJECT)
|
||||
set(type_to_create OBJECT)
|
||||
math(EXPR option_type_count "${option_type_count}+1")
|
||||
endif()
|
||||
|
||||
if(option_type_count GREATER 1)
|
||||
message(FATAL_ERROR
|
||||
"Multiple type options were given. Only one should be used."
|
||||
)
|
||||
endif()
|
||||
|
||||
# If no explicit type option is set, default to the flavor of the Qt build.
|
||||
# This in contrast to CMake which defaults to STATIC.
|
||||
if(NOT arg_STATIC AND NOT arg_SHARED AND NOT arg_MODULE AND NOT arg_INTERFACE
|
||||
AND NOT arg_OBJECT)
|
||||
if(QT6_IS_SHARED_LIBS_BUILD)
|
||||
set(type_to_create SHARED)
|
||||
else()
|
||||
set(type_to_create STATIC)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_library(${target} ${type_to_create} ${arg_UNPARSED_ARGUMENTS})
|
||||
|
||||
_qt_internal_apply_win_prefix_and_suffix("${target}")
|
||||
|
||||
if(arg_MODULE AND APPLE)
|
||||
# CMake defaults to using .so extensions for loadable modules, aka plugins,
|
||||
# but Qt plugins are actually suffixed with .dylib.
|
||||
set_property(TARGET "${target}" PROPERTY SUFFIX ".dylib")
|
||||
endif()
|
||||
|
||||
if(ANDROID)
|
||||
qt6_android_apply_arch_suffix("${target}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
|
||||
function(qt_add_library)
|
||||
qt6_add_library(${ARGV})
|
||||
endfunction()
|
||||
endif()
|
||||
|
||||
# By default Qt6 forces usage of utf8 sources for consumers of Qt.
|
||||
# Users can opt out of utf8 sources by calling this function with the target name of their
|
||||
# application or library.
|
||||
|
Loading…
x
Reference in New Issue
Block a user