-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFunctions.cmake
192 lines (170 loc) · 7.5 KB
/
Functions.cmake
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# MinecraftClone
# Copyright (C) © 2022 Petr Alexandrovich Sabanov
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
cmake_minimum_required(VERSION 3.24.2)
# VERSION 0.9.1
# TODO Windows and MacOS support
# Returns list of libraries in a variable with name stored in OUT_VAR.
# Has the following options:
# REQUIRED - if defined the function will produce en error, otherwise won't.
# QUIT - if defined the function will not message if a library not found, otherwise will.
function(find_libraries OUT_VAR)
set(options REQUIRED QUIET)
cmake_parse_arguments(OPTION "${options}" "" "" "${ARGN}")
list(REMOVE_ITEM ARGN ${options})
# making empty list
unset(LIBRARIES_LIST)
foreach(LIBRARY IN ITEMS ${ARGN})
# making a unique variable for every library just in case
set(${LIBRARY}_FOUND FALSE)
if(EXISTS ${LIBRARY})
# checking absolute or relative to project path
list(APPEND LIBRARIES_LIST ${LIBRARY})
set(${LIBRARY}_FOUND TRUE)
else()
# checking if pkg-config can find it
find_package(PkgConfig)
pkg_check_modules(LIB_${LIBRARY} QUIET ${LIBRARY})
if(DEFINED LIB_${LIBRARY}_LIBRARIES AND NOT LIB_${LIBRARY}_LIBRARIES STREQUAL "")
list(APPEND LIBRARIES_LIST ${LIB_${LIBRARY}_LIBRARIES})
set(${LIBRARY}_FOUND TRUE)
endif()
endif()
# library is found, no need to search further
if(${${LIBRARY}_FOUND} STREQUAL "TRUE")
continue()
endif()
# directories to search
set(LIBRARY_SEARCH_DIRECTORIES ${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES})
# searching in project and some other directories too
list(APPEND LIBRARY_SEARCH_DIRECTORIES
${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/lib ${PROJECT_SOURCE_DIR}/libs
${PROJECT_SOURCE_DIR}/library ${PROJECT_SOURCE_DIR}/libraries
${PROJECT_SOURCE_DIR}/l ${PROJECT_SOURCE_DIR}/L
${LIB_DIR} ${LIBS_DIR} ${LIBRARY_DIR} ${LIBRARIES_DIR}
${LIB_DIRECTORY} ${LIBS_DIRECTORY} ${LIBRARY_DIRECTORY} ${LIBRARIES_DIRECTORY}
${LIB_FOLDER} ${LIBS_FOLDER} ${LIBRARY_FOLDER} ${LIBRARIES_FOLDER})
# searching
foreach(LIB_DIR IN ITEMS ${LIBRARY_SEARCH_DIRECTORIES})
if(EXISTS ${LIB_DIR}/${LIBRARY})
list(APPEND LIBRARIES_LIST ${LIB_DIR}/${LIBRARY})
set(${LIBRARY}_FOUND TRUE)
elseif(EXISTS ${LIB_DIR}/${LIBRARY}.a)
list(APPEND LIBRARIES_LIST ${LIB_DIR}/${LIBRARY}.a)
set(${LIBRARY}_FOUND TRUE)
elseif(EXISTS ${LIB_DIR}/${LIBRARY}.so)
list(APPEND LIBRARIES_LIST ${LIB_DIR}/${LIBRARY}.so)
set(${LIBRARY}_FOUND TRUE)
elseif(EXISTS ${LIB_DIR}/lib${LIBRARY})
list(APPEND LIBRARIES_LIST ${LIB_DIR}/lib${LIBRARY})
set(${LIBRARY}_FOUND TRUE)
elseif(EXISTS ${LIB_DIR}/lib${LIBRARY}.a)
list(APPEND LIBRARIES_LIST ${LIB_DIR}/lib${LIBRARY}.a)
set(${LIBRARY}_FOUND TRUE)
elseif(EXISTS ${LIB_DIR}/lib${LIBRARY}.so)
list(APPEND LIBRARIES_LIST ${LIB_DIR}/lib${LIBRARY}.so)
set(${LIBRARY}_FOUND TRUE)
endif()
# library is found, no need to search further
if(${${LIBRARY}_FOUND} STREQUAL "TRUE")
break()
endif()
endforeach()
# library not found
if(NOT ${${LIBRARY}_FOUND} STREQUAL "TRUE")
if(${OPTION_REQUIRED} STREQUAL "TRUE")
message(FATAL_ERROR "Cannot find library ${LIBRARY}.")
elseif(${OPTION_QUIET} STREQUAL "FALSE")
message("find_libraries: Cannot find library ${LIBRARY}.")
endif()
endif()
endforeach()
# returning libraries list
set(${OUT_VAR} ${LIBRARIES_LIST} PARENT_SCOPE)
endfunction()
# Set include, source, test, resource and out directories.
# !!! CMAKE_ARCHIVE_OUTPUT_DIRECTORY must be set before this function !!!
# Creates variables in the parent scope:
# HEADER_DIR, HEADER_FILES - directory with header files, corresponding files list
# SOURCE_DIR, SOURCE_FILES - directory with .cpp (.cc) files, corresponding files list
# TEST_DIR, TEST_FILES - directory with test files, corresponding files list
# RESOURCE_DIR, RESOURCE_FILES - directory with resource files, corresponding files list
# INCLUDE_DIR, INCLUDE_FILES - directory with headers that this project includes, corresponding files list
# LIB_DIR, LIB_FILES - directory with library files, corresponding files list
# OUT_DIR - directory with compiler output
# OUT_DIR is used for all output directories of the compiler
function(set_project_directories HEADER_DIR SOURCE_DIR TEST_DIR RESOURCE_DIR INCLUDE_DIR LIB_DIR OUT_DIR)
include_directories(${HEADER_DIR} ${INCLUDE_DIR})
# index files
if(NOT HEADER_DIR STREQUAL "")
file(GLOB_RECURSE HEADER_FILES CONFIGURE_DEPENDS
${HEADER_DIR}/*.h ${HEADER_DIR}/*.hh ${HEADER_DIR}/*.hpp ${HEADER_DIR}/*.hxx)
endif()
if(NOT SOURCE_DIR STREQUAL "")
file(GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS
${SOURCE_DIR}/*.c ${SOURCE_DIR}/*.cc ${SOURCE_DIR}/*.cpp ${SOURCE_DIR}/*.cxx)
endif()
if(NOT TEST_DIR STREQUAL "")
file(GLOB_RECURSE TEST_FILES CONFIGURE_DEPENDS
${TEST_DIR}/*.c ${TEST_DIR}/*.cc ${TEST_DIR}/*.cpp ${TEST_DIR}/*.cxx
${TEST_DIR}/*.h ${TEST_DIR}/*.hh ${TEST_DIR}/*.hpp ${TEST_DIR}/*.hxx)
endif()
if(NOT RESOURCE_DIR STREQUAL "")
file(GLOB_RECURSE RESOURCE_FILES CONFIGURE_DEPENDS
${RESOURCE_DIR}/*)
endif()
if(NOT INCLUDE_DIR STREQUAL "")
file(GLOB_RECURSE INCLUDE_FILES CONFIGURE_DEPENDS
${INCLUDE_DIR}/*.h ${INCLUDE_DIR}/*.hh ${INCLUDE_DIR}/*.hpp ${INCLUDE_DIR}/*.hxx)
endif()
if(NOT LIB_DIR STREQUAL "")
file(GLOB_RECURSE LIB_FILES CONFIGURE_DEPENDS
${LIB_DIR}/*.a ${LIB_DIR}/*.so)
endif()
# set out directory and create it
set(OUT_DIR ${OUT_DIR} PARENT_SCOPE)
if(IS_ABSOLUTE ${OUT_DIR})
set(ABSOLUTE_OUT_DIR ${OUT_DIR})
else()
set(ABSOLUTE_OUT_DIR ${PROJECT_BINARY_DIR}/${OUT_DIR})
endif()
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${ABSOLUTE_OUT_DIR} PARENT_SCOPE)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${ABSOLUTE_OUT_DIR} PARENT_SCOPE)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${ABSOLUTE_OUT_DIR} PARENT_SCOPE)
set(CMAKE_PDB_OUTPUT_DIRECTORY ${ABSOLUTE_OUT_DIR} PARENT_SCOPE)
set(CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY ${ABSOLUTE_OUT_DIR} PARENT_SCOPE)
execute_process(COMMAND mkdir -p ${ABSOLUTE_OUT_DIR}/)
# set variables in the parent scope
set(HEADER_DIR ${HEADER_DIR} PARENT_SCOPE)
set(SOURCE_DIR ${SOURCE_DIR} PARENT_SCOPE)
set(TEST_DIR ${TEST_DIR} PARENT_SCOPE)
set(RESOURCE_DIR ${RESOURCE_DIR} PARENT_SCOPE)
set(INCLUDE_DIR ${INCLUDE_DIR} PARENT_SCOPE)
set(LIB_DIR ${LIB_DIR} PARENT_SCOPE)
set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE)
set(SOURCE_FILES ${SOURCE_FILES} PARENT_SCOPE)
set(TEST_FILES ${TEST_FILES} PARENT_SCOPE)
set(RESOURCE_FILES ${RESOURCE_FILES} PARENT_SCOPE)
set(INCLUDE_FILES ${INCLUDE_FILES} PARENT_SCOPE)
set(LIB_FILES ${LIB_FILES} PARENT_SCOPE)
endfunction()
# Adds `strip` command for the executable
function(add_strip_command EXECUTABLE_NAME EXECUTABLE_PATH)
cmake_parse_arguments(STRIP "" "" "OPTIONS" ${ARGN})
add_custom_command(TARGET ${EXECUTABLE_NAME} POST_BUILD
COMMAND strip ${STRIP_OPTIONS} ${EXECUTABLE_PATH}
COMMENT "Stripping executable: ${EXECUTABLE_NAME}")
endfunction()