Skip to content

Commit 0550fa1

Browse files
committed
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 #190 which was originally discovered when doing this change.
1 parent 7714dee commit 0550fa1

File tree

6 files changed

+149
-52
lines changed

6 files changed

+149
-52
lines changed

CMakeLists.txt

+84-17
Original file line numberDiff line numberDiff line change
@@ -74,19 +74,74 @@ endif()
7474
if(CUKE_USE_STATIC_BOOST)
7575
set(Boost_USE_STATIC_LIBS ON)
7676
find_package(Boost ${BOOST_MIN_VERSION} COMPONENTS ${CUKE_CORE_BOOST_LIBS} REQUIRED)
77-
78-
if(NOT MSVC)
79-
find_package(Threads)
80-
set(CUKE_EXTRA_LIBRARIES ${CUKE_EXTRA_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
81-
endif()
8277
else()
8378
set(CMAKE_CXX_FLAGS "-DBOOST_ALL_DYN_LINK ${CMAKE_CXX_FLAGS}")
8479
set(Boost_USE_STATIC_LIBS OFF)
8580
find_package(Boost ${BOOST_MIN_VERSION} COMPONENTS ${CUKE_CORE_BOOST_LIBS} REQUIRED)
8681
endif()
8782

88-
include_directories(${Boost_INCLUDE_DIRS})
89-
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})
83+
# Create import targets for CMake versions older than 3.5 (actually older FindBoost.cmake)
84+
if(Boost_USE_STATIC_LIBS)
85+
set(LIBRARY_TYPE STATIC)
86+
else()
87+
# Just because we don't ask for static doesn't mean we're not getting static
88+
set(LIBRARY_TYPE UNKNOWN)
89+
endif()
90+
if(Boost_INCLUDE_DIRS AND NOT TARGET Boost::boost)
91+
add_library(Boost::boost INTERFACE IMPORTED)
92+
set_target_properties(Boost::boost PROPERTIES
93+
"INTERFACE_INCLUDE_DIRECTORIES" "${Boost_INCLUDE_DIRS}")
94+
endif()
95+
if(Boost_THREAD_LIBRARY AND NOT TARGET Boost::thread)
96+
find_package(Threads REQUIRED)
97+
add_library(Boost::thread ${LIBRARY_TYPE} IMPORTED)
98+
set_target_properties(Boost::thread PROPERTIES
99+
"IMPORTED_LOCATION" "${Boost_THREAD_LIBRARY}"
100+
"INTERFACE_LINK_LIBRARIES" "Threads::Threads;Boost::boost"
101+
)
102+
endif()
103+
if(Boost_SYSTEM_LIBRARY AND NOT TARGET Boost::system)
104+
add_library(Boost::system ${LIBRARY_TYPE} IMPORTED)
105+
set_target_properties(Boost::system PROPERTIES
106+
"IMPORTED_LOCATION" "${Boost_SYSTEM_LIBRARY}"
107+
"INTERFACE_LINK_LIBRARIES" "Boost::boost"
108+
)
109+
endif()
110+
if(Boost_FILESYSTEM_LIBRARY AND NOT TARGET Boost::filesystem)
111+
add_library(Boost::filesystem ${LIBRARY_TYPE} IMPORTED)
112+
set_target_properties(Boost::filesystem PROPERTIES
113+
"IMPORTED_LOCATION" "${Boost_FILESYSTEM_LIBRARY}"
114+
"INTERFACE_LINK_LIBRARIES" "Boost::system;Boost::boost"
115+
)
116+
endif()
117+
if(Boost_REGEX_LIBRARY AND NOT TARGET Boost::regex)
118+
add_library(Boost::regex ${LIBRARY_TYPE} IMPORTED)
119+
set_target_properties(Boost::regex PROPERTIES
120+
"IMPORTED_LOCATION" "${Boost_REGEX_LIBRARY}"
121+
"INTERFACE_LINK_LIBRARIES" "Boost::boost"
122+
)
123+
endif()
124+
if(Boost_DATE_TIME_LIBRARY AND NOT TARGET Boost::date_time)
125+
add_library(Boost::date_time ${LIBRARY_TYPE} IMPORTED)
126+
set_target_properties(Boost::date_time PROPERTIES
127+
"IMPORTED_LOCATION" "${Boost_DATE_TIME_LIBRARY}"
128+
"INTERFACE_LINK_LIBRARIES" "Boost::boost"
129+
)
130+
endif()
131+
if(Boost_PROGRAM_OPTIONS_LIBRARY AND NOT TARGET Boost::program_options)
132+
add_library(Boost::program_options ${LIBRARY_TYPE} IMPORTED)
133+
set_target_properties(Boost::program_options PROPERTIES
134+
"IMPORTED_LOCATION" "${Boost_PROGRAM_OPTIONS_LIBRARY}"
135+
"INTERFACE_LINK_LIBRARIES" "Boost::boost"
136+
)
137+
endif()
138+
if(Boost_UNIT_TEST_FRAMEWORK_LIBRARY AND NOT TARGET Boost::unit_test_framework)
139+
add_library(Boost::unit_test_framework ${LIBRARY_TYPE} IMPORTED)
140+
set_target_properties(Boost::unit_test_framework PROPERTIES
141+
"IMPORTED_LOCATION" "${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}"
142+
"INTERFACE_LINK_LIBRARIES" "Boost::boost"
143+
)
144+
endif()
90145

91146
#
92147
# GTest
@@ -106,20 +161,35 @@ endif()
106161

107162
if(NOT CUKE_DISABLE_QT)
108163
find_package(Qt5Core)
164+
find_package(Qt5Gui)
109165
find_package(Qt5Widgets)
110166
find_package(Qt5Test)
111167

112-
if(${Qt5Core_FOUND} AND ${Qt5Widgets_FOUND} AND ${Qt5Test_FOUND})
168+
if(Qt5Core_FOUND AND Qt5Gui_FOUND AND Qt5Widgets_FOUND AND Qt5Test_FOUND)
113169
message(STATUS "Found Qt version: ${Qt5Core_VERSION_STRING}")
114-
set(QT_LIBRARIES Qt5::Core Qt5::Widgets Qt5::Test)
115-
if(NOT Qt5Core_VERSION_STRING VERSION_LESS 5.7 AND (NOT DEFINED CMAKE_CXX_STANDARD OR NOT CMAKE_CXX_STANDARD STREQUAL 98))
170+
if(NOT Qt5Core_VERSION_STRING VERSION_LESS 5.7 AND (NOT DEFINED CMAKE_CXX_STANDARD OR NOT CMAKE_CXX_STANDARD STREQUAL 98))
116171
message(STATUS "C++11 is needed from Qt version 5.7.0, building with c++11 enabled")
117172
set(CMAKE_CXX_STANDARD 11)
118173
endif()
174+
add_library(Qt::Core INTERFACE IMPORTED)
175+
add_library(Qt::Gui INTERFACE IMPORTED)
176+
add_library(Qt::Widgets INTERFACE IMPORTED)
177+
add_library(Qt::Test INTERFACE IMPORTED)
178+
set_target_properties(Qt::Core PROPERTIES INTERFACE_LINK_LIBRARIES Qt5::Core )
179+
set_target_properties(Qt::Gui PROPERTIES INTERFACE_LINK_LIBRARIES Qt5::Gui )
180+
set_target_properties(Qt::Widgets PROPERTIES INTERFACE_LINK_LIBRARIES Qt5::Widgets)
181+
set_target_properties(Qt::Test PROPERTIES INTERFACE_LINK_LIBRARIES Qt5::Test )
119182
else()
120183
find_package(Qt4 COMPONENTS QtCore QtGui QtTest)
121184
if(QT4_FOUND)
122-
set(QT_LIBRARIES Qt4::QtCore Qt4::QtGui Qt4::QtTest)
185+
add_library(Qt::Core INTERFACE IMPORTED)
186+
add_library(Qt::Gui INTERFACE IMPORTED)
187+
add_library(Qt::Widgets INTERFACE IMPORTED)
188+
add_library(Qt::Test INTERFACE IMPORTED)
189+
set_target_properties(Qt::Core PROPERTIES INTERFACE_LINK_LIBRARIES Qt4::QtCore)
190+
set_target_properties(Qt::Gui PROPERTIES INTERFACE_LINK_LIBRARIES Qt4::QtGui )
191+
set_target_properties(Qt::Widgets PROPERTIES INTERFACE_LINK_LIBRARIES Qt4::QtGui )
192+
set_target_properties(Qt::Test PROPERTIES INTERFACE_LINK_LIBRARIES Qt4::QtTest)
123193
include(${QT_USE_FILE})
124194
endif()
125195
endif()
@@ -177,8 +247,6 @@ endif()
177247
#
178248

179249
set(CUKE_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
180-
include_directories(${CUKE_INCLUDE_DIR})
181-
set(CUKE_LIBRARIES cucumber-cpp ${CUKE_EXTRA_LIBRARIES})
182250
add_subdirectory(3rdparty/json_spirit)
183251
add_subdirectory(src)
184252

@@ -208,10 +276,10 @@ else()
208276
add_executable(e2e-steps EXCLUDE_FROM_ALL ${CUKE_DYNAMIC_CPP_STEPS})
209277
# Mark this file as generated so it isn't required at CMake generation time (it is necessary when the target gets built though)
210278
set_source_files_properties(${CUKE_DYNAMIC_CPP_STEPS} PROPERTIES GENERATED TRUE)
211-
target_link_libraries(e2e-steps PRIVATE ${CUKE_LIBRARIES})
279+
target_link_libraries(e2e-steps PRIVATE cucumber-cpp)
212280
#Boost test lib required for boost specific scenario "Predicate Message"
213-
if(Boost_UNIT_TEST_FRAMEWORK_FOUND)
214-
target_link_libraries(e2e-steps PRIVATE ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
281+
if(TARGET Boost::unit_test_framework)
282+
target_link_libraries(e2e-steps PRIVATE Boost::unit_test_framework)
215283
else()
216284
set(CUKE_E2E_TAGS "--tags ~@boost")
217285
endif()
@@ -242,7 +310,6 @@ else()
242310
${CUKE_E2E_TAGS}
243311
${ARGN}
244312
${CUKE_FEATURES_DIR}
245-
DEPENDS cucumber-cpp
246313
${USES_TERMINAL}
247314
)
248315
endfunction(add_feature_target)

examples/Calc/CMakeLists.txt

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
11
project(Calc)
22

33
add_library(Calc src/Calculator)
4-
target_include_directories(Calc PUBLIC src)
4+
target_include_directories(Calc INTERFACE src)
55

66
if(TARGET GTest::GTest)
77
add_executable(GTestCalculatorSteps features/step_definitions/GTestCalculatorSteps)
8-
target_link_libraries(GTestCalculatorSteps Calc ${CUKE_LIBRARIES} GTest::GTest)
8+
target_link_libraries(GTestCalculatorSteps PRIVATE Calc cucumber-cpp GTest::GTest)
99

1010
list(FIND CMAKE_CXX_COMPILE_FEATURES cxx_variadic_templates HAS_VARIADIC_TEMPLATES)
1111
if(HAS_VARIADIC_TEMPLATES GREATER -1)
1212
add_executable(FuncArgsCalculatorSteps features/step_definitions/FuncArgsCalculatorSteps)
13-
target_link_libraries(FuncArgsCalculatorSteps Calc ${CUKE_LIBRARIES} GTest::GTest)
13+
target_link_libraries(FuncArgsCalculatorSteps PRIVATE Calc cucumber-cpp GTest::GTest)
1414

1515
target_compile_features(FuncArgsCalculatorSteps PRIVATE cxx_variadic_templates)
1616
endif()
1717
endif()
1818

19-
if(Boost_UNIT_TEST_FRAMEWORK_FOUND)
19+
if(TARGET Boost::unit_test_framework)
2020
add_executable(BoostCalculatorSteps features/step_definitions/BoostCalculatorSteps)
21-
target_link_libraries(BoostCalculatorSteps Calc ${CUKE_LIBRARIES} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
21+
target_link_libraries(BoostCalculatorSteps PRIVATE Calc cucumber-cpp Boost::unit_test_framework)
2222
endif()
2323

24-
if(Qt5TEST_FOUND)
24+
if(TARGET Qt::Test)
2525
add_executable(QtTestCalculatorSteps features/step_definitions/QtTestCalculatorSteps)
26-
target_link_libraries(QtTestCalculatorSteps Calc Qt5::Test ${CUKE_LIBRARIES})
26+
target_link_libraries(QtTestCalculatorSteps Calc Qt::Test cucumber-cpp)
2727
endif()

examples/CalcQt/CMakeLists.txt

+16-10
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,33 @@
11
project(CalcQt)
22

3-
if(QT_LIBRARIES)
3+
if(TARGET Qt::Core AND TARGET Qt::Gui AND TARGET Qt::Widgets AND TARGET Qt::Test)
44
add_library(libcalcqt src/CalculatorWidget.cpp src/CalculatorWidget.h)
55
set_target_properties(libcalcqt PROPERTIES AUTOMOC ON)
6-
target_include_directories(libcalcqt PUBLIC src)
7-
target_link_libraries(libcalcqt ${QT_LIBRARIES})
6+
target_include_directories(libcalcqt INTERFACE src)
7+
target_link_libraries(libcalcqt
8+
PUBLIC
9+
Qt::Core
10+
Qt::Widgets
11+
PRIVATE
12+
Qt::Gui
13+
)
814

915
add_executable(calcqt src/CalcQt.cpp)
10-
target_link_libraries(calcqt libcalcqt ${QT_LIBRARIES})
16+
target_link_libraries(calcqt PRIVATE libcalcqt Qt::Widgets)
1117

12-
if(Qt5TEST_FOUND)
18+
if(Qt::Test)
1319
add_executable(QtTestCalculatorQtSteps features/step_definitions/QtTestCalculatorQtSteps)
14-
target_link_libraries(QtTestCalculatorQtSteps PRIVATE libcalcqt ${QT_LIBRARIES} ${CUKE_LIBRARIES})
20+
target_link_libraries(QtTestCalculatorQtSteps PRIVATE libcalcqt Qt::Test cucumber-cpp)
1521
endif()
1622

17-
if(Boost_UNIT_TEST_FRAMEWORK_FOUND)
18-
add_executable(BoostCalculatorQtSteps features/step_definitions/BoostCalculatorQtSteps)
19-
target_link_libraries(BoostCalculatorQtSteps libcalcqt ${CUKE_LIBRARIES} ${QT_LIBRARIES} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
23+
if(TARGET Boost::unit_test_framework)
24+
add_executable(BoostCalculatorQtSteps features/step_definitions/BoostCalculatorQtSteps.cpp)
25+
target_link_libraries(BoostCalculatorQtSteps PRIVATE libcalcqt Boost::unit_test_framework cucumber-cpp Qt::Test)
2026
endif()
2127

2228
if(TARGET GTest::GTest)
2329
add_executable(GTestCalculatorQtSteps features/step_definitions/GTestCalculatorQtSteps)
24-
target_link_libraries(GTestCalculatorQtSteps libcalcqt ${CUKE_LIBRARIES} GTest::GTest ${QT_LIBRARIES})
30+
target_link_libraries(GTestCalculatorQtSteps PRIVATE libcalcqt cucumber-cpp GTest::GTest Qt::Test)
2531
endif()
2632

2733
endif()

examples/FeatureShowcase/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ project(FeatureShowcase)
33
if(TARGET GTest::GTest)
44
function(add_cucumber_executable)
55
add_executable(FeatureShowcaseSteps ${ARGV})
6-
target_link_libraries(FeatureShowcaseSteps ${CUKE_LIBRARIES} GTest::GTest)
6+
target_link_libraries(FeatureShowcaseSteps PRIVATE cucumber-cpp GTest::GTest)
77
foreach(_arg ${ARGN})
88
get_filename_component(OBJECT_PREFIX ${_arg} NAME_WE)
99
set_source_files_properties(${_arg} PROPERTIES COMPILE_FLAGS "-DCUKE_OBJECT_PREFIX=${OBJECT_PREFIX}")

src/CMakeLists.txt

+32-11
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,21 @@ set(CUKE_SOURCES
1515
connectors/wire/WireProtocolCommands.cpp
1616
)
1717

18-
set(CUKE_DEP_LIBRARIES json_spirit.header)
19-
2018
if(TARGET GTest::GTest)
21-
list(APPEND CUKE_DEP_LIBRARIES GTest::GTest)
19+
list(APPEND CUKE_EXTRA_PRIVATE_LIBRARIES GTest::GTest)
2220
list(APPEND CUKE_SOURCES drivers/GTestDriver.cpp)
2321
endif()
2422

25-
if(Boost_UNIT_TEST_FRAMEWORK_FOUND)
23+
if(TARGET Boost::unit_test_framework)
24+
list(APPEND CUKE_EXTRA_PRIVATE_LIBRARIES Boost::unit_test_framework)
2625
list(APPEND CUKE_SOURCES drivers/BoostDriver.cpp)
2726
endif()
2827

29-
if(Qt5TEST_FOUND)
28+
if(TARGET Qt::Test)
3029
qt5_wrap_cpp(MOC_FILE ../include/cucumber-cpp/internal/drivers/QtTestDriver.hpp)
3130
list(APPEND CUKE_SOURCES ${MOC_FILE})
3231
list(APPEND CUKE_SOURCES drivers/QtTestDriver.cpp)
33-
list(APPEND CUKE_DEP_LIBRARIES Qt5::Test)
32+
list(APPEND CUKE_EXTRA_PRIVATE_LIBRARIES Qt::Test)
3433
endif()
3534

3635
if(CMAKE_EXTRA_GENERATOR OR MSVC_IDE)
@@ -45,9 +44,31 @@ endif()
4544
add_library(cucumber-cpp-nomain STATIC ${CUKE_SOURCES})
4645
add_library(cucumber-cpp STATIC ${CUKE_SOURCES} main.cpp)
4746

48-
if(MINGW)
49-
list(APPEND CUKE_DEP_LIBRARIES ws2_32)
50-
endif(MINGW)
47+
foreach(TARGET
48+
cucumber-cpp-nomain
49+
cucumber-cpp
50+
)
51+
target_include_directories(${TARGET} PUBLIC ${CMAKE_SOURCE_DIR}/include)
52+
target_link_libraries(${TARGET}
53+
PUBLIC
54+
Boost::boost
55+
Boost::regex
56+
PRIVATE
57+
Boost::date_time
58+
Boost::filesystem
59+
Boost::thread
60+
json_spirit.header
61+
${CUKE_EXTRA_PRIVATE_LIBRARIES}
62+
)
63+
if(MINGW)
64+
target_link_libraries(${TARGET}
65+
PRIVATE
66+
ws2_32
67+
)
68+
endif(MINGW)
69+
endforeach()
5170

52-
target_link_libraries(cucumber-cpp-nomain PRIVATE ${CUKE_DEP_LIBRARIES})
53-
target_link_libraries(cucumber-cpp PRIVATE ${CUKE_DEP_LIBRARIES})
71+
target_link_libraries(cucumber-cpp
72+
PRIVATE
73+
Boost::program_options
74+
)

tests/CMakeLists.txt

+9-6
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ function(cuke_add_driver_test TEST_FILE)
22
get_filename_component(TEST_NAME ${TEST_FILE} NAME)
33
message(STATUS "Adding " ${TEST_NAME})
44
add_executable(${TEST_NAME} ${TEST_FILE}.cpp)
5-
target_link_libraries(${TEST_NAME} cucumber-cpp-nomain ${CUKE_EXTRA_LIBRARIES} ${ARGN})
5+
target_link_libraries(${TEST_NAME} PRIVATE cucumber-cpp-nomain ${ARGN})
66
add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME})
77
endfunction()
88

@@ -11,7 +11,7 @@ if(TARGET GMock::Main)
1111
get_filename_component(TEST_NAME ${TEST_FILE} NAME)
1212
message(STATUS "Adding " ${TEST_NAME})
1313
add_executable(${TEST_NAME} ${TEST_FILE}.cpp)
14-
target_link_libraries(${TEST_NAME} cucumber-cpp-nomain ${CUKE_EXTRA_LIBRARIES} ${ARGN} GMock::Main)
14+
target_link_libraries(${TEST_NAME} PRIVATE cucumber-cpp-nomain ${ARGN} GMock::Main)
1515
gtest_add_tests(${TEST_NAME} "" ${TEST_FILE}.cpp)
1616
# Run all tests in executable at once too. This ensures that the used fixtures get tested
1717
# properly too. Additionally gather the output in jUnit compatible output for CI.
@@ -46,12 +46,15 @@ if(TARGET GTest::Main)
4646
endif()
4747
endif()
4848

49-
if(Boost_UNIT_TEST_FRAMEWORK_FOUND)
50-
cuke_add_driver_test(integration/drivers/BoostDriverTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
49+
if(TARGET Boost::unit_test_framework)
50+
cuke_add_driver_test(integration/drivers/BoostDriverTest Boost::unit_test_framework)
5151
endif()
5252

53-
if(Qt5TEST_FOUND)
54-
cuke_add_driver_test(integration/drivers/QtTestDriverTest ${QT_LIBRARIES})
53+
if((TARGET Qt::Test)
54+
# FIXME: not including this in the test suite due to memory leak #190
55+
AND (NOT VALGRIND_TESTS)
56+
)
57+
cuke_add_driver_test(integration/drivers/QtTestDriverTest Qt::Test)
5558
endif()
5659

5760
cuke_add_driver_test(integration/drivers/GenericDriverTest)

0 commit comments

Comments
 (0)