be2d05a4bc
Makes helping with build issues easier as we readily see what versions are being used. Cmake already prints the version but only when run the first time and not on subsequent calls, so the information is often lost
278 lines
7.8 KiB
CMake
278 lines
7.8 KiB
CMake
#
|
|
# Collection of cmake utility functions
|
|
#
|
|
|
|
# message_colored {{{
|
|
|
|
function(message_colored message_level text color)
|
|
string(ASCII 27 esc)
|
|
message(${message_level} "${esc}[${color}m${text}${esc}[0m")
|
|
endfunction()
|
|
|
|
# }}}
|
|
# colored_option {{{
|
|
|
|
function(colored_option text flag)
|
|
# Append version of option, if ${flag}_VERSION is set
|
|
set(version ${${flag}_VERSION})
|
|
|
|
if(NOT "${version}" STREQUAL "")
|
|
set(text "${text} (${version})")
|
|
endif()
|
|
|
|
if(${flag})
|
|
message_colored(STATUS "[X]${text}" "32;1")
|
|
else()
|
|
message_colored(STATUS "[ ]${text}" "37;2")
|
|
endif()
|
|
endfunction()
|
|
|
|
# }}}
|
|
|
|
# make_executable {{{
|
|
|
|
function(make_executable target_name)
|
|
set(zero_value_args)
|
|
set(one_value_args PACKAGE)
|
|
set(multi_value_args SOURCES INCLUDE_DIRS PKG_DEPENDS CMAKE_DEPENDS TARGET_DEPENDS RAW_DEPENDS)
|
|
|
|
cmake_parse_arguments(BIN
|
|
"${zero_value_args}" "${one_value_args}"
|
|
"${multi_value_args}" ${ARGN})
|
|
|
|
# add defined INCLUDE_DIRS
|
|
include_directories(${BIN_INCLUDE_DIRS})
|
|
|
|
# add INCLUDE_DIRS for all external dependencies
|
|
foreach(DEP ${BIN_TARGET_DEPENDS} ${BIN_PKG_DEPENDS} ${BIN_CMAKE_DEPENDS})
|
|
string(TOUPPER ${DEP} DEP)
|
|
include_directories(${${DEP}_INCLUDE_DIRS})
|
|
include_directories(${${DEP}_INCLUDEDIR})
|
|
endforeach()
|
|
|
|
# create target
|
|
add_executable(${target_name} ${BIN_SOURCES})
|
|
|
|
# set the output file basename the same for static and shared
|
|
set_target_properties(${target_name} PROPERTIES OUTPUT_NAME ${target_name})
|
|
|
|
# link libraries from pkg-config imports
|
|
foreach(DEP ${BIN_PKG_DEPENDS})
|
|
string(TOUPPER ${DEP} DEP)
|
|
target_link_libraries(${target_name} ${${DEP}_LDFLAGS})
|
|
endforeach()
|
|
|
|
# link libraries from cmake imports
|
|
foreach(DEP ${BIN_CMAKE_DEPENDS})
|
|
string(TOUPPER ${DEP} DEP)
|
|
target_link_libraries(${target_name}
|
|
${${DEP}_LIB}
|
|
${${DEP}_LIBRARY}
|
|
${${DEP}_LIBRARIES})
|
|
endforeach()
|
|
|
|
# link libraries that are build as part of this project
|
|
target_link_libraries(${target_name}
|
|
${BIN_TARGET_DEPENDS}
|
|
${BIN_RAW_DEPENDS})
|
|
|
|
# install targets
|
|
install(TARGETS ${target_name}
|
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
COMPONENT runtime)
|
|
endfunction()
|
|
|
|
# }}}
|
|
# make_library {{{
|
|
|
|
function(make_library target_name)
|
|
set(zero_value_args SHARED STATIC)
|
|
set(one_value_args PACKAGE HEADER_INSTALL_DIR)
|
|
set(multi_value_args SOURCES HEADERS INCLUDE_DIRS PKG_DEPENDS CMAKE_DEPENDS TARGET_DEPENDS RAW_DEPENDS)
|
|
|
|
cmake_parse_arguments(LIB
|
|
"${zero_value_args}" "${one_value_args}"
|
|
"${multi_value_args}" ${ARGN})
|
|
|
|
# make the header paths absolute
|
|
foreach(HEADER ${LIB_HEADERS})
|
|
set(LIB_HEADERS_ABS ${LIB_HEADERS_ABS} ${PROJECT_SOURCE_DIR}/include/${HEADER})
|
|
endforeach()
|
|
|
|
# add defined INCLUDE_DIRS
|
|
foreach(DIR ${LIB_INCLUDE_DIRS})
|
|
string(TOUPPER ${DIR} DIR)
|
|
include_directories(${DIR})
|
|
include_directories(${${DIR}_INCLUDE_DIRS})
|
|
endforeach()
|
|
|
|
# add INCLUDE_DIRS for all external dependencies
|
|
foreach(DEP ${LIB_TARGET_DEPENDS} ${LIB_PKG_DEPENDS} ${LIB_CMAKE_DEPENDS})
|
|
string(TOUPPER ${DEP} DEP)
|
|
include_directories(${${DEP}_INCLUDE_DIRS} ${${DEP}_INCLUDEDIRS})
|
|
endforeach()
|
|
|
|
if(LIB_SHARED)
|
|
list(APPEND library_targets ${target_name}_shared)
|
|
endif()
|
|
if(LIB_STATIC)
|
|
list(APPEND library_targets ${target_name}_static)
|
|
endif()
|
|
|
|
foreach(library_target_name ${library_targets})
|
|
message(STATUS "${library_target_name}")
|
|
add_library(${library_target_name}
|
|
${LIB_HEADERS_ABS}
|
|
${LIB_SOURCES})
|
|
|
|
# link libraries from pkg-config imports
|
|
foreach(DEP ${LIB_PKG_DEPENDS})
|
|
string(TOUPPER ${DEP} DEP)
|
|
target_link_libraries(${library_target_name} ${${DEP}_LDFLAGS})
|
|
endforeach()
|
|
|
|
# link libraries from cmake imports
|
|
foreach(DEP ${LIB_CMAKE_DEPENDS})
|
|
string(TOUPPER ${DEP} DEP)
|
|
target_link_libraries(${library_target_name}
|
|
${${DEP}_LIB}
|
|
${${DEP}_LIBRARY}
|
|
${${DEP}_LIBRARIES})
|
|
endforeach()
|
|
|
|
# link libraries that are build as part of this project
|
|
foreach(DEP ${LIB_TARGET_DEPENDS})
|
|
string(TOUPPER ${DEP} DEP)
|
|
if(LIB_BUILD_SHARED)
|
|
target_link_libraries(${library_target_name} ${DEP}_shared)
|
|
endif()
|
|
if(LIB_BUILD_STATIC)
|
|
target_link_libraries(${library_target_name} ${DEP}_static)
|
|
endif()
|
|
endforeach()
|
|
|
|
if(${LIB_RAW_DEPENDS})
|
|
if(LIB_BUILD_STATIC)
|
|
target_link_libraries(${library_target_name} ${LIB_RAW_DEPENDS})
|
|
endif()
|
|
endif()
|
|
|
|
# set the output file basename
|
|
set_target_properties(${library_target_name} PROPERTIES OUTPUT_NAME ${target_name})
|
|
|
|
# install headers
|
|
install(FILES ${LIBRARY_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${LIB_HEADERS_ABS})
|
|
|
|
# install targets
|
|
install(TARGETS ${LIBRARY_TARGETS}
|
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
COMPONENT library)
|
|
endforeach()
|
|
endfunction()
|
|
|
|
# }}}
|
|
|
|
# queryfont {{{
|
|
|
|
function(queryfont output_variable fontname)
|
|
set(multi_value_args FIELDS)
|
|
cmake_parse_arguments(ARG "" "" "${multi_value_args}" ${ARGN})
|
|
|
|
find_program(BIN_FCLIST fc-list)
|
|
if(NOT BIN_FCLIST)
|
|
message_colored(WARNING "Failed to locate `fc-list`" "33;1")
|
|
return()
|
|
endif()
|
|
|
|
string(REPLACE ";" " " FIELDS "${ARG_FIELDS}")
|
|
if(NOT FIELDS)
|
|
set(FIELDS family)
|
|
endif()
|
|
|
|
execute_process(
|
|
COMMAND sh -c "${BIN_FCLIST} : ${FIELDS}"
|
|
RESULT_VARIABLE status
|
|
OUTPUT_VARIABLE output
|
|
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
STRING(REGEX REPLACE ";" "\\\\;" output "${output}")
|
|
STRING(REGEX REPLACE "\n" ";" output "${output}")
|
|
STRING(TOLOWER "${output}" output)
|
|
|
|
foreach(match LISTS ${output})
|
|
if(${match} MATCHES ".*${fontname}.*$")
|
|
list(APPEND matches ${match})
|
|
endif()
|
|
endforeach()
|
|
|
|
if(matches)
|
|
list(GET matches 0 output_variable)
|
|
set(output_variable "${output_variable}" PARENT_SCOPE)
|
|
message(STATUS "Found font: ${output_variable}")
|
|
else()
|
|
message_colored(STATUS "Font not found: ${fontname}" "33;1")
|
|
endif()
|
|
endfunction()
|
|
|
|
# }}}
|
|
# querybin {{{
|
|
|
|
function(querybin binary_name)
|
|
find_program(BIN_${binary_name} ${binary_name})
|
|
if(NOT BIN_${binary_name})
|
|
message_colored(FATAL_ERROR "Failed to locate ${binary_name} binary" 31)
|
|
endif()
|
|
endfunction()
|
|
|
|
# }}}
|
|
# querylib {{{
|
|
|
|
function(querylib flag type pkg out_library out_include_dirs)
|
|
if(${flag})
|
|
if(${type} STREQUAL "cmake")
|
|
find_package(${pkg} REQUIRED)
|
|
string(TOUPPER ${pkg} pkg_upper)
|
|
list(APPEND ${out_library} ${${pkg_upper}_LIBRARY})
|
|
list(APPEND ${out_include_dirs} ${${pkg_upper}_INCLUDE_DIR})
|
|
elseif(${type} STREQUAL "pkg-config")
|
|
find_package(PkgConfig REQUIRED)
|
|
pkg_check_modules(PKG_${flag} REQUIRED ${pkg})
|
|
|
|
# Set packet version so that it can be used in the summary
|
|
set(${flag}_VERSION ${PKG_${flag}_VERSION} PARENT_SCOPE)
|
|
list(APPEND ${out_library} ${PKG_${flag}_LIBRARIES})
|
|
list(APPEND ${out_include_dirs} ${PKG_${flag}_INCLUDE_DIRS})
|
|
else()
|
|
message(FATAL_ERROR "Invalid lookup type '${type}'")
|
|
endif()
|
|
set(${out_library} ${${out_library}} PARENT_SCOPE)
|
|
set(${out_include_dirs} ${${out_include_dirs}} PARENT_SCOPE)
|
|
endif()
|
|
endfunction()
|
|
|
|
# }}}
|
|
# checklib {{{
|
|
|
|
function(checklib flag type pkg)
|
|
if(NOT DEFINED ${flag})
|
|
if(${type} STREQUAL "cmake")
|
|
find_package(${pkg} QUIET)
|
|
set(${flag} ${${pkg}_FOUND} CACHE BOOL "")
|
|
elseif(${type} STREQUAL "pkg-config")
|
|
find_package(PkgConfig REQUIRED)
|
|
pkg_check_modules(PKG_${flag} QUIET ${pkg})
|
|
set(${flag} ${PKG_${flag}_FOUND} CACHE BOOL "")
|
|
elseif(${type} STREQUAL "binary")
|
|
find_program(BIN_${flag} ${pkg})
|
|
set(${flag} ${BIN_${flag}} CACHE BOOL "")
|
|
else()
|
|
message(FATAL_ERROR "Invalid lookup type '${type}'")
|
|
endif()
|
|
endif()
|
|
endfunction()
|
|
|
|
# }}}
|