summaryrefslogtreecommitdiff
path: root/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake
blob: e82b05fd89788af10adcdd233c28f2bb79fb7eaa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
cmake_minimum_required(VERSION 3.12)

project(FindPkgConfig_IMPORTED_TARGET C)

find_package(PkgConfig REQUIRED)
pkg_check_modules(NCURSES IMPORTED_TARGET QUIET ncurses)

message(STATUS "source: ${CMAKE_CURRENT_SOURCE_DIR} bin ${CMAKE_CURRENT_BINARY_DIR}")

if (NCURSES_FOUND)
  set(tgt PkgConfig::NCURSES)
  if (NOT TARGET ${tgt})
    message(FATAL_ERROR "FindPkgConfig found ncurses, but did not create an imported target for it")
  endif ()
  set(prop_found FALSE)
  foreach (prop IN ITEMS INTERFACE_INCLUDE_DIRECTORIES INTERFACE_LINK_LIBRARIES INTERFACE_COMPILE_OPTIONS)
    get_target_property(value ${tgt} ${prop})
    if (value)
      message(STATUS "Found property ${prop} on target: ${value}")
      set(prop_found TRUE)
    endif ()
  endforeach ()
  if (NOT prop_found)
    message(FATAL_ERROR "target ${tgt} found, but it has no properties")
  endif ()
else ()
  message(STATUS "skipping test; ncurses not found")
endif ()


# Setup for the remaining package tests below
set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH)
set(fakePkgDir ${CMAKE_CURRENT_BINARY_DIR}/pc-fakepackage)
foreach(i 1 2)
  set(pname cmakeinternalfakepackage${i})
  file(WRITE ${fakePkgDir}/lib/lib${pname}.a "")
  file(WRITE ${fakePkgDir}/lib/${pname}.lib  "")
  file(WRITE ${fakePkgDir}/lib/pkgconfig/${pname}.pc
"Name: CMakeInternalFakePackage${i}
Description: Dummy package (${i}) for FindPkgConfig IMPORTED_TARGET test
Version: 1.2.3
Libs: -l${pname}
")
endforeach()

# Always find the .pc file in the calls further below so that we can test that
# the import target find_library() calls handle the NO...PATH options correctly
set(ENV{PKG_CONFIG_PATH} ${fakePkgDir}/lib/pkgconfig)

# Confirm correct behavior of NO_CMAKE_PATH, ensuring we only find the library
# for the imported target if we have both set CMAKE_PREFIX_PATH and have not
# given the NO_CMAKE_PATH option
unset(CMAKE_PREFIX_PATH)
unset(ENV{CMAKE_PREFIX_PATH})
pkg_check_modules(FakePackage1 QUIET IMPORTED_TARGET cmakeinternalfakepackage1)
if (TARGET PkgConfig::FakePackage1)
  message(FATAL_ERROR "Have import target for fake package 1 with no path prefix")
endif()

set(CMAKE_PREFIX_PATH ${fakePkgDir})
pkg_check_modules(FakePackage1 QUIET IMPORTED_TARGET NO_CMAKE_PATH cmakeinternalfakepackage1)
if (TARGET PkgConfig::FakePackage1)
  message(FATAL_ERROR "Have import target for fake package 1 with ignored cmake path")
endif()

pkg_check_modules(FakePackage1 REQUIRED QUIET IMPORTED_TARGET cmakeinternalfakepackage1)
if (NOT TARGET PkgConfig::FakePackage1)
  message(FATAL_ERROR "No import target for fake package 1 with prefix path")
endif()

# find targets in subdir and check their visibility
add_subdirectory(target_subdir)
if (TARGET PkgConfig::FakePackage1_dir)
  message(FATAL_ERROR "imported target PkgConfig::FakePackage1_dir is visible outside it's directory")
endif()

if (NOT TARGET PkgConfig::FakePackage1_global)
  message(FATAL_ERROR "imported target PkgConfig::FakePackage1_global is not visible outside it's directory")
endif()

# And now do the same for the NO_CMAKE_ENVIRONMENT_PATH - ENV{CMAKE_PREFIX_PATH}
# combination
unset(CMAKE_PREFIX_PATH)
unset(ENV{CMAKE_PREFIX_PATH})
pkg_check_modules(FakePackage2 QUIET IMPORTED_TARGET cmakeinternalfakepackage2)
if (TARGET PkgConfig::FakePackage2)
  message(FATAL_ERROR "Have import target for fake package 2 with no path prefix")
endif()

set(ENV{CMAKE_PREFIX_PATH} ${fakePkgDir})
pkg_check_modules(FakePackage2 QUIET IMPORTED_TARGET NO_CMAKE_ENVIRONMENT_PATH cmakeinternalfakepackage2)
if (TARGET PkgConfig::FakePackage2)
  message(FATAL_ERROR "Have import target for fake package 2 with ignored cmake path")
endif()

pkg_check_modules(FakePackage2 REQUIRED QUIET IMPORTED_TARGET cmakeinternalfakepackage2)
if (NOT TARGET PkgConfig::FakePackage2)
  message(FATAL_ERROR "No import target for fake package 2 with prefix path")
endif()

# check that the full library path is also returned
if (NOT FakePackage2_LINK_LIBRARIES STREQUAL "${fakePkgDir}/lib/libcmakeinternalfakepackage2.a")
  message(FATAL_ERROR "FakePackage2_LINK_LIBRARIES has bad content on first run: ${FakePackage2_LINK_LIBRARIES}")
endif()

# the information in *_LINK_LIBRARIES is not cached, so ensure is also is present on second run
unset(FakePackage2_LINK_LIBRARIES)
pkg_check_modules(FakePackage2 REQUIRED QUIET IMPORTED_TARGET cmakeinternalfakepackage2)
if (NOT FakePackage2_LINK_LIBRARIES STREQUAL "${fakePkgDir}/lib/libcmakeinternalfakepackage2.a")
  message(FATAL_ERROR "FakePackage2_LINK_LIBRARIES has bad content on second run: ${FakePackage2_LINK_LIBRARIES}")
endif()

set(pname fakelinkoptionspackage)
file(WRITE ${fakePkgDir}/lib/pkgconfig/${pname}.pc
"Name: FakeLinkOptionsPackage
Description: Dummy package for FindPkgConfig IMPORTED_TARGET INTERFACE_LINK_OPTIONS test
Version: 1.2.3
Libs: -e dummy_main
")

set(expected_link_options -e dummy_main)
pkg_check_modules(FakeLinkOptionsPackage REQUIRED QUIET IMPORTED_TARGET fakelinkoptionspackage)
if (NOT TARGET PkgConfig::FakeLinkOptionsPackage)
  message(FATAL_ERROR "No import target for fake link options package")
endif()
get_target_property(link_options PkgConfig::FakeLinkOptionsPackage INTERFACE_LINK_OPTIONS)
if (NOT link_options STREQUAL expected_link_options)
  message(FATAL_ERROR
    "Additional link options not present in INTERFACE_LINK_OPTIONS property"
    "expected: \"${expected_link_options}\", but got \"${link_options}\""
  )
endif()