From 0550fa124700f3eb101994277b0973a9a1a401fa Mon Sep 17 00:00:00 2001 From: Giel van Schijndel Date: Sun, 1 Jan 2017 23:19:40 +0100 Subject: [PATCH] Use dependencies via target_link_libraries exclusively This allows all dependencies to be resolved in CMake's generation step instead of before that time during script execution. Additionally properties such as transitive dependencies are now handled properly and include directories of dependencies automatically added to the include path. NOTE: This includes a workaround for cucumber/cucumber-cpp#190 which was originally discovered when doing this change. --- CMakeLists.txt | 101 ++++++++++++++++++++---- examples/Calc/CMakeLists.txt | 14 ++-- examples/CalcQt/CMakeLists.txt | 26 +++--- examples/FeatureShowcase/CMakeLists.txt | 2 +- src/CMakeLists.txt | 43 +++++++--- tests/CMakeLists.txt | 15 ++-- 6 files changed, 149 insertions(+), 52 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5737d257..561b50dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,19 +74,74 @@ endif() if(CUKE_USE_STATIC_BOOST) set(Boost_USE_STATIC_LIBS ON) find_package(Boost ${BOOST_MIN_VERSION} COMPONENTS ${CUKE_CORE_BOOST_LIBS} REQUIRED) - - if(NOT MSVC) - find_package(Threads) - set(CUKE_EXTRA_LIBRARIES ${CUKE_EXTRA_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) - endif() else() set(CMAKE_CXX_FLAGS "-DBOOST_ALL_DYN_LINK ${CMAKE_CXX_FLAGS}") set(Boost_USE_STATIC_LIBS OFF) find_package(Boost ${BOOST_MIN_VERSION} COMPONENTS ${CUKE_CORE_BOOST_LIBS} REQUIRED) endif() -include_directories(${Boost_INCLUDE_DIRS}) -set(CUKE_EXTRA_LIBRARIES ${CUKE_EXTRA_LIBRARIES} ${Boost_THREAD_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_FILESYSTEM_LIBRARY}) +# Create import targets for CMake versions older than 3.5 (actually older FindBoost.cmake) +if(Boost_USE_STATIC_LIBS) + set(LIBRARY_TYPE STATIC) +else() + # Just because we don't ask for static doesn't mean we're not getting static + set(LIBRARY_TYPE UNKNOWN) +endif() +if(Boost_INCLUDE_DIRS AND NOT TARGET Boost::boost) + add_library(Boost::boost INTERFACE IMPORTED) + set_target_properties(Boost::boost PROPERTIES + "INTERFACE_INCLUDE_DIRECTORIES" "${Boost_INCLUDE_DIRS}") +endif() +if(Boost_THREAD_LIBRARY AND NOT TARGET Boost::thread) + find_package(Threads REQUIRED) + add_library(Boost::thread ${LIBRARY_TYPE} IMPORTED) + set_target_properties(Boost::thread PROPERTIES + "IMPORTED_LOCATION" "${Boost_THREAD_LIBRARY}" + "INTERFACE_LINK_LIBRARIES" "Threads::Threads;Boost::boost" + ) +endif() +if(Boost_SYSTEM_LIBRARY AND NOT TARGET Boost::system) + add_library(Boost::system ${LIBRARY_TYPE} IMPORTED) + set_target_properties(Boost::system PROPERTIES + "IMPORTED_LOCATION" "${Boost_SYSTEM_LIBRARY}" + "INTERFACE_LINK_LIBRARIES" "Boost::boost" + ) +endif() +if(Boost_FILESYSTEM_LIBRARY AND NOT TARGET Boost::filesystem) + add_library(Boost::filesystem ${LIBRARY_TYPE} IMPORTED) + set_target_properties(Boost::filesystem PROPERTIES + "IMPORTED_LOCATION" "${Boost_FILESYSTEM_LIBRARY}" + "INTERFACE_LINK_LIBRARIES" "Boost::system;Boost::boost" + ) +endif() +if(Boost_REGEX_LIBRARY AND NOT TARGET Boost::regex) + add_library(Boost::regex ${LIBRARY_TYPE} IMPORTED) + set_target_properties(Boost::regex PROPERTIES + "IMPORTED_LOCATION" "${Boost_REGEX_LIBRARY}" + "INTERFACE_LINK_LIBRARIES" "Boost::boost" + ) +endif() +if(Boost_DATE_TIME_LIBRARY AND NOT TARGET Boost::date_time) + add_library(Boost::date_time ${LIBRARY_TYPE} IMPORTED) + set_target_properties(Boost::date_time PROPERTIES + "IMPORTED_LOCATION" "${Boost_DATE_TIME_LIBRARY}" + "INTERFACE_LINK_LIBRARIES" "Boost::boost" + ) +endif() +if(Boost_PROGRAM_OPTIONS_LIBRARY AND NOT TARGET Boost::program_options) + add_library(Boost::program_options ${LIBRARY_TYPE} IMPORTED) + set_target_properties(Boost::program_options PROPERTIES + "IMPORTED_LOCATION" "${Boost_PROGRAM_OPTIONS_LIBRARY}" + "INTERFACE_LINK_LIBRARIES" "Boost::boost" + ) +endif() +if(Boost_UNIT_TEST_FRAMEWORK_LIBRARY AND NOT TARGET Boost::unit_test_framework) + add_library(Boost::unit_test_framework ${LIBRARY_TYPE} IMPORTED) + set_target_properties(Boost::unit_test_framework PROPERTIES + "IMPORTED_LOCATION" "${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}" + "INTERFACE_LINK_LIBRARIES" "Boost::boost" + ) +endif() # # GTest @@ -106,20 +161,35 @@ endif() if(NOT CUKE_DISABLE_QT) find_package(Qt5Core) + find_package(Qt5Gui) find_package(Qt5Widgets) find_package(Qt5Test) - if(${Qt5Core_FOUND} AND ${Qt5Widgets_FOUND} AND ${Qt5Test_FOUND}) + if(Qt5Core_FOUND AND Qt5Gui_FOUND AND Qt5Widgets_FOUND AND Qt5Test_FOUND) message(STATUS "Found Qt version: ${Qt5Core_VERSION_STRING}") - set(QT_LIBRARIES Qt5::Core Qt5::Widgets Qt5::Test) - if(NOT Qt5Core_VERSION_STRING VERSION_LESS 5.7 AND (NOT DEFINED CMAKE_CXX_STANDARD OR NOT CMAKE_CXX_STANDARD STREQUAL 98)) + if(NOT Qt5Core_VERSION_STRING VERSION_LESS 5.7 AND (NOT DEFINED CMAKE_CXX_STANDARD OR NOT CMAKE_CXX_STANDARD STREQUAL 98)) message(STATUS "C++11 is needed from Qt version 5.7.0, building with c++11 enabled") set(CMAKE_CXX_STANDARD 11) endif() + add_library(Qt::Core INTERFACE IMPORTED) + add_library(Qt::Gui INTERFACE IMPORTED) + add_library(Qt::Widgets INTERFACE IMPORTED) + add_library(Qt::Test INTERFACE IMPORTED) + set_target_properties(Qt::Core PROPERTIES INTERFACE_LINK_LIBRARIES Qt5::Core ) + set_target_properties(Qt::Gui PROPERTIES INTERFACE_LINK_LIBRARIES Qt5::Gui ) + set_target_properties(Qt::Widgets PROPERTIES INTERFACE_LINK_LIBRARIES Qt5::Widgets) + set_target_properties(Qt::Test PROPERTIES INTERFACE_LINK_LIBRARIES Qt5::Test ) else() find_package(Qt4 COMPONENTS QtCore QtGui QtTest) if(QT4_FOUND) - set(QT_LIBRARIES Qt4::QtCore Qt4::QtGui Qt4::QtTest) + add_library(Qt::Core INTERFACE IMPORTED) + add_library(Qt::Gui INTERFACE IMPORTED) + add_library(Qt::Widgets INTERFACE IMPORTED) + add_library(Qt::Test INTERFACE IMPORTED) + set_target_properties(Qt::Core PROPERTIES INTERFACE_LINK_LIBRARIES Qt4::QtCore) + set_target_properties(Qt::Gui PROPERTIES INTERFACE_LINK_LIBRARIES Qt4::QtGui ) + set_target_properties(Qt::Widgets PROPERTIES INTERFACE_LINK_LIBRARIES Qt4::QtGui ) + set_target_properties(Qt::Test PROPERTIES INTERFACE_LINK_LIBRARIES Qt4::QtTest) include(${QT_USE_FILE}) endif() endif() @@ -177,8 +247,6 @@ endif() # set(CUKE_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) -include_directories(${CUKE_INCLUDE_DIR}) -set(CUKE_LIBRARIES cucumber-cpp ${CUKE_EXTRA_LIBRARIES}) add_subdirectory(3rdparty/json_spirit) add_subdirectory(src) @@ -208,10 +276,10 @@ else() add_executable(e2e-steps EXCLUDE_FROM_ALL ${CUKE_DYNAMIC_CPP_STEPS}) # Mark this file as generated so it isn't required at CMake generation time (it is necessary when the target gets built though) set_source_files_properties(${CUKE_DYNAMIC_CPP_STEPS} PROPERTIES GENERATED TRUE) - target_link_libraries(e2e-steps PRIVATE ${CUKE_LIBRARIES}) + target_link_libraries(e2e-steps PRIVATE cucumber-cpp) #Boost test lib required for boost specific scenario "Predicate Message" - if(Boost_UNIT_TEST_FRAMEWORK_FOUND) - target_link_libraries(e2e-steps PRIVATE ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) + if(TARGET Boost::unit_test_framework) + target_link_libraries(e2e-steps PRIVATE Boost::unit_test_framework) else() set(CUKE_E2E_TAGS "--tags ~@boost") endif() @@ -242,7 +310,6 @@ else() ${CUKE_E2E_TAGS} ${ARGN} ${CUKE_FEATURES_DIR} - DEPENDS cucumber-cpp ${USES_TERMINAL} ) endfunction(add_feature_target) diff --git a/examples/Calc/CMakeLists.txt b/examples/Calc/CMakeLists.txt index 2da0c9dc..3641aec6 100644 --- a/examples/Calc/CMakeLists.txt +++ b/examples/Calc/CMakeLists.txt @@ -1,27 +1,27 @@ project(Calc) add_library(Calc src/Calculator) -target_include_directories(Calc PUBLIC src) +target_include_directories(Calc INTERFACE src) if(TARGET GTest::GTest) add_executable(GTestCalculatorSteps features/step_definitions/GTestCalculatorSteps) - target_link_libraries(GTestCalculatorSteps Calc ${CUKE_LIBRARIES} GTest::GTest) + target_link_libraries(GTestCalculatorSteps PRIVATE Calc cucumber-cpp GTest::GTest) list(FIND CMAKE_CXX_COMPILE_FEATURES cxx_variadic_templates HAS_VARIADIC_TEMPLATES) if(HAS_VARIADIC_TEMPLATES GREATER -1) add_executable(FuncArgsCalculatorSteps features/step_definitions/FuncArgsCalculatorSteps) - target_link_libraries(FuncArgsCalculatorSteps Calc ${CUKE_LIBRARIES} GTest::GTest) + target_link_libraries(FuncArgsCalculatorSteps PRIVATE Calc cucumber-cpp GTest::GTest) target_compile_features(FuncArgsCalculatorSteps PRIVATE cxx_variadic_templates) endif() endif() -if(Boost_UNIT_TEST_FRAMEWORK_FOUND) +if(TARGET Boost::unit_test_framework) add_executable(BoostCalculatorSteps features/step_definitions/BoostCalculatorSteps) - target_link_libraries(BoostCalculatorSteps Calc ${CUKE_LIBRARIES} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) + target_link_libraries(BoostCalculatorSteps PRIVATE Calc cucumber-cpp Boost::unit_test_framework) endif() -if(Qt5TEST_FOUND) +if(TARGET Qt::Test) add_executable(QtTestCalculatorSteps features/step_definitions/QtTestCalculatorSteps) - target_link_libraries(QtTestCalculatorSteps Calc Qt5::Test ${CUKE_LIBRARIES}) + target_link_libraries(QtTestCalculatorSteps Calc Qt::Test cucumber-cpp) endif() diff --git a/examples/CalcQt/CMakeLists.txt b/examples/CalcQt/CMakeLists.txt index 2d6ca8c7..66139cee 100644 --- a/examples/CalcQt/CMakeLists.txt +++ b/examples/CalcQt/CMakeLists.txt @@ -1,27 +1,33 @@ project(CalcQt) -if(QT_LIBRARIES) +if(TARGET Qt::Core AND TARGET Qt::Gui AND TARGET Qt::Widgets AND TARGET Qt::Test) add_library(libcalcqt src/CalculatorWidget.cpp src/CalculatorWidget.h) set_target_properties(libcalcqt PROPERTIES AUTOMOC ON) - target_include_directories(libcalcqt PUBLIC src) - target_link_libraries(libcalcqt ${QT_LIBRARIES}) + target_include_directories(libcalcqt INTERFACE src) + target_link_libraries(libcalcqt + PUBLIC + Qt::Core + Qt::Widgets + PRIVATE + Qt::Gui + ) add_executable(calcqt src/CalcQt.cpp) - target_link_libraries(calcqt libcalcqt ${QT_LIBRARIES}) + target_link_libraries(calcqt PRIVATE libcalcqt Qt::Widgets) - if(Qt5TEST_FOUND) + if(Qt::Test) add_executable(QtTestCalculatorQtSteps features/step_definitions/QtTestCalculatorQtSteps) - target_link_libraries(QtTestCalculatorQtSteps PRIVATE libcalcqt ${QT_LIBRARIES} ${CUKE_LIBRARIES}) + target_link_libraries(QtTestCalculatorQtSteps PRIVATE libcalcqt Qt::Test cucumber-cpp) endif() - if(Boost_UNIT_TEST_FRAMEWORK_FOUND) - add_executable(BoostCalculatorQtSteps features/step_definitions/BoostCalculatorQtSteps) - target_link_libraries(BoostCalculatorQtSteps libcalcqt ${CUKE_LIBRARIES} ${QT_LIBRARIES} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) + if(TARGET Boost::unit_test_framework) + add_executable(BoostCalculatorQtSteps features/step_definitions/BoostCalculatorQtSteps.cpp) + target_link_libraries(BoostCalculatorQtSteps PRIVATE libcalcqt Boost::unit_test_framework cucumber-cpp Qt::Test) endif() if(TARGET GTest::GTest) add_executable(GTestCalculatorQtSteps features/step_definitions/GTestCalculatorQtSteps) - target_link_libraries(GTestCalculatorQtSteps libcalcqt ${CUKE_LIBRARIES} GTest::GTest ${QT_LIBRARIES}) + target_link_libraries(GTestCalculatorQtSteps PRIVATE libcalcqt cucumber-cpp GTest::GTest Qt::Test) endif() endif() diff --git a/examples/FeatureShowcase/CMakeLists.txt b/examples/FeatureShowcase/CMakeLists.txt index 80819185..3955de7c 100644 --- a/examples/FeatureShowcase/CMakeLists.txt +++ b/examples/FeatureShowcase/CMakeLists.txt @@ -3,7 +3,7 @@ project(FeatureShowcase) if(TARGET GTest::GTest) function(add_cucumber_executable) add_executable(FeatureShowcaseSteps ${ARGV}) - target_link_libraries(FeatureShowcaseSteps ${CUKE_LIBRARIES} GTest::GTest) + target_link_libraries(FeatureShowcaseSteps PRIVATE cucumber-cpp GTest::GTest) foreach(_arg ${ARGN}) get_filename_component(OBJECT_PREFIX ${_arg} NAME_WE) set_source_files_properties(${_arg} PROPERTIES COMPILE_FLAGS "-DCUKE_OBJECT_PREFIX=${OBJECT_PREFIX}") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ceea26bb..4691cb2f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,22 +15,21 @@ set(CUKE_SOURCES connectors/wire/WireProtocolCommands.cpp ) -set(CUKE_DEP_LIBRARIES json_spirit.header) - if(TARGET GTest::GTest) - list(APPEND CUKE_DEP_LIBRARIES GTest::GTest) + list(APPEND CUKE_EXTRA_PRIVATE_LIBRARIES GTest::GTest) list(APPEND CUKE_SOURCES drivers/GTestDriver.cpp) endif() -if(Boost_UNIT_TEST_FRAMEWORK_FOUND) +if(TARGET Boost::unit_test_framework) + list(APPEND CUKE_EXTRA_PRIVATE_LIBRARIES Boost::unit_test_framework) list(APPEND CUKE_SOURCES drivers/BoostDriver.cpp) endif() -if(Qt5TEST_FOUND) +if(TARGET Qt::Test) qt5_wrap_cpp(MOC_FILE ../include/cucumber-cpp/internal/drivers/QtTestDriver.hpp) list(APPEND CUKE_SOURCES ${MOC_FILE}) list(APPEND CUKE_SOURCES drivers/QtTestDriver.cpp) - list(APPEND CUKE_DEP_LIBRARIES Qt5::Test) + list(APPEND CUKE_EXTRA_PRIVATE_LIBRARIES Qt::Test) endif() if(CMAKE_EXTRA_GENERATOR OR MSVC_IDE) @@ -45,9 +44,31 @@ endif() add_library(cucumber-cpp-nomain STATIC ${CUKE_SOURCES}) add_library(cucumber-cpp STATIC ${CUKE_SOURCES} main.cpp) -if(MINGW) - list(APPEND CUKE_DEP_LIBRARIES ws2_32) -endif(MINGW) +foreach(TARGET + cucumber-cpp-nomain + cucumber-cpp +) + target_include_directories(${TARGET} PUBLIC ${CMAKE_SOURCE_DIR}/include) + target_link_libraries(${TARGET} + PUBLIC + Boost::boost + Boost::regex + PRIVATE + Boost::date_time + Boost::filesystem + Boost::thread + json_spirit.header + ${CUKE_EXTRA_PRIVATE_LIBRARIES} + ) + if(MINGW) + target_link_libraries(${TARGET} + PRIVATE + ws2_32 + ) + endif(MINGW) +endforeach() -target_link_libraries(cucumber-cpp-nomain PRIVATE ${CUKE_DEP_LIBRARIES}) -target_link_libraries(cucumber-cpp PRIVATE ${CUKE_DEP_LIBRARIES}) +target_link_libraries(cucumber-cpp + PRIVATE + Boost::program_options +) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 08cd314e..a51e736e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -2,7 +2,7 @@ function(cuke_add_driver_test TEST_FILE) get_filename_component(TEST_NAME ${TEST_FILE} NAME) message(STATUS "Adding " ${TEST_NAME}) add_executable(${TEST_NAME} ${TEST_FILE}.cpp) - target_link_libraries(${TEST_NAME} cucumber-cpp-nomain ${CUKE_EXTRA_LIBRARIES} ${ARGN}) + target_link_libraries(${TEST_NAME} PRIVATE cucumber-cpp-nomain ${ARGN}) add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME}) endfunction() @@ -11,7 +11,7 @@ if(TARGET GMock::Main) get_filename_component(TEST_NAME ${TEST_FILE} NAME) message(STATUS "Adding " ${TEST_NAME}) add_executable(${TEST_NAME} ${TEST_FILE}.cpp) - target_link_libraries(${TEST_NAME} cucumber-cpp-nomain ${CUKE_EXTRA_LIBRARIES} ${ARGN} GMock::Main) + target_link_libraries(${TEST_NAME} PRIVATE cucumber-cpp-nomain ${ARGN} GMock::Main) gtest_add_tests(${TEST_NAME} "" ${TEST_FILE}.cpp) # Run all tests in executable at once too. This ensures that the used fixtures get tested # properly too. Additionally gather the output in jUnit compatible output for CI. @@ -46,12 +46,15 @@ if(TARGET GTest::Main) endif() endif() -if(Boost_UNIT_TEST_FRAMEWORK_FOUND) - cuke_add_driver_test(integration/drivers/BoostDriverTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) +if(TARGET Boost::unit_test_framework) + cuke_add_driver_test(integration/drivers/BoostDriverTest Boost::unit_test_framework) endif() -if(Qt5TEST_FOUND) - cuke_add_driver_test(integration/drivers/QtTestDriverTest ${QT_LIBRARIES}) +if((TARGET Qt::Test) + # FIXME: not including this in the test suite due to memory leak #190 + AND (NOT VALGRIND_TESTS) + ) + cuke_add_driver_test(integration/drivers/QtTestDriverTest Qt::Test) endif() cuke_add_driver_test(integration/drivers/GenericDriverTest)