From 6607a48357c15bf0cfee54b743146926ad1fdcdb Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 24 Jul 2016 13:55:33 +0000 Subject: [PATCH] CMake: refactor inclusion of external libraries. This commit makes common external packages always be included through find_package to eliminate differences in variables set, wraps find_package for vendored libraries on Windows to factor out common code, and removes miscellaneous useless code elsewhere in dependency handling. This also fixes a problem where pkg-config would pick up `build` libraries instead of `host` when cross-compiling. --- .gitmodules | 4 +- CMakeLists.txt | 75 ++++++++++------------------- cmake/DisableWarnings.cmake | 15 ++++++ cmake/FindVendoredPackage.cmake | 54 +++++++++++++++++++++ cmake/Toolchain-mingw32.cmake | 14 +++--- cmake/Toolchain-mingw64.cmake | 14 +++--- extlib/{libfreetype => freetype} | 0 src/CMakeLists.txt | 81 +++++++++++--------------------- 8 files changed, 139 insertions(+), 118 deletions(-) create mode 100644 cmake/DisableWarnings.cmake create mode 100644 cmake/FindVendoredPackage.cmake rename extlib/{libfreetype => freetype} (100%) diff --git a/.gitmodules b/.gitmodules index dabc567d..ad5c136e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,8 +5,8 @@ [submodule "extlib/libpng"] path = extlib/libpng url = https://github.com/glennrp/libpng -[submodule "extlib/libfreetype"] - path = extlib/libfreetype +[submodule "extlib/freetype"] + path = extlib/freetype url = http://git.sv.nongnu.org/r/freetype/freetype2.git [submodule "extlib/libdxfrw"] path = extlib/libdxfrw diff --git a/CMakeLists.txt b/CMakeLists.txt index 709a4d12..d82622cc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -121,56 +121,26 @@ message(STATUS "Using in-tree libdxfrw") add_subdirectory(extlib/libdxfrw) if(WIN32) - # Configure Freetype first. If done later, it will notice that - # zlib is available, try to use it and promptly break on MSVC - # in a very obscure way. Given that the only use of zlib, bzip2 - # and png support is in support for extremely obsolete Unix fonts, - # we don't care. - find_package(Freetype) + include(FindVendoredPackage) - if(NOT FREETYPE_FOUND) - message(STATUS "Using in-tree libfreetype") + find_vendored_package(Freetype freetype + WITH_ZLIB OFF + WITH_BZip2 OFF + WITH_PNG OFF + WITH_HarfBuzz OFF + FREETYPE_LIBRARY freetype + FREETYPE_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/extlib/freetype/include) - add_subdirectory(extlib/libfreetype EXCLUDE_FROM_ALL) + find_vendored_package(ZLIB zlib + ZLIB_LIBRARY zlibstatic + ZLIB_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/extlib/zlib) + list(APPEND ZLIB_INCLUDE_DIR ${CMAKE_BINARY_DIR}/extlib/zlib) - set(FREETYPE_LIBRARY - freetype) - set(FREETYPE_INCLUDE_DIRS - "${CMAKE_SOURCE_DIR}/extlib/libfreetype/include") - find_package(Freetype REQUIRED) - endif() - - find_package(ZLIB) - - if(NOT ZLIB_FOUND) - message(STATUS "Using in-tree zlib") - add_subdirectory(extlib/zlib EXCLUDE_FROM_ALL) - - message(STATUS "Using in-tree libpng") - set(ZLIB_LIBRARY - zlibstatic) - set(ZLIB_INCLUDE_DIR - "${CMAKE_SOURCE_DIR}/extlib/zlib" - "${CMAKE_BINARY_DIR}/extlib/zlib") - find_package(ZLIB REQUIRED) - endif() - - find_package(PNG) - - if(NOT PNG_FOUND) - message(STATUS "Using in-tree libpng") - - set(SKIP_INSTALL_ALL - ON) - add_subdirectory(extlib/libpng EXCLUDE_FROM_ALL) - - set(PNG_LIBRARY - png16_static) - set(PNG_PNG_INCLUDE_DIR - "${CMAKE_SOURCE_DIR}/extlib/libpng" - "${CMAKE_BINARY_DIR}/extlib/libpng") - find_package(PNG REQUIRED) - endif() + find_vendored_package(PNG libpng + SKIP_INSTALL_ALL ON + PNG_LIBRARY png16_static + PNG_PNG_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/extlib/libpng) + list(APPEND PNG_PNG_INCLUDE_DIR ${CMAKE_BINARY_DIR}/extlib/libpng) if(NOT MINGW) message(STATUS "Using prebuilt SpaceWare") @@ -183,20 +153,25 @@ if(WIN32) elseif(APPLE) set(CMAKE_FIND_FRAMEWORK LAST) + find_package(ZLIB REQUIRED) find_package(PNG REQUIRED) find_package(Freetype REQUIRED) + find_library(APPKIT_LIBRARY AppKit REQUIRED) else() # Linux and compatible systems find_package(Backtrace) find_package(SpaceWare) - # Use freedesktop's pkg-config to locate everything. + find_package(ZLIB REQUIRED) + find_package(PNG REQUIRED) + find_package(Freetype REQUIRED) + + # Use freedesktop's pkg-config to locate everything else. find_package(PkgConfig REQUIRED) - pkg_check_modules(ZLIB REQUIRED zlib) - pkg_check_modules(PNG REQUIRED libpng) pkg_check_modules(FONTCONFIG REQUIRED fontconfig) pkg_check_modules(JSONC REQUIRED json-c) pkg_check_modules(FREETYPE REQUIRED freetype2) + pkg_check_modules(CAIRO REQUIRED cairo) set(HAVE_GTK TRUE) if(GUI STREQUAL "gtk3") diff --git a/cmake/DisableWarnings.cmake b/cmake/DisableWarnings.cmake new file mode 100644 index 00000000..372e4408 --- /dev/null +++ b/cmake/DisableWarnings.cmake @@ -0,0 +1,15 @@ +# Disables all warnings on MSVC and GNU-compatible compilers. + +function(disable_warnings) + if(CMAKE_C_COMPILER_ID STREQUAL GNU OR CMAKE_C_COMPILER_ID STREQUAL Clang) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w" PARENT_SCOPE) + elseif(CMAKE_C_COMPILER_ID STREQUAL MSVC) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W0" PARENT_SCOPE) + endif() + + if(CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w" PARENT_SCOPE) + elseif(CMAKE_CXX_COMPILER_ID STREQUAL MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W0" PARENT_SCOPE) + endif() +endfunction() diff --git a/cmake/FindVendoredPackage.cmake b/cmake/FindVendoredPackage.cmake new file mode 100644 index 00000000..78da0e8b --- /dev/null +++ b/cmake/FindVendoredPackage.cmake @@ -0,0 +1,54 @@ +# Find the given library in the system locations, or build in-tree if not found. +# +# Arguments: +# PKG_NAME - name of the package as passed to find_package +# PKG_PATH - name of the source tree relative to extlib/ +# +# The rest of the arguments are VARIABLE VALUE pairs. If the library is not found, +# every VARIABLE will be set to VALUE and find_package will be rerun with the REQUIRED flag. +# Regardless of where the library was found, only the specfied VARIABLEs that start with +# ${PKG_NAME} will be set in the parent scope. +# +# All warnings in the in-tree package are disabled. + +include(DisableWarnings) + +function(find_vendored_package PKG_NAME PKG_PATH) + find_package(${PKG_NAME}) + + set(cfg_name) + foreach(item ${ARGN}) + if(NOT cfg_name) + set(cfg_name ${item}) + else() + set(${cfg_name} ${item}) + set(cfg_name) + endif() + endforeach() + + disable_warnings() + + string(TOUPPER ${PKG_NAME} VAR_NAME) + if(NOT ${VAR_NAME}_FOUND) + message(STATUS "Using in-tree ${PKG_PATH}") + set(${VAR_NAME}_IN_TREE YES CACHE INTERNAL "") + + add_subdirectory(extlib/${PKG_PATH} EXCLUDE_FROM_ALL) + find_package(${PKG_NAME} REQUIRED) + elseif(${VAR_NAME}_IN_TREE) + add_subdirectory(extlib/${PKG_PATH} EXCLUDE_FROM_ALL) + endif() + + # Now put everything we just discovered into the cache. + set(cfg_name) + foreach(item ${ARGN} ${VAR_NAME}_FOUND) + if(NOT cfg_name) + set(cfg_name ${item}) + else() + if(cfg_name MATCHES "^${VAR_NAME}") + set(${cfg_name} "${${cfg_name}}" CACHE INTERNAL "") + endif() + set(cfg_name) + endif() + endforeach() +endfunction() diff --git a/cmake/Toolchain-mingw32.cmake b/cmake/Toolchain-mingw32.cmake index a3591c87..a8767fdd 100644 --- a/cmake/Toolchain-mingw32.cmake +++ b/cmake/Toolchain-mingw32.cmake @@ -1,13 +1,15 @@ -SET(CMAKE_SYSTEM_NAME Windows) +set(CMAKE_SYSTEM_NAME Windows) -SET(TRIPLE i686-w64-mingw32) +set(TRIPLE i686-w64-mingw32) -SET(CMAKE_C_COMPILER ${TRIPLE}-gcc) -SET(CMAKE_CXX_COMPILER ${TRIPLE}-g++) -SET(CMAKE_RC_COMPILER ${TRIPLE}-windres) +set(CMAKE_C_COMPILER ${TRIPLE}-gcc) +set(CMAKE_CXX_COMPILER ${TRIPLE}-g++) +set(CMAKE_RC_COMPILER ${TRIPLE}-windres) -SET(CMAKE_FIND_ROOT_PATH /usr/${TRIPLE}) +set(CMAKE_FIND_ROOT_PATH /usr/${TRIPLE}) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +set(ENV{PKG_CONFIG_LIBDIR} /usr/${TRIPLE}/lib/pkgconfig) diff --git a/cmake/Toolchain-mingw64.cmake b/cmake/Toolchain-mingw64.cmake index 6841214b..7f85f355 100644 --- a/cmake/Toolchain-mingw64.cmake +++ b/cmake/Toolchain-mingw64.cmake @@ -1,13 +1,15 @@ -SET(CMAKE_SYSTEM_NAME Windows) +set(CMAKE_SYSTEM_NAME Windows) -SET(TRIPLE x86_64-w64-mingw32) +set(TRIPLE x86_64-w64-mingw32) -SET(CMAKE_C_COMPILER ${TRIPLE}-gcc) -SET(CMAKE_CXX_COMPILER ${TRIPLE}-g++) -SET(CMAKE_RC_COMPILER ${TRIPLE}-windres) +set(CMAKE_C_COMPILER ${TRIPLE}-gcc) +set(CMAKE_CXX_COMPILER ${TRIPLE}-g++) +set(CMAKE_RC_COMPILER ${TRIPLE}-windres) -SET(CMAKE_FIND_ROOT_PATH /usr/${TRIPLE}) +set(CMAKE_FIND_ROOT_PATH /usr/${TRIPLE}) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +set(ENV{PKG_CONFIG_LIBDIR} /usr/${TRIPLE}/lib/pkgconfig) diff --git a/extlib/libfreetype b/extlib/freetype similarity index 100% rename from extlib/libfreetype rename to extlib/freetype diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 250c1058..c9cd204c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,31 +1,12 @@ -# global - include(GNUInstallDirs) -include_directories( - ${OPENGL_INCLUDE_DIR} - ${PNG_INCLUDE_DIRS} - ${FREETYPE_INCLUDE_DIRS}) - -link_directories( - ${PNG_LIBRARY_DIRS} - ${FREETYPE_LIBRARY_DIRS}) - -add_definitions( - ${PNG_CFLAGS_OTHER}) +# configuration include_directories( ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/built ${CMAKE_CURRENT_BINARY_DIR}) -if(SPACEWARE_FOUND) - include_directories( - ${SPACEWARE_INCLUDE_DIR}) -endif() - set(HAVE_SPACEWARE ${SPACEWARE_FOUND}) -set(HAVE_GTK ${GTKMM_FOUND}) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) @@ -75,16 +56,28 @@ if(NOT WIN32) PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) endif() -# platform dependencies +# solvespace dependencies + +include_directories( + ${OPENGL_INCLUDE_DIR} + ${ZLIB_INCLUDE_DIR} + ${PNG_PNG_INCLUDE_DIR} + ${FREETYPE_INCLUDE_DIRS}) + +if(SPACEWARE_FOUND) + include_directories( + ${SPACEWARE_INCLUDE_DIR}) +endif() if(WIN32) set(platform_SOURCES platform/w32main.cpp) set(platform_LIBRARIES - comctl32) + comctl32 + ${SPACEWARE_LIBRARIES}) elseif(APPLE) - add_definitions( + add_compile_options( -fobjc-arc) set(platform_SOURCES @@ -98,29 +91,19 @@ elseif(APPLE) set(platform_LIBRARIES ${APPKIT_LIBRARY}) elseif(HAVE_GTK) - include_directories( - ${GTKMM_INCLUDE_DIRS} - ${JSONC_INCLUDE_DIRS} - ${FONTCONFIG_INCLUDE_DIRS}) - - link_directories( - ${GTKMM_LIBRARY_DIRS} - ${JSONC_LIBRARY_DIRS} - ${FONTCONFIG_LIBRARY_DIRS}) - - add_definitions( - ${GTKMM_CFLAGS_OTHER} - ${JSONC_CFLAGS_OTHER} - ${FONTCONFIG_CFLAGS_OTHER}) - set(platform_SOURCES platform/gtkmain.cpp render/rendergl.cpp) set(platform_LIBRARIES - ${GTKMM_LIBRARIES} - ${JSONC_LIBRARIES} - ${FONTCONFIG_LIBRARIES}) + ${Backtrace_LIBRARIES} + ${SPACEWARE_LIBRARIES}) + + foreach(pkg_config_lib GTKMM JSONC FONTCONFIG) + include_directories(${${pkg_config_lib}_INCLUDE_DIRS}) + link_directories(${${pkg_config_lib}_LIBRARY_DIRS}) + list(APPEND platform_LIBRARIES ${${pkg_config_lib}_LIBRARIES}) + endforeach() endif() # solvespace executable @@ -199,9 +182,9 @@ add_dependencies(solvespace target_link_libraries(solvespace dxfrw ${OPENGL_LIBRARIES} - ${PNG_LIBRARIES} - ${ZLIB_LIBRARIES} - ${FREETYPE_LIBRARIES} + ${ZLIB_LIBRARY} + ${PNG_LIBRARY} + ${FREETYPE_LIBRARY} ${platform_LIBRARIES}) if(WIN32 AND NOT MINGW) @@ -209,16 +192,6 @@ if(WIN32 AND NOT MINGW) LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO") endif() -if(SPACEWARE_FOUND) - target_link_libraries(solvespace - ${SPACEWARE_LIBRARIES}) -endif() - -if(Backtrace_FOUND) - target_link_libraries(solvespace - ${Backtrace_LIBRARIES}) -endif() - if(APPLE) foreach(lib ${platform_BUNDLED_LIBS}) get_filename_component(name ${lib} NAME)