CedaCommon.cmake
# CedaCommon.cmake
if (MSVC)
add_definitions(
# Target Windows XP SP2
# cxSocket is using GetAddrInfoW() which requires WinXP SP2 and later
/D_WIN32_WINNT=0x0502
# GraphicsMagick is using std::unary_function which is removed in C++17
/D_HAS_AUTO_PTR_ETC=1
/D_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS
)
# Currently by default MSVC only supports C++14, need this to enable using things like std::optional, std::filesystem
add_compile_options(/std:c++latest)
# warning C5033: 'register' is no longer a supported storage class
# This is caused by the Python headers
add_compile_options(/wd5033)
endif()
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
message("Adding switches for clang")
# See http://clang-developers.42468.n3.nabble.com/clang-cl-error-on-building-simple-cpp-with-only-windows-h-boost-mutex-included-td4049894.html
add_definitions(/DBOOST_SP_USE_STD_ATOMIC)
# C:\python27x64\include/unicodeobject.h(534,5): error: ISO C++17 does not allow 'register' storage class specifier [-Wregister]
add_compile_options(-Wregister)
endif()
# https://github.com/boostorg/system/issues/32
add_definitions(/DHAVE_SNPRINTF)
if (NOT BUILD_SHARED_LIBS)
if (MSVC)
message("Using static versions of the C Run Time library")
# /MD : Link with the multithread, DLL version of the run-time library.
# /MT : Link with the multithread, static version of the run-time library.
set(CompilerFlags
CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_RELWITHDEBINFO
CMAKE_C_FLAGS
CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_RELWITHDEBINFO
)
foreach(CompilerFlag ${CompilerFlags})
string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}")
endforeach()
endif()
endif()
function(cedaSetDefaultsForTarget targetname)
# Configure where to output generated binaries
# *.lib will go to ARCHIVE_OUTPUT_DIRECTORY
# *.so will go to LIBRARY_OUTPUT_DIRECTORY
# *.dll will go to RUNTIME_OUTPUT_DIRECTORY
set_target_properties(${targetname} PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)
target_compile_definitions(${targetname}
PRIVATE
CEDA_USE_BOOST_MULTIPRECISION
# Performance repercussions!
# CEDA_CHECK_ASSERTIONS
# CEDA_ASSERTION_FAILURE_THROWS_EXCEPTION
)
if ("${CMAKE_BUILD_TYPE}" MATCHES "Debug")
target_compile_definitions(${targetname} PRIVATE CEDA_CHECK_ASSERTIONS)
endif()
if (MSVC)
target_compile_definitions(${targetname}
PRIVATE
# Eliminate deprecation warnings for the older, less secure CRT functions such as strcpy.
# Many old CRT functions have newer, more secure versions. If a secure function exists,
# the older, less secure version is marked as deprecated and the new version has the
# _s ("secure") suffix.
_CRT_SECURE_NO_WARNINGS
)
endif()
endfunction()
###################################################################################################
# linkTargetWithLibs
function(linkTargetWithLibs targetname)
foreach(libname ${ARGN})
find_library(FOUND_${libname} NAMES ${libname})
message("Target ${targetname} linking with library ${libname} : ${FOUND_${libname}}")
target_link_libraries(${targetname} PRIVATE ${FOUND_${libname}})
endforeach()
endfunction()
###################################################################################################
# linkTargetWithwxWidgets
function(linkTargetWithwxWidgets targetname)
target_compile_definitions(${targetname} PRIVATE CEDA_USING_WXWIDGETS _UNICODE UNICODE __WXMSW__ wxUSE_GUI=1)
if (BUILD_SHARED_LIBS)
target_compile_definitions(${targetname} PRIVATE -DWXUSINGDLL)
endif()
find_path(WXWIDGETS_INCLUDE_DIR wx/wx.h)
message("WXWIDGETS_INCLUDE_DIR = ${WXWIDGETS_INCLUDE_DIR}")
target_include_directories(${targetname} PRIVATE ${WXWIDGETS_INCLUDE_DIR})
if ("${CMAKE_BUILD_TYPE}" MATCHES "Debug")
target_compile_definitions(${targetname} PRIVATE __WXDEBUG__)
linkTargetWithLibs(${targetname}
wxbase31ud
wxbase31ud_net
wxbase31ud_xml
wxmsw31ud_adv
wxmsw31ud_aui
wxmsw31ud_core
wxmsw31ud_gl
wxmsw31ud_html
wxmsw31ud_media
wxmsw31ud_propgrid
wxmsw31ud_qa
wxmsw31ud_ribbon
wxmsw31ud_richtext
wxmsw31ud_stc
wxmsw31ud_webview
wxmsw31ud_xrc
libpng16d
zlibd)
elseif( ("${CMAKE_BUILD_TYPE}" MATCHES "Release") OR ("${CMAKE_BUILD_TYPE}" MATCHES "RelWithDebInfo") )
linkTargetWithLibs(${targetname}
wxbase31u
wxbase31u_net
wxbase31u_xml
wxmsw31u_adv
wxmsw31u_aui
wxmsw31u_core
wxmsw31u_gl
wxmsw31u_html
wxmsw31u_media
wxmsw31u_propgrid
wxmsw31u_qa
wxmsw31u_ribbon
wxmsw31u_richtext
wxmsw31u_stc
wxmsw31u_webview
wxmsw31u_xrc
libpng16
zlib)
endif()
target_link_libraries(${targetname} PRIVATE winmm comctl32 oleacc rpcrt4 shlwapi version wsock32)
endfunction()
###################################################################################################
# linkTargetWithPython2
function(linkTargetWithPython2 targetname)
target_include_directories(${targetname} PRIVATE ${Python2_INCLUDE_DIRS})
target_link_libraries(${targetname} PRIVATE ${Python2_LIBRARIES})
endfunction()
###################################################################################################
# linkTargetWithFfi
# (libffi)
function(linkTargetWithFfi targetname)
find_path(FFI_INCLUDE_DIR ffi.h)
message("FFI_INCLUDE_DIR = ${FFI_INCLUDE_DIR}")
target_include_directories(${targetname} PRIVATE ${FFI_INCLUDE_DIR})
find_library(FFI_LIBRARY NAMES ffi libffi)
message("FFI_LIBRARY = ${FFI_LIBRARY}")
target_link_libraries(${targetname} PRIVATE ${FFI_LIBRARY})
endfunction()
###################################################################################################
# linkTargetWithPango
function(linkTargetWithPango targetname)
find_path(PANGO_INCLUDE_DIR pango/pango.h)
message("PANGO_INCLUDE_DIR = ${PANGO_INCLUDE_DIR}")
target_include_directories(${targetname} PRIVATE ${PANGO_INCLUDE_DIR})
linkTargetWithLibs(${targetname} pango-1.0 pangocairo-1.0 pangoft2-1.0 pangowin32-1.0 gobject-2.0)
endfunction()
###################################################################################################
# linkTargetWithCairo
function(linkTargetWithCairo targetname)
find_path(CAIRO_INCLUDE_DIR cairo/cairo.h)
message("CAIRO_INCLUDE_DIR = ${CAIRO_INCLUDE_DIR}")
target_include_directories(${targetname} PRIVATE ${CAIRO_INCLUDE_DIR})
if ("${CMAKE_BUILD_TYPE}" MATCHES "Debug")
linkTargetWithLibs(${targetname} cairod cairo-gobjectd)
elseif( ("${CMAKE_BUILD_TYPE}" MATCHES "Release") OR ("${CMAKE_BUILD_TYPE}" MATCHES "RelWithDebInfo") )
linkTargetWithLibs(${targetname} cairo cairo-gobject)
endif()
endfunction()
###################################################################################################
# linkTargetWithTurboJpeg
function(linkTargetWithTurboJpeg targetname)
find_path(TURBOJPEG_INCLUDE_DIR turbojpeg.h)
message("TURBOJPEG_INCLUDE_DIR = ${TURBOJPEG_INCLUDE_DIR}")
target_include_directories(${targetname} PRIVATE ${TURBOJPEG_INCLUDE_DIR})
linkTargetWithLibs(${targetname} turbojpeg jpeg)
endfunction()
###################################################################################################
# linkTargetWithWebP
function(linkTargetWithWebP targetname)
find_path(WEBP_INCLUDE_DIRS webp/decode.h)
message("WEBP_INCLUDE_DIRS = ${WEBP_INCLUDE_DIRS}")
target_include_directories(${targetname} PRIVATE ${WEBP_INCLUDE_DIRS})
if ("${CMAKE_BUILD_TYPE}" MATCHES "Debug")
linkTargetWithLibs(${targetname} webpd)
elseif( ("${CMAKE_BUILD_TYPE}" MATCHES "Release") OR ("${CMAKE_BUILD_TYPE}" MATCHES "RelWithDebInfo") )
linkTargetWithLibs(${targetname} webp)
endif()
endfunction()
###################################################################################################
# cedaFindBoost
function(cedaFindBoost)
message("----------------------- boost --------------------------")
if (CEDA_CUSTOM_BUILD_ANDROID)
# This is a hack for allowing our own build of boost for android
# (static boost for android libraries were built on Windows with clang, ndk 19r using our own bash script
# 'buildboostandroid_linux' or 'buildboostandroid_windows' running under git bash)
# It not clear how to make our own build of boost work with Kitware's undocumented FindBoost.cmake
# We can probably make it work, Cameron Lowell Palmer claims it can be done on stackoverflow:
# https://stackoverflow.com/questions/18715694/cmake-doesnt-find-boost-libraries-while-using-android-cmake-toolchain-file
# It is assumed BOOST_INCLUDEDIR and BOOST_LIBRARYDIR are provided in the command line arguments to cmake
# (see windows_build_ceda_sdk_android.bat)
add_definitions(
-DBOOST_UUID_RANDOM_PROVIDER_FORCE_POSIX
)
foreach(name system thread filesystem)
message("Using custom build of boost for android for static library ${BOOST_LIBRARYDIR}/libboost_${name}.a")
add_library(Boost::${name} STATIC IMPORTED)
set_target_properties(Boost::${name} PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${BOOST_INCLUDEDIR}"
IMPORTED_LOCATION "${BOOST_LIBRARYDIR}/libboost_${name}.a"
)
endforeach()
else()
# Boost_ADDITIONAL_VERSIONS can be set to a list of boost versions not known to the cmake FindBoost.cmake module
set(Boost_ADDITIONAL_VERSIONS "1.69.0" "1.69")
#find_package(boost REQUIRED)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost REQUIRED COMPONENTS atomic chrono system thread filesystem locale)
message("Boost_FOUND = ${Boost_FOUND}")
message("Boost_VERSION = ${Boost_VERSION}")
message("Boost_LIB_VERSION = ${Boost_LIB_VERSION}")
message("Boost_INCLUDE_DIRS = ${Boost_INCLUDE_DIRS}")
message("Boost_LIBRARIES = ${Boost_LIBRARIES}")
endif()
endfunction(cedaFindBoost)
# Avoid the need to add the current directory to the include path every time
# https://cmake.org/cmake/help/v3.11/variable/CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE.html#variable:CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE
# If this variable is enabled, CMake automatically adds for each shared library target, static library target,
# module target and executable target, CMAKE_CURRENT_SOURCE_DIR and CMAKE_CURRENT_BINARY_DIR to the
# INTERFACE_INCLUDE_DIRECTORIES target property.
# By default CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE is OFF.
set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
####################################################################################################
# Allow a global list of ceda projects to be defined
set_property(GLOBAL PROPERTY GP_CEDA_PROJECTS "")
function(cedaAddProject arg)
set_property(GLOBAL APPEND PROPERTY GP_CEDA_PROJECTS "${arg}")
endfunction()
####################################################################################################
# Allow a global list of projects that are dependent on ceda projects to be defined
set_property(GLOBAL PROPERTY GP_DEPENDENT_CEDA_PROJECTS "")
function(cedaAddDependentProject arg)
set_property(GLOBAL APPEND PROPERTY GP_DEPENDENT_CEDA_PROJECTS "${arg}")
endfunction()
###################################################################################################
# Allow a global list of ceda source roots to be defined
set_property(GLOBAL PROPERTY GP_CEDA_SOURCE_ROOTS "")
function(cedaAddSourceRoot arg)
set_property(GLOBAL APPEND PROPERTY GP_CEDA_SOURCE_ROOTS "${arg}")
endfunction()
###################################################################################################
macro(cedaSetSourceRoot arg)
# Various values are saved in global properties:
#
# GP_CEDA_XCPP
# GP_CEDA_XCPPCONFIG
# GP_CEDA_CONFIG
# GP_CEDA_PLATFORM
#
# This is necessary because a subdirectory cmake scope may include CedaCommon.cmake and yet the 'last step' call-back
# to cedaRunXcppOnWorkspace may occur in a parent scope where the cmake variables set from CedaCommon.cmake may not be
# visible.
set_property(GLOBAL PROPERTY GP_CEDA_XCPP ${Ceda_XCPP})
set_property(GLOBAL PROPERTY GP_CEDA_XCPPCONFIG ${Ceda_XCPPCONFIG})
# "Debug", "Release" or "RelWithDebInfo"
set_property(GLOBAL PROPERTY GP_CEDA_CONFIG ${CMAKE_BUILD_TYPE})
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "AMD64")
if (${CMAKE_SIZEOF_VOID_P} EQUAL "8")
set(cedaPlatform "Windows-x64")
else()
# If CMAKE_SIZEOF_VOID_P disagrees with CMAKE_SYSTEM_PROCESSOR then go by CMAKE_SIZEOF_VOID_P
set(cedaPlatform "Windows-x86")
endif()
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86")
set(cedaPlatform "Windows-x86")
else()
set(cedaPlatform ${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR})
endif()
else()
set(cedaPlatform ${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR})
endif()
set_property(GLOBAL PROPERTY GP_CEDA_PLATFORM ${cedaPlatform})
set(LIBTYPE "")
if (NOT BUILD_SHARED_LIBS)
set(LIBTYPE "-static")
endif()
# For example CMAKE_BINARY_DIR = C:/cedanet/build-ceda-sdk-samples/Win64-Debug
# So CEDA_XCPP_ROOT = C:/cedanet/build-ceda-sdk-samples/Win64-Debug/ceda-build/xcppsource/Win64/Release
get_property(cedaConfig GLOBAL PROPERTY GP_CEDA_CONFIG)
set(CEDA_XCPP_ROOT ${CMAKE_BINARY_DIR}/ceda-build/xcppsource/${cedaPlatform}/${cedaConfig})
set(CEDA_SOURCE_ROOT "${arg}")
cedaAddSourceRoot("${arg}")
include_directories(${CEDA_XCPP_ROOT})
include_directories(${CEDA_SOURCE_ROOT})
endmacro()
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/ceda-build)
###################################################################################################
#
# +---------------------------+
# | editable sources cxObject | ${editSourcePath}
# +---------------------------+
# |
# \|/ add_custom_target(${name}.in SOURCES ${editSourceFiles})
# |
# +---------------------------+
# | cxObject.in | ${name}.in
# +---------------------------+
# |
# \|/ add_dependencies(CEDA_RUN_XCPP ${name}.in)
# |
# add_executable(Xcpp ...) |
# +---------+ +---------------------------+
# | Xcpp |----->-----| CEDA_RUN_XCPP | add_custom_target(CEDA_RUN_XCPP)
# +---------+ | +---------------------------+ add_custom_command(TARGET CEDA_RUN_XCPP COMMAND ... WORKING_DIRECTORY ... BYPRODUCTS ${sourceFiles})
# | |
# add_dependencies(CEDA_RUN_XCPP Xcpp) |
# | set_source_files_properties(${sourceFiles} PROPERTIES GENERATED 1)
# \|/ (BYPRODUCTS)
# |
# +---------------------------+
# | generated C++ files | ${sourceFiles}
# +---------------------------+
# |
# \|/ add_library(${name} SHARED ${sourceFiles})
# |
# +---------------------------+
# | cxObject.dll | ${name}
# +---------------------------+
set_property(GLOBAL PROPERTY GP_CEDA_BYPRODUCTS "")
add_custom_target(CEDA_RUN_XCPP)
###################################################################################################
# cedaRunXcppOnWorkspace
#
# This is a private function which is called at the end of the configure step to set the command
# used to execute Xcpp to translate all the files in the ceda projects in the virtual tree
function(cedaRunXcppOnWorkspace)
message("------------------------ last step -------------------------")
get_property(cedaByProducts GLOBAL PROPERTY GP_CEDA_BYPRODUCTS)
get_property(cedaProjects GLOBAL PROPERTY GP_CEDA_PROJECTS)
get_property(cedaDependentProjects GLOBAL PROPERTY GP_DEPENDENT_CEDA_PROJECTS)
get_property(cedaSourceRoots GLOBAL PROPERTY GP_CEDA_SOURCE_ROOTS)
get_property(cedaHostOs GLOBAL PROPERTY GP_CEDA_HOST_OS)
get_property(cedaHostOsVersion GLOBAL PROPERTY GP_CEDA_HOST_OS_VERSION)
get_property(cedaTargetOs GLOBAL PROPERTY GP_CEDA_TARGET_OS)
get_property(cedaTargetOsVersion GLOBAL PROPERTY GP_CEDA_TARGET_OS_VERSION)
get_property(cedaPlatform GLOBAL PROPERTY GP_CEDA_PLATFORM)
get_property(cedaConfig GLOBAL PROPERTY GP_CEDA_CONFIG)
get_property(cedaXcpp GLOBAL PROPERTY GP_CEDA_XCPP)
get_property(cedaXcppConfig GLOBAL PROPERTY GP_CEDA_XCPPCONFIG)
message("cedaProjects = ${cedaProjects}")
message("cedaDependentProjects = ${cedaDependentProjects}")
message("cedaSourceRoots = ${cedaSourceRoots}")
message("cedaPlatform = ${cedaPlatform}")
message("cedaConfig = ${cedaConfig}")
message("cedaXcpp = ${cedaXcpp}")
message("cedaXcppConfig = ${cedaXcppConfig}")
set(wslist "")
foreach(s ${cedaProjects})
if (NOT wslist STREQUAL "")
set(wslist "${wslist} ")
endif()
set(wslist "${wslist}'${s}'")
endforeach()
set(vtlist "")
foreach(s ${cedaSourceRoots})
if (NOT vtlist STREQUAL "")
set(vtlist "${vtlist} ")
endif()
set(vtlist "${vtlist}'${s}'")
endforeach()
# CMAKE_HOST_SYSTEM_NAME
# Name of the OS CMake is running on.
# On systems that have the uname command, this variable is set to the output of uname -s.
# Linux, Windows, and Darwin for Mac OS X are the values found on the big three operating systems.
# CMAKE_SYSTEM_NAME
# "Windows", "WindowsCE", "WindowsPhone", "WindowsStore", "Linux", "Darwin" or "Android"
# CMAKE_HOST_SYSTEM_PROCESSOR
# The name of the CPU CMake is running on.
# On systems that support uname, this variable is set to the output of uname -p,
# on windows it is set to the value of the environment variable PROCESSOR_ARCHITECTURE (which can be AMD64, IA64 or x86).
# CMAKE_CXX_COMPILER_ID
# "MSVC", "GNU" or "Clang"
# MSVC_VERSION
# The version of Microsoft Visual C/C++ being used if any.
# Known version numbers are:
# 1200 = VS 6.0
# 1300 = VS 7.0
# 1310 = VS 7.1
# 1400 = VS 8.0
# 1500 = VS 9.0
# 1600 = VS 10.0
# 1700 = VS 11.0
# 1800 = VS 12.0
# 1900 = VS 14.0
# platform='${cedaPlatform}'
# Example 1: Run windows_build_ceda_sdk_android.bat on a x64 machine:
# CMAKE_HOST_SYSTEM_NAME = Windows
# CMAKE_HOST_SYSTEM_PROCESSOR = AMD64
# CMAKE_HOST_SYSTEM_VERSION = 10.0.17134
# CMAKE_SYSTEM_NAME = Android
# CMAKE_SYSTEM_PROCESSOR = aarch64
# CMAKE_SYSTEM_VERSION = 1
# CMAKE_CXX_COMPILER_ID = Clang
# Example 2: Run windows_package_ceda_sdk.bat on a x64 machine:
# CMAKE_HOST_SYSTEM_NAME = Windows
# CMAKE_HOST_SYSTEM_PROCESSOR = AMD64
# CMAKE_HOST_SYSTEM_VERSION = 10.0.17134
# CMAKE_SYSTEM_NAME = Windows
# CMAKE_SYSTEM_PROCESSOR = AMD64
# CMAKE_SYSTEM_VERSION = 10.0.17134
# CMAKE_CXX_COMPILER_ID = MSVC
# MSVC_VERSION = 1915
set(defaultToDll false)
if (BUILD_SHARED_LIBS)
set(defaultToDll true)
endif()
add_custom_command(TARGET CEDA_RUN_XCPP
COMMAND ${cedaXcpp}
HOST_SYSTEM_NAME='${CMAKE_HOST_SYSTEM_NAME}'
HOST_SYSTEM_PROCESSOR='${CMAKE_HOST_SYSTEM_PROCESSOR}'
HOST_SYSTEM_VERSION='${CMAKE_HOST_SYSTEM_VERSION}'
SYSTEM_NAME='${CMAKE_SYSTEM_NAME}'
SYSTEM_PROCESSOR='${CMAKE_SYSTEM_PROCESSOR}'
SYSTEM_VERSION='${CMAKE_SYSTEM_VERSION}'
CXX_COMPILER_ID='${CMAKE_CXX_COMPILER_ID}'
MSVC_VERSION='${MSVC_VERSION}'
PLATFORM='${cedaPlatform}'
Ceda_XCPPCONFIG='${cedaXcppConfig}'
${cedaXcppConfig}/base.xcpp
mode=build
config='${cedaConfig}'
defaultToDll=${defaultToDll}
workspaces={${wslist}} virtualTree={${vtlist}}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/ceda-build
BYPRODUCTS ${cedaByProducts})
if(TARGET Xcpp)
# The executable Xcpp must be built before it can be used to translate files from xc++ to c++
# Xcpp ---> CEDA_RUN_XCPP
add_dependencies(CEDA_RUN_XCPP Xcpp)
endif()
foreach(s ${cedaDependentProjects})
add_dependencies(${s} CEDA_RUN_XCPP)
endforeach()
endfunction(cedaRunXcppOnWorkspace)
###################################################################################################
# This is a hack to ensure cedaRunXcppOnWorkspace() is called exactly at the end of the
# configure step. It involves watching the variable CMAKE_BACKWARDS_COMPATIBILITY which happens
# to be accessed at this time.
# It is a little fragile, it is important to be sure nothing else accesses CMAKE_BACKWARDS_COMPATIBILITY
# See https://stackoverflow.com/questions/15760580/execute-command-or-macro-in-cmake-as-the-last-step-before-the-configure-step-f
set_property(GLOBAL PROPERTY GP_CEDA_HAS_CONFIGURED_XCPP FALSE)
function(EndOfConfigurationHook Variable Access)
if(${Variable} STREQUAL CMAKE_BACKWARDS_COMPATIBILITY AND (${Access} STREQUAL UNKNOWN_READ_ACCESS OR ${Access} STREQUAL READ_ACCESS))
get_property(v GLOBAL PROPERTY GP_CEDA_HAS_CONFIGURED_XCPP)
if (NOT ${v})
cedaRunXcppOnWorkspace()
set_property(GLOBAL PROPERTY GP_CEDA_HAS_CONFIGURED_XCPP TRUE)
endif()
endif()
endfunction()
variable_watch(CMAKE_BACKWARDS_COMPATIBILITY EndOfConfigurationHook)
###################################################################################################
# cedaTarget
function(cedaTarget)
cmake_parse_arguments(
PARSED_ARGS # prefix of output variables
"EXE;XCPP" # list of names of the boolean arguments (only defined ones will be true)
"NAMESPACE;PROJPATH" # list of names of mono-valued arguments
"LIBS;INCLUDES" # list of names of multi-valued arguments (output variables are lists)
${ARGN} # arguments of the function to parse, here we take the all original ones
)
# note: if it remains unparsed arguments, here, they can be found in variable PARSED_ARGS_UNPARSED_ARGUMENTS
if(NOT PARSED_ARGS_PROJPATH)
message(FATAL_ERROR "PROJPATH parameter required in call to cedaTarget")
endif()
set(projPath ${PARSED_ARGS_PROJPATH})
set(libs ${PARSED_ARGS_LIBS})
set(includes ${PARSED_ARGS_INCLUDES})
cedaAddProject(${projPath})
get_filename_component(name ${projPath} NAME)
if (${PARSED_ARGS_EXE})
set(targetType "executable")
else()
set(targetType "library")
endif()
message("------------------------------------------------- ${targetType} ${projPath} -------------------------------------------------")
message("xcpp = ${PARSED_ARGS_XCPP}")
message("libs = ${libs}")
message("includes = ${includes}")
if (${PARSED_ARGS_XCPP})
set(editSourcePath ${CEDA_SOURCE_ROOT}/${projPath})
set(sourcePath ${CEDA_XCPP_ROOT}/${projPath})
message("editSourcePath = ${editSourcePath}")
message("sourcePath = ${sourcePath}")
file(GLOB_RECURSE editSourceFiles ${editSourcePath}/*.h ${editSourcePath}/*.cpp)
# Calculate the list of paths of the read-only source files which are output by Xcpp
set(sourceFiles "") # create empty list
foreach(esf ${editSourceFiles})
string(REPLACE ${editSourcePath} ${sourcePath} out ${esf})
list(APPEND sourceFiles ${out})
endforeach(esf)
add_custom_target(${name}.in SOURCES ${editSourceFiles})
add_dependencies(CEDA_RUN_XCPP ${name}.in)
# Make sure add_executable() / add_library() don't balk because they work with generated files
set_source_files_properties(${sourceFiles} PROPERTIES GENERATED 1)
# Allow BYPRODUCTS to be specified for the command to run Xcpp, to ensure Ninga generator accounts for which
# generated files have changed when it builds targets that depend on those generated files.
set_property(GLOBAL APPEND PROPERTY GP_CEDA_BYPRODUCTS ${sourceFiles})
else()
set(sourcePath ${CEDA_SOURCE_ROOT}/${projPath})
file(GLOB_RECURSE sourceFiles ${sourcePath}/*.h ${sourcePath}/*.cpp)
endif()
list (LENGTH sourceFiles numSourceFiles)
message("${numSourceFiles} source files")
if (${PARSED_ARGS_EXE})
add_executable(${name} ${sourceFiles})
else()
add_library(${name} ${sourceFiles})
if(PARSED_ARGS_NAMESPACE)
# allow qualified name of library to be used
message("Allowing ${PARSED_ARGS_NAMESPACE}::${name} to be used as alias of ${name}")
add_library(${PARSED_ARGS_NAMESPACE}::${name} ALIAS ${name})
endif()
endif()
# The scoping is private because we require other dependent targets to used fully qualified include paths
# (E.g. #include "Ceda/cxUtils/Archive.h")
target_include_directories(${name} PRIVATE ${sourcePath} ${sourcePath}/src ${includes})
target_link_libraries(${name} PUBLIC ${libs})
cedaSetDefaultsForTarget(${name})
if (NOT ${PARSED_ARGS_EXE})
if (NOT BUILD_SHARED_LIBS)
# It is important that this macro be public so it is visible to all users of the library
# (i.e. so that users of the library see it as a static library or else they might apply __declspec(dllimport)
# under the MSVC compiler and end up with unreslved symbol linker errors)
target_compile_definitions(${name} PUBLIC ${name}_STATIC_LIBRARY)
endif()
target_compile_definitions(${name} PRIVATE ${name}_EXPORTS)
# Creates a header file which helps switch between building shared and static libraries
#include(GenerateExportHeader)
#generate_export_header(${name})
#generate_export_header(${name}
# EXPORT_MACRO_NAME ${name}_API
# EXPORT_FILE_NAME ${CMAKE_BINARY_DIR}/include/${name}/core/common.h
#)
endif()
endfunction(cedaTarget)
###################################################################################################
# showCommonVars
function(showCommonVars)
message("--------------- common vars -------------------")
message("PROJECT_NAME = ${PROJECT_NAME}")
message("PROJECT_SOURCE_DIR = ${PROJECT_SOURCE_DIR}")
message("CMAKE_PROJECT_VERSION = ${CMAKE_PROJECT_VERSION}")
message("CMAKE_PROJECT_VERSION_MAJOR = ${CMAKE_PROJECT_VERSION_MAJOR}")
message("CMAKE_PROJECT_VERSION_MINOR = ${CMAKE_PROJECT_VERSION_MINOR}")
message("CMAKE_PROJECT_VERSION_PATCH = ${CMAKE_PROJECT_VERSION_PATCH}")
message("PROJECT_VERSION = ${PROJECT_VERSION}")
message("PROJECT_VERSION_MAJOR = ${PROJECT_VERSION_MAJOR}")
message("PROJECT_VERSION_MINOR = ${PROJECT_VERSION_MINOR}")
message("PROJECT_VERSION_PATCH = ${PROJECT_VERSION_PATCH}")
message("CMAKE_SOURCE_DIR = ${CMAKE_SOURCE_DIR}")
message("CMAKE_CURRENT_SOURCE_DIR = ${CMAKE_CURRENT_SOURCE_DIR}")
message("CMAKE_BINARY_DIR = ${CMAKE_BINARY_DIR}")
message("CMAKE_CURRENT_BINARY_DIR = ${CMAKE_CURRENT_BINARY_DIR}")
message("EXECUTABLE_OUTPUT_PATH = ${EXECUTABLE_OUTPUT_PATH}")
message("LIBRARY_OUTPUT_PATH = ${LIBRARY_OUTPUT_PATH}")
message("CMAKE_HOST_SYSTEM_NAME = ${CMAKE_HOST_SYSTEM_NAME}")
message("CMAKE_HOST_SYSTEM_PROCESSOR = ${CMAKE_HOST_SYSTEM_PROCESSOR}")
message("CMAKE_HOST_SYSTEM_VERSION = ${CMAKE_HOST_SYSTEM_VERSION}")
message("CMAKE_SYSTEM_NAME = ${CMAKE_SYSTEM_NAME}")
message("CMAKE_SYSTEM_PROCESSOR = ${CMAKE_SYSTEM_PROCESSOR}")
message("CMAKE_SYSTEM_VERSION = ${CMAKE_SYSTEM_VERSION}")
message("CMAKE_SIZEOF_VOID_P = ${CMAKE_SIZEOF_VOID_P}")
# The version of Microsoft Visual C/C++ being used if any.
# Known version numbers are:
# 1200 = VS 6.0
# 1300 = VS 7.0
# 1310 = VS 7.1
# 1400 = VS 8.0
# 1500 = VS 9.0
# 1600 = VS 10.0
# 1700 = VS 11.0
# 1800 = VS 12.0
# 1900 = VS 14.0
message("MSVC_VERSION = ${MSVC_VERSION}")
# Default value for the ANDROID_API target property.
message("CMAKE_ANDROID_API = ${CMAKE_ANDROID_API}")
# Default value for the ANDROID_GUI target property of executables
message("CMAKE_ANDROID_GUI = ${CMAKE_ANDROID_GUI}")
# Use the install path for the RPATH
# Normally CMake uses the build tree for the RPATH when building executables etc on systems that
# use RPATH. When the software is installed the executables etc are relinked by CMake to have
# the install RPATH. If this variable is set to true then the software is always built with the
# install path for the RPATH and does not need to be relinked when installed.
message("CMAKE_BUILD_WITH_INSTALL_RPATH = ${CMAKE_BUILD_WITH_INSTALL_RPATH}")
# Output directory for MS debug symbol .pdb files generated by the compiler while building source files.
# This variable is used to initialize the COMPILE_PDB_OUTPUT_DIRECTORY property on all the targets.
message("CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY = ${CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY}")
message("UNIX = ${UNIX}")
message("WIN32 = ${WIN32}")
message("APPLE = ${APPLE}")
message("MSYS = ${MSYS}")
message("CMAKE_CXX_COMPILER_ID = ${CMAKE_CXX_COMPILER_ID}")
message("CMAKE_CXX_COMPILER_VERSION = ${CMAKE_CXX_COMPILER_VERSION}")
message("CMAKE_SYSROOT = ${CMAKE_SYSROOT}")
message("CMAKE_FIND_ROOT_PATH = ${CMAKE_FIND_ROOT_PATH}")
message("CMAKE_TOOLCHAIN_FILE = ${CMAKE_TOOLCHAIN_FILE}")
message("CMAKE_PREFIX_PATH = ${CMAKE_PREFIX_PATH}")
message("CMAKE_SYSTEM_PREFIX_PATH = ${CMAKE_SYSTEM_PREFIX_PATH}")
message("CMAKE_INCLUDE_PATH = ${CMAKE_INCLUDE_PATH}")
message("CMAKE_SYSTEM_INCLUDE_PATH = ${CMAKE_SYSTEM_INCLUDE_PATH}")
message("CMAKE_FRAMEWORK_PATH = ${CMAKE_FRAMEWORK_PATH}")
message("CMAKE_SYSTEM_FRAMEWORK_PATH = ${CMAKE_SYSTEM_FRAMEWORK_PATH}")
message("CMAKE_LIBRARY_ARCHITECTURE = ${CMAKE_LIBRARY_ARCHITECTURE}")
message("CMAKE_INSTALL_PREFIX = ${CMAKE_INSTALL_PREFIX}")
message("CMAKE_INSTALL_LIBDIR = ${CMAKE_INSTALL_LIBDIR}")
message("CMAKE_INSTALL_BINDIR = ${CMAKE_INSTALL_BINDIR}")
message("CMAKE_INSTALL_INCLUDEDIR = ${CMAKE_INSTALL_INCLUDEDIR}")
message("CMAKE_MODULE_PATH = ${CMAKE_MODULE_PATH}")
message("CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}")
message("CMAKE_CONFIGURATION_TYPES = ${CMAKE_CONFIGURATION_TYPES}")
message("VCPKG_TARGET_TRIPLET = ${VCPKG_TARGET_TRIPLET}")
message("BUILD_SHARED_LIBS = ${BUILD_SHARED_LIBS}")
message("CMAKE_CXX_FLAGS = ${CMAKE_CXX_FLAGS}")
message("CMAKE_CXX_FLAGS_DEBUG = ${CMAKE_CXX_FLAGS_DEBUG}")
message("CMAKE_CXX_FLAGS_RELEASE = ${CMAKE_CXX_FLAGS_RELEASE}")
message("CMAKE_CXX_FLAGS_RELWITHDEBINFO = ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
message("CMAKE_C_FLAGS = ${CMAKE_C_FLAGS}")
message("CMAKE_C_FLAGS_DEBUG = ${CMAKE_C_FLAGS_DEBUG}")
message("CMAKE_C_FLAGS_RELEASE = ${CMAKE_C_FLAGS_RELEASE}")
message("CMAKE_C_FLAGS_RELWITHDEBINFO = ${CMAKE_C_FLAGS_RELWITHDEBINFO}")
message("CMAKE_EXE_LINKER_FLAGS = ${CMAKE_EXE_LINKER_FLAGS}")
endfunction(showCommonVars)
###################################################################################################
# showFindVars
function(showFindVars)
message("CMAKE_PREFIX_PATH = ${CMAKE_PREFIX_PATH}")
message("CMAKE_FRAMEWORK_PATH = ${CMAKE_FRAMEWORK_PATH}")
message("CMAKE_APPBUNDLE_PATH = ${CMAKE_APPBUNDLE_PATH}")
message("CMAKE_SYSTEM_PREFIX_PATH = ${CMAKE_SYSTEM_PREFIX_PATH}")
message("CMAKE_SYSTEM_FRAMEWORK_PATH = ${CMAKE_SYSTEM_FRAMEWORK_PATH}")
message("CMAKE_SYSTEM_APPBUNDLE_PATH = ${CMAKE_SYSTEM_APPBUNDLE_PATH}")
message("CMAKE_FIND_ROOT_PATH = ${CMAKE_FIND_ROOT_PATH}")
message("CMAKE_SYSROOT = ${CMAKE_SYSROOT}")
message("CMAKE_STAGING_PREFIX = ${CMAKE_STAGING_PREFIX}")
endfunction(showFindVars)
###################################################################################################
# showCedaVars
function(showCedaVars)
message("--------------- CEDA vars -------------------")
message("Ceda_ROOT = ${Ceda_ROOT}")
message("Ceda_CMAKE = ${Ceda_CMAKE}")
message("Ceda_SDK = ${Ceda_SDK}")
message("Ceda_BIN = ${Ceda_BIN}")
message("Ceda_HOST_BIN = ${Ceda_HOST_BIN}")
message("Ceda_LIB = ${Ceda_LIB}")
message("Ceda_INCLUDE = ${Ceda_INCLUDE}")
message("Ceda_EXPORT = ${Ceda_EXPORT}")
message("Ceda_XCPP = ${Ceda_XCPP}")
message("Ceda_XCPPCONFIG = ${Ceda_XCPPCONFIG}")
message("Ceda_LIBRARIES = ${Ceda_LIBRARIES}")
# The <Package>_FOUND variable is set to true or false, depending on whether the package was found.
message("Ceda_FOUND = ${Ceda_FOUND}")
# The <Package>_DIR cache variable is set to the location of the package configuration file.
message("Ceda_DIR = ${Ceda_DIR}")
# Full provided version string
message("Ceda_VERSION = ${Ceda_VERSION}")
# Major version if provided, else 0
message("Ceda_VERSION_MAJOR = ${Ceda_VERSION_MAJOR}")
# Minor version if provided, else 0
message("Ceda_VERSION_MINOR = ${Ceda_VERSION_MINOR}")
# Patch version if provided, else 0
message("Ceda_VERSION_PATCH = ${Ceda_VERSION_PATCH}")
# Tweak version if provided, else 0
message("Ceda_VERSION_TWEAK = ${Ceda_VERSION_TWEAK}")
# Number of version components, 0 to 4
message("Ceda_VERSION_COUNT = ${Ceda_VERSION_COUNT}")
# CedaSdk_VERSION = 0.0.0
# CedaSdk_VERSION_MAJOR = 0
# CedaSdk_VERSION_MINOR = 0
# CedaSdk_VERSION_PATCH = 0
message("CedaSdk_VERSION = ${CedaSdk_VERSION}")
message("CedaSdk_VERSION_MAJOR = ${CedaSdk_VERSION_MAJOR}")
message("CedaSdk_VERSION_MINOR = ${CedaSdk_VERSION_MINOR}")
message("CedaSdk_VERSION_PATCH = ${CedaSdk_VERSION_PATCH}")
endfunction(showCedaVars)
###################################################################################################
# cedaSetInstallDefaults
macro(cedaSetInstallDefaults)
# Given the name Ceda, cmake looks for a file called CedaConfig.cmake or ceda-config.cmake. The full set of locations
# is specified in the find_package() command documentation. One place it looks is:
# <prefix>/lib/cmake/Ceda*/
# <prefix>/cmake/
# where Ceda* is a case-insensitive globbing expression. In our example the globbing expression will match
# <prefix>/lib/cmake/ceda-1.2 and the package configuration file will be found.
#set(INSTALL_CONFIGDIR "lib/cmake/Ceda")
set(INSTALL_CONFIGDIR "cmake")
if ("${CMAKE_BUILD_TYPE}" MATCHES "Debug")
set(CMAKE_INSTALL_BINDIR "debug/bin")
set(CMAKE_INSTALL_LIBDIR "debug/lib")
else()
set(CMAKE_INSTALL_BINDIR "bin") # redundant - this is the default
set(CMAKE_INSTALL_LIBDIR "lib") # redundant - this is the default
endif()
set(CMAKE_INSTALL_INCLUDEDIR "include") # redundant - this is the default
set(CMAKE_INSTALL_EXPORTDIR "export")
endmacro()
###################################################################################################
# cedaWriteCmakeVarsToFile
function (cedaWriteCmakeVarsToFile pathToFile)
file(WRITE ${pathToFile} "")
get_cmake_property(Vars VARIABLES)
foreach(Var ${Vars})
if (NOT ("${Var}" MATCHES "^ARG") AND
NOT ("${Var}" MATCHES "^_") AND
NOT ("${${Var}}" MATCHES "\"") AND
NOT ("${${Var}}" MATCHES "\\\\") AND
NOT ("${Var}" STREQUAL "CMAKE_CXX_COMPILER_PRODUCED_OUTPUT") AND
NOT ("${${Var}}" STREQUAL ""))
file(APPEND ${pathToFile} "set(${Var} \"${${Var}}\")\n")
endif()
endforeach()
endfunction()
###################################################################################################
# cedaAddPythonPackage
function(cedaAddPythonPackage)
cmake_parse_arguments(
PARSED_ARGS # prefix of output variables
"" # list of names of the boolean arguments (only defined ones will be true)
"NAME;SOURCEDIR" # list of names of mono-valued arguments
"SOURCEFILES;LIBS;GLOBS" # list of names of multi-valued arguments (output variables are lists)
${ARGN} # arguments of the function to parse, here we take the all original ones
)
if(NOT PARSED_ARGS_NAME)
message(FATAL_ERROR "NAME parameter required in call to cedaAddPythonPackage")
endif()
if(NOT PARSED_ARGS_SOURCEDIR)
message(FATAL_ERROR "SOURCEDIR parameter required in call to cedaAddPythonPackage")
endif()
if(NOT PARSED_ARGS_SOURCEFILES)
message(FATAL_ERROR "SOURCEFILES parameter required in call to cedaAddPythonPackage")
endif()
if(NOT PARSED_ARGS_LIBS)
message(FATAL_ERROR "LIBS parameter required in call to cedaAddPythonPackage")
endif()
message(NAME = ${PARSED_ARGS_NAME})
message(SOURCEDIR = ${PARSED_ARGS_SOURCEDIR})
foreach(sourceFile ${PARSED_ARGS_SOURCEFILES})
message(SOURCEFILE = ${sourceFile})
endforeach()
foreach(lib ${PARSED_ARGS_LIBS})
message(LIB = ${lib})
endforeach()
set(packageName ${PARSED_ARGS_NAME})
set(pathToSrcPackage ${PARSED_ARGS_SOURCEDIR})
set(pathToDstPackage "${CMAKE_CURRENT_BINARY_DIR}/${packageName}_package")
cedaWriteCmakeVarsToFile(${CMAKE_CURRENT_BINARY_DIR}/vars.cmake)
file(MAKE_DIRECTORY ${pathToDstPackage}/${packageName}/lib)
set(wheelDeps "") # create empty list
foreach(f ${PARSED_ARGS_SOURCEFILES})
add_custom_command(
OUTPUT ${pathToDstPackage}/${f}
DEPENDS ${pathToSrcPackage}/${f}
COMMENT "Copying ${pathToSrcPackage}/${f} to ${pathToDstPackage}/${f}"
COMMAND ${CMAKE_COMMAND} -DINPUTFILE=${pathToSrcPackage}/${f}
-DOUTPUTFILE=${pathToDstPackage}/${f}
-DVARSFILE=${CMAKE_CURRENT_BINARY_DIR}/vars.cmake
-P ${Ceda_CMAKE}/ConfigureFile.cmake)
list(APPEND wheelDeps ${pathToDstPackage}/${f})
endforeach()
set(counter "0")
foreach(f ${PARSED_ARGS_GLOBS})
# A witness is needed for copying files determined by a glob expression because
# we don't know what files are copied at configure time.
set(witness ${CMAKE_CURRENT_BINARY_DIR}/copied_glob_${counter}_witness)
# Increment the counter
math(EXPR counter "${counter}+1")
add_custom_command(
OUTPUT ${witness}
COMMENT "Copying files matching ${f} to ${pathToDstPackage}/${packageName}/lib"
COMMAND ${CMAKE_COMMAND} -DFILES_TO_COPY=${f}
-DDEST_FOLDER=${pathToDstPackage}/${packageName}/lib
-P ${Ceda_CMAKE}/GlobRecurseFileCopy.cmake
COMMAND ${CMAKE_COMMAND} -E touch ${witness})
list(APPEND wheelDeps ${witness})
endforeach()
foreach(tgt ${PARSED_ARGS_LIBS})
# A witness file is used for the command to copy the shared library file
# This is needed because the name of the shared library file involves the generator expression
# $<TARGET_FILE:${tgt}> and this cannot be evaluated at configure time
set(witness ${CMAKE_CURRENT_BINARY_DIR}/copied_${tgt}_witness)
add_custom_command(
OUTPUT ${witness}
DEPENDS ${tgt}
COMMENT "Copying ${tgt} library to ${pathToDstPackage}/${packageName}/lib"
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${tgt}> ${pathToDstPackage}/${packageName}/lib
COMMAND ${CMAKE_COMMAND} -E touch ${witness})
list(APPEND wheelDeps ${witness})
endforeach()
# A witness file is used for the command to create and install the wheel file
# This is needed because the name of the wheel file is not known at configure time
add_custom_command(
OUTPUT ${pathToDstPackage}/dist/installed_witness
DEPENDS ${wheelDeps}
COMMENT "Creating and installing ${packageName} wheel"
COMMAND ${CMAKE_COMMAND} -DPython2_EXECUTABLE=${Python2_EXECUTABLE} -DPACKAGE=${pathToDstPackage} -P ${Ceda_CMAKE}/CreateAndInstallWheel.cmake)
add_custom_target(${packageName} ALL DEPENDS ${pathToDstPackage}/dist/installed_witness)
endfunction()
###################################################################################################
# cedaAddJni
# Example:
# pythonPackageName = pypizza
# cppJniLib = pizza_jni
# javaJniJar = PizzaJni
# generateJniPythonScript = ${CMAKE_CURRENT_SOURCE_DIR}/generate_pizza_jni_wrappers.py
# cppLibs = "MyCompany::Time;MyCompany::Shapes;MyCompany::Pizza"
function(cedaAddJni pythonPackageName cppJniLib javaJniJar generateJniPythonScript cppLibs)
find_package(Java REQUIRED)
find_package(JNI REQUIRED)
# Path to witness file which is touched after all the .java and .cpp JNI files have been
# created by the python script
set(generate_jni_files_witness ${CMAKE_CURRENT_BINARY_DIR}/generated_jni_files_witness)
# Paths for where the generated .cpp and .java files will be written
set(cppFolderPath ${CMAKE_CURRENT_BINARY_DIR}/cpp)
set(javaFolderPath ${CMAKE_CURRENT_BINARY_DIR}/java)
# These directories must be created at configure time, because the python script doesn't create them
file(MAKE_DIRECTORY ${cppFolderPath})
file(MAKE_DIRECTORY ${javaFolderPath})
# JniFiles.cmake is a generated file which is checked into the source tree in the repo, and only updated
# when it changes.
#
# It sets the variable 'jniCppFiles' to a list of relative paths of the generated JNI cpp files.
#
# This is done so we have the list of paths to the generated files at configure time, making it possible
# for this CMakeLists.txt file to provide the list of paths to the generated files in the call to
# add_library (see below) for the jni library.
#
# This avoids the need for an <a href="https://cmake.org/cmake/help/latest/module/ExternalProject.html">ExternalProject</a>
# as discussed here: <a href="https://stackoverflow.com/questions/4222326/cmake-compiling-generated-files">CMake Compiling Generated Files</a>
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/JniFiles.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/JniFiles.cmake)
else()
message("ERROR : ${CMAKE_CURRENT_SOURCE_DIR}/JniFiles.cmake doesn't exist - run the build to create it then reconfigure")
set(jniCppFiles dummy.cpp)
set(jniJavaFiles dummy.java)
endif()
# Calculate jnifullPathCppFiles to be a list of full paths to the generated cpp files by prepending
# ${cppFolderPath} to each relative path in ${jniCppFiles}
set(jnifullPathCppFiles "")
foreach(f ${jniCppFiles})
list(APPEND jnifullPathCppFiles ${cppFolderPath}/${f})
endforeach()
set(jnifullPathJavaFiles "")
foreach(f ${jniJavaFiles})
list(APPEND jnifullPathJavaFiles ${javaFolderPath}/${f})
endforeach()
# Without this add_library() may balk at configure time if the generated files don't exist yet
# (since they are only created at build time).
set_source_files_properties(${jnifullPathCppFiles} PROPERTIES GENERATED 1)
set_source_files_properties(${jnifullPathJavaFiles} PROPERTIES GENERATED 1)
# Add command to run the python script ${generateJniPythonScript} to generate the JNI files.
add_custom_command(
OUTPUT ${generate_jni_files_witness}
BYPRODUCTS ${jnifullPathCppFiles} ${jnifullPathJavaFiles}
DEPENDS ${generateJniPythonScript} ${pythonPackageName}
COMMENT "Running ${generateJniPythonScript} ${javaFolderPath} ${cppFolderPath}"
COMMAND ${Python2_EXECUTABLE} ${generateJniPythonScript} ${javaFolderPath} ${cppFolderPath}
COMMAND ${CMAKE_COMMAND} -DCPP_PATH=${cppFolderPath} -DJAVA_PATH=${javaFolderPath} -DOUPUT_PATH=${CMAKE_CURRENT_SOURCE_DIR}/JniFiles.cmake -P ${Ceda_CMAKE}/GlobJniFiles.cmake
COMMAND ${CMAKE_COMMAND} -E touch ${generate_jni_files_witness})
add_custom_target(GenScriptTarget_${javaJniJar} DEPENDS ${generate_jni_files_witness})
add_library(${cppJniLib} SHARED ${jnifullPathCppFiles})
cedaAddDependentProject(${cppJniLib})
cedaSetDefaultsForTarget(${cppJniLib})
target_include_directories(${cppJniLib} PRIVATE ${JNI_INCLUDE_DIRS})
target_link_libraries(${cppJniLib} Ceda::cxUtils Ceda::cxObject Ceda::cxPersistStore Ceda::cxJava ${cppLibs})
###################################################################################################
# Create ${javaJniJar}.jar
include(UseJava)
set(CMAKE_JAVA_COMPILE_FLAGS "-source" "1.8" "-target" "1.8")
# This command creates the file ${javaJniJar}.jar.
set(CMAKE_JNI_TARGET TRUE)
add_jar(${javaJniJar} SOURCES ${jnifullPathJavaFiles})
# Make sure the .java files are generated before they are compiled into a jar file
add_dependencies(${javaJniJar} GenScriptTarget_${javaJniJar})
endfunction()