Skip to content

Commit f59c009

Browse files
author
Anton Pantyukhin
committed
Do not overload 'find_package' because this is undocumented CMake feature
1 parent 2c3ccb6 commit f59c009

File tree

5 files changed

+48
-40
lines changed

5 files changed

+48
-40
lines changed

CMakeLists.txt

Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,42 +4,38 @@ project(mylib
44
DESCRIPTION "Template for C++ library built with CMake"
55
LANGUAGES CXX)
66

7+
include(cmake/utils.cmake)
8+
set_project_is_top_level()
9+
10+
add_library(mylib) # initialized below
11+
add_library(mylib::mylib ALIAS mylib)
12+
713
#----------------------------------------------------------------------------------------------------------------------
814
# general settings and options
915
#----------------------------------------------------------------------------------------------------------------------
1016

11-
include(cmake/utils.cmake)
1217
include(GNUInstallDirs)
1318

14-
string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}" is_top_level)
15-
1619
# MYLIB_SHARED_LIBS option (undefined by default) can be used to force shared/static build
1720
option(MYLIB_BUILD_TESTS "Build mylib tests" OFF)
1821
option(MYLIB_BUILD_EXAMPLES "Build mylib examples" OFF)
1922
option(MYLIB_BUILD_DOCS "Build mylib documentation" OFF)
20-
option(MYLIB_INSTALL "Generate target for installing mylib" ${is_top_level})
23+
option(MYLIB_INSTALL "Generate target for installing mylib" ${PROJECT_IS_TOP_LEVEL})
24+
set_if_undefined(MYLIB_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/mylib-${PROJECT_VERSION}" CACHE
25+
STRING "Install path for mylib package-related CMake files")
26+
27+
if(DEFINED MYLIB_SHARED_LIBS)
28+
set(BUILD_SHARED_LIBS ${MYLIB_SHARED_LIBS})
29+
endif()
2130

2231
if(NOT DEFINED CMAKE_BUILD_TYPE AND NOT DEFINED CMAKE_CONFIGURATION_TYPES)
2332
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
2433
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
2534
endif()
2635

27-
if(DEFINED MYLIB_SHARED_LIBS)
28-
set(BUILD_SHARED_LIBS ${MYLIB_SHARED_LIBS})
29-
endif()
30-
3136
set_if_undefined(CMAKE_CXX_VISIBILITY_PRESET hidden)
3237
set_if_undefined(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
3338

34-
set_if_undefined(MYLIB_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/mylib-${PROJECT_VERSION}" CACHE
35-
STRING "Install path for mylib package-related CMake files")
36-
37-
add_library(mylib) # initialized below
38-
add_library(mylib::mylib ALIAS mylib)
39-
40-
# make 'find_package(mylib)' do nothing in subprojects because target is already defined
41-
list(APPEND defined_targets mylib)
42-
4339
#----------------------------------------------------------------------------------------------------------------------
4440
# mylib dependencies
4541
#----------------------------------------------------------------------------------------------------------------------
@@ -105,15 +101,15 @@ if(MYLIB_INSTALL AND NOT CMAKE_SKIP_INSTALL_RULES)
105101
ARCHIVE COMPONENT mylib-dev
106102
PUBLIC_HEADER COMPONENT mylib-dev DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/mylib")
107103

108-
set(export_file "mylib-shared-export.cmake")
104+
set(targets_file "mylib-shared-targets.cmake")
109105

110106
if(NOT BUILD_SHARED_LIBS)
111-
set(export_file "mylib-static-export.cmake")
107+
set(targets_file "mylib-static-targets.cmake")
112108
endif()
113109

114110
install(EXPORT mylib_export
115111
COMPONENT mylib-dev
116-
FILE "${export_file}"
112+
FILE "${targets_file}"
117113
DESTINATION "${MYLIB_INSTALL_CMAKEDIR}"
118114
NAMESPACE mylib::)
119115

@@ -148,17 +144,8 @@ endif()
148144
# other targets
149145
#----------------------------------------------------------------------------------------------------------------------
150146

151-
# makes 'find_package' skip search for already defined targets in subdirectories
152-
macro(find_package)
153-
string(TOLOWER "${ARG0}" name)
154-
155-
if(NOT ${name} IN_LIST ${defined_targets})
156-
_find_package(${ARGV})
157-
endif()
158-
endmacro()
159-
160147
if(MYLIB_BUILD_TESTS)
161-
if(${is_top_level})
148+
if(PROJECT_IS_TOP_LEVEL)
162149
enable_testing()
163150
endif()
164151

cmake/mylib-config.cmake.in

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@
2020
@PACKAGE_INIT@
2121

2222
macro(import_targets type)
23-
if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/mylib-${type}-export.cmake")
23+
if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/mylib-${type}-targets.cmake")
2424
set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "mylib ${type} libraries were requested but not found")
2525
set(${CMAKE_FIND_PACKAGE_NAME}_FOUND OFF)
2626
return()
2727
endif()
2828

29-
include("${CMAKE_CURRENT_LIST_DIR}/mylib-${type}-export.cmake")
29+
include("${CMAKE_CURRENT_LIST_DIR}/mylib-${type}-targets.cmake")
3030
endmacro()
3131

3232
if(NOT TARGET mylib::mylib)
@@ -38,9 +38,9 @@ if(NOT TARGET mylib::mylib)
3838
else()
3939
set(type "static")
4040
endif()
41-
elseif(BUILD_SHARED_LIBS AND EXISTS "${CMAKE_CURRENT_LIST_DIR}/mylib-shared-export.cmake")
41+
elseif(BUILD_SHARED_LIBS AND EXISTS "${CMAKE_CURRENT_LIST_DIR}/mylib-shared-targets.cmake")
4242
set(type "shared")
43-
elseif(EXISTS "${CMAKE_CURRENT_LIST_DIR}/mylib-static-export.cmake")
43+
elseif(EXISTS "${CMAKE_CURRENT_LIST_DIR}/mylib-static-targets.cmake")
4444
set(type "static")
4545
else()
4646
set(type "shared")

cmake/utils.cmake

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,19 @@ macro(set_if_undefined variable)
77
endif()
88
endmacro()
99

10+
# set_project_is_top_level()
11+
#
12+
# Sets variable PROJECT_IS_TOP_LEVEL for older CMake versions.
13+
macro(set_project_is_top_level)
14+
if(NOT DEFINED PROJECT_IS_TOP_LEVEL)
15+
if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
16+
set(PROJECT_IS_TOP_LEVEL YES)
17+
else()
18+
set(PROJECT_IS_TOP_LEVEL NO)
19+
endif()
20+
endif()
21+
endmacro()
22+
1023
# win_copy_deps_to_target_dir(<target> [<target-dep>]...)
1124
#
1225
# Creates custom command to copy runtime dependencies to target's directory after building the target.
@@ -15,7 +28,9 @@ endmacro()
1528
# On CMake 3.21 or newer, function uses TARGET_RUNTIME_DLLS generator expression to obtain list of runtime
1629
# dependencies. Specified dependencies (if any) are still used to find and copy PDB files for debug builds.
1730
function(win_copy_deps_to_target_dir target)
18-
if(NOT WIN32 OR "${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
31+
set_project_is_top_level()
32+
33+
if(NOT WIN32 OR PROJECT_IS_TOP_LEVEL)
1934
return()
2035
endif()
2136

examples/add/CMakeLists.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
cmake_minimum_required(VERSION 3.14)
22
project(mylib-add LANGUAGES CXX)
3+
34
include("../../cmake/utils.cmake")
5+
set_project_is_top_level()
46

5-
find_package(mylib REQUIRED)
7+
if(PROJECT_IS_TOP_LEVEL)
8+
find_package(mylib REQUIRED)
9+
endif()
610

711
set(sources main.cpp)
812
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" FILES ${sources})

tests/CMakeLists.txt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
cmake_minimum_required(VERSION 3.14)
22
project(mylib-tests)
3+
34
include("../cmake/utils.cmake")
5+
set_project_is_top_level()
46

57
#----------------------------------------------------------------------------------------------------------------------
68
# general settings and options
79
#----------------------------------------------------------------------------------------------------------------------
810

9-
string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}" is_top_level)
10-
11-
if(is_top_level)
11+
if(PROJECT_IS_TOP_LEVEL)
1212
enable_testing()
1313
endif()
1414

@@ -32,7 +32,9 @@ FetchContent_MakeAvailable(googletest)
3232
# tests dependencies
3333
#----------------------------------------------------------------------------------------------------------------------
3434

35-
find_package(mylib REQUIRED)
35+
if(PROJECT_IS_TOP_LEVEL)
36+
find_package(mylib REQUIRED)
37+
endif()
3638

3739
#----------------------------------------------------------------------------------------------------------------------
3840
# tests sources

0 commit comments

Comments
 (0)