forked from andlabs/libui
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CMakeLists.txt
237 lines (214 loc) · 7.44 KB
/
CMakeLists.txt
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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# 3 june 2016
# see https://cmake.org/gitweb?p=cmake.git;a=commit;h=95cdf132489c79e88a10fdf7a7566fa002c7680b (thanks ngladitz in irc.freenode.net/#cmake)
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
# TODOs
# - silence entering/leaving messages?
# - uname -s for more refined OS control
# - Haiku for haiku
# - debian DESTDIR? https://github.com/andlabs/libui/pull/10
# - libui-combined* needs to be deleted so that custom command can run every time
# - add notelemetry.obj to *ALL TARGETS* on VS2015 and up - https://www.infoq.com/news/2016/06/visual-cpp-telemetry
# - switch to 3.1.0 features
# the docs say we need to set this up prior to project()
# the docs don't say this, but the CACHE part is important; see https://stackoverflow.com/questions/34208360/cmake-seems-to-ignore-cmake-osx-deployment-target
# TODO figure out what other variables must be set with CACHE
# TODO figure out if FORCE is needed here
# TODO figure out whether STRING "" is best or if something else is better; also what FORCE does because I forget and later I say it's needed
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.8" CACHE STRING "" FORCE)
# we want to disable incremental linking
# see also:
# - https://github.com/bulletphysics/bullet3/blob/master/CMakeLists.txt#L43
# - https://cmake.org/pipermail/cmake/2010-February/035174.html
# this must also go before project()
set(MSVC_INCREMENTAL_DEFAULT ON)
# default to debug builds
# do this before project() just to be safe
# either DEBUG or Debug will work; we use DEBUG as that's what cmake does internally (https://cmake.org/pipermail/cmake/2013-June/055177.html)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE DEBUG CACHE STRING "" FORCE)
endif()
project(libui)
option(BUILD_SHARED_LIBS "Whether to build libui as a shared library or a static library" ON)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/out")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/out")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/out")
set(CMAKE_PDB_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/out")
if(APPLE)
set(_OSNAME darwin)
set(_HASVERSION TRUE)
set(_VERSION "A")
# always use our rpath
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
# the / is required by some older versions of OS X
set(CMAKE_INSTALL_RPATH "@executable_path/")
set(CMAKE_MACOSX_RPATH TRUE)
elseif(WIN32)
set(_OSNAME windows)
# and don't include the default libraries with ANY of the builds
# note the CACHE FORCE stuff is required here
set(CMAKE_C_STANDARD_LIBRARIES CACHE STRING "" FORCE)
set(CMAKE_CXX_STANDARD_LIBRARIES CACHE STRING "" FORCE)
else()
set(_OSNAME unix)
set(_HASVERSION TRUE)
set(_VERSION "0")
# always use our rpath
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
set(CMAKE_INSTALL_RPATH "\$ORIGIN")
endif()
# common flags
if(MSVC)
# TODO subsystem version
# TODO /Wall does too much
# TODO -Wno-switch equivalent
# TODO /sdl turns C4996 into an ERROR
# don't use /analyze; that requires us to write annotations everywhere
# TODO undecided flags from qo?
# the RTC flags are only supplied in debug builds because they are only supposed to be used by debug builds (see "This is because run-time error checks are not valid in a release (optimized) build." in https://docs.microsoft.com/cpp/build/reference/rtc-run-time-error-checks)
# /RTCc is not supplied because it's discouraged as of VS2015; see https://www.reddit.com/r/cpp/comments/46mhne/rtcc_rejects_conformant_code_with_visual_c_2015/d06auq5
# /EHsc is to shut the compiler up in some cases
# TODO make /EHsc C++-only
set(_COMMON_CFLAGS
/W4 /wd4100
/bigobj /nologo
$<$<CONFIG:Debug>:/RTC1 /RTCs /RTCu>
/EHsc
)
# note the /MANIFEST:NO (which must be / and uppercase); thanks FraGag (https://github.com/andlabs/libui/issues/93#issuecomment-223183436)
# TODO warnings on undefined symbols
set(_COMMON_LDFLAGS
/LARGEADDRESSAWARE
/NOLOGO
/INCREMENTAL:NO
/MANIFEST:NO
)
# TODO autogenerate a .def file?
# more incremental linking fixes
# TODO actually get rid of incremental linking here
else()
set(_COMMON_CFLAGS
-Wall -Wextra -pedantic
-Wno-unused-parameter
-Wno-switch
-fvisibility=hidden
)
# don't use C_VERSION or CXX_VERSION because they use GNU standards
# TODO we can actually do this; set both C_EXTENSIONS and CXX_EXTENSIONS to OFF
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --std=c99")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++11")
set(_COMMON_LDFLAGS
-fvisibility=hidden
)
# don't require shipping the MinGW-w64 DLLs
if(WIN32)
list(APPEND _COMMON_LDFLAGS
-static
-static-libgcc
-static-libstdc++
)
endif()
# TODO document this
if(ADDRESS_SANITIZER)
set(_COMMON_CFLAGS ${_COMMON_CFLAGS}
-fsanitize=address
-fno-omit-frame-pointer
)
set(_COMMON_LDFLAGS ${_COMMON_LDFLAGS}
-fsanitize=address
-fno-omit-frame-pointer
)
endif()
endif()
# problem:
# - target_link_libraries() only supports - for flags
# - but cmake only doesn't generate the manifest if the flag has a /
macro(_target_link_options_private _target)
foreach(_opt IN LISTS ${ARGN})
set_property(TARGET ${_target} APPEND_STRING PROPERTY
LINK_FLAGS " ${_opt}")
endforeach()
endmacro()
add_subdirectory("common")
add_subdirectory("${_OSNAME}")
add_library(libui ${_LIBUI_SOURCES})
target_include_directories(libui
PUBLIC .
PRIVATE ${_LIBUI_INCLUEDIRS})
target_compile_definitions(libui
PRIVATE ${_LIBUI_DEFS})
# cmake produces this for us by default but only for shared libraries
target_compile_definitions(libui
PRIVATE libui_EXPORTS)
target_compile_options(libui
PUBLIC ${_COMMON_CFLAGS}
PRIVATE ${_LIBUI_CFLAGS})
# TODO link directories?
if(BUILD_SHARED_LIBS)
target_link_libraries(libui
PRIVATE ${_LIBUI_LIBS})
endif()
# TODO INTERFACE libs don't inherit to grandhcildren?
# on Windows the linker for static libraries is different; don't give it the flags
if(BUILD_SHARED_LIBS)
_target_link_options_private(libui
_COMMON_LDFLAGS
_LIBUI_LDFLAGS)
endif()
if(NOT BUILD_SHARED_LIBS)
# TODO figure out a way to tell libui that it's static
target_compile_definitions(libui
PUBLIC _UI_STATIC)
endif()
if(NOT MSVC)
# on non-MSVC compilers cmake adds an extra lib-
# note that we apply this to libui, not to any intermediates
set_target_properties(libui PROPERTIES
OUTPUT_NAME ui)
# flags for warning on undefined symbols
# TODO figure out why FreeBSD follows linked libraries here
# TODO figure out MSVC equivalents
if(BUILD_SHARED_LIBS)
if(NOT (${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD))
# on OS X we don't need to do this; Apple's linker warns about undefined symbols in -shared builds!
if(NOT APPLE)
target_link_libraries(libui
PRIVATE -Wl,--no-undefined -Wl,--no-allow-shlib-undefined
)
endif()
endif()
endif()
endif()
if(BUILD_SHARED_LIBS)
if(_HASVERSION)
set_target_properties(libui PROPERTIES
SOVERSION "${_VERSION}")
endif()
endif()
macro(_add_exec _name)
# TODOTODO re-add WIN32 when merging back
add_executable(${_name}
EXCLUDE_FROM_ALL
${ARGN})
target_link_libraries(${_name} libui)
_target_link_options_private(${_name}
_COMMON_LDFLAGS)
# make shared-linked executables PIC too
if(BUILD_SHARED_LIBS)
set_property(TARGET ${_name} PROPERTY
POSITION_INDEPENDENT_CODE True)
endif()
# TODO see above about INTERFACE
if(NOT BUILD_SHARED_LIBS)
target_link_libraries(${_name}
${_LIBUI_LIBS})
endif()
# TODOfor some reason these don't propagate
if(NOT WIN32)
target_include_directories(${_name}
PUBLIC .)
target_compile_options(${_name}
PUBLIC ${_COMMON_CFLAGS})
endif()
endmacro()
add_subdirectory("test")
add_subdirectory("examples")