summaryrefslogtreecommitdiff
path: root/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake
blob: 69ab4da000f4918798ab8867e3ca04c3f351a089 (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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
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} -l${pname}-doesnotexist
")
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)

# find targets in subdir and check their visibility
add_subdirectory(target_subdir)

set(tgt PkgConfig::FakePackage1_dir)
if (TARGET ${tgt})
  message(FATAL_ERROR "imported target \"${tgt}\" is visible outside its directory")
endif()

set(tgt PkgConfig::FakePackage1_global)
if (NOT TARGET ${tgt})
  message(FATAL_ERROR "imported target \"${tgt}\" is not visible outside its 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})
set(ENV{CMAKE_PREFIX_PATH} ${fakePkgDir})

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 2 library entries exist
list(LENGTH FakePackage2_LINK_LIBRARIES fp2_nlibs)
if (NOT fp2_nlibs EQUAL 2)
  message(FATAL_ERROR "FakePackage2_LINK_LIBRARIES has ${fp2_nlibs} entries but should have exactly 2")
endif()

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

# check that the library that couldn't be found still shows up
list(GET FakePackage2_LINK_LIBRARIES 1 fp2_lib1)
if (NOT fp2_lib1 STREQUAL "cmakeinternalfakepackage2-doesnotexist")
  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;cmakeinternalfakepackage2-doesnotexist")
  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
Cflags: -I/special -isystem /other -isystem/more -DA-isystem/foo
")

set(expected_link_options -e dummy_main)
pkg_check_modules(FakeLinkOptionsPackage REQUIRED QUIET IMPORTED_TARGET fakelinkoptionspackage)

set(tgt PkgConfig::FakeLinkOptionsPackage)
message(STATUS "Verifying target \"${tgt}\"")
if (NOT TARGET ${tgt})
  message(FATAL_ERROR "No import target for fake link options package")
endif()

# Some versions of pkg-config on Windows don't parse the Libs and Cflags
# correctly. The pkg-config that comes with Strawberry perl is one example.
# It appears to treat the dummymain part of Libs as a library and only returns
# -e. It also doesn't recognize "-isystem /other", presumably because it doesn't
# support having a space between "-isystem" and the directory after it (it does
# give us the "-isystem/more" flag). Since we can't reliably test for these,
# we don't enable these checks on Windows.
if(NOT WIN32)
  get_target_property(link_options ${tgt} INTERFACE_LINK_OPTIONS)
  if (NOT link_options STREQUAL expected_link_options)
    message(FATAL_ERROR
      "Additional link options not present in INTERFACE_LINK_OPTIONS property\n"
      "expected: \"${expected_link_options}\", but got \"${link_options}\""
    )
  endif()

  get_target_property(inc_dirs ${tgt} INTERFACE_INCLUDE_DIRECTORIES)
  set(expected_inc_dirs "/special" "/other" "/more")

  if (NOT inc_dirs STREQUAL expected_inc_dirs)
    message(FATAL_ERROR
      "Additional include directories not correctly present in INTERFACE_INCLUDE_DIRECTORIES property\n"
      "expected: \"${expected_inc_dirs}\", got \"${inc_dirs}\""
    )
  endif ()
endif()

get_target_property(c_opts ${tgt} INTERFACE_COMPILE_OPTIONS)
set(expected_c_opts "-DA-isystem/foo") # this is an invalid option, but a good testcase
if (NOT c_opts STREQUAL expected_c_opts)
    message(FATAL_ERROR
      "Additional compile options not present in INTERFACE_COMPILE_OPTIONS property\n"
      "expected: \"${expected_c_opts}\", got \"${c_opts}\""
    )
endif ()