# NOTE: # # - Use function() whenever possible, macro() doesn't start a new # variable scope and needs careful handling to avoid left overs. # # - To 'export' values or lists, use the macros SET_GLOBAL() and # LIST_APPEND_GLOBAL(). # # LIST_APPEND_GLOBAL(Var Element) # # Append to a list in the global variable scope (cache internal) function(LIST_APPEND_GLOBAL _var _element) set(_local ${${_var}}) list(APPEND _local ${_element}) set(${_var} ${_local} CACHE INTERNAL "") endfunction() # SET_GLOBAL(Var Value [Help]) # # Set a variable in the global variable scope (cache internal) function(SET_GLOBAL _var _value) set(${_var} "${_value}" CACHE INTERNAL "${ARGN}") endfunction() unset(EFL_ALL_OPTIONS CACHE) unset(EFL_ALL_LIBS CACHE) unset(EFL_ALL_TESTS CACHE) unset(EFL_PKG_CONFIG_MISSING_OPTIONAL CACHE) # EFL_OPTION_BACKEND(Name Help Backend1 ... BackendN # [DEPENDS "COND1; COND2; NOT COND3" FAILED_VALUE] # [REQUIRED]) # # Wrapper around EFL_OPTION() and EFL_BACKEND_CHOICES() # that creates an option 'CHOICE' within possible backends # when these are found (${Backend}_FOUND). # # The REQUIRED keyword will force a valid backend, otherwise 'none' is # allowed. # # If a backend was chose, then ${Name}_CFLAGS and ${Name}_LDFLAGS are # set to lists based on ${Backend}_CFLAGS or # ${Backend}_INCLUDE_DIR/${Backend}_INCLUDE_DIRS and # ${Backend}_LDFLAGS or ${Backend}_LIBRARIES function(EFL_OPTION_BACKEND _name _help) cmake_parse_arguments(PARAMS "" "" "DEPENDS" ${ARGN}) EFL_BACKEND_CHOICES(${_name} ${PARAMS_UNPARSED_ARGUMENTS}) EFL_OPTION(${_name} "${_help}" "${${_name}_DEFAULT}" CHOICE ${${_name}_CHOICES} DEPENDS ${PARAMS_DEPENDS}) if(NOT ${_name} STREQUAL "none") string(TOUPPER "${${_name}}" _backend) if(DEFINED ${_backend}_CFLAGS) set(_cflags ${${_backend}_CFLAGS}) else() set(_cflags "") foreach(_d ${${_backend}_INCLUDE_DIR} ${${_backend}_INCLUDE_DIRS}) list(APPEND _cflags "-I${_d}") endforeach() endif() if(DEFINED ${_backend}_LDFLAGS) set(_ldflags ${${_backend}_LDFLAGS}) else() set(_ldflags "") foreach(_d ${${_backend}_LIBRARIES}) list(APPEND _ldflags "-l${_d}") endforeach() else() endif() SET_GLOBAL(${_name}_CFLAGS "${_cflags}") SET_GLOBAL(${_name}_LDFLAGS "${_ldflags}") SET_GLOBAL(${_name}_ENABLED ON) else() unset(${_name}_CFLAGS CACHE) unset(${_name}_LDFLAGS CACHE) SET_GLOBAL(${_name}_ENABLED OFF) endif() endfunction() # EFL_OPTION(Name Help Default [STRING|BOOL|FILEPATH|PATH] # [CHOICE c1;...;cN] # [DEPENDS "COND1; COND2; NOT COND3" FAILED_VALUE]) # # Declare an option() that will be automatically printed by # EFL_OPTIONS_SUMMARY() # # To extend the EFL_OPTIONS_SUMMARY() message, use # EFL_OPTION_SET_MESSAGE(Name Message) function(EFL_OPTION _name _help _defval) cmake_parse_arguments(PARAMS "" "" "CHOICE;DEPENDS" ${ARGN}) set(_type) set(_vartype) set(_choices) list(LENGTH PARAMS_UNPARSED_ARGUMENTS _argc) if(_argc LESS 1) set(_type BOOL) set(_vartype BOOL) else() list(GET PARAMS_UNPARSED_ARGUMENTS 0 _type) set(_vartype ${_type}) list(REMOVE_AT PARAMS_UNPARSED_ARGUMENTS 0) endif() if(PARAMS_CHOICE) set(_type CHOICE) set(_vartype STRING) SET_GLOBAL(EFL_OPTION_CHOICES_${_name} "${PARAMS_CHOICE}" "Possible values for ${_name}") set(_choices " (Choices: ${PARAMS_CHOICE})") endif() if(_type STREQUAL "BOOL") # force ON/OFF representation if(_defval) set(_defval ON) else() set(_defval OFF) endif() endif() if(EFL_LIB_CURRENT) if(NOT DEFINED EFL_ALL_OPTIONS_${EFL_LIB_CURRENT}) LIST_APPEND_GLOBAL(EFL_ALL_OPTIONS EFL_ALL_OPTIONS_${EFL_LIB_CURRENT}) endif() LIST_APPEND_GLOBAL(EFL_ALL_OPTIONS_${EFL_LIB_CURRENT} ${_name}) else() LIST_APPEND_GLOBAL(EFL_ALL_OPTIONS ${_name}) endif() SET_GLOBAL(EFL_OPTION_DEFAULT_${_name} "${_defval}" "Default value for ${_name}") SET_GLOBAL(EFL_OPTION_TYPE_${_name} "${_vartype}" "Type of ${_name}") set(_available ON) if(PARAMS_DEPENDS) list(LENGTH PARAMS_DEPENDS _count) list(GET PARAMS_DEPENDS 0 _deps) list(GET PARAMS_DEPENDS 1 _deps_failure_value) if(_deps_failure_value STREQUAL "NOTFOUND") message(FATAL_ERROR "EFL_OPTION(${_name}) has DEPENDS but no value when dependencies fail") endif() set(_missing_deps "") foreach(_d ${_deps}) if(${_d}) else() set(_available OFF) list(APPEND _missing_deps "${_d}") endif() endforeach() endif() if(_available) if(DEFINED EFL_OPTION_ORIGINAL_VALUE_${_name}) set(${_name} ${EFL_OPTION_ORIGINAL_VALUE_${_name}} CACHE ${_type} "${_help}${_choices}" FORCE) unset(EFL_OPTION_ORIGINAL_VALUE_${_name} CACHE) else() set(${_name} ${_defval} CACHE ${_type} "${_help}${_choices}") endif() unset(EFL_OPTION_DEPENDS_MISSING_${_name} CACHE) option(${_name} "${_help}${_choices}" "${${_name}}") else() if(NOT DEFINED EFL_OPTION_ORIGINAL_VALUE_${_name}) if(DEFINED ${_name}) SET_GLOBAL(EFL_OPTION_ORIGINAL_VALUE_${_name} "${${_name}}") endif() endif() SET_GLOBAL(EFL_OPTION_DEPENDS_MISSING_${_name} "${_missing_deps}") set(${_name} "${_deps_failure_value}" CACHE "${_type}" "Missing dependencies (${_help}${_choices})" FORCE) endif() if(_choices) list(FIND PARAMS_CHOICE "${${_name}}" _ret) if(${_ret} EQUAL -1) message(FATAL_ERROR "Invalid choice ${_name}=${${_name}}${_choices}") endif() endif() endfunction() # EFL_OPTION_SET_MESSAGE(Name Message) # # Extends the summary line output by EFL_OPTIONS_SUMMARY() # with more details. function(EFL_OPTION_SET_MESSAGE _name _message) SET_GLOBAL(EFL_OPTION_MESSAGE_${_name} "${_message}") endfunction() # _EFL_OPTIONS_SUMMARY_INTERNAL(Prefix Option) # # Internal function for EFL_OPTIONS_SUMMARY(). function(_EFL_OPTIONS_SUMMARY_INTERNAL _prefix _o) set(_v ${${_o}}) set(_d ${EFL_OPTION_DEFAULT_${_o}}) if(EFL_OPTION_DEPENDS_MISSING_${_o}) set(_i "requires: ${EFL_OPTION_DEPENDS_MISSING_${_o}}, was: ${EFL_OPTION_ORIGINAL_VALUE_${_o}}") elseif("${_v}" STREQUAL "${_d}") set(_i "default") else() set(_i "default: ${_d}") endif() if(EFL_OPTION_MESSAGE_${_o}) set(_m " [${EFL_OPTION_MESSAGE_${_o}}]") else() set(_m) endif() message(STATUS "${_prefix}${_o}=${_v} (${_i})${_m}") endfunction() # EFL_OPTIONS_SUMMARY() # Shows the summary of options, their values and related messages. function(EFL_OPTIONS_SUMMARY) message(STATUS "EFL ${PROJECT_VERSION} Options Summary:") message(STATUS " CMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}") message(STATUS " CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}") foreach(_o ${EFL_ALL_OPTIONS}) if(_o MATCHES "^EFL_ALL_OPTIONS_") string(REGEX REPLACE "^EFL_ALL_OPTIONS_" "" _name "${_o}") message(STATUS "") message(STATUS " ${_name} options:") foreach(_so ${${_o}}) _EFL_OPTIONS_SUMMARY_INTERNAL(" " ${_so}) endforeach() else() _EFL_OPTIONS_SUMMARY_INTERNAL(" " ${_o}) endif() endforeach() message(STATUS "") message(STATUS "EFL Libraries:") foreach(_o ${EFL_ALL_LIBS}) message(STATUS " ${_o}${_mods}") foreach(_m ${${_o}_MODULES}) string(REGEX REPLACE "^${_o}-module-" "" _m ${_m}) message(STATUS " dynamic: ${_m}") endforeach() foreach(_m ${${_o}_STATIC_MODULES}) string(REGEX REPLACE "^${_o}-module-" "" _m ${_m}) message(STATUS " static.: ${_m}") endforeach() unset(_m) endforeach() if(EFL_PKG_CONFIG_MISSING_OPTIONAL) message(STATUS "") message(STATUS "The following pkg-config optional modules are missing:") foreach(_m ${EFL_PKG_CONFIG_MISSING_OPTIONAL}) message(STATUS " ${_m}") endforeach() unset(_m) endif() endfunction() set(EFL_ALL_LIBS) set(EFL_ALL_TESTS) # EFL_FINALIZE() # # Finalize EFL processing, adding extra targets. function(EFL_FINALIZE) add_custom_target(all-libs DEPENDS ${EFL_ALL_LIBS}) add_custom_target(all-tests DEPENDS ${EFL_ALL_TESTS}) endfunction() set(VAR_HEADER_FILE_CONTENT HEADER_FILE_CONTENT CACHE INTERNAL "") unset(${VAR_HEADER_FILE_CONTENT} CACHE) unset(CHECK_SCOPE CACHE) unset(CHECK_SCOPE_UPPERCASE CACHE) # CHECK_INIT(scope) # # Initialize the scope for the following FUNC_CHECK, TYPE_CHECK, # HEADER_CHECK... calls. function(CHECK_INIT scope) set(CHECK_SCOPE scope CACHE INTERNAL "Scope of current *_CHECK functions") if(scope) string(TOUPPER ${scope} scope_uc) SET_GLOBAL(CHECK_SCOPE_UPPERCASE ${scope_uc}) set(_suffix "_${scope_uc}") else() set(_suffix "") endif() SET_GLOBAL(VAR_HEADER_FILE_CONTENT HEADER_FILE_CONTENT${_suffix}) SET_GLOBAL(${VAR_HEADER_FILE_CONTENT} "") endfunction() # CHECK_APPEND_DEFINE(name value) # # If value evaluates to true: # #define ${name} ${value} # otherwise: # /* #undef ${name} */ # # NOTE: ${name} is not modified at all, if it must include # CHECK_SCOPE_UPPERCASE or CHECK_SCOPE, do it yourself. function(CHECK_APPEND_DEFINE name value) SET_GLOBAL(${VAR_HEADER_FILE_CONTENT} "${${VAR_HEADER_FILE_CONTENT}}#ifdef ${name}\n#undef ${name}\n#endif\n") if(value) if(value STREQUAL ON OR value STREQUAL TRUE) set(value 1) endif() SET_GLOBAL(${VAR_HEADER_FILE_CONTENT} "${${VAR_HEADER_FILE_CONTENT}}#define ${name} ${value}\n\n") else() SET_GLOBAL(${VAR_HEADER_FILE_CONTENT} "${${VAR_HEADER_FILE_CONTENT}}/* #undef ${name} */\n\n") endif() endfunction() # CHECK_NAME_DEFAULT(name variable) # # Create the default name based on ${name} # and stores in ${variable}. # # This will automatically prepend ${CHECK_SCOPE_UPPERCASE} if it's # defined, will translate everything to uppercase and fix it to be a # valid C-symbol. function(CHECK_NAME_DEFAULT name var) string(TOUPPER ${name} v) string(REGEX REPLACE "[^a-zA-Z0-9]" "_" v "${v}") string(REGEX REPLACE "_{2,}" "_" v "${v}") if(CHECK_SCOPE_UPPERCASE) set(v "${CHECK_SCOPE_UPPERCASE}_${v}") endif() set(${var} ${v} PARENT_SCOPE) endfunction() # HEADER_CHECK(header [NAME variable] [INCLUDE_FILES extra1.h .. extraN.h]) # # Check if the header file exists, in such case define variable # in configuration file. # # Variable defaults to HAVE_${HEADER}, where HEADER is the uppercase # representation of the first parameter. It can be overridden using # NAME keyword. # # To include extra files, then use INCLUDE_FILES keyword. function(HEADER_CHECK header) CHECK_NAME_DEFAULT(HAVE_${header} var) cmake_parse_arguments(PARAMS "" "NAME" "INCLUDE_FILES" ${ARGN}) if(PARAMS_NAME) set(var ${PARAMS_NAME}) endif() set(CMAKE_EXTRA_INCLUDE_FILES "${PARAMS_INCLUDE_FILES}") CHECK_INCLUDE_FILE(${header} ${var}) CHECK_APPEND_DEFINE(${var} "${${var}}") endfunction() # FUNC_CHECK(func [NAME variable] # [INCLUDE_FILES header1.h .. headerN.h] # [LIBRARIES lib1 ... libN] # [DEFINITIONS -DA=1 .. -DN=123] # [FLAGS -cmdlineparam1 .. -cmdlineparamN] # [CXX]) # # Check if the function exists, in such case define variable in # configuration file. # # Variable defaults to HAVE_${FUNC}, where FUNC is the uppercase # representation of the first parameter. It can be overridden using # NAME keyword. # # To define include files use INCLUDE_FILES keyword. # # To use C++ compiler, use CXX keyword function(FUNC_CHECK func) CHECK_NAME_DEFAULT(HAVE_${func} var) cmake_parse_arguments(PARAMS "CXX" "NAME" "INCLUDE_FILES;LIBRARIES;DEFINITIONS;FLAGS" ${ARGN}) set(CMAKE_REQUIRED_LIBRARIES "${PARAMS_LIBRARIES}") set(CMAKE_REQUIRED_DEFINITIONS "${PARAMS_DEFINITIONS}") set(CMAKE_REQUIRED_FLAGS "${PARAMS_FLAGS}") if(PARAMS_NAME) set(var ${PARAMS_NAME}) endif() if(PARAMS_CXX) check_cxx_symbol_exists(${func} "${PARAMS_INCLUDE_FILES}" ${var}) else() check_symbol_exists(${func} "${PARAMS_INCLUDE_FILES}" ${var}) endif() CHECK_APPEND_DEFINE(${var} "${${var}}") endfunction() # TYPE_CHECK(type [NAME variable] [SIZEOF variable] # [INCLUDE_FILES file1.h ... fileN.h] # [LIBRARIES lib1 ... libN] # [DEFINITIONS -DA=1 .. -DN=123] # [FLAGS -cmdlineparam1 .. -cmdlineparamN] # [CXX]) # # Check if the type exists and its size, in such case define variable # in configuration file. # # Variable defaults to HAVE_${TYPE}, where TYPE is the uppercase # representation of the first parameter. It can be overridden using # NAME keyword. # # To define include files use INCLUDE_FILES keyword. # # To use C++ compiler, use CXX keyword function(TYPE_CHECK type) CHECK_NAME_DEFAULT(HAVE_${type} var) CHECK_NAME_DEFAULT(SIZEOF_${type} sizeof) cmake_parse_arguments(PARAMS "CXX" "NAME;SIZEOF" "INCLUDE_FILES;LIBRARIES;DEFINITIONS;FLAGS" ${ARGN}) set(CMAKE_REQUIRED_LIBRARIES "${PARAMS_LIBRARIES}") set(CMAKE_REQUIRED_DEFINITIONS "${PARAMS_DEFINITIONS}") set(CMAKE_REQUIRED_FLAGS "${PARAMS_FLAGS}") set(CMAKE_EXTRA_INCLUDE_FILES "${PARAMS_INCLUDE_FILES}") if(PARAMS_NAME) set(var ${PARAMS_NAME}) endif() if(PARAMS_SIZEOF) set(sizeof ${PARAMS_SIZEOF}) endif() if(PARAMS_CXX) set(lang CXX) else() set(lang C) endif() CHECK_TYPE_SIZE(${type} ${var} LANGUAGE ${lang}) CHECK_APPEND_DEFINE(${var} "${HAVE_${var}}") CHECK_APPEND_DEFINE(${sizeof} "${${var}}") endfunction() # EFL_HEADER_CHECKS_FINALIZE(file) # # Write the configuration gathered with HEADER_CHECK(), TYPE_CHECK() # and FUNC_CHECK() to the given file. function(EFL_HEADER_CHECKS_FINALIZE file) get_filename_component(filename ${file} NAME) string(TOUPPER _${filename}_ file_sym) string(REGEX REPLACE "[^a-zA-Z0-9]" "_" file_sym "${file_sym}") file(WRITE ${file}.new "#ifndef ${file_sym}\n#define ${file_sym} 1\n\n${${VAR_HEADER_FILE_CONTENT}}\n#endif /* ${file_sym} */\n") if (NOT EXISTS ${file}) file(RENAME ${file}.new ${file}) message(STATUS "${file} was generated.") else() file(MD5 ${file}.new _new_md5) file(MD5 ${file} _old_md5) if(_new_md5 STREQUAL _old_md5) message(STATUS "${file} is unchanged.") else() file(REMOVE ${file}) file(RENAME ${file}.new ${file}) message(STATUS "${file} was updated.") endif() endif() unset(${VAR_HEADER_FILE_CONTENT} CACHE) # allow to reuse with an empty contents unset(CHECK_SCOPE CACHE) unset(CHECK_SCOPE_UPPERCASE CACHE) set(VAR_HEADER_FILE_CONTENT HEADER_FILE_CONTENT CACHE INTERNAL "") endfunction() # EFL_FILES_TO_ABSOLUTE(Var Source_Dir Binary_Dir [file1 ... fileN]) # # Convert list of files to absolute path. If not absolute, then # check inside Source_Dir and if it fails assumes it's inside Binary_Dir function(EFL_FILES_TO_ABSOLUTE _var _srcdir _bindir) set(_lst "") foreach(f ${ARGN}) if(EXISTS "${f}" OR IS_ABSOLUTE "${f}") list(APPEND _lst "${f}") elseif(EXISTS "${_srcdir}/${f}") list(APPEND _lst "${_srcdir}/${f}") else() list(APPEND _lst "${_bindir}/${f}") endif() endforeach() set(${_var} "${_lst}" PARENT_SCOPE) endfunction() # EFL_PKG_CONFIG_EVAL_TO(Var Name [module1 ... moduleN]) # # Evaluate the list of of pkg-config modules and assign to variable # Var. If it's missing, abort with a message saying ${Name} is missing # the list of modules. # # OPTIONAL keyword may be used to convert the remaining elements in optional # packages. function(EFL_PKG_CONFIG_EVAL_TO _var _name) set(_found "") set(_missing "") set(_missing_optional "") set(_optional OFF) set(_have_definitions "") foreach(f ${ARGN}) if(${f} STREQUAL "OPTIONAL") set(_optional ON) else() string(REGEX REPLACE "[><=].*\$" "" v "${f}") string(REGEX REPLACE "[^A-Za-z0-9]" "_" v "${v}") string(TOUPPER "${v}" v) pkg_check_modules(PKG_CONFIG_DEP_${v} ${f}) if(PKG_CONFIG_DEP_${v}_FOUND) list(APPEND _found ${f}) list(APPEND _have_definitions "-DHAVE_${v}=1" "-DENABLE_${v}=1") elseif(_optional) list(APPEND _missing_optional ${f}) LIST_APPEND_GLOBAL(EFL_PKG_CONFIG_MISSING_OPTIONAL ${f}) else() list(APPEND _missing ${f}) else() endif() endif() endforeach() unset(${_var}_CFLAGS CACHE) unset(${_var}_LDFLAGS CACHE) unset(PKG_CONFIG_${_var} CACHE) unset(PKG_CONFIG_${_var}_CFLAGS CACHE) unset(PKG_CONFIG_${_var}_FOUND CACHE) unset(PKG_CONFIG_${_var}_INCLUDE_DIRS CACHE) unset(PKG_CONFIG_${_var}_INCLUDEDIR CACHE) unset(PKG_CONFIG_${_var}_LDFLAGS CACHE) unset(PKG_CONFIG_${_var}_LIBDIR CACHE) unset(PKG_CONFIG_${_var}_LIBRARIES CACHE) unset(PKG_CONFIG_${_var}_LIBRARIES CACHE) unset(PKG_CONFIG_${_var}_LIBRARIES_DIR CACHE) unset(PKG_CONFIG_${_var}_LIBS CACHE) unset(PKG_CONFIG_${_var}_VERSION CACHE) if(NOT _missing) SET_GLOBAL(${_var} "${_found}") SET_GLOBAL(${_var}_MISSING "${_missing_optional}") if(_found) pkg_check_modules(PKG_CONFIG_${_var} ${_found}) SET_GLOBAL(${_var}_CFLAGS "${_have_definitions};${PKG_CONFIG_${_var}_CFLAGS}") SET_GLOBAL(${_var}_LDFLAGS "${PKG_CONFIG_${_var}_LDFLAGS}") endif() else() message(FATAL_ERROR "${_name} missing required pkg-config modules: ${_missing}") endif() endfunction() # EFL_PKG_CONFIG_EVAL(Name Private_List Public_List) # # Evaluates both lists and creates ${Name}_PKG_CONFIG_REQUIRES as well as # ${Name}_PKG_CONFIG_REQUIRES_PRIVATE with found elements. # # OPTIONAL keyword may be used to convert the remaining elements in optional # packages. function(EFL_PKG_CONFIG_EVAL _target _private _public) EFL_PKG_CONFIG_EVAL_TO(${_target}_PKG_CONFIG_REQUIRES ${_target} ${_public}) EFL_PKG_CONFIG_EVAL_TO(${_target}_PKG_CONFIG_REQUIRES_PRIVATE ${_target} ${_private}) set(_lst ${${_target}_PKG_CONFIG_REQUIRES_MISSING}) foreach(_e ${${_target}_PKG_CONFIG_REQUIRES_PRIVATE_MISSING}) list(APPEND _lst ${_e}) endforeach() if(_lst) message(STATUS "${_target} missing optional pkg-config: ${_lst}") endif() endfunction() function(EFL_PKG_CONFIG_LIB_WRITE) set(_pkg_config_requires) set(_pkg_config_requires_private) set(_libraries) set(_public_libraries) get_target_property(_pkg_config_name ${EFL_LIB_CURRENT} PKG_CONFIG_NAME) get_target_property(_version ${EFL_LIB_CURRENT} VERSION) get_target_property(eo_files_public ${EFL_LIB_CURRENT} EFL_EO_PUBLIC) if(eo_files_public) set(_eoinfo "eoincludedir=\${datarootdir}/eolian/include eolian_flags=-I\${pc_sysrootdir}\${eoincludedir}/${EFL_LIB_CURRENT}-${PROJECT_VERSION_MAJOR}") else() set(_eoinfo "") endif() foreach(_e ${${EFL_LIB_CURRENT}_PKG_CONFIG_REQUIRES}) set(_pkg_config_requires "${_pkg_config_requires} ${_e}") endforeach() foreach(_e ${${EFL_LIB_CURRENT}_PKG_CONFIG_REQUIRES_PRIVATE}) set(_pkg_config_requires_private "${_pkg_config_requires_private} ${_e}") endforeach() foreach(_e ${LIBRARIES}) if(TARGET ${_e}) if(NOT _e MATCHES "^support-") get_target_property(_sub_pc_name ${_e} PKG_CONFIG_NAME) get_target_property(_sub_version ${_e} VERSION) set(_pkg_config_requires_private "${_pkg_config_requires_private} ${_sub_pc_name}>=${_sub_version}") else() get_target_property(_type ${_e} TYPE) if(_type STREQUAL SHARED_LIBRARY) get_target_property(_oname ${_e} OUTPUT_NAME) set(_libraries "${_libraries} -l${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/efl/support/v-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}/${CMAKE_SHARED_LIBRARY_PREFIX}${_oname}${CMAKE_SHARED_LIBRARY_SUFFIX}") endif() endif() else() set(_libraries "${_libraries} -l${_e}") endif() endforeach() foreach(_e ${PUBLIC_LIBRARIES}) if(TARGET ${_e}) get_target_property(_sub_pc_name ${_e} PKG_CONFIG_NAME) get_target_property(_sub_version ${_e} VERSION) set(_pkg_config_requires "${_pkg_config_requires} ${_sub_pc_name}>=${_sub_version}") else() set(_public_libraries "${_public_libraries} -l${_e}") endif() endforeach() if(NOT ${EFL_LIB_CURRENT} STREQUAL "efl") set(_cflags " -I\${includedir}/${EFL_LIB_CURRENT}-${PROJECT_VERSION_MAJOR}") endif() # TODO: handle eolian needs set(_contents "prefix=${CMAKE_INSTALL_PREFIX} exec_prefix=\${prefix} libdir=\${exec_prefix}/${CMAKE_INSTALL_LIBDIR} includedir=\${prefix}/include datarootdir=\${prefix}/share datadir=\${datarootdir} pkgdatadir=\${datadir}/${EFL_LIB_CURRENT} modules=\${libdir}/${EFL_LIB_CURRENT}/modules ${_eoinfo} Name: ${_pkg_config_name} Description: ${DESCRIPTION} Version: ${_version} Requires:${_pkg_config_requires} Requires.private:${_pkg_config_requires_private} Libs: -L\${libdir} -l${EFL_LIB_CURRENT}${_public_libraries} Libs.private:${_libraries} Cflags: -I\${includedir}/efl-${PROJECT_VERSION_MAJOR}${_cflags} ") file(WRITE "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/pkgconfig/${_pkg_config_name}.pc" "${_contents}") install(FILES "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/pkgconfig/${_pkg_config_name}.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") endfunction() # _EFL_INCLUDE_OR_DETECT(Name Source_Dir) # # Internal macro that will include(${Source_Dir}/CMakeLists.txt) if # that exists, otherwise will check if there is a single source file, # in that case it will automatically define SOURCES to that (including # extras such as headers and .eo) # # Name is only used to print out messages when it's auto-detected. macro(_EFL_INCLUDE_OR_DETECT _name _srcdir) if(EXISTS ${_srcdir}/CMakeLists.txt) include(${_srcdir}/CMakeLists.txt) else() # doc says it's not recommended because it can't know if more files # were added, but we're doing this explicitly to handle one file. file(GLOB _autodetect_files RELATIVE ${_srcdir} ${_srcdir}/*.c ${_srcdir}/*.h ${_srcdir}/*.hh ${_srcdir}/*.cxx ${_srcdir}/*.cpp ) list(LENGTH _autodetect_files _autodetect_files_count) if(_autodetect_files_count GREATER 1) message(WARNING "${_name}: ${_srcdir} contains no CMakeLists.txt and contains more than one source file. Don't know what to do, then ignored.") elseif(_autodetect_files_count EQUAL 1) file(GLOB SOURCES RELATIVE ${_srcdir} ${_srcdir}/*.c ${_srcdir}/*.h ${_srcdir}/*.hh ${_srcdir}/*.cxx ${_srcdir}/*.cpp ) file(GLOB EO_FILES RELATIVE ${_srcdir} ${_srcdir}/*.eo ${_srcdir}/*.eot ) message(STATUS "${_name} auto-detected as: ${SOURCES}") if(EO_FILES) message(STATUS "${_name} EO auto-detected as: ${EO_FILES}") endif() else() message(STATUS "${_name} contains no auto-detectable sources.") endif() unset(_autodetect_files_count) unset(_autodetect_files) endif() endmacro() # _EFL_LIB_PROCESS_MODULES_INTERNAL() # # Internal function to process modules of current EFL_LIB() function(_EFL_LIB_PROCESS_MODULES_INTERNAL) unset(${EFL_LIB_CURRENT}_MODULES CACHE) unset(${EFL_LIB_CURRENT}_STATIC_MODULES CACHE) if(EXISTS ${EFL_MODULES_SOURCE_DIR}/CMakeLists.txt) message(FATAL_ERROR "${EFL_MODULES_SOURCE_DIR}/CMakeLists.txt shouldn't exist. Modules are expected to be defined in their own directory.") else() file(GLOB modules RELATIVE ${EFL_MODULES_SOURCE_DIR} ${EFL_MODULES_SOURCE_DIR}/*) foreach(module ${modules}) if(IS_DIRECTORY ${EFL_MODULES_SOURCE_DIR}/${module}) set(EFL_MODULE_SCOPE ${module}) file(GLOB submodules RELATIVE ${EFL_MODULES_SOURCE_DIR}/${EFL_MODULE_SCOPE} ${EFL_MODULES_SOURCE_DIR}/${EFL_MODULE_SCOPE}/*) foreach(submodule ${submodules}) if(IS_DIRECTORY ${EFL_MODULES_SOURCE_DIR}/${EFL_MODULE_SCOPE}/${submodule}) EFL_MODULE(${submodule}) endif() unset(submodule) unset(submodules) endforeach() else() set(EFL_MODULE_SCOPE) EFL_MODULE(${module}) endif() unset(EFL_MODULE_SCOPE) endforeach() endif() if(${EFL_LIB_CURRENT}_MODULES) add_custom_target(${EFL_LIB_CURRENT}-modules DEPENDS ${${EFL_LIB_CURRENT}_MODULES}) endif() endfunction() # _EFL_LIB_PROCESS_BINS_INTERNAL() # # Internal function to process bins of current EFL_LIB() function(_EFL_LIB_PROCESS_BINS_INTERNAL) unset(${EFL_LIB_CURRENT}_BINS CACHE) if(EXISTS ${EFL_BIN_SOURCE_DIR}/CMakeLists.txt) EFL_BIN(${EFL_LIB_CURRENT}) else() file(GLOB bins RELATIVE ${EFL_BIN_SOURCE_DIR} ${EFL_BIN_SOURCE_DIR}/*) foreach(bin ${bins}) if(IS_DIRECTORY ${EFL_BIN_SOURCE_DIR}/${bin}) EFL_BIN(${bin}) endif() endforeach() endif() if(NOT ${EFL_LIB_CURRENT}_BINS AND EXISTS ${EFL_BIN_SOURCE_DIR} AND NOT EXISTS ${EFL_BIN_SOURCE_DIR}/CMakeLists.txt) EFL_BIN(${EFL_LIB_CURRENT}) endif() if(${EFL_LIB_CURRENT}_BINS) add_custom_target(${EFL_LIB_CURRENT}-bins DEPENDS ${${EFL_LIB_CURRENT}_BINS}) endif() endfunction() # _EFL_LIB_PROCESS_TESTS_INTERNAL() # # Internal function to process tests of current EFL_LIB() function(_EFL_LIB_PROCESS_TESTS_INTERNAL) unset(${EFL_LIB_CURRENT}_TESTS CACHE) if(EXISTS ${EFL_TESTS_SOURCE_DIR}/CMakeLists.txt) EFL_TEST(${EFL_LIB_CURRENT}) else() file(GLOB tests RELATIVE ${EFL_TESTS_SOURCE_DIR} ${EFL_TESTS_SOURCE_DIR}/*) foreach(test ${tests}) if(IS_DIRECTORY ${EFL_TESTS_SOURCE_DIR}/${test}) EFL_TEST(${test}) endif() endforeach() endif() if(NOT ${EFL_LIB_CURRENT}_TESTS AND EXISTS ${EFL_TESTS_SOURCE_DIR} AND NOT EXISTS ${EFL_TESTS_SOURCE_DIR}/CMakeLists.txt) EFL_TEST(${EFL_LIB_CURRENT}) endif() if(${EFL_LIB_CURRENT}_TESTS) add_custom_target(${EFL_LIB_CURRENT}-tests DEPENDS ${${EFL_LIB_CURRENT}_TESTS}) LIST_APPEND_GLOBAL(EFL_ALL_TESTS ${EFL_LIB_CURRENT}-tests) endif() endfunction() define_property(TARGET PROPERTY EFL_EO_PRIVATE BRIEF_DOCS "EFL's .eo/.eot files associated with this target and not installed" FULL_DOCS "The list of all .eo or .eot files this target uses but doesn't install") define_property(TARGET PROPERTY EFL_EO_PUBLIC BRIEF_DOCS "EFL's .eo/.eot files associated with this target and installed" FULL_DOCS "The list of all .eo or .eot files this target uses and installs") define_property(TARGET PROPERTY PKG_CONFIG_NAME BRIEF_DOCS "The name to use with pkg-config (.pc) files" FULL_DOCS "This is usually the target name unless some backward compatibility or translations are needed") # EFL_SUPPORT_LIB(Name) # # adds a support library as src/static_libs/${Name}, this will # generate a static library that can be later referred by other # targets using support-${Name} # # This is simiar to EFL_LIB(), however defaults to STATIC libraries # and if set to SHARED will install to # ${CMAKE_INSTALL_LIBDIR}/efl/support/v-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} # and it shouldn't set any PUBLIC_HEADERS or PKG_CONFIG_REQUIRES. function(EFL_SUPPORT_LIB _target) set(EFL_LIB_CURRENT ${_target}) set(EFL_LIB_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/static_libs/${_target}) set(EFL_LIB_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/src/static_libs/${_target}) set(DESCRIPTION) set(PKG_CONFIG_REQUIRES) set(PKG_CONFIG_REQUIRES_PRIVATE) set(INCLUDE_DIRECTORIES) set(SYSTEM_INCLUDE_DIRECTORIES) set(OUTPUT_NAME) set(SOURCES) set(PUBLIC_HEADERS) set(VERSION) set(SOVERSION) set(LIBRARY_TYPE STATIC) set(OBJECT_DEPENDS) set(DEPENDENCIES) set(LIBRARIES) set(PUBLIC_LIBRARIES) set(DEFINITIONS) set(COMPILE_FLAGS) set(LINK_FLAGS) include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/config/${_target}.cmake OPTIONAL) include(${EFL_LIB_SOURCE_DIR}/CMakeLists.txt) if(NOT SOURCES) message(WARNING "${EFL_LIB_SOURCE_DIR}/CMakeLists.txt defines no SOURCES") return() endif() if(PUBLIC_HEADERS) message(WARNING "${EFL_LIB_SOURCE_DIR}/CMakeLists.txt should not define PUBLIC_HEADERS, it's not to be installed.") endif() if(PKG_CONFIG_REQUIRES) message(WARNING "${EFL_LIB_SOURCE_DIR}/CMakeLists.txt should not define PKG_CONFIG_REQUIRES. Use PKG_CONFIG_REQUIRES_PRIVATE instead") endif() EFL_FILES_TO_ABSOLUTE(_sources ${EFL_LIB_SOURCE_DIR} ${EFL_LIB_BINARY_DIR} ${SOURCES}) EFL_FILES_TO_ABSOLUTE(_obj_deps ${EFL_LIB_SOURCE_DIR} ${EFL_LIB_BINARY_DIR} ${OBJECT_DEPENDS}) EFL_PKG_CONFIG_EVAL(${_target} "${PKG_CONFIG_REQUIRES_PRIVATE}" "${PKG_CONFIG_REQUIRES}") set(__link_flags ${${_target}_PKG_CONFIG_REQUIRES_PRIVATE_LDFLAGS} ${${_target}_PKG_CONFIG_REQUIRES_LDFLAGS} ${LINK_FLAGS}) set(__compile_flags ${${_target}_PKG_CONFIG_REQUIRES_PRIVATE_CFLAGS} ${${_target}_PKG_CONFIG_REQUIRES_CFLAGS} ${COMPILE_FLAGS}) set(_link_flags) foreach(_l ${__link_flags}) set(_link_flags "${_link_flags} ${_l}") endforeach() set(_compile_flags) foreach(_c ${__compile_flags}) set(_compile_flags "${_compile_flags} ${_c}") endforeach() set(_libraries) foreach(_l ${LIBRARIES}) if(${_l} MATCHES "^find-") string(REGEX REPLACE "^find-" "" _v "${_l}") list(APPEND _libraries ${${_v}_LIBRARIES}) list(APPEND SYSTEM_INCLUDE_DIRECTORIES ${${_v}_INCLUDE_DIR}) else() list(APPEND _libraries ${_l}) endif() endforeach() set(LIBRARIES ${_libraries}) set(_public_libraries) foreach(_l ${PUBLIC_LIBRARIES}) if(${_l} MATCHES "^find-") string(REGEX REPLACE "^find-" "" _v "${_l}") list(APPEND _public_libraries ${${_v}_LIBRARIES}) list(APPEND SYSTEM_INCLUDE_DIRECTORIES ${${_v}_INCLUDE_DIR}) else() list(APPEND _public_libraries ${_l}) endif() endforeach() set(PUBLIC_LIBRARIES ${_public_libraries}) add_library(support-${_target} ${LIBRARY_TYPE} ${_sources} ${_headers}) set_target_properties(support-${_target} PROPERTIES OBJECT_DEPENDS "${_obj_deps}" LINK_FLAGS "${_link_flags}" COMPILE_FLAGS "${_compile_flags}") if(DEPENDENCIES) add_dependencies(support-${_target} ${DEPENDENCIES}) endif() if(LIBRARIES) target_link_libraries(support-${_target} LINK_PRIVATE ${LIBRARIES}) endif() if(PUBLIC_LIBRARIES) target_link_libraries(support-${_target} PUBLIC ${PUBLIC_LIBRARIES}) endif() target_include_directories(support-${_target} PUBLIC ${INCLUDE_DIRECTORIES} ${EFL_LIB_SOURCE_DIR} ${EFL_LIB_BINARY_DIR} ) if(SYSTEM_INCLUDE_DIRECTORIES) target_include_directories(support-${_target} SYSTEM PUBLIC ${SYSTEM_INCLUDE_DIRECTORIES}) endif() if(DEFINITIONS) target_compile_definitions(support-${_target} PRIVATE ${DEFINITIONS}) endif() if(NOT OUTPUT_NAME) set(OUTPUT_NAME "support-${_target}") endif() set_target_properties(support-${_target} PROPERTIES OUTPUT_NAME ${OUTPUT_NAME}) if(VERSION AND SOVERSION) set_target_properties(support-${_target} PROPERTIES VERSION ${VERSION} SOVERSION ${SOVERSION}) endif() if(LIBRARY_TYPE STREQUAL "SHARED") install(TARGETS support-${_target} RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}/efl/support/v-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/efl/support/v-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}) set_target_properties(support-${_target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}/efl/support/v-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} RUNTIME_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}/efl/support/v-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}) else() set_target_properties(support-${_target} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}/efl/support/v-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} POSITION_INDEPENDENT_CODE TRUE) endif() include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/post/${_target}.cmake OPTIONAL) endfunction() # EFL_LIB(Name) # # adds a library ${Name} automatically setting object/target # properties based on script-modifiable variables: # - DESCRIPTION: results in ${Name}_DESCRIPTION and fills pkg-config files. # - PKG_CONFIG_REQUIRES: results in ${Name}_PKG_CONFIG_REQUIRES and # fills pkg-config files. Elements after 'OPTIONAL' keyword are # optional. # - PKG_CONFIG_REQUIRES_PRIVATE: results in # ${Name}_PKG_CONFIG_REQUIRES_PRIVATE and fills pkg-config # files. Elements after 'OPTIONAL' keyword are optional. # - INCLUDE_DIRECTORIES: results in target_include_directories # - SYSTEM_INCLUDE_DIRECTORIES: results in target_include_directories(SYSTEM) # - OUTPUT_NAME # - SOURCES source files that are needed. Eo files should go in # PUBLIC_EO_FILES or EO_FILES. # - PUBLIC_HEADERS # - VERSION (defaults to project version) # - SOVERSION (defaults to project major version) # - LIBRARY_TYPE: SHARED or STATIC, defaults to SHARED # - OBJECT_DEPENDS: say this object depends on other files (ie: includes) # - DEPENDENCIES: results in add_dependencies() # - LIBRARIES: results in target_link_libraries(LINK_PRIVATE) # - PUBLIC_LIBRARIES: results in target_link_libraries(LINK_PUBLIC) # - DEFINITIONS: target_compile_definitions() # - PUBLIC_EO_FILES: the eo files will be used to build that lib, and will be installed to the filesystem # - EO_FILES: the eo files will be used to build that lib but not installed. # - COMPILE_FLAGS: extra CFLAGS to append. # - LINK_FLAGS: extra LDFLAGS to append. # # Defines the following variables that can be used within the included files: # - EFL_LIB_CURRENT to ${Name} # - EFL_LIB_SOURCE_DIR to source dir of ${Name} libraries # - EFL_LIB_BINARY_DIR to binary dir of ${Name} libraries # - EFL_BIN_SOURCE_DIR to source dir of ${Name} executables # - EFL_BIN_BINARY_DIR to binary dir of ${Name} executables # - EFL_MODULES_SOURCE_DIR to source dir of ${Name} modules # - EFL_MODULES_BINARY_DIR to binary dir of ${Name} modules # - EFL_TESTS_SOURCE_DIR to source dir of ${Name} tests # - EFL_TESTS_BINARY_DIR to binary dir of ${Name} tests # - EFL_UTILS_DIR to the binary dir of ${Name} utility binaries # (those that should exist in runtime but not visible from $PATH) # # Modules are processed like: # - loop for directories in src/modules/${EFL_LIB_CURRENT}: # - if a src/modules/${EFL_LIB_CURRENT}/${Module}/CMakeLists.txt # use variables as documented in EFL_MODULE() # - otherwise loop for scoped-modules in # src/modules/${EFL_LIB_CURRENT}/${EFL_MODULE_SCOPE}/CMakeLists.txt # and use variables as documented in EFL_MODULE() # # EFL_MODULE() will handle MODULE_TYPE=ON;OFF;STATIC, handling # dependencies and installation in the proper path, considering # ${EFL_MODULE_SCOPE} whenever it's set. # # Binaries and tests are processed similarly: # - if src/bin/${EFL_LIB_CURRENT}/CMakeLists.txt exist, then use # variables as documented in EFL_BIN() or EFL_TEST(). The target # will be called ${EFL_LIB_CURRENT}-bin or ${EFL_LIB_CURRENT}-test # and the test OUTPUT_NAME defaults to ${EFL_LIB_CURRENT}_suite. # - otherwise loop for directories in src/bin/${EFL_LIB_CURRENT} and # for each src/bin/${EFL_LIB_CURRENT}/${Entry}/CMakeLists.txt use # variables as documented in EFL_BIN() or EFL_TEST(). Binaries # must provide an unique name that will be used as both target and # OUTPUT_NAME. Tests will generate targets # ${EFL_LIB_CURRENT}-test-${Entry}, while OUTPUT_NAME is ${Entry}. # # NOTE: src/modules/${EFL_LIB_CURRENT}/CMakeLists.txt is not # allowed as it makes no sense to have a single module named # after the library. # function(EFL_LIB _target) set(EFL_LIB_CURRENT ${_target}) set(EFL_LIB_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/${_target}) set(EFL_LIB_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/src/lib/${_target}) set(EFL_BIN_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/bin/${_target}) set(EFL_BIN_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/src/bin/${_target}) set(EFL_MODULES_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/modules/${_target}) set(EFL_MODULES_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/src/modules/${_target}) set(EFL_TESTS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/tests/${_target}) set(EFL_TESTS_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/src/tests/${_target}) set(EFL_UTILS_DIR ${CMAKE_INSTALL_LIBDIR}/${_target}/utils/v-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}) unset(EFL_ALL_OPTIONS_${EFL_LIB_CURRENT} CACHE) set(DESCRIPTION) set(PKG_CONFIG_REQUIRES) set(PKG_CONFIG_REQUIRES_PRIVATE) set(PKG_CONFIG_NAME) set(INCLUDE_DIRECTORIES) set(SYSTEM_INCLUDE_DIRECTORIES) set(OUTPUT_NAME) set(SOURCES) set(PUBLIC_HEADERS) set(VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}) set(SOVERSION ${PROJECT_VERSION_MAJOR}) set(LIBRARY_TYPE SHARED) set(OBJECT_DEPENDS) set(DEPENDENCIES) set(LIBRARIES) set(PUBLIC_LIBRARIES) set(DEFINITIONS) set(PUBLIC_EO_FILES) set(EO_FILES) set(COMPILE_FLAGS) set(LINK_FLAGS) string(TOUPPER "${_target}" _target_uc) include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/config/${_target}.cmake OPTIONAL) include(${EFL_LIB_SOURCE_DIR}/CMakeLists.txt OPTIONAL) if(LIBRARY_TYPE STREQUAL SHARED AND NOT PUBLIC_HEADERS) message(FATAL_ERROR "Shared libraries must install public headers!") endif() if(NOT PKG_CONFIG_NAME) string(REPLACE "_" "-" PKG_CONFIG_NAME ${EFL_LIB_CURRENT}) endif() #merge public eo files into sources set(SOURCES ${SOURCES} ${PUBLIC_EO_FILES} ${EO_FILES}) EFL_FILES_TO_ABSOLUTE(_headers ${EFL_LIB_SOURCE_DIR} ${EFL_LIB_BINARY_DIR} ${PUBLIC_HEADERS}) EFL_FILES_TO_ABSOLUTE(_sources ${EFL_LIB_SOURCE_DIR} ${EFL_LIB_BINARY_DIR} ${SOURCES}) EFL_FILES_TO_ABSOLUTE(_obj_deps ${EFL_LIB_SOURCE_DIR} ${EFL_LIB_BINARY_DIR} ${OBJECT_DEPENDS}) EFL_FILES_TO_ABSOLUTE(_public_eo_files ${EFL_LIB_SOURCE_DIR} ${EFL_LIB_BINARY_DIR} ${PUBLIC_EO_FILES}) EFL_FILES_TO_ABSOLUTE(_eo_files ${EFL_LIB_SOURCE_DIR} ${EFL_LIB_BINARY_DIR} ${EO_FILES}) foreach(public_eo_file ${PUBLIC_EO_FILES}) list(APPEND _headers ${EFL_LIB_BINARY_DIR}/${public_eo_file}.h) endforeach() unset(public_eo_file) EFL_PKG_CONFIG_EVAL(${_target} "${PKG_CONFIG_REQUIRES_PRIVATE}" "${PKG_CONFIG_REQUIRES}") set(__link_flags ${${_target}_PKG_CONFIG_REQUIRES_PRIVATE_LDFLAGS} ${${_target}_PKG_CONFIG_REQUIRES_LDFLAGS} ${LINK_FLAGS}) set(__compile_flags ${${_target}_PKG_CONFIG_REQUIRES_PRIVATE_CFLAGS} ${${_target}_PKG_CONFIG_REQUIRES_CFLAGS} -DPACKAGE_DATA_DIR=\\"${CMAKE_INSTALL_FULL_DATADIR}/${_target}/\\" ${COMPILE_FLAGS}) set(_link_flags) foreach(_l ${__link_flags}) set(_link_flags "${_link_flags} ${_l}") endforeach() set(_compile_flags) foreach(_c ${__compile_flags}) set(_compile_flags "${_compile_flags} ${_c}") endforeach() set(_libraries) foreach(_l ${LIBRARIES}) if(${_l} MATCHES "^find-") string(REGEX REPLACE "^find-" "" _v "${_l}") list(APPEND _libraries ${${_v}_LIBRARIES}) list(APPEND SYSTEM_INCLUDE_DIRECTORIES ${${_v}_INCLUDE_DIR}) else() list(APPEND _libraries ${_l}) endif() endforeach() set(LIBRARIES ${_libraries}) set(_public_libraries) foreach(_l ${PUBLIC_LIBRARIES}) if(${_l} MATCHES "^find-") string(REGEX REPLACE "^find-" "" _v "${_l}") list(APPEND _public_libraries ${${_v}_LIBRARIES}) list(APPEND SYSTEM_INCLUDE_DIRECTORIES ${${_v}_INCLUDE_DIR}) else() list(APPEND _public_libraries ${_l}) endif() endforeach() set(PUBLIC_LIBRARIES ${_public_libraries}) add_library(${_target} ${LIBRARY_TYPE} ${_sources} ${_headers}) set_target_properties(${_target} PROPERTIES FRAMEWORK TRUE DEFINE_SYMBOL "EFL_${_target_uc}_BUILD" PUBLIC_HEADER "${_headers}" OBJECT_DEPENDS "${_obj_deps}" EFL_EO_PRIVATE "${_eo_files}" EFL_EO_PUBLIC "${_public_eo_files}" PKG_CONFIG_NAME "${PKG_CONFIG_NAME}" LINK_FLAGS "${_link_flags}" COMPILE_FLAGS "${_compile_flags} -DDLL_EXPORT") if(DEPENDENCIES) add_dependencies(${_target} ${DEPENDENCIES}) endif() if(LIBRARIES) target_link_libraries(${_target} LINK_PRIVATE ${LIBRARIES}) endif() if(PUBLIC_LIBRARIES) target_link_libraries(${_target} PUBLIC ${PUBLIC_LIBRARIES}) endif() target_include_directories(${_target} PUBLIC ${INCLUDE_DIRECTORIES} ${EFL_LIB_SOURCE_DIR} ${EFL_LIB_BINARY_DIR} ) if(SYSTEM_INCLUDE_DIRECTORIES) target_include_directories(${_target} SYSTEM PUBLIC ${SYSTEM_INCLUDE_DIRECTORIES}) endif() if(DEFINITIONS) target_compile_definitions(${_target} PRIVATE ${DEFINITIONS}) endif() if(OUTPUT_NAME) set_target_properties(${_target} PROPERTIES OUTPUT_NAME ${OUTPUT_NAME}) endif() if(VERSION AND SOVERSION) set_target_properties(${_target} PROPERTIES VERSION ${VERSION} SOVERSION ${SOVERSION}) endif() EFL_CREATE_EO_RULES(${_target} ${EFL_LIB_SOURCE_DIR} ${EFL_LIB_BINARY_DIR}) EFL_PKG_CONFIG_LIB_WRITE() install(TARGETS ${_target} PUBLIC_HEADER DESTINATION include/${_target}-${PROJECT_VERSION_MAJOR} RUNTIME DESTINATION bin ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(FILES ${_public_eo_files} DESTINATION share/eolian/include/${_target}-${PROJECT_VERSION_MAJOR} ) file(WRITE ${CMAKE_BINARY_DIR}/share/${_target}/checkme "") install(FILES ${CMAKE_BINARY_DIR}/share/${_target}/checkme DESTINATION share/${_target}) # do not leak those into binaries, modules or tests unset(_sources) unset(_headers) unset(_obj_deps) unset(_public_eo_files) unset(_eo_files) unset(INCLUDE_DIRECTORIES) unset(SYSTEM_INCLUDE_DIRECTORIES) unset(OUTPUT_NAME) unset(SOURCES) unset(PUBLIC_HEADERS) unset(VERSION) unset(SOVERSION) unset(LIBRARY_TYPE) unset(OBJECT_DEPENDS) unset(DEPENDENCIES) unset(LIBRARIES) unset(PUBLIC_LIBRARIES) unset(DEFINITIONS) unset(DESCRIPTION) unset(PUBLIC_EO_FILES) unset(EO_FILES) unset(PKG_CONFIG_REQUIRES) unset(PKG_CONFIG_REQUIRES_PRIVATE) unset(PKG_CONFIG_NAME) _EFL_LIB_PROCESS_BINS_INTERNAL() _EFL_LIB_PROCESS_MODULES_INTERNAL() _EFL_LIB_PROCESS_TESTS_INTERNAL() include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/post/${_target}.cmake OPTIONAL) LIST_APPEND_GLOBAL(EFL_ALL_LIBS ${_target}) endfunction() # EFL_BIN(Name) # # Adds a binary (executable) for ${EFL_LIB_CURRENT} using # ${EFL_BIN_SOURCE_DIR} and ${EFL_BIN_BINARY_DIR} # # Settings: # - INCLUDE_DIRECTORIES: results in target_include_directories # - SYSTEM_INCLUDE_DIRECTORIES: results in target_include_directories(SYSTEM) # - OUTPUT_NAME # - SOURCES # - OBJECT_DEPENDS: say this object depends on other files (ie: includes) # - DEPENDENCIES: results in add_dependencies(), defaults to # ${EFL_LIB_CURRENT}-modules # - LIBRARIES: results in target_link_libraries() # - DEFINITIONS: target_compile_definitions() # - INSTALL_DIR: defaults to bin. If empty, won't install. # - COMPILE_FLAGS: extra CFLAGS to append. # - LINK_FLAGS: extra LDFLAGS to append. # - EFL_UTILITY: if ON, will be installed to EFL_UTILS_DIR instead of # bin, not being exposed to $PATH. # # NOTE: it's meant to be called by files included by EFL_LIB() or similar, # otherwise you need to prepare the environment yourself. function(EFL_BIN _binname) set(INCLUDE_DIRECTORIES) set(SYSTEM_INCLUDE_DIRECTORIES) set(OUTPUT_NAME ${_binname}) set(SOURCES) set(OBJECT_DEPENDS) if(TARGET ${EFL_LIB_CURRENT}-modules) set(DEPENDENCIES ${EFL_LIB_CURRENT}-modules) else() set(DEPENDENCIES) endif() set(LIBRARIES) set(DEFINITIONS) set(INSTALL ON) set(INSTALL_DIR bin) set(PKG_CONFIG_REQUIRES) set(PKG_CONFIG_REQUIRES_PRIVATE) set(COMPILE_FLAGS) set(LINK_FLAGS) set(EFL_UTILITY OFF) if(_binname STREQUAL ${EFL_LIB_CURRENT}) set(_binsrcdir "${EFL_BIN_SOURCE_DIR}") set(_binbindir "${EFL_BIN_BINARY_DIR}") set(_bintarget "${EFL_LIB_CURRENT}-bin") # otherwise target would exist else() set(_binsrcdir "${EFL_BIN_SOURCE_DIR}/${_binname}") set(_binbindir "${EFL_BIN_BINARY_DIR}/${_binname}") set(_bintarget "${_binname}") endif() _EFL_INCLUDE_OR_DETECT("Binary ${_bintarget}" ${_binsrcdir}) if(NOT SOURCES) message(WARNING "${_binsrcdir}/CMakeLists.txt defines no SOURCES") return() endif() if(PUBLIC_HEADERS) message(WARNING "${_binsrcdir}/CMakeLists.txt should not define PUBLIC_HEADERS, it's not to be installed.") endif() if(PKG_CONFIG_REQUIRES) message(WARNING "${_binsrcdir}/CMakeLists.txt should not define PKG_CONFIG_REQUIRES. Use PKG_CONFIG_REQUIRES_PRIVATE instead") endif() if(EFL_UTILITY AND INSTALL_DIR STREQUAL "bin") set(INSTALL_DIR ${EFL_UTILS_DIR}) endif() EFL_FILES_TO_ABSOLUTE(_sources ${_binsrcdir} ${_binbindir} ${SOURCES}) EFL_FILES_TO_ABSOLUTE(_obj_deps ${_binsrcdir} ${_binbindir} ${OBJECT_DEPENDS}) EFL_PKG_CONFIG_EVAL(${_bintarget} "${PKG_CONFIG_REQUIRES_PRIVATE}" "") set(_libraries) foreach(_l ${LIBRARIES}) if(${_l} MATCHES "^find-") string(REGEX REPLACE "^find-" "" _v "${_l}") list(APPEND _libraries ${${_v}_LIBRARIES}) list(APPEND SYSTEM_INCLUDE_DIRECTORIES ${${_v}_INCLUDE_DIR}) else() list(APPEND _libraries ${_l}) endif() endforeach() set(LIBRARIES ${_libraries}) add_executable(${_bintarget} ${_sources}) if(_obj_deps) set_target_properties(${_bintarget} PROPERTIES OBJECT_DEPENDS "${_obj_deps}") endif() if(DEPENDENCIES) add_dependencies(${_bintarget} ${DEPENDENCIES}) endif() target_include_directories(${_bintarget} PRIVATE ${_binrcdir} ${_binbindir} ${INCLUDE_DIRECTORIES}) if(SYSTEM_INCLUDE_DIRECTORIES) target_include_directories(${_bintarget} SYSTEM PRIVATE ${SYSTEM_INCLUDE_DIRECTORIES}) endif() target_link_libraries(${_bintarget} LINK_PRIVATE ${EFL_LIB_CURRENT} ${LIBRARIES}) if(DEFINITIONS) target_compile_definitions(${_bintarget} PRIVATE ${DEFINITIONS}) endif() if(OUTPUT_NAME) set_target_properties(${_bintarget} PROPERTIES OUTPUT_NAME ${OUTPUT_NAME}) endif() set(_link_flags) foreach(_l ${${_bintarget}_PKG_CONFIG_REQUIRES_PRIVATE_LDFLAGS} ${LINK_FLAGS}) set(_link_flags "${_link_flags} ${_l}") endforeach() set(_compile_flags) foreach(_c ${${_bintarget}_PKG_CONFIG_REQUIRES_PRIVATE_CFLAGS} ${COMPILE_FLAGS}) set(_compile_flags "${_compile_flags} ${_c}") endforeach() set_target_properties(${_bintarget} PROPERTIES LINK_FLAGS "${_link_flags}" COMPILE_FLAGS "${_compile_flags} -DPACKAGE_DATA_DIR=\\\"${CMAKE_INSTALL_FULL_DATADIR}/${_target}/\\\" -DPACKAGE_SRC_DIR=\\\"${CMAKE_SOURCE_DIR}/\\\"") if(INSTALL_DIR) install(TARGETS ${_bintarget} RUNTIME DESTINATION ${INSTALL_DIR}) set_target_properties(${_bintarget} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${INSTALL_DIR}) endif() LIST_APPEND_GLOBAL(${EFL_LIB_CURRENT}_BINS ${_bintarget}) endfunction() # EFL_TEST(Name) # # Adds a test for ${EFL_LIB_CURRENT} using # ${EFL_TESTS_SOURCE_DIR} and ${EFL_TESTS_BINARY_DIR} # # Settings: # - INCLUDE_DIRECTORIES: results in target_include_directories # - SYSTEM_INCLUDE_DIRECTORIES: results in target_include_directories(SYSTEM) # - OUTPUT_NAME # - SOURCES # - OBJECT_DEPENDS: say this object depends on other files (ie: includes) # - DEPENDENCIES: results in add_dependencies(), defaults to # ${EFL_LIB_CURRENT}-modules # - LIBRARIES: results in target_link_libraries() # - DEFINITIONS: target_compile_definitions() # - COMPILE_FLAGS: extra CFLAGS to append. # - LINK_FLAGS: extra LDFLAGS to append. # # NOTE: it's meant to be called by files included by EFL_LIB() or similar, # otherwise you need to prepare the environment yourself. function(EFL_TEST _testname) if(NOT CHECK_FOUND) message(STATUS "${EFL_LIB_CURRENT} test ${_testname} ignored since no 'check' library was found.") return() endif() set(INCLUDE_DIRECTORIES) set(SYSTEM_INCLUDE_DIRECTORIES) set(OUTPUT_NAME ${_testname}) set(SOURCES) set(OBJECT_DEPENDS) if(TARGET ${EFL_LIB_CURRENT}-modules) set(DEPENDENCIES ${EFL_LIB_CURRENT}-modules) else() set(DEPENDENCIES) endif() set(LIBRARIES) set(DEFINITIONS) set(PKG_CONFIG_REQUIRES) set(PKG_CONFIG_REQUIRES_PRIVATE) set(COMPILE_FLAGS) set(LINK_FLAGS) if(_testname STREQUAL ${EFL_LIB_CURRENT}) set(_testsrcdir "${EFL_TESTS_SOURCE_DIR}") set(_testbindir "${EFL_TESTS_BINARY_DIR}") set(_testtarget "${EFL_LIB_CURRENT}-test") # otherwise target would exist set(OUTPUT_NAME "${EFL_LIB_CURRENT}_suite") # backward compatible elseif(_testname STREQUAL "suite") set(_testsrcdir "${EFL_TESTS_SOURCE_DIR}/${_testname}") set(_testbindir "${EFL_TESTS_BINARY_DIR}/${_testname}") set(_testtarget "${EFL_LIB_CURRENT}-test") # target for main test, as above set(OUTPUT_NAME "${EFL_LIB_CURRENT}_suite") # backward compatible else() set(_testsrcdir "${EFL_TESTS_SOURCE_DIR}/${_testname}") set(_testbindir "${EFL_TESTS_BINARY_DIR}/${_testname}") set(_testtarget "${EFL_LIB_CURRENT}-test-${_testname}") endif() _EFL_INCLUDE_OR_DETECT("Test ${_testtarget}" ${_testsrcdir}) if(NOT SOURCES) message(WARNING "${_testsrcdir}/CMakeLists.txt defines no SOURCES") return() endif() if(PUBLIC_HEADERS) message(WARNING "${_testsrcdir}/CMakeLists.txt should not define PUBLIC_HEADERS, it's not to be installed.") endif() if(PKG_CONFIG_REQUIRES) message(WARNING "${_testsrcdir}/CMakeLists.txt should not define PKG_CONFIG_REQUIRES. Use PKG_CONFIG_REQUIRES_PRIVATE instead") endif() EFL_FILES_TO_ABSOLUTE(_sources ${_testsrcdir} ${_testbindir} ${SOURCES}) EFL_FILES_TO_ABSOLUTE(_obj_deps ${_testsrcdir} ${_testbindir} ${OBJECT_DEPENDS}) EFL_PKG_CONFIG_EVAL(${_testtarget} "${PKG_CONFIG_REQUIRES_PRIVATE}" "") set(_libraries) foreach(_l ${LIBRARIES}) if(${_l} MATCHES "^find-") string(REGEX REPLACE "^find-" "" _v "${_l}") list(APPEND _libraries ${${_v}_LIBRARIES}) list(APPEND SYSTEM_INCLUDE_DIRECTORIES ${${_v}_INCLUDE_DIR}) else() list(APPEND _libraries ${_l}) endif() endforeach() set(LIBRARIES ${_libraries}) add_executable(${_testtarget} EXCLUDE_FROM_ALL ${_sources}) if(_obj_deps) set_target_properties(${_testtarget} PROPERTIES OBJECT_DEPENDS "${_obj_deps}") endif() if(DEPENDENCIES) add_dependencies(${_testtarget} ${DEPENDENCIES}) endif() target_include_directories(${_testtarget} PRIVATE ${_testsrcdir} ${_testbindir} ${EFL_TESTS_SOURCE_DIR} ${EFL_TESTS_BINARY_DIR} ${INCLUDE_DIRECTORIES}) target_include_directories(${_testtarget} SYSTEM PRIVATE ${SYSTEM_INCLUDE_DIRECTORIES} ${CHECK_INCLUDE_DIRS}) target_link_libraries(${_testtarget} LINK_PRIVATE ${EFL_LIB_CURRENT} ${LIBRARIES} ${CHECK_LIBRARIES}) target_compile_definitions(${_testtarget} PRIVATE "-DPACKAGE_DATA_DIR=\"${EFL_TESTS_SOURCE_DIR}\"" "-DTESTS_SRC_DIR=\"${_testsrcdir}\"" "-DTESTS_BUILD_DIR=\"${_testbindir}\"" "-DTESTS_WD=\"\"" ${DEFINITIONS} ) if(OUTPUT_NAME) set_target_properties(${_testtarget} PROPERTIES OUTPUT_NAME ${OUTPUT_NAME}) endif() set(_link_flags) foreach(_l ${${_testtarget}_PKG_CONFIG_REQUIRES_PRIVATE_LDFLAGS} ${LINK_FLAGS}) set(_link_flags "${_link_flags} ${_l}") endforeach() set(_compile_flags) foreach(_c ${${_testtarget}_PKG_CONFIG_REQUIRES_PRIVATE_CFLAGS} ${COMPILE_FLAGS}) set(_compile_flags "${_compile_flags} ${_c}") endforeach() set_target_properties(${_testtarget} PROPERTIES LINK_FLAGS "${_link_flags}" COMPILE_FLAGS "${_compile_flags}" LIBRARY_OUTPUT_DIRECTORY "${_testbindir}" RUNTIME_OUTPUT_DIRECTORY "${_testbindir}") add_test(NAME ${_testtarget} COMMAND ${_testtarget}) LIST_APPEND_GLOBAL(${EFL_LIB_CURRENT}_TESTS ${_testtarget}) add_test(${_testtarget}-build "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target ${_testtarget}) set_tests_properties(${_testtarget} PROPERTIES DEPENDS ${_testtarget}-build) endfunction() # EFL_MODULE(Name) # # Adds a module for ${EFL_LIB_CURRENT} using # ${EFL_MODULES_SOURCE_DIR} and ${EFL_MODULES_BINARY_DIR} # as well as ${EFL_MODULE_SCOPE} if it's contained into # a subdir, such as eina's "mp" or evas "engines". # # To keep it simple to use, user is only expected to define variables: # - SOURCES # - OBJECT_DEPENDS # - LIBRARIES # - INCLUDE_DIRECTORIES # - SYSTEM_INCLUDE_DIRECTORIES # - DEFINITIONS # - MODULE_TYPE: one of ON;OFF;STATIC, defaults to ON # - INSTALL_DIR: defaults to # ${CMAKE_INSTALL_LIBDIR}/${EFL_LIB_CURRENT}/modules/${EFL_MODULE_SCOPE}/${Name}/v-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}/. # If empty, won't install. # - PKG_CONFIG_REQUIRES_PRIVATE: results in # ${Name}_PKG_CONFIG_REQUIRES_PRIVATE. Elements after 'OPTIONAL' # keyword are optional. # - COMPILE_FLAGS: extra CFLAGS to append. # - LINK_FLAGS: extra LDFLAGS to append. # # NOTE: since the file will be included it shouldn't mess with global variables! function(EFL_MODULE _modname) if(EFL_MODULE_SCOPE) set(_modsrcdir ${EFL_MODULES_SOURCE_DIR}/${EFL_MODULE_SCOPE}/${_modname}) set(_modoutdir ${CMAKE_INSTALL_LIBDIR}/${EFL_LIB_CURRENT}/modules/${EFL_MODULE_SCOPE}/${_modname}/v-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}) set(_modbindir ${EFL_MODULES_BINARY_DIR}/${EFL_MODULE_SCOPE}/${_modname}) set(_modtarget ${EFL_LIB_CURRENT}-module-${EFL_MODULE_SCOPE}-${_modname}) string(TOUPPER "${EFL_LIB_CURRENT}_MODULE_TYPE_${EFL_MODULE_SCOPE}_${_modname}" _modoptionname) if(NOT DEFINED ${_modoptionname}_DEFAULT) set(${_modoptionname}_DEFAULT "ON") endif() EFL_OPTION(${_modoptionname} "Build ${EFL_LIB_CURRENT} module ${EFL_MODULE_SCOPE}/${_modname}" ${${_modoptionname}_DEFAULT} CHOICE ON;OFF;STATIC) else() set(_modsrcdir ${EFL_MODULES_SOURCE_DIR}/${_modname}) set(_modoutdir ${CMAKE_INSTALL_LIBDIR}/${EFL_LIB_CURRENT}/modules/${_modname}/v-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}) set(_modbindir ${EFL_MODULES_BINARY_DIR}/${_modname}) set(_modtarget ${EFL_LIB_CURRENT}-module-${_modname}) string(TOUPPER "${EFL_LIB_CURRENT}_MODULE_TYPE_${_modname}" _modoptionname) if(NOT DEFINED ${_modoptionname}_DEFAULT) set(${_modoptionname}_DEFAULT "ON") endif() EFL_OPTION(${_modoptionname} "Build ${EFL_LIB_CURRENT} module ${_modname}" ${${_modoptionname}_DEFAULT} CHOICE ON;OFF;STATIC) endif() set(SOURCES) set(OBJECT_DEPENDS) set(LIBRARIES) set(INCLUDE_DIRECTORIES) set(SYSTEM_INCLUDE_DIRECTORIES) set(DEFINITIONS) set(MODULE_TYPE "${${_modoptionname}}") set(INSTALL_DIR ${_modoutdir}) set(PKG_CONFIG_REQUIRES) set(PKG_CONFIG_REQUIRES_PRIVATE) set(COMPILE_FLAGS) set(LINK_FLAGS) _EFL_INCLUDE_OR_DETECT("Module ${_modtarget}" ${_modsrcdir}) if(NOT SOURCES) message(WARNING "${_modsrcdir}/CMakeLists.txt defines no SOURCES") return() endif() if(PUBLIC_HEADERS) message(WARNING "${_modsrcdir}/CMakeLists.txt should not define PUBLIC_HEADERS, it's not to be installed.") endif() if(PKG_CONFIG_REQUIRES) message(WARNING "${_modsrcdir}/CMakeLists.txt should not define PKG_CONFIG_REQUIRES. Use PKG_CONFIG_REQUIRES_PRIVATE instead") endif() if("${MODULE_TYPE}" STREQUAL "OFF") return() elseif("${MODULE_TYPE}" STREQUAL "STATIC") set(_modtype STATIC) else() set(_modtype MODULE) endif() EFL_FILES_TO_ABSOLUTE(_sources ${_modsrcdir} ${_modbindir} ${SOURCES}) EFL_FILES_TO_ABSOLUTE(_obj_deps ${_modsrcdir} ${_modbindir} ${OBJECT_DEPENDS}) EFL_PKG_CONFIG_EVAL(${_modtarget} "${PKG_CONFIG_REQUIRES_PRIVATE}" "") set(_libraries) foreach(_l ${LIBRARIES}) if(${_l} MATCHES "^find-") string(REGEX REPLACE "^find-" "" _v "${_l}") list(APPEND _libraries ${${_v}_LIBRARIES}) list(APPEND SYSTEM_INCLUDE_DIRECTORIES ${${_v}_INCLUDE_DIR}) else() list(APPEND _libraries ${_l}) endif() endforeach() set(LIBRARIES ${_libraries}) add_library(${_modtarget} ${_modtype} ${_sources}) set_target_properties(${_modtarget} PROPERTIES OBJECT_DEPENDS "${_obj_deps}" PREFIX "" OUTPUT_NAME "module") target_include_directories(${_modtarget} PRIVATE ${_modsrcdir} ${_modbindir} ${INCLUDE_DIRECTORIES}) target_include_directories(${_modtarget} SYSTEM PUBLIC ${SYSTEM_INCLUDE_DIRECTORIES}) target_link_libraries(${_modtarget} LINK_PRIVATE ${LIBRARIES}) target_compile_definitions(${_modtarget} PRIVATE ${DEFINITIONS}) set(_link_flags) foreach(_l ${${_modtarget}_PKG_CONFIG_REQUIRES_PRIVATE_LDFLAGS} ${LINK_FLAGS}) set(_link_flags "${_link_flags} ${_l}") endforeach() set(_compile_flags) foreach(_c ${${_modtarget}_PKG_CONFIG_REQUIRES_PRIVATE_CFLAGS} ${COMPILE_FLAGS}) set(_compile_flags "${_compile_flags} ${_c}") endforeach() set_target_properties(${_modtarget} PROPERTIES LINK_FLAGS "${_link_flags}" COMPILE_FLAGS "${_compile_flags}" LIBRARY_OUTPUT_DIRECTORY "${_modoutdir}" ARCHIVE_OUTPUT_DIRECTORY "${_modoutdir}" RUNTIME_OUTPUT_DIRECTORY "${_modoutdir}") if("${MODULE_TYPE}" STREQUAL "STATIC") target_link_libraries(${EFL_LIB_CURRENT} LINK_PRIVATE ${_modtarget}) target_compile_definitions(${EFL_LIB_CURRENT} PRIVATE "-D${_modoptionname}_STATIC=1") target_include_directories(${_modtarget} PRIVATE ${EFL_LIB_SOURCE_DIR} ${EFL_LIB_BINARY_DIR}) set_target_properties(${_modtarget} PROPERTIES POSITION_INDEPENDENT_CODE TRUE) LIST_APPEND_GLOBAL(${EFL_LIB_CURRENT}_STATIC_MODULES ${_modtarget}) else() target_link_libraries(${_modtarget} LINK_PRIVATE ${EFL_LIB_CURRENT}) target_compile_definitions(${EFL_LIB_CURRENT} PRIVATE "-D${_modoptionname}_DYNAMIC=1") LIST_APPEND_GLOBAL(${EFL_LIB_CURRENT}_MODULES ${_modtarget}) if(INSTALL_DIR) install(TARGETS ${_modtarget} LIBRARY DESTINATION "${INSTALL_DIR}") endif() endif() endfunction() macro(EFL_PROJECT version) if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release") project(efl VERSION ${version}) else ("${CMAKE_BUILD_TYPE}" STREQUAL "Release") execute_process( COMMAND git rev-list --count HEAD WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE GIT_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE ) project(efl VERSION ${version}.${GIT_VERSION}) endif ("${CMAKE_BUILD_TYPE}" STREQUAL "Release") message("VERSION ${PROJECT_VERSION}") endmacro() # Will use the source of the given target to create rules for creating # the .eo.c and .eo.h files. The INCLUDE_DIRECTORIES of the target will be used function(EFL_CREATE_EO_RULES target source_dir generation_dir) get_target_property(eo_files_private ${target} EFL_EO_PRIVATE) get_target_property(eo_files_public ${target} EFL_EO_PUBLIC) if(NOT eo_files_private AND NOT eo_files_public) return() endif() get_target_property(link_libraries ${target} LINK_LIBRARIES) set(all_libraries ${target} ${link_libraries}) set(include_cmd "") foreach(link_target ${all_libraries}) if(TARGET ${link_target}) list(APPEND include_cmd -I${CMAKE_SOURCE_DIR}/src/lib/${link_target}) endif() endforeach() set(all_eo_gen_files "") set(extra_include_dirs "") foreach(file ${eo_files_private} ${eo_files_public}) get_filename_component(ext ${file} EXT) string(REGEX REPLACE "^${source_dir}/" "" filename "${file}") string(REGEX REPLACE "^${CMAKE_SOURCE_DIR}/" "" relfile "${file}") # if sources are located in subdiretories get_filename_component(reldir "${filename}" DIRECTORY) if(reldir) file(MAKE_DIRECTORY "${generation_dir}/${reldir}") get_filename_component(absdir "${file}" DIRECTORY) set(rel_include_cmd -I${absdir}) list(APPEND extra_include_dirs "${generation_dir}/${reldir}") else() set(rel_include_cmd) endif() if(${ext} STREQUAL ".eo") set(file_eo_gen_files ${generation_dir}/${filename}.c ${generation_dir}/${filename}.h ${generation_dir}/${filename}.legacy.h) set(out_cmd -gchl -o c:${generation_dir}/${filename}.c -o h:${generation_dir}/${filename}.h -o l:${generation_dir}/${filename}.legacy.h) elseif(${ext} STREQUAL ".eot") set(file_eo_gen_files ${generation_dir}/${filename}.h) set(out_cmd -gh -o h:${generation_dir}/${filename}.h) else() message(FATAL_ERROR "Unsupported eo file type: ${file}") endif() #add the custom rule if(file_eo_gen_files) add_custom_command( OUTPUT ${file_eo_gen_files} COMMAND ${EOLIAN_BIN} ${rel_include_cmd} ${include_cmd} ${EOLIAN_EXTRA_PARAMS} ${out_cmd} ${file} DEPENDS ${file} COMMENT "EOLIAN ${relfile}" ) list(APPEND all_eo_gen_files ${file_eo_gen_files}) endif() endforeach() if(all_eo_gen_files) file(MAKE_DIRECTORY ${generation_dir}) add_custom_target(${target}-eo DEPENDS ${all_eo_gen_files} ) if(extra_include_dirs) list(REMOVE_DUPLICATES extra_include_dirs) target_include_directories(${target} PUBLIC ${extra_include_dirs}) endif() add_dependencies(${target} ${target}-eo) if(${EOLIAN_BIN} STREQUAL ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/eolian_gen) add_dependencies(${target}-eo eolian-bin) endif() endif() endfunction() # EFL_BACKEND_CHOICES(Prefix Choice1 .. ChoiceN) # # Helper that will check ${ChoiceN}_FOUND and if so append to # ${_prefix}_CHOICES as well set the first found option (in order!) as # ${_prefix}_DEFAULT and ${_prefix}_FOUND to ON if at least one was # found. function(EFL_BACKEND_CHOICES _prefix) cmake_parse_arguments(PARAMS "REQUIRED" "" "" ${ARGN}) set(_choices "") set(_defval "none") set(_found OFF) foreach(c ${PARAMS_UNPARSED_ARGUMENTS}) if(${c}_FOUND) string(TOLOWER "${c}" c_lc) if(_defval STREQUAL "none") set(_defval ${c_lc}) endif() set(_found ON) list(APPEND _choices ${c_lc}) endif() endforeach() if(PARAMS_REQUIRED AND NOT _found) message(FATAL_ERROR "${_prefix} backend was required (one of ${PARAMS_UNPARSED_ARGUMENTS}) but none was found!") elseif(NOT PARAMS_REQUIRED) list(APPEND _choices "none") endif() set(${_prefix}_FOUND ${_found} PARENT_SCOPE) set(${_prefix}_CHOICES ${_choices} PARENT_SCOPE) set(${_prefix}_DEFAULT ${_defval} PARENT_SCOPE) endfunction()