File: Common.cmake

package info (click to toggle)
allegro5 2%3A5.2.11.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 11,160 kB
  • sloc: ansic: 111,580; cpp: 12,589; objc: 4,605; java: 2,845; python: 2,715; javascript: 1,238; sh: 1,008; makefile: 41; xml: 25; pascal: 24
file content (422 lines) | stat: -rw-r--r-- 15,915 bytes parent folder | download
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
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
function(set_our_header_properties)
    foreach(file ${ARGN})
        # Infer which subdirectory this header file should be installed.
        set(loc ${file})
        string(REPLACE "${CMAKE_CURRENT_BINARY_DIR}/" "" loc ${loc})
        string(REGEX REPLACE "^include/" "" loc ${loc})
        string(REGEX REPLACE "/[-A-Za-z0-9_]+[.](h|inl)$" "" loc ${loc})
        string(REGEX REPLACE "^addons/[^/]+/" "" loc ${loc})

        # If we have inferred correctly then it should be under allegro5.
        string(REGEX MATCH "^allegro5" matched ${loc})
        if(matched STREQUAL "allegro5")
            # MACOSX_PACKAGE_LOCATION is also used in install_our_headers.
            set_source_files_properties(${file}
                PROPERTIES
                MACOSX_PACKAGE_LOCATION Headers/${loc}
                )
        else()
            message(FATAL_ERROR "Could not infer where to install ${file}")
        endif()
    endforeach(file)
endfunction(set_our_header_properties)

# Normally CMake caches the "failure" result of a compile test, preventing it
# from re-running. These helpers delete the cache variable on failure so that
# CMake will try again next time.
function(run_c_compile_test source var)
    check_c_source_compiles("${source}" ${var})
    if (NOT ${var})
        unset(${var} CACHE)
    endif(NOT ${var})
endfunction(run_c_compile_test)

function(run_cxx_compile_test source var)
    check_cxx_source_compiles("${source}" ${var})
    if (NOT ${var})
        unset(${var} CACHE)
    endif(NOT ${var})
endfunction(run_cxx_compile_test)

function(append_lib_type_suffix var)
    string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_TOLOWER)
    if(CMAKE_BUILD_TYPE_TOLOWER STREQUAL "debug")
        set(${var} "${${var}}-debug" PARENT_SCOPE)
    endif(CMAKE_BUILD_TYPE_TOLOWER STREQUAL "debug")
    if(CMAKE_BUILD_TYPE_TOLOWER MATCHES "profile")
        set(${var} "${${var}}-profile" PARENT_SCOPE)
    endif(CMAKE_BUILD_TYPE_TOLOWER MATCHES "profile")
endfunction(append_lib_type_suffix)

function(append_lib_linkage_suffix var)
    if(NOT BUILD_SHARED_LIBS)
        set(${var} "${${var}}-static" PARENT_SCOPE)
    endif(NOT BUILD_SHARED_LIBS)
endfunction(append_lib_linkage_suffix)

# Oh my. CMake really is bad for this - but I couldn't find a better
# way.
function(sanitize_cmake_link_flags ...)
    set(return)
    foreach(lib ${ARGV})
        # Watch out for -framework options (OS X)
        if(NOT lib MATCHES "-framework.*" AND NOT lib MATCHES ".*framework")
            # Remove absolute path.
            string(REGEX REPLACE "/.*/(.*)" "\\1" lib ${lib})

            # Remove .a/.so/.dylib.
            string(REGEX REPLACE "lib(.*)\\.a" "\\1" lib ${lib})
            string(REGEX REPLACE "lib(.*)\\.so" "\\1" lib ${lib})
            string(REGEX REPLACE "lib(.*)\\.dylib" "\\1" lib ${lib})

            # Remove -l prefix if it's there already.
            string(REGEX REPLACE "-l(.*)" "\\1" lib ${lib})

            # Make sure we don't include our own libraries.
            # FIXME: Use a global list instead of a very unstable regexp.
            if(NOT lib MATCHES "allegro_.*" AND NOT lib STREQUAL "allegro" AND NOT lib STREQUAL "allegro_audio")
                set(return "${return} -l${lib}")
            endif()
        endif(NOT lib MATCHES "-framework.*" AND NOT lib MATCHES ".*framework")
    endforeach(lib)
    set(return ${return} PARENT_SCOPE)
endfunction(sanitize_cmake_link_flags)

function(add_our_library target framework_name sources extra_flags link_with)
    # BUILD_SHARED_LIBS controls whether this is a shared or static library.
    add_library(${target} ${sources})
    target_include_directories(${target} INTERFACE $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
    list(APPEND ALLEGRO_TARGETS "${target}")
    list(REMOVE_DUPLICATES ALLEGRO_TARGETS)
    set(ALLEGRO_TARGETS "${ALLEGRO_TARGETS}" CACHE INTERNAL "internal")

    if(MSVC)
        # Compile with multiple processors
        set(extra_flags "${extra_flags} /MP")
        if(WANT_STATIC_RUNTIME)
            if(CMAKE_BUILD_TYPE STREQUAL Debug)
                set(extra_flags "${extra_flags} /MTd")
            else()
                set(extra_flags "${extra_flags} /MT")
            endif()
            if (NOT BUILD_SHARED_LIBS)
                # /Zl instructs MSVC to not mention the CRT used at all,
                # allowing the static libraries to be combined with any CRT version
                # in the final dll/exe.
                set(extra_flags "${extra_flags} /Zl")
            endif()
        endif()
    elseif(MINGW)
        if(WANT_STATIC_RUNTIME)
            # TODO: The -static is a bit of a hack for MSYS2 to force the static linking of pthreads.
            # There has to be a better way.
            set(extra_link_flags "-static-libgcc -static-libstdc++ -static -lpthread -Wl,--exclude-libs=libpthread.a -Wl,--exclude-libs=libgcc_eh.a")
        endif()
    endif()

    if(WIN32)
        set(extra_flags "${extra_flags} -DUNICODE -D_UNICODE")
    endif()

    if(NOT BUILD_SHARED_LIBS)
        set(static_flag "-DALLEGRO_STATICLINK")
    endif(NOT BUILD_SHARED_LIBS)

    if(NOT ANDROID)
        set_target_properties(${target}
            PROPERTIES
            COMPILE_FLAGS "${extra_flags} ${static_flag} -DALLEGRO_LIB_BUILD"
            LINK_FLAGS "${extra_link_flags}"
            VERSION ${ALLEGRO_VERSION}
            SOVERSION ${ALLEGRO_SOVERSION}
            )
    else(NOT ANDROID)
        set_target_properties(${target}
            PROPERTIES
            COMPILE_FLAGS "${extra_flags} ${static_flag} -DALLEGRO_LIB_BUILD"
            )
        set_property(GLOBAL APPEND PROPERTY JNI_LIBS ${target})
    endif(NOT ANDROID)

    # Construct the output name.
    set(output_name ${target})
    append_lib_type_suffix(output_name)
    append_lib_linkage_suffix(output_name)
    set_target_properties(${target}
        PROPERTIES
        OUTPUT_NAME ${output_name}
        )

    # Put version numbers on DLLs but not on import libraries nor static
    # archives.  Make MinGW not add a lib prefix to DLLs, to match MSVC.
    if(WIN32 AND SHARED)
        set_target_properties(${target}
            PROPERTIES
            PREFIX ""
            SUFFIX -${ALLEGRO_SOVERSION}.dll
            IMPORT_SUFFIX ${CMAKE_IMPORT_LIBRARY_SUFFIX}
            )
    endif()

    # Suppress errors about _mangled_main_address being undefined on Mac OS X.
    if(MACOSX)
        set_target_properties(${target}
            PROPERTIES
            LINK_FLAGS "-undefined dynamic_lookup"
            )
    endif(MACOSX)

    # Specify a list of libraries to be linked into the specified target.
    # Library dependencies are transitive by default.  Any target which links
    # with this target will therefore pull in these dependencies automatically.
    target_link_libraries(${target} ${link_with})

    # Set list of dependencies that the user would need to explicitly link with
    # if static linking.
    sanitize_cmake_link_flags(${link_with})
    set_target_properties(${target}
        PROPERTIES
        static_link_with "${return}"
        )
    set_our_framework_properties(${target} ${framework_name})
    install_our_library(${target} ${output_name})
endfunction(add_our_library)

macro(add_our_addon_library target framework_name sources extra_flags link_with)
    if(WANT_MONOLITH)
        set(MONOLITH_DEFINES "${MONOLITH_DEFINES} ${extra_flags}")
    else()
        add_our_library(${target} ${framework_name} "${sources}" "${extra_flags}" "${link_with}")
        target_include_directories(${target} INTERFACE
            $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
        if(ANDROID)
            record_android_load_libs(${target} "${link_with}")
        endif()
    endif()
endmacro(add_our_addon_library)

# Record in a custom target property 'ANDROID_LOAD_LIBS' the list of shared
# objects that will need to be bundled with the APK and loaded manually if
# linking with this target.
function(record_android_load_libs target libs)
    set(load_libs)
    foreach(lib ${libs})
        if(lib MATCHES "/lib[^/]+[.]so$" AND NOT lib MATCHES "/sysroot/")
            list(APPEND load_libs "${lib}")
        endif()
    endforeach()
    set_target_properties(${target} PROPERTIES ANDROID_LOAD_LIBS "${load_libs}")
endfunction(record_android_load_libs)

function(set_our_framework_properties target nm)
    if(WANT_FRAMEWORKS)
        if(WANT_EMBED)
            set(install_name_dir "@executable_path/../Frameworks")
        else()
            set(install_name_dir "${FRAMEWORK_INSTALL_PREFIX}")
        endif(WANT_EMBED)
        set_target_properties(${target}
            PROPERTIES
            FRAMEWORK on
            OUTPUT_NAME ${nm}
            INSTALL_NAME_DIR "${install_name_dir}"
            )
    endif(WANT_FRAMEWORKS)
endfunction(set_our_framework_properties)

function(install_our_library target filename)
    install(TARGETS ${target}
            FRAMEWORK DESTINATION "${FRAMEWORK_INSTALL_PREFIX}"
            # Doesn't work, see below.
            # PUBLIC_HEADER DESTINATION "include"
            )
    if(MSVC AND BUILD_SHARED_LIBS)
        install(FILES ${CMAKE_BINARY_DIR}/lib/\${CMAKE_INSTALL_CONFIG_NAME}/${filename}.pdb
            DESTINATION ${CMAKE_INSTALL_LIBDIR}
            CONFIGURATIONS Debug RelWithDebInfo
        )
    endif()
endfunction(install_our_library)

# Unfortunately, CMake's PUBLIC_HEADER support doesn't install into nested
# directories well, otherwise we could rely on install(TARGETS) to install
# header files associated with the target.  Instead we use the install(FILES)
# to install headers.  We reuse the MACOSX_PACKAGE_LOCATION property,
# substituting the "Headers" prefix with "include".

# NOTE: modern design is to use `target_sources(FILE_SET)` which requires CMake 3.23
function(install_our_headers)
    if(NOT WANT_FRAMEWORKS)
        foreach(hdr ${ARGN})
            get_source_file_property(LOC ${hdr} MACOSX_PACKAGE_LOCATION)
            string(REGEX REPLACE "^Headers" "include" LOC ${LOC})
            install(FILES ${hdr} DESTINATION ${LOC})
        endforeach()
    endif()
endfunction(install_our_headers)

function(fix_executable nm)
    if(IPHONE)
        string(REPLACE "_" "" bundle_nm ${nm})
        set_target_properties(${nm} PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.liballeg.${bundle_nm}")

        # FIXME:We want those as project attributes, not target attributes, but I don't know how
        set_target_properties(${nm} PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer")

        # We have to add an icon to every executable on IPhone else
        # cmake won't create a resource copy build phase for us.
        # And re-creating those by hand would be a major pain.
        set_target_properties(${nm} PROPERTIES MACOSX_BUNDLE_ICON_FILE icon.png)

        set_source_files_properties("${CMAKE_SOURCE_DIR}/misc/icon.png" PROPERTIES
            MACOSX_PACKAGE_LOCATION "Resources"
        )

    endif(IPHONE)
endfunction(fix_executable)

# Ads a target for an executable target `nm`.
#
# Arguments:
#
#    SRCS - Sources. If empty, assumes it to be ${nm}.c
#    LIBS - Libraries to link to.
#    DEFINES - Additional defines.
#
# Free variable: EXECUTABLE_TYPE
function(add_our_executable nm)
    set(flags) # none
    set(single_args) # none
    set(multi_args SRCS LIBS DEFINES)
    cmake_parse_arguments(OPTS "${flags}" "${single_args}" "${multi_args}"
        ${ARGN})

    if(NOT OPTS_SRCS)
        set(OPTS_SRCS "${nm}.c")
    endif()

    if(IPHONE)
        set(EXECUTABLE_TYPE MACOSX_BUNDLE)
        set(OPTS_SRCS ${OPTS_SRCS} "${CMAKE_SOURCE_DIR}/misc/icon.png")
    endif()

    add_executable(${nm} ${EXECUTABLE_TYPE} ${OPTS_SRCS})
    target_link_libraries(${nm} ${OPTS_LIBS})
    if(WANT_POPUP_EXAMPLES AND SUPPORT_NATIVE_DIALOG)
        list(APPEND OPTS_DEFINES ALLEGRO_POPUP_EXAMPLES)
    endif()
    if(NOT BUILD_SHARED_LIBS)
        list(APPEND OPTS_DEFINES ALLEGRO_STATICLINK)
    endif()

    foreach(d ${OPTS_DEFINES})
        set_property(TARGET ${nm} APPEND PROPERTY COMPILE_DEFINITIONS ${d})
    endforeach()

    set(extra_flags "")

    if(MSVC)
        # Compile with multiple processors
        set(extra_flags "/MP")
        if(WANT_STATIC_RUNTIME)
            if(CMAKE_BUILD_TYPE STREQUAL Debug)
                set(extra_flags "${extra_flags} /MTd")
            else()
                set(extra_flags "${extra_flags} /MT")
            endif()
        endif()
    endif()

    if(WIN32)
        set(extra_flags "${extra_flags} -DUNICODE -D_UNICODE")
    endif()

    set_target_properties(${nm} PROPERTIES COMPILE_FLAGS "${extra_flags}")

    if(MINGW)
        if(NOT CMAKE_BUILD_TYPE STREQUAL Debug)
            set_target_properties(${nm} PROPERTIES LINK_FLAGS "-Wl,-subsystem,windows")
        endif()
    endif()

    fix_executable(${nm})
endfunction()

function(add_copy_commands src dest destfilesvar)
    set(destfiles)
    foreach(basename ${ARGN})
        list(APPEND destfiles "${dest}/${basename}")
        add_custom_command(
            OUTPUT  "${dest}/${basename}"
            DEPENDS "${src}/${basename}"
            COMMAND "${CMAKE_COMMAND}" -E copy
                    "${src}/${basename}" "${dest}/${basename}"
            )
    endforeach()
    set(${destfilesvar} "${destfiles}" PARENT_SCOPE)
endfunction()

# Recreate data directory for out-of-source builds.
# Note: a symlink is unsafe as make clean will delete the contents
# of the pointed-to directory.
#
# Files are only copied if they don't are inside a .svn folder so we
# won't end up with read-only .svn folders in the build folder.
function(copy_data_dir_to_build target src dest)
    if(IPHONE)
        return()
    endif(IPHONE)

    if(src STREQUAL dest)
        return()
    endif()

    file(GLOB_RECURSE files RELATIVE "${src}" "${src}/*")
    add_copy_commands("${src}" "${dest}" destfiles "${files}")
    add_custom_target(${target} DEPENDS ${destfiles})
endfunction(copy_data_dir_to_build)

macro(add_monolith_sources var addon sources)
    foreach(s ${${sources}})
        list(APPEND ${var} ${addon}/${s})
    endforeach(s ${sources})
endmacro(add_monolith_sources addon sources)

# This macro is called by each addon. It expects the following variables to
# exist:
#
# ${ADDON}_SOURCES
# ${ADDON}_INCLUDE_FILES
# ${ADDON}_INCLUDE_DIRECTORIES
# ${ADDON}_LINK_DIRECTORIES
# ${ADDON}_DEFINES
# ${ADDON}_LIBRARIES
#
# This is useful so we can build the monolith library without having any other
# special code for it in the addon CMakeLists.txt files.
macro(add_addon addon)
    add_addon2(${addon} allegro_${addon})
endmacro(add_addon)

macro(add_addon2 addon addon_target)
    string(TOUPPER ${addon} ADDON)
    set(SUPPORT_${ADDON} 1 PARENT_SCOPE)
    set(${ADDON}_LINK_WITH ${addon_target} PARENT_SCOPE)
    add_monolith_sources(MONOLITH_SOURCES addons/${addon} ${ADDON}_SOURCES)
    add_monolith_sources(MONOLITH_SOURCES addons/${addon} ${ADDON}_INCLUDE_FILES)
    add_monolith_sources(MONOLITH_HEADERS addons/${addon} ${ADDON}_INCLUDE_FILES)
    set(MONOLITH_SOURCES ${MONOLITH_SOURCES} PARENT_SCOPE)
    list(APPEND MONOLITH_INCLUDE_DIRECTORIES ${${ADDON}_INCLUDE_DIRECTORIES})
    list(APPEND MONOLITH_INCLUDE_DIRECTORIES addons/${addon})
    list(APPEND MONOLITH_LINK_DIRECTORIES ${${ADDON}_LINK_DIRECTORIES})
    list(APPEND MONOLITH_LIBRARIES ${${ADDON}_LIBRARIES})
    set(MONOLITH_DEFINES "${MONOLITH_DEFINES} ${${ADDON}_DEFINES}")
    set(MONOLITH_INCLUDE_DIRECTORIES ${MONOLITH_INCLUDE_DIRECTORIES} PARENT_SCOPE)
    set(MONOLITH_LINK_DIRECTORIES ${MONOLITH_LINK_DIRECTORIES} PARENT_SCOPE)
    set(MONOLITH_LIBRARIES ${MONOLITH_LIBRARIES} PARENT_SCOPE)
    set(MONOLITH_HEADERS ${MONOLITH_HEADERS} PARENT_SCOPE)
    set(MONOLITH_DEFINES ${MONOLITH_DEFINES} PARENT_SCOPE)
endmacro(add_addon2)

#-----------------------------------------------------------------------------#
# vim: set ft=cmake sts=4 sw=4 et: