Commit
This module is like FetchContent in CMake 3.11, but for the moment it may be more inviting to hackers not to require that yet. The principle is explained here: https://crascit.com/2015/07/25/cmake-gtest/ It allows us to work with CMake in a more natural environment for CMake-submodules, which are otherwise nigh-uncontrollable in between escaping variables in CMake syntax and CMake being extremely bad at taking command-line arguments. (A fact I utterly despise as a regular user just downloading a project to compile & try.) Upping the minimum CMake version over 3.3 should also allow us to get rid of a few braindead Android-related workarounds for sdcv, where we had to completely force-feed the `.a` suffix.
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Distributed under the OSI-approved MIT License. See accompanying | ||
# file LICENSE or https://github.com/Crascit/DownloadProject for details. | ||
|
||
cmake_minimum_required(VERSION 3.5.1) | ||
|
||
project(${DL_ARGS_PROJ}-download NONE) | ||
|
||
include(ExternalProject) | ||
ExternalProject_Add(${DL_ARGS_PROJ}-download | ||
${DL_ARGS_UNPARSED_ARGUMENTS} | ||
SOURCE_DIR "${DL_ARGS_SOURCE_DIR}" | ||
BINARY_DIR "${DL_ARGS_BINARY_DIR}" | ||
CONFIGURE_COMMAND "" | ||
BUILD_COMMAND "" | ||
INSTALL_COMMAND "" | ||
TEST_COMMAND "" | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
# Distributed under the OSI-approved MIT License. See accompanying | ||
# file LICENSE or https://github.com/Crascit/DownloadProject for details. | ||
# | ||
# MODULE: DownloadProject | ||
# | ||
# PROVIDES: | ||
# download_project( PROJ projectName | ||
# [PREFIX prefixDir] | ||
# [DOWNLOAD_DIR downloadDir] | ||
# [SOURCE_DIR srcDir] | ||
# [BINARY_DIR binDir] | ||
# [QUIET] | ||
# ... | ||
# ) | ||
# | ||
# Provides the ability to download and unpack a tarball, zip file, git repository, | ||
# etc. at configure time (i.e. when the cmake command is run). How the downloaded | ||
# and unpacked contents are used is up to the caller, but the motivating case is | ||
# to download source code which can then be included directly in the build with | ||
# add_subdirectory() after the call to download_project(). Source and build | ||
# directories are set up with this in mind. | ||
# | ||
# The PROJ argument is required. The projectName value will be used to construct | ||
# the following variables upon exit (obviously replace projectName with its actual | ||
# value): | ||
# | ||
# projectName_SOURCE_DIR | ||
# projectName_BINARY_DIR | ||
# | ||
# The SOURCE_DIR and BINARY_DIR arguments are optional and would not typically | ||
# need to be provided. They can be specified if you want the downloaded source | ||
# and build directories to be located in a specific place. The contents of | ||
# projectName_SOURCE_DIR and projectName_BINARY_DIR will be populated with the | ||
# locations used whether you provide SOURCE_DIR/BINARY_DIR or not. | ||
# | ||
# The DOWNLOAD_DIR argument does not normally need to be set. It controls the | ||
# location of the temporary CMake build used to perform the download. | ||
# | ||
# The PREFIX argument can be provided to change the base location of the default | ||
# values of DOWNLOAD_DIR, SOURCE_DIR and BINARY_DIR. If all of those three arguments | ||
# are provided, then PREFIX will have no effect. The default value for PREFIX is | ||
# CMAKE_BINARY_DIR. | ||
# | ||
# The QUIET option can be given if you do not want to show the output associated | ||
# with downloading the specified project. | ||
# | ||
# In addition to the above, any other options are passed through unmodified to | ||
# ExternalProject_Add() to perform the actual download, patch and update steps. | ||
# The following ExternalProject_Add() options are explicitly prohibited (they | ||
# are reserved for use by the download_project() command): | ||
# | ||
# CONFIGURE_COMMAND | ||
# BUILD_COMMAND | ||
# INSTALL_COMMAND | ||
# TEST_COMMAND | ||
# | ||
# Only those ExternalProject_Add() arguments which relate to downloading, patching | ||
# and updating of the project sources are intended to be used. Also note that at | ||
# least one set of download-related arguments are required. | ||
# | ||
# If using CMake 3.2 or later, the UPDATE_DISCONNECTED option can be used to | ||
# prevent a check at the remote end for changes every time CMake is run | ||
# after the first successful download. See the documentation of the ExternalProject | ||
# module for more information. It is likely you will want to use this option if it | ||
# is available to you. Note, however, that the ExternalProject implementation contains | ||
# bugs which result in incorrect handling of the UPDATE_DISCONNECTED option when | ||
# using the URL download method or when specifying a SOURCE_DIR with no download | ||
# method. Fixes for these have been created, the last of which is scheduled for | ||
# inclusion in CMake 3.8.0. Details can be found here: | ||
# | ||
# https://gitlab.kitware.com/cmake/cmake/commit/bdca68388bd57f8302d3c1d83d691034b7ffa70c | ||
# https://gitlab.kitware.com/cmake/cmake/issues/16428 | ||
# | ||
# If you experience build errors related to the update step, consider avoiding | ||
# the use of UPDATE_DISCONNECTED. | ||
# | ||
# EXAMPLE USAGE: | ||
# | ||
# include(DownloadProject) | ||
# download_project(PROJ googletest | ||
# GIT_REPOSITORY https://github.com/google/googletest.git | ||
# GIT_TAG master | ||
# UPDATE_DISCONNECTED 1 | ||
# QUIET | ||
# ) | ||
# | ||
# add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR}) | ||
# | ||
#======================================================================================== | ||
|
||
|
||
set(_DownloadProjectDir "${CMAKE_CURRENT_LIST_DIR}") | ||
|
||
include(CMakeParseArguments) | ||
|
||
function(download_project) | ||
|
||
set(options QUIET) | ||
set(oneValueArgs | ||
PROJ | ||
PREFIX | ||
DOWNLOAD_DIR | ||
SOURCE_DIR | ||
BINARY_DIR | ||
# Prevent the following from being passed through | ||
CONFIGURE_COMMAND | ||
BUILD_COMMAND | ||
INSTALL_COMMAND | ||
TEST_COMMAND | ||
) | ||
set(multiValueArgs "") | ||
|
||
cmake_parse_arguments(DL_ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) | ||
|
||
# Hide output if requested | ||
if (DL_ARGS_QUIET) | ||
set(OUTPUT_QUIET "OUTPUT_QUIET") | ||
else() | ||
unset(OUTPUT_QUIET) | ||
message(STATUS "Downloading/updating ${DL_ARGS_PROJ}") | ||
endif() | ||
|
||
# Set up where we will put our temporary CMakeLists.txt file and also | ||
# the base point below which the default source and binary dirs will be. | ||
# The prefix must always be an absolute path. | ||
if (NOT DL_ARGS_PREFIX) | ||
set(DL_ARGS_PREFIX "${CMAKE_BINARY_DIR}") | ||
else() | ||
get_filename_component(DL_ARGS_PREFIX "${DL_ARGS_PREFIX}" ABSOLUTE | ||
BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}") | ||
endif() | ||
if (NOT DL_ARGS_DOWNLOAD_DIR) | ||
set(DL_ARGS_DOWNLOAD_DIR "${DL_ARGS_PREFIX}/${DL_ARGS_PROJ}-download") | ||
endif() | ||
|
||
# Ensure the caller can know where to find the source and build directories | ||
if (NOT DL_ARGS_SOURCE_DIR) | ||
set(DL_ARGS_SOURCE_DIR "${DL_ARGS_PREFIX}/${DL_ARGS_PROJ}-src") | ||
endif() | ||
if (NOT DL_ARGS_BINARY_DIR) | ||
set(DL_ARGS_BINARY_DIR "${DL_ARGS_PREFIX}/${DL_ARGS_PROJ}-build") | ||
endif() | ||
set(${DL_ARGS_PROJ}_SOURCE_DIR "${DL_ARGS_SOURCE_DIR}" PARENT_SCOPE) | ||
set(${DL_ARGS_PROJ}_BINARY_DIR "${DL_ARGS_BINARY_DIR}" PARENT_SCOPE) | ||
|
||
# The way that CLion manages multiple configurations, it causes a copy of | ||
# the CMakeCache.txt to be copied across due to it not expecting there to | ||
# be a project within a project. This causes the hard-coded paths in the | ||
# cache to be copied and builds to fail. To mitigate this, we simply | ||
# remove the cache if it exists before we configure the new project. It | ||
# is safe to do so because it will be re-generated. Since this is only | ||
# executed at the configure step, it should not cause additional builds or | ||
# downloads. | ||
file(REMOVE "${DL_ARGS_DOWNLOAD_DIR}/CMakeCache.txt") | ||
|
||
# Create and build a separate CMake project to carry out the download. | ||
# If we've already previously done these steps, they will not cause | ||
# anything to be updated, so extra rebuilds of the project won't occur. | ||
# Make sure to pass through CMAKE_MAKE_PROGRAM in case the main project | ||
# has this set to something not findable on the PATH. | ||
configure_file("${_DownloadProjectDir}/DownloadProject.CMakeLists.cmake.in" | ||
"${DL_ARGS_DOWNLOAD_DIR}/CMakeLists.txt") | ||
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" | ||
-D "CMAKE_MAKE_PROGRAM:FILE=${CMAKE_MAKE_PROGRAM}" | ||
. | ||
RESULT_VARIABLE result | ||
${OUTPUT_QUIET} | ||
WORKING_DIRECTORY "${DL_ARGS_DOWNLOAD_DIR}" | ||
) | ||
if(result) | ||
message(FATAL_ERROR "CMake step for ${DL_ARGS_PROJ} failed: ${result}") | ||
endif() | ||
execute_process(COMMAND ${CMAKE_COMMAND} --build . | ||
RESULT_VARIABLE result | ||
${OUTPUT_QUIET} | ||
WORKING_DIRECTORY "${DL_ARGS_DOWNLOAD_DIR}" | ||
) | ||
if(result) | ||
message(FATAL_ERROR "Build step for ${DL_ARGS_PROJ} failed: ${result}") | ||
endif() | ||
|
||
endfunction() |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ cmake_minimum_required(VERSION 3.5.1) | |
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}/../cmake_modules") | ||
include("koreader_thirdparty_common") | ||
include("koreader_thirdparty_git") | ||
include("DownloadProject") | ||
|
||
enable_language(C CXX) | ||
|
||
|
@@ -27,20 +28,14 @@ assert_var_defined(ZLIB_DIR) | |
|
||
ep_get_source_dir(SOURCE_DIR) | ||
|
||
if(DEFINED ENV{ANDROID}) | ||
set(CRIPPLED_BY_ANDROID_FILES "${SOURCE_DIR}/src/libwrapper.cpp ${SOURCE_DIR}/src/sdcv.cpp ${SOURCE_DIR}/src/utils.cpp") | ||
set(PATCH_CMD "${ISED} 's|_(|(|' ${CRIPPLED_BY_ANDROID_FILES}") | ||
set(PATCH_CMD "${PATCH_CMD} && ${ISED} 's|#include <glib/gi18n.h>||' ${CRIPPLED_BY_ANDROID_FILES}") | ||
set(PATCH_CMD sh -c "${PATCH_CMD}") | ||
endif() | ||
|
||
# because cmake needs all kinds of annoying special cmake variables | ||
set(CMAKE_EXE_LINKER_FLAGS "${LDFLAGS} -static-libstdc++") | ||
if(DEFINED ENV{DARWIN}) | ||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework CoreFoundation -framework Security") | ||
endif() | ||
|
||
if(DEFINED ENV{ANDROID}) | ||
set(CMAKE_SYSTEM_NAME Android) | ||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static") | ||
endif() | ||
|
||
|
@@ -59,8 +54,6 @@ set(CMAKE_PREFIX_PATH "${GLIB2_INCLUDE_DIRS}$<SEMICOLON>${ZLIB_DIR}$<SEMICOLON>$ | |
# Which is funny, because the .a is in the *same* directory. Just saying. | ||
# Instead we add semi-hardcoded references to the right libraries in GLIB2_LIBRARIES | ||
if(DEFINED ENV{ANDROID} OR DEFINED ENV{DARWIN}) | ||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") | ||
|
||
# glib2 also needs to link with libiconv and gettext | ||
# this is a fairly clean hack | ||
# CMAKE_CXX_FLAGS with -I and -L doesn't seem to have much of an effect | ||
|
@@ -72,26 +65,13 @@ set(ZLIB_LIBRARIES "${ZLIB}") | |
# I just want to be able to -I and -L and have things work. CMake, CMake... | ||
set(ZLIB_LIBRARY_RELEASE "${ZLIB}") | ||
|
||
### Includes and libraries | ||
# By overspecifying the heck out of everything we hope to force CMake into the | ||
# equivalent of a couple of simple -I and -L flags because the proper method | ||
# with CMAKE_PREFIX_PATH and CMAKE_FIND_LIBRARY_SUFFIXES does. not. work | ||
set(CFG_OPTS "-DGLIB2_INCLUDE_DIRS='${GLIB2_INCLUDE_DIRS}' -DGLIB2_LIBRARIES='${GLIB2_LIBRARIES}' -DZLIB_INCLUDE_DIR='${ZLIB_INCLUDE_DIR}' -DZLIB_LIBRARIES='${ZLIB_LIBRARIES}' -DZLIB_LIBRARY_RELEASE='${ZLIB_LIBRARY_RELEASE}'") | ||
# These are the directories where we tell CMake to search for libs and includes | ||
set(CFG_OPTS "${CFG_OPTS} -DCMAKE_PREFIX_PATH='${CMAKE_PREFIX_PATH}'") | ||
if($ENV{ANDROID}) | ||
# the default `;` causes escape issues | ||
# we could escape it but on Android we only want .a and otherwise the default | ||
set(CFG_OPTS "${CFG_OPTS} -DCMAKE_FIND_LIBRARY_SUFFIXES='${CMAKE_FIND_LIBRARY_SUFFIXES}'") | ||
set(CFG_OPTS "${CFG_OPTS} -DCMAKE_SYSTEM_NAME=Android -DCMAKE_SYSTEM_VERSION=1") | ||
endif() | ||
### Compiler and linker flags | ||
set(CFG_OPTS "${CFG_OPTS} -DCMAKE_C_COMPILER='${CMAKE_C_COMPILER}' -DCMAKE_C_COMPILER_LAUNCHER='${CMAKE_C_COMPILER_LAUNCHER}' -DCMAKE_C_COMPILER_ARG1='${CMAKE_C_COMPILER_ARG1}' -DCMAKE_CXX_COMPILER='${CMAKE_CXX_COMPILER}' -DCMAKE_CXX_COMPILER_LAUNCHER='${CMAKE_CXX_COMPILER_LAUNCHER}' -DCMAKE_CXX_COMPILER_ARG1='${CMAKE_CXX_COMPILER_ARG1}' -DCMAKE_CXX_FLAGS='${CXXFLAGS}' -DCMAKE_EXE_LINKER_FLAGS='${CMAKE_EXE_LINKER_FLAGS}'") | ||
### Disable some sdcv stuff we don't need | ||
set(CFG_OPTS "${CFG_OPTS} -DENABLE_NLS:BOOL=False -DWITH_READLINE:BOOL=False") | ||
### Disable the silly build tree RPATH | ||
set(CFG_OPTS "${CFG_OPTS} -DCMAKE_SKIP_BUILD_RPATH:BOOL=True") | ||
set(CFG_CMD sh -c "${CMAKE_COMMAND} ${CFG_OPTS}") | ||
set(CMAKE_SKIP_BUILD_RPATH True) | ||
|
||
# These need to be option(), not set(), for deep & profound CMake reasons | ||
option(ENABLE_NLS False) | ||
option(WITH_READLINE False) | ||
|
||
# Force utf8 command line parsing, and accept not-found -u dictnames | ||
set(PATCH_CMD2 sh -c "patch -N -p1 < ${CMAKE_CURRENT_SOURCE_DIR}/sdcv.patch || true") | ||
|
||
|
@@ -102,14 +82,11 @@ ko_write_gitclone_script( | |
${SOURCE_DIR} | ||
) | ||
|
||
include(ExternalProject) | ||
ExternalProject_Add( | ||
${PROJECT_NAME} | ||
include(DownloadProject) | ||
download_project( | ||
PROJ ${PROJECT_NAME} | ||
DOWNLOAD_COMMAND ${CMAKE_COMMAND} -P ${GIT_CLONE_SCRIPT_FILENAME} | ||
BUILD_IN_SOURCE 1 | ||
PATCH_COMMAND COMMAND ${PATCH_CMD} COMMAND ${PATCH_CMD2} | ||
CONFIGURE_COMMAND ${CFG_CMD} | ||
BUILD_COMMAND $(MAKE) -j${PARALLEL_JOBS} | ||
# skip install | ||
INSTALL_COMMAND "" | ||
PATCH_COMMAND COMMAND ${PATH_CMD2} | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
poire-z
Contributor
|
||
) | ||
|
||
add_subdirectory(${SOURCE_DIR}) |
@poire-z In what scenario did this Andoid patch make a difference @poire-z ? I ask because I accidentally typod but I didn't notice any issues. :-)