# 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 $<$:/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")