1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-04-29 23:29:41 +02:00
audacity/cmake-proxies/cmake-modules/AudacityFunctions.cmake
Paul Licameli 4a2fc192e6 Bug2799: mod-script-pipe fails to load on Mac...
... This broke at commit 938bbeb with changes in CMake scripts.

This can be fixed by invoking CopyLibs.cmake for modules too.

This affects only the macOS build.
2021-06-09 15:06:21 -04:00

679 lines
23 KiB
CMake

#
# A collection of functions and macros
#
# Defines several useful directory paths for the active context.
macro( def_vars )
set( _SRCDIR "${CMAKE_CURRENT_SOURCE_DIR}" )
set( _INTDIR "${CMAKE_CURRENT_BINARY_DIR}" )
set( _PRVDIR "${CMAKE_CURRENT_BINARY_DIR}/private" )
set( _PUBDIR "${CMAKE_CURRENT_BINARY_DIR}/public" )
endmacro()
# Helper to organize sources into folders for the IDEs
macro( organize_source root prefix sources )
set( cleaned )
foreach( source ${sources} )
# Remove generator expressions
string( REGEX REPLACE ".*>:(.*)>*" "\\1" source "${source}" )
string( REPLACE ">" "" source "${source}" )
# Remove keywords
string( REGEX REPLACE "^[A-Z]+$" "" source "${source}" )
# Add to cleaned
list( APPEND cleaned "${source}" )
endforeach()
# Define the source groups
if( "${prefix}" STREQUAL "" )
source_group( TREE "${root}" FILES ${cleaned} )
else()
source_group( TREE "${root}" PREFIX ${prefix} FILES ${cleaned} )
endif()
endmacro()
# Given a directory, recurse to all defined subdirectories and assign
# the given folder name to all of the targets found.
function( set_dir_folder dir folder)
get_property( subdirs DIRECTORY "${dir}" PROPERTY SUBDIRECTORIES )
foreach( sub ${subdirs} )
set_dir_folder( "${sub}" "${folder}" )
endforeach()
get_property( targets DIRECTORY "${dir}" PROPERTY BUILDSYSTEM_TARGETS )
foreach( target ${targets} )
get_target_property( type "${target}" TYPE )
if( NOT "${type}" STREQUAL "INTERFACE_LIBRARY" )
set_target_properties( ${target} PROPERTIES FOLDER ${folder} )
endif()
endforeach()
endfunction()
# Helper to retrieve the settings returned from pkg_check_modules()
macro( get_package_interface package )
set( INCLUDES
${${package}_INCLUDE_DIRS}
)
set( LINKDIRS
${${package}_LIBDIR}
)
# We resolve the full path of each library to ensure the
# correct one is referenced while linking
foreach( lib ${${package}_LIBRARIES} )
find_library( LIB_${lib} ${lib} HINTS ${LINKDIRS} )
list( APPEND LIBRARIES ${LIB_${lib}} )
endforeach()
endmacro()
# Set the cache and context value
macro( set_cache_value var value )
set( ${var} "${value}" )
set_property( CACHE ${var} PROPERTY VALUE "${value}" )
endmacro()
# Set the given property and its config specific brethren to the same value
function( set_target_property_all target property value )
set_target_properties( "${target}" PROPERTIES "${property}" "${value}" )
foreach( type ${CMAKE_CONFIGURATION_TYPES} )
string( TOUPPER "${property}_${type}" prop )
set_target_properties( "${target}" PROPERTIES "${prop}" "${value}" )
endforeach()
endfunction()
# Taken from wxWidgets and modified for Audacity
#
# cmd_option(<name> <desc> [default] [STRINGS strings])
# The default is ON if third parameter isn't specified
function( cmd_option name desc )
cmake_parse_arguments( OPTION "" "" "STRINGS" ${ARGN} )
if( ARGC EQUAL 2 )
if( OPTION_STRINGS )
list( GET OPTION_STRINGS 1 default )
else()
set( default ON )
endif()
else()
set( default ${OPTION_UNPARSED_ARGUMENTS} )
endif()
if( OPTION_STRINGS )
set( cache_type STRING )
else()
set( cache_type BOOL )
endif()
set( ${name} "${default}" CACHE ${cache_type} "${desc}" )
if( OPTION_STRINGS )
set_property( CACHE ${name} PROPERTY STRINGS ${OPTION_STRINGS} )
# Check valid value
set( value_is_valid FALSE )
set( avail_values )
foreach( opt ${OPTION_STRINGS} )
if( ${name} STREQUAL opt )
set( value_is_valid TRUE )
break()
endif()
string( APPEND avail_values " ${opt}" )
endforeach()
if( NOT value_is_valid )
message( FATAL_ERROR "Invalid value \"${${name}}\" for option ${name}. Valid values are: ${avail_values}" )
endif()
endif()
set( ${name} "${${name}}" PARENT_SCOPE )
endfunction()
# Downloads NuGet packages
#
# Why this is needed...
#
# To get NuGet to work, you have to add the VS_PACKAGE_REFERENCES
# property to a target. This target must NOT be a UTILITY target,
# which is what we use to compile the message catalogs and assemble
# the manual. We could add that property to the Audacity target and
# CMake would add the required nodes to the VS project. And when the
# Audacity target is built, the NuGet packages would get automatically
# downloaded. This also means that the locale and manual targets
# must be dependent on the Audacity target so the packages would get
# downloaded before they execute. This would be handled by the CMake
# provided ALL_BUILD target which is, by default, set as the startup
# project in Visual Studio. Sweet right? Well, not quite...
#
# We want the Audacity target to be the startup project to provide
# easier debugging. But, if we do that, the ALL_BUILD target is no
# longer "in control" and any dependents of the Audacity target would
# not get built. So, targets like "nyquist" and "plug-ins" would have
# to be manually built. This is not what we want since Nyquist would
# not be available during Audacity debugging because the Nyquist runtime
# would not be copied into the destination folder alonside the Audacity
# executable.
#
# To remedy this conundrum, we simply download the NuGet packages
# ourselves and make the Audacity target dependent on the targets
# mentioned above. This ensures that the dest folder is populated
# and laid out like Audacity expects.
#
function( nuget_package dir name version )
# Generate the full package directory name
set( pkgdir "${CMAKE_BINARY_DIR}/packages/${name}/${version}" )
# Don't download it again if the package directory already exists
if( NOT EXISTS "${pkgdir}" )
set( pkgurl "https://www.nuget.org/api/v2/package/${name}/${version}" )
# Create the package directory
file( MAKE_DIRECTORY "${pkgdir}" )
# And download the package into the package directory
file( DOWNLOAD "${pkgurl}" "${pkgdir}/package.zip" )
# Extract the contents of the package into the package directory
execute_process(
COMMAND
${CMAKE_COMMAND} -E tar x "${pkgdir}/package.zip"
WORKING_DIRECTORY
${pkgdir}
)
endif()
# Return the package directory name to the caller
set( ${dir} "${pkgdir}" PARENT_SCOPE )
endfunction()
# Determines if the linker supports the "-platform_version" argument
# on macOS.
macro( check_for_platform_version )
if( NOT DEFINED LINKER_SUPPORTS_PLATFORM_VERSION )
execute_process(
COMMAND
ld -platform_version macos 1.1 1.1
ERROR_VARIABLE
error
)
if( error MATCHES ".*unknown option.*" )
set( PLATFORM_VERSION_SUPPORTED no CACHE INTERNAL "" )
else()
set( PLATFORM_VERSION_SUPPORTED yes CACHE INTERNAL "" )
endif()
endif()
endmacro()
# To be used to compile all C++ in the application and modules
function( audacity_append_common_compiler_options var use_pch )
if( NOT use_pch )
list( APPEND ${var}
PRIVATE
# include the correct config file; give absolute path to it, so
# that this works whether in src, modules, libraries
$<$<PLATFORM_ID:Windows>:/FI${CMAKE_BINARY_DIR}/src/private/configwin.h>
$<$<PLATFORM_ID:Darwin>:-include ${CMAKE_BINARY_DIR}/src/private/configmac.h>
$<$<NOT:$<PLATFORM_ID:Windows,Darwin>>:-include ${CMAKE_BINARY_DIR}/src/private/configunix.h>
)
endif()
list( APPEND ${var}
-DAUDACITY_VERSION=${AUDACITY_VERSION}
-DAUDACITY_RELEASE=${AUDACITY_RELEASE}
-DAUDACITY_REVISION=${AUDACITY_REVISION}
-DAUDACITY_MODLEVEL=${AUDACITY_MODLEVEL}
# Version string for visual display
-DAUDACITY_VERSION_STRING=L"${AUDACITY_VERSION}.${AUDACITY_RELEASE}.${AUDACITY_REVISION}${AUDACITY_SUFFIX}"
# This value is used in the resource compiler for Windows
-DAUDACITY_FILE_VERSION=L"${AUDACITY_VERSION},${AUDACITY_RELEASE},${AUDACITY_REVISION},${AUDACITY_MODLEVEL}"
# This renames a good use of this C++ keyword that we don't need
# to review when hunting for leaks because of naked new and delete.
-DPROHIBITED==delete
# Reviewed, certified, non-leaky uses of NEW that immediately entrust
# their results to RAII objects.
# You may use it in NEW code when constructing a wxWindow subclass
# with non-NULL parent window.
# You may use it in NEW code when the NEW expression is the
# constructor argument for a standard smart
# pointer like std::unique_ptr or std::shared_ptr.
-Dsafenew=new
$<$<CXX_COMPILER_ID:MSVC>:/permissive->
$<$<CXX_COMPILER_ID:AppleClang,Clang>:-Wno-underaligned-exception-object>
$<$<CXX_COMPILER_ID:AppleClang,Clang>:-Werror=return-type>
$<$<CXX_COMPILER_ID:AppleClang,Clang>:-Werror=dangling-else>
$<$<CXX_COMPILER_ID:AppleClang,Clang>:-Werror=return-stack-address>
# Yes, CMake will change -D to /D as needed for Windows:
-DWXINTL_NO_GETTEXT_MACRO
$<$<CXX_COMPILER_ID:MSVC>:-D_USE_MATH_DEFINES>
$<$<CXX_COMPILER_ID:MSVC>:-DNOMINMAX>
# Define/undefine _DEBUG
# Yes, -U to /U too as needed for Windows:
$<IF:$<CONFIG:Release>,-U_DEBUG,-D_DEBUG=1>
)
# Definitions controlled by the AUDACITY_BUILD_LEVEL switch
if( AUDACITY_BUILD_LEVEL EQUAL 0 )
list( APPEND ${var} -DIS_ALPHA -DUSE_ALPHA_MANUAL )
elseif( AUDACITY_BUILD_LEVEL EQUAL 1 )
list( APPEND ${var} -DIS_BETA -DUSE_ALPHA_MANUAL )
else()
list( APPEND ${var} -DIS_RELEASE )
endif()
set( ${var} "${${var}}" PARENT_SCOPE )
endfunction()
function( import_export_symbol var module_name )
# compute, e.g. "TRACK_UI_API" from module name "mod-track-ui"
string( REGEX REPLACE "^mod-" "" symbol "${module_name}" )
string( REGEX REPLACE "^lib-" "" symbol "${symbol}" )
string( TOUPPER "${symbol}" symbol )
string( REPLACE "-" "_" symbol "${symbol}" )
string( APPEND symbol "_API" )
set( "${var}" "${symbol}" PARENT_SCOPE )
endfunction()
function( import_symbol_define var module_name )
import_export_symbol( symbol "${module_name}" )
if( CMAKE_SYSTEM_NAME MATCHES "Windows" )
set( value "_declspec(dllimport)" )
elseif( HAVE_VISIBILITY )
set( value "__attribute__((visibility(\"default\")))" )
else()
set( value "" )
endif()
set( "${var}" "${symbol}=${value}" PARENT_SCOPE )
endfunction()
function( export_symbol_define var module_name )
import_export_symbol( symbol "${module_name}" )
if( CMAKE_SYSTEM_NAME MATCHES "Windows" )
set( value "_declspec(dllexport)" )
elseif( HAVE_VISIBILITY )
set( value "__attribute__((visibility(\"default\")))" )
else()
set( value "" )
endif()
set( "${var}" "${symbol}=${value}" PARENT_SCOPE )
endfunction()
# shorten a target name for purposes of generating a dependency graph picture
function( canonicalize_node_name var node )
# strip generator expressions
string( REGEX REPLACE ".*>.*:(.*)>" "\\1" node "${node}" )
# omit the "-interface" for alias targets to modules
string( REGEX REPLACE "-interface\$" "" node "${node}" )
# shorten names of standard libraries or Apple frameworks
string( REGEX REPLACE "^-(l|framework )" "" node "${node}" )
# shorten paths
get_filename_component( node "${node}" NAME_WE )
set( "${var}" "${node}" PARENT_SCOPE )
endfunction()
function( audacity_module_fn NAME SOURCES IMPORT_TARGETS
ADDITIONAL_DEFINES ADDITIONAL_LIBRARIES LIBTYPE )
set( TARGET ${NAME} )
set( TARGET_ROOT ${CMAKE_CURRENT_SOURCE_DIR} )
message( STATUS "========== Configuring ${TARGET} ==========" )
def_vars()
if (LIBTYPE STREQUAL "MODULE" AND CMAKE_SYSTEM_NAME MATCHES "Windows")
set( REAL_LIBTYPE SHARED )
else()
set( REAL_LIBTYPE "${LIBTYPE}" )
endif()
add_library( ${TARGET} ${REAL_LIBTYPE} )
# Manual propagation seems to be necessary from
# interface libraries -- just doing target_link_libraries naming them
# doesn't work as promised
# compute INCLUDES
set( INCLUDES )
list( APPEND INCLUDES PUBLIC ${TARGET_ROOT} )
# compute DEFINES
set( DEFINES )
list( APPEND DEFINES ${ADDITIONAL_DEFINES} )
# send the file to the proper place in the build tree, by setting the
# appropriate property for the platform
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
set( DIRECTORY_PROPERTY RUNTIME_OUTPUT_DIRECTORY )
else ()
set( DIRECTORY_PROPERTY LIBRARY_OUTPUT_DIRECTORY )
endif ()
if (LIBTYPE STREQUAL "MODULE")
set( ATTRIBUTES "shape=box" )
set_target_property_all( ${TARGET} ${DIRECTORY_PROPERTY} "${_MODDIR}" )
set_target_properties( ${TARGET}
PROPERTIES
PREFIX ""
FOLDER "modules" # for IDE organization
)
if( CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin" )
add_custom_command(
TARGET ${TARGET}
COMMAND ${CMAKE_COMMAND}
-D SRC="${_MODDIR}/${TARGET}.so"
-D WXWIN="${_SHARED_PROXY_BASE_PATH}/$<CONFIG>"
-P ${AUDACITY_MODULE_PATH}/CopyLibs.cmake
POST_BUILD )
endif()
else()
set( ATTRIBUTES "shape=octagon" )
set_target_property_all( ${TARGET} ${DIRECTORY_PROPERTY} "${_SHARED_PROXY_PATH}" )
set_target_properties( ${TARGET}
PROPERTIES
PREFIX ""
FOLDER "libraries" # for IDE organization
INSTALL_NAME_DIR ""
BUILD_WITH_INSTALL_NAME_DIR YES
)
endif()
if( "wxBase" IN_LIST IMPORT_TARGETS OR "wxwidgets::base" IN_LIST IMPORT_TARGETS )
string( APPEND ATTRIBUTES " style=filled" )
endif()
export_symbol_define( export_symbol "${TARGET}" )
import_symbol_define( import_symbol "${TARGET}" )
list( APPEND DEFINES
PRIVATE "${export_symbol}"
INTERFACE "${import_symbol}"
)
set( LOPTS
PRIVATE
$<$<PLATFORM_ID:Darwin>:-undefined dynamic_lookup>
)
# compute LIBRARIES
set( LIBRARIES )
foreach( IMPORT ${IMPORT_TARGETS} )
list( APPEND LIBRARIES "${IMPORT}" )
endforeach()
list( APPEND LIBRARIES ${ADDITIONAL_LIBRARIES} )
# list( TRANSFORM SOURCES PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/" )
# Compute compilation options.
# Perhaps a another function argument in future to customize this too.
set( OPTIONS )
audacity_append_common_compiler_options( OPTIONS NO )
organize_source( "${TARGET_ROOT}" "" "${SOURCES}" )
target_sources( ${TARGET} PRIVATE ${SOURCES} )
target_compile_definitions( ${TARGET} PRIVATE ${DEFINES} )
target_compile_options( ${TARGET} ${OPTIONS} )
target_include_directories( ${TARGET} PUBLIC ${TARGET_ROOT} )
target_link_options( ${TARGET} PRIVATE ${LOPTS} )
target_link_libraries( ${TARGET} PUBLIC ${LIBRARIES} )
if( NOT CMAKE_SYSTEM_NAME MATCHES "Windows" )
add_custom_command(
TARGET "${TARGET}"
POST_BUILD
COMMAND $<IF:$<CONFIG:Debug>,echo,strip> -x $<TARGET_FILE:${TARGET}>
)
endif()
if( NOT REAL_LIBTYPE STREQUAL "MODULE" )
if( CMAKE_SYSTEM_NAME MATCHES "Windows" )
set( REQUIRED_LOCATION "${_EXEDIR}" )
elseif( CMAKE_SYSTEM_NAME MATCHES "Darwin")
set( REQUIRED_LOCATION "${_PKGLIB}" )
else()
set( REQUIRED_LOCATION "${_DEST}/${_PKGLIB}" )
endif()
add_custom_command(TARGET ${TARGET} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
"$<TARGET_FILE:${TARGET}>"
"${REQUIRED_LOCATION}/$<TARGET_FILE_NAME:${TARGET}>"
)
endif()
# define an additional interface library target
set(INTERFACE_TARGET "${TARGET}-interface")
if (NOT REAL_LIBTYPE STREQUAL "MODULE")
add_library("${INTERFACE_TARGET}" ALIAS "${TARGET}")
else()
add_library("${INTERFACE_TARGET}" INTERFACE)
foreach(PROP
INTERFACE_INCLUDE_DIRECTORIES
INTERFACE_COMPILE_DEFINITIONS
INTERFACE_LINK_LIBRARIES
)
get_target_property( PROPS "${TARGET}" "${PROP}" )
if (PROPS)
set_target_properties(
"${INTERFACE_TARGET}"
PROPERTIES "${PROP}" "${PROPS}" )
endif()
endforeach()
endif()
# collect dependency information
list( APPEND GRAPH_EDGES "\"${TARGET}\" [${ATTRIBUTES}]" )
if (NOT LIBTYPE STREQUAL "MODULE")
list( APPEND GRAPH_EDGES "\"Audacity\" -> \"${TARGET}\"" )
endif ()
set(ACCESS PUBLIC PRIVATE INTERFACE)
foreach( IMPORT ${IMPORT_TARGETS} )
if(IMPORT IN_LIST ACCESS)
continue()
endif()
canonicalize_node_name(IMPORT "${IMPORT}")
list( APPEND GRAPH_EDGES "\"${TARGET}\" -> \"${IMPORT}\"" )
endforeach()
set( GRAPH_EDGES "${GRAPH_EDGES}" PARENT_SCOPE )
endfunction()
# Set up for defining a module target.
# All modules depend on the application.
# Pass a name and sources, and a list of other targets.
# Use the interface compile definitions and include directories of the
# other targets, and link to them.
# More defines, and more target libraries (maybe generator expressions)
# may be given too.
macro( audacity_module NAME SOURCES IMPORT_TARGETS
ADDITIONAL_DEFINES ADDITIONAL_LIBRARIES )
# The extra indirection of a function call from this macro, and
# re-assignment of GRAPH_EDGES, is so that a module definition may
# call this macro, and it will (correctly) collect edges for the
# CMakeLists.txt in the directory above it; but otherwise we take
# advantage of function scoping of variables.
audacity_module_fn(
"${NAME}"
"${SOURCES}"
"${IMPORT_TARGETS}"
"${ADDITIONAL_DEFINES}"
"${ADDITIONAL_LIBRARIES}"
"MODULE"
)
set( GRAPH_EDGES "${GRAPH_EDGES}" PARENT_SCOPE )
endmacro()
# Set up for defining a library target.
# The application depends on all libraries.
# Pass a name and sources, and a list of other targets.
# Use the interface compile definitions and include directories of the
# other targets, and link to them.
# More defines, and more target libraries (maybe generator expressions)
# may be given too.
macro( audacity_library NAME SOURCES IMPORT_TARGETS
ADDITIONAL_DEFINES ADDITIONAL_LIBRARIES )
# ditto comment in the previous macro
audacity_module_fn(
"${NAME}"
"${SOURCES}"
"${IMPORT_TARGETS}"
"${ADDITIONAL_DEFINES}"
"${ADDITIONAL_LIBRARIES}"
"SHARED"
)
set( GRAPH_EDGES "${GRAPH_EDGES}" PARENT_SCOPE )
# Collect list of libraries for the executable to declare dependency on
list( APPEND AUDACITY_LIBRARIES "${NAME}" )
set( AUDACITY_LIBRARIES "${AUDACITY_LIBRARIES}" PARENT_SCOPE )
endmacro()
# A special macro for header only libraries
macro( audacity_header_only_library NAME SOURCES IMPORT_TARGETS
ADDITIONAL_DEFINES )
# ditto comment in the previous macro
add_library( ${NAME} INTERFACE )
target_include_directories ( ${NAME} INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} )
target_sources( ${NAME} INTERFACE ${SOURCES})
target_link_libraries( ${NAME} INTERFACE ${IMPORT_TARGETS} )
target_compile_definitions( ${NAME} INTERFACE ${ADDITIONAL_DEFINES} )
list( APPEND AUDACITY_LIBRARIES "${NAME}" )
set( AUDACITY_LIBRARIES "${AUDACITY_LIBRARIES}" PARENT_SCOPE )
endmacro()
#
# Add individual library targets
#
# Parms:
# dir directory name within the cmake-proxies directory.
# (Doesn't HAVE to match the same directory in lib-src,
# but it usually does.)
#
# name suffix for the cmake user options
#
# symbol suffix for the "USE_<symbol>" variable that the Audacity
# target uses to include/exclude functionality.
#
# required Determines if the library is required or not. If it is,
# the user is not given the option of enabling/disabling it.
#
# check Determines if local/system checks should be performed here
# or in the subdirectory config.
#
# packages A list of packages required for this target in pkg-config
# format.
function( addlib dir name symbol required check )
set( subdir "${CMAKE_SOURCE_DIR}/cmake-proxies/${dir}" )
set( bindir "${CMAKE_BINARY_DIR}/cmake-proxies/${dir}" )
# Extract the list of packages from the function args
list( SUBLIST ARGV 5 -1 packages )
# Define target's name and it's source directory
set( TARGET ${dir} )
set( TARGET_ROOT ${libsrc}/${dir} )
# Define the option name
set( use ${_OPT}use_${name} )
# If we're not checking for system or local here, then let the
# target config handle the rest.
if( NOT check )
add_subdirectory( ${subdir} ${bindir} EXCLUDE_FROM_ALL )
return()
endif()
# If the target isn't required, allow the user to select which one
# to use or disable it entirely
set( desc "local" )
if( packages )
set( sysopt "system" )
string( PREPEND desc "system (if available), " )
set( default "${${_OPT}lib_preference}" )
else()
set( default "local" )
endif()
if( NOT required )
set( reqopt "off" )
string( APPEND desc ", off" )
endif()
cmd_option( ${use}
"Use ${name} library [${desc}]"
"${default}"
STRINGS ${sysopt} "local" ${reqopt}
)
# Bail if the target will not be used
if( ${use} STREQUAL "off" )
message( STATUS "========== ${name} disabled ==========" )
set( USE_${symbol} OFF CACHE INTERNAL "" FORCE )
return()
endif()
# Let the Audacity target know that this library will be used
set( USE_${symbol} ON CACHE INTERNAL "" FORCE )
if ( TARGET "${TARGET}" )
return()
endif()
message( STATUS "========== Configuring ${name} ==========" )
# Check for the system package(s) if the user prefers it
if( ${use} STREQUAL "system" )
# Look them up
pkg_check_modules( PKG_${TARGET} ${packages} )
if( PKG_${TARGET}_FOUND )
message( STATUS "Using '${name}' system library" )
# Create the target interface library
add_library( ${TARGET} INTERFACE IMPORTED GLOBAL )
# Retrieve the package information
get_package_interface( PKG_${TARGET} )
# And add it to our target
target_include_directories( ${TARGET} INTERFACE ${INCLUDES} )
target_link_libraries( ${TARGET} INTERFACE ${LIBRARIES} )
elseif( ${_OPT}obey_system_dependencies )
message( FATAL_ERROR "Failed to find the system package ${name}" )
else()
set( ${use} "local" )
set_property( CACHE ${use} PROPERTY VALUE "local" )
endif()
endif()
# User wants the local package or the system one wasn't found
if( ${use} STREQUAL "local" )
message( STATUS "Using '${name}' local library" )
# Pull in the target config
add_subdirectory( ${subdir} ${bindir} EXCLUDE_FROM_ALL )
# Get the list of targets defined by that config
get_property( targets DIRECTORY "${subdir}" PROPERTY BUILDSYSTEM_TARGETS )
# Set the folder (for the IDEs) for each one
foreach( target ${targets} )
# Skip interface libraries since they don't have any source to
# present in the IDEs
get_target_property( type "${target}" TYPE )
if( NOT "${type}" STREQUAL "INTERFACE_LIBRARY" )
set_target_properties( ${target} PROPERTIES FOLDER "lib-src" )
endif()
endforeach()
endif()
endfunction()