X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=cmake%2FQuasselMacros.cmake;h=9f576cd7aa8f259769a488a5361989a23623abca;hp=318defb85e7af23543823fbb610240c4fdf95b0b;hb=cf64023910d5b42477f6158f4cee853cc7f7f3f8;hpb=a7acde8447823f9cd5f25aae569a1ec3a0174073 diff --git a/cmake/QuasselMacros.cmake b/cmake/QuasselMacros.cmake index 318defb8..9f576cd7 100644 --- a/cmake/QuasselMacros.cmake +++ b/cmake/QuasselMacros.cmake @@ -7,21 +7,37 @@ ################################################################################################### include(CMakeParseArguments) +include(GenerateExportHeader) +include(QuasselCompileFeatures) ################################################################################################### # Adds a library target for a Quassel module. # -# It expects the (CamelCased) module name as a parameter, and derives various +# quassel_add_module(Module [STATIC] [EXPORT]) +# +# The function expects the (CamelCased) module name as a parameter, and derives various # strings from it. For example, quassel_add_module(Client) produces # - a library target named quassel_client with output name (lib)quassel-client(.so) # - an alias target named Quassel::Client in global scope # +# If the optional argument STATIC is given, a static library is built; otherwise, on +# platforms other than Windows, a shared library is created. For shared libraries, also +# an install rule is added. +# +# To generate an export header for the library, specify EXPORT. The header will be named +# ${module}-export.h (where ${module} is the lower-case name of the module). +# # The function exports the TARGET variable which can be used in the current scope # for setting source files, properties, link dependencies and so on. # To refer to the target outside of the current scope, e.g. for linking, use # the alias name. # function(quassel_add_module _module) + set(options EXPORT STATIC NOINSTALL) + set(oneValueArgs ) + set(multiValueArgs ) + cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + # Derive target, alias target, output name from the given module name set(alias "Quassel::${_module}") set(target ${alias}) @@ -29,17 +45,46 @@ function(quassel_add_module _module) string(REPLACE "::" "_" target ${target}) string(REPLACE "_" "-" output_name ${target}) - add_library(${target} STATIC "") - add_library(${alias} ALIAS ${target}) + if (ARG_STATIC) + set(buildmode STATIC) + else() + set(buildmode SHARED) + endif() - set_target_properties(${target} PROPERTIES - OUTPUT_NAME ${output_name} - ) + add_library(${target} ${buildmode} "") + add_library(${alias} ALIAS ${target}) + target_link_libraries(${target} PRIVATE Qt5::Core) target_include_directories(${target} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE ${CMAKE_CURRENT_BINARY_DIR} # for generated files ) + target_compile_features(${target} PUBLIC ${QUASSEL_COMPILE_FEATURES}) + + set_target_properties(${target} PROPERTIES + OUTPUT_NAME ${output_name} + VERSION ${QUASSEL_MAJOR}.${QUASSEL_MINOR}.${QUASSEL_PATCH} + ) + + if (buildmode STREQUAL "SHARED" AND NOT ${ARG_NOINSTALL}) + install(TARGETS ${target} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) + endif() + + if (ARG_EXPORT) + string(TOLOWER ${_module} lower_module) + string(TOUPPER ${_module} upper_module) + string(REPLACE "::" "-" header_base ${lower_module}) + string(REPLACE "::" "_" macro_base ${upper_module}) + generate_export_header(${target} + BASE_NAME ${macro_base} + EXPORT_FILE_NAME ${CMAKE_BINARY_DIR}/export/${header_base}-export.h + ) + target_include_directories(${target} PUBLIC ${CMAKE_BINARY_DIR}/export) + endif() # Export the target name for further use set(TARGET ${target} PARENT_SCOPE) @@ -113,8 +158,9 @@ function(quassel_add_resource _name) WORKING_DIRECTORY ${basedir} ) - # Generate library target that can be referenced elsewhere - quassel_add_module(Resource::${_name}) + # Generate library target that can be referenced elsewhere. Force static, because + # we can't easily export symbols from the generated sources. + quassel_add_module(Resource::${_name} STATIC) target_sources(${TARGET} PRIVATE ${qrc_srcpath}) set_target_properties(${TARGET} PROPERTIES AUTOMOC OFF AUTOUIC OFF AUTORCC OFF) @@ -122,6 +168,64 @@ function(quassel_add_resource _name) set(RESOURCE_TARGET ${TARGET} PARENT_SCOPE) endfunction() +################################################################################################### +# Adds a unit test case +# +# quassel_add_test(TestName +# [LIBRARIES lib1 lib2...] +# ) +# +# The test name is given in CamelCase as first and mandatory parameter. The corresponding source file +# is expected the lower-cased test name plus the .cpp extension. +# The test case is automatically linked against Qt5::Test, GMock, Quassel::Common and +# Quassel::Test::Main, which contains the main function. This main function also instantiates a +# QCoreApplication, so the event loop can be used in test cases. +# +# Additional libraries can be given using the LIBRARIES argument. +# +# Test cases should include testglobal.h, which transitively includes the GTest/GMock headers and +# exports the main function. +# +# The compiled test case binary is located in the unit/ directory in the build directory. +# +function(quassel_add_test _target) + set(options ) + set(oneValueArgs ) + set(multiValueArgs LIBRARIES) + cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + string(TOLOWER ${_target} lower_target) + set(srcfile ${lower_target}.cpp) + + list(APPEND ARG_LIBRARIES + Qt5::Test + Quassel::Common + Quassel::Test::Global + Quassel::Test::Main + ) + + if (WIN32) + # On Windows, tests need to be built in the same directory that contains the libraries + set(output_dir "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") + else() + # On other platforms, separate the test cases out + set(output_dir "${CMAKE_BINARY_DIR}/unit") + endif() + + add_executable(${_target} ${srcfile}) + set_target_properties(${_target} PROPERTIES + OUTPUT_NAME ${_target} + RUNTIME_OUTPUT_DIRECTORY "${output_dir}" + ) + target_link_libraries(${_target} PUBLIC ${ARG_LIBRARIES}) + + add_test( + NAME ${_target} + COMMAND $ + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + ) +endfunction() + ################################################################################################### # target_link_if_exists(Target # [PUBLIC dep1 dep2...] @@ -158,38 +262,3 @@ function(target_link_if_exists _target) endforeach() endif() endfunction() - -###################################### -# Macros for dealing with translations -###################################### - -# This generates a .ts from a .po file -macro(generate_ts outvar basename) - set(input ${basename}.po) - set(output ${CMAKE_BINARY_DIR}/po/${basename}.ts) - add_custom_command(OUTPUT ${output} - COMMAND $ - ARGS -i ${input} - -of ts - -o ${output} - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/po -# This is a workaround to add (duplicate) strings that lconvert missed to the .ts - COMMAND $ - ARGS -silent - ${CMAKE_SOURCE_DIR}/src/ - -ts ${output} - DEPENDS ${basename}.po) - set(${outvar} ${output}) -endmacro(generate_ts outvar basename) - -# This generates a .qm from a .ts file -macro(generate_qm outvar basename) - set(input ${CMAKE_BINARY_DIR}/po/${basename}.ts) - set(output ${CMAKE_BINARY_DIR}/po/${basename}.qm) - add_custom_command(OUTPUT ${output} - COMMAND $ - ARGS -silent - ${input} - DEPENDS ${basename}.ts) - set(${outvar} ${output}) -endmacro(generate_qm outvar basename)