* CMake build infrastructure The squashed commit that builds and packages releases for the SIMH simulator suite with CMake, version 3.14 or newer. See README-CMake.md for documentation.
346 lines
16 KiB
CMake
346 lines
16 KiB
CMake
##+
|
|
## dep-link.cmake: Create the dependency interface libraries
|
|
##-
|
|
|
|
add_library(simh_regexp INTERFACE)
|
|
add_library(simh_video INTERFACE)
|
|
add_library(simh_network INTERFACE)
|
|
|
|
## LIBPCAP is a special case
|
|
set(LIBPCAP_PROJECT "libpcap")
|
|
set(LIBPCAP_ARCHIVE_NAME "libpcap")
|
|
set(LIBPCAP_RELEASE "1.10.1")
|
|
set(LIBPCAP_ARCHIVE_TYPE "tar.gz")
|
|
set(LIBPCAP_TAR_ARCHIVE "${LIBPCAP_ARCHIVE_NAME}-${LIBPCAP_RELEASE}.${LIBPCAP_ARCHIVE_TYPE}")
|
|
set(LIBPCAP_SOURCE_URL "https://github.com/the-tcpdump-group/libpcap/archive/refs/tags/${LIBPCAP_TAR_ARCHIVE}")
|
|
|
|
function(fix_interface_libs _targ)
|
|
get_target_property(_aliased ${_targ} ALIASED_TARGET)
|
|
if(NOT _aliased)
|
|
set(fixed_libs)
|
|
get_property(orig_libs TARGET ${_targ} PROPERTY INTERFACE_LINK_LIBRARIES)
|
|
foreach(each_lib IN LISTS ${_lib})
|
|
string(STRIP ${each_lib} stripped_lib)
|
|
list(APPEND fixed_libs ${stripped_lib})
|
|
message("** \"${each_lib}\" -> \"${stripped_lib}\"")
|
|
endforeach ()
|
|
set_property(TARGET ${_targ} PROPERTY INTERFACE_LINK_LIBRARIES ${fixed_libs})
|
|
endif ()
|
|
endfunction ()
|
|
|
|
## Ubuntu 16.04 -- when we find the SDL2 library, there are trailing spaces. Strip
|
|
## spaces from SDL2_LIBRARIES (and potentially others as we find them).
|
|
function (fix_libraries _lib)
|
|
set(fixed_libs)
|
|
foreach(each_lib IN LISTS ${_lib})
|
|
string(STRIP ${each_lib} stripped_lib)
|
|
list(APPEND fixed_libs ${stripped_lib})
|
|
endforeach ()
|
|
set(${_lib} ${fixed_libs} PARENT_SCOPE)
|
|
endfunction ()
|
|
|
|
set(BUILD_WITH_VIDEO FALSE)
|
|
IF (WITH_VIDEO)
|
|
## +10 chaotic neutral hack: The SDL2_ttf CMake configuration include "-lfreetype" and
|
|
## "-lharfbuzz", but, if you're on MacOS, you need to tell the linker where these libraries
|
|
## are located...
|
|
set(ldirs)
|
|
foreach (lname ${FREETYPE_LIBRARIES} ${FREETYPE_LIBRARY} ${HARFBUZZ_LIBRARIES} ${HARFBUZZ_LIBRARY})
|
|
get_filename_component(dirname "${lname}" DIRECTORY)
|
|
if (dirname)
|
|
list(APPEND ldirs ${dirname})
|
|
endif()
|
|
endforeach ()
|
|
get_property(ilink_dirs TARGET simh_video PROPERTY INTERFACE_LINK_DIRECTORIES)
|
|
list(APPEND ilink_dirs ${ldirs})
|
|
set_property(TARGET simh_video PROPERTY INTERFACE_LINK_DIRECTORIES ${ilink_dirs})
|
|
unset(ilink_dirs)
|
|
unset(ldirs)
|
|
|
|
IF (SDL2_ttf_FOUND)
|
|
IF (WIN32 AND TARGET SDL2_ttf::SDL2_ttf-static)
|
|
target_link_libraries(simh_video INTERFACE SDL2_ttf::SDL2_ttf-static)
|
|
list(APPEND VIDEO_PKG_STATUS "SDL2_ttf static")
|
|
ELSEIF (TARGET SDL2_ttf::SDL2_ttf)
|
|
target_link_libraries(simh_video INTERFACE SDL2_ttf::SDL2_ttf)
|
|
list(APPEND VIDEO_PKG_STATUS "SDL2_ttf dynamic")
|
|
ELSEIF (TARGET PkgConfig::SDL2_ttf)
|
|
target_link_libraries(simh_video INTERFACE PkgConfig::SDL2_ttf)
|
|
list(APPEND VIDEO_PKG_STATUS "pkg-config SDL2_ttf")
|
|
ELSEIF (DEFINED SDL_ttf_LIBRARIES AND DEFINED SDL_ttf_INCLUDE_DIRS)
|
|
target_link_libraries(simh_video INTERFACE ${SDL_ttf_LIBRARIES})
|
|
target_include_directories(simh_video INTERFACE ${SDL_ttf_INCLUDE_DIRS})
|
|
list(APPEND VIDEO_PKG_STATUS "detected SDL2_ttf")
|
|
ELSE ()
|
|
message(FATAL_ERROR "SDL2_ttf_FOUND set but no SDL2_ttf::SDL2_ttf import library or SDL_ttf_LIBRARIES/SDL_ttf_INCLUDE_DIRS? ")
|
|
ENDIF ()
|
|
ENDIF (SDL2_ttf_FOUND)
|
|
|
|
IF (SDL2_FOUND)
|
|
target_compile_definitions(simh_video INTERFACE USE_SIM_VIDEO HAVE_LIBSDL)
|
|
##
|
|
## Hopefully this hack can go away. Had to move the target_compile_definitions
|
|
## over to add_simulator.cmake to accomodate the BESM6 SDL irregularity.
|
|
##
|
|
## (keep) if (CMAKE_HOST_APPLE)
|
|
## (keep) ## NOTE: This shouldn't be just an Apple platform quirk; SDL_main should
|
|
## (keep) ## be used by all platforms. <sigh!>
|
|
## (keep) target_compile_definitions(simh_video INTERFACE SDL_MAIN_AVAILABLE)
|
|
## (keep) endif ()
|
|
|
|
## Link to SDL2main if defined for this platform.
|
|
target_link_libraries(simh_video INTERFACE $<TARGET_NAME_IF_EXISTS:SDL2::SDL2main>)
|
|
|
|
IF (WIN32 AND TARGET SDL2::SDL2-static AND TARGET SDL2_ttf::SDL2_ttf-static)
|
|
## Prefer the static version on Windows, but only if SDL2_ttf is also static.
|
|
target_link_libraries(simh_video INTERFACE SDL2::SDL2-static)
|
|
list(APPEND VIDEO_PKG_STATUS "SDL2 static")
|
|
ELSEIF (TARGET SDL2::SDL2)
|
|
fix_interface_libs(SDL2::SDL2)
|
|
target_link_libraries(simh_video INTERFACE SDL2::SDL2)
|
|
list(APPEND VIDEO_PKG_STATUS "SDL2 dynamic")
|
|
ELSEIF (TARGET PkgConfig::SDL2)
|
|
fix_interface_libs(PkgConfig::SDL2)
|
|
target_link_libraries(simh_video INTERFACE PkgConfig::SDL2)
|
|
list(APPEND VIDEO_PKG_STATUS "pkg-config SDL2")
|
|
ELSEIF (DEFINED SDL2_LIBRARIES AND DEFINED SDL2_INCLUDE_DIRS)
|
|
fix_libraries(SDL2_LIBRARIES)
|
|
target_link_libraries(simh_video INTERFACE ${SDL2_LIBRARIES})
|
|
target_include_directories(simh_video INTERFACE ${SDL2_INCLUDE_DIRS})
|
|
list(APPEND VIDEO_PKG_STATUS "detected SDL2")
|
|
ELSE ()
|
|
message(FATAL_ERROR "SDL2_FOUND set but no SDL2::SDL2 import library or SDL2_LIBRARIES/SDL2_INCLUDE_DIRS?")
|
|
ENDIF ()
|
|
ENDIF (SDL2_FOUND)
|
|
|
|
IF (NOT USING_VCPKG AND FREETYPE_FOUND)
|
|
if (TARGET Freetype::Freetype)
|
|
target_link_libraries(simh_video INTERFACE freetype)
|
|
list(APPEND VIDEO_PKG_STATUS "Freetype::Freetype")
|
|
ELSEIF (TARGET PkgConfig::Freetype)
|
|
target_link_libraries(simh_video INTERFACE PkgConfig::Freetype)
|
|
list(APPEND VIDEO_PKG_STATUS "pkg-config Freetype")
|
|
ELSE ()
|
|
target_link_libraries(simh_video INTERFACE ${FREETYPE_LIBRARIES})
|
|
target_include_directories(simh_video INTERFACE ${FREETYPE_INCLUDE_DIRS})
|
|
list(APPEND VIDEO_PKG_STATUS "detected Freetype")
|
|
ENDIF ()
|
|
ENDIF ()
|
|
|
|
IF (PNG_FOUND)
|
|
if (TARGET PNG::PNG)
|
|
target_link_libraries(simh_video INTERFACE PNG::PNG)
|
|
list(APPEND VIDEO_PKG_STATUS "interface PNG")
|
|
elseif (TARGET PkgConfig::PNG)
|
|
target_link_libraries(simh_video INTERFACE PkgConfig::PNG)
|
|
list(APPEND VIDEO_PKG_STATUS "pkg-config PNG")
|
|
else ()
|
|
target_include_directories(simh_video INTERFACE ${PNG_INCLUDE_DIRS})
|
|
target_link_libraries(simh_video INTERFACE ${PNG_LIBRARIES})
|
|
list(APPEND VIDEO_PKG_STATUS "detected PNG")
|
|
endif ()
|
|
ENDIF (PNG_FOUND)
|
|
|
|
set(BUILD_WITH_VIDEO TRUE)
|
|
ELSE ()
|
|
set(VIDEO_PKG_STATUS "video support disabled")
|
|
ENDIF()
|
|
|
|
if (WITH_REGEX)
|
|
## TEMP: Use PCRE until patches for PCRE2 are avaiable.
|
|
##
|
|
## 1. Prefer PCRE2 over PCRE (unless PREFER_PCRE is set)
|
|
## 2. Prefer interface libraries before using detected find_package
|
|
## variables.
|
|
IF (TARGET PkgConfig::PCRE)
|
|
target_link_libraries(simh_regexp INTERFACE PkgConfig::PCRE)
|
|
if (PREFER_PCRE)
|
|
target_compile_definitions(simh_regexp INTERFACE HAVE_PCRE_H)
|
|
set(PCRE_PKG_STATUS "pkg-config pcre")
|
|
else ()
|
|
target_compile_definitions(simh_regexp INTERFACE HAVE_PCRE2_H)
|
|
if (WIN32)
|
|
## Use static linkage (vice DLL) on Windows:
|
|
target_compile_definitions(simh_regexp INTERFACE PCRE2_STATIC)
|
|
endif ()
|
|
set(PCRE_PKG_STATUS "pkg-config pcre2")
|
|
endif ()
|
|
ELSEIF (TARGET unofficial::pcre::pcre)
|
|
## vcpkg:
|
|
target_link_libraries(simh_regexp INTERFACE unofficial::pcre::pcre)
|
|
target_compile_definitions(simh_regexp INTERFACE HAVE_PCRE_H)
|
|
target_compile_definitions(simh_regexp INTERFACE PCRE_STATIC)
|
|
set(PCRE_PKG_STATUS "vcpkg pcre")
|
|
ELSEIF (NOT PREFER_PCRE AND PCRE2_FOUND)
|
|
target_compile_definitions(simh_regexp INTERFACE HAVE_PCRE2_H)
|
|
target_include_directories(simh_regexp INTERFACE ${PCRE2_INCLUDE_DIRS})
|
|
if (NOT WIN32)
|
|
target_link_libraries(simh_regexp INTERFACE ${PCRE2_LIBRARY})
|
|
else ()
|
|
## Use static linkage (vice DLL) on Windows:
|
|
target_compile_definitions(simh_regexp INTERFACE PCRE2_STATIC)
|
|
endif ()
|
|
|
|
set(PCRE_PKG_STATUS "detected pcre2")
|
|
ELSEIF (PCRE_FOUND)
|
|
target_compile_definitions(simh_regexp INTERFACE HAVE_PCRE_H)
|
|
target_include_directories(simh_regexp INTERFACE ${PCRE_INCLUDE_DIRS})
|
|
target_link_libraries(simh_regexp INTERFACE ${PCRE_LIBRARY})
|
|
if (WIN32)
|
|
target_compile_definitions(simh_regexp INTERFACE PCRE_STATIC)
|
|
endif ()
|
|
set(PCRE_PKG_STATUS "detected pcre")
|
|
endif ()
|
|
endif ()
|
|
|
|
if ((WITH_REGEX OR WITH_VIDEO) AND ZLIB_FOUND)
|
|
target_compile_definitions(simh_regexp INTERFACE HAVE_ZLIB)
|
|
target_compile_definitions(simh_video INTERFACE HAVE_ZLIB)
|
|
if (TARGET ZLIB::ZLIB)
|
|
target_link_libraries(simh_regexp INTERFACE ZLIB::ZLIB)
|
|
target_link_libraries(simh_video INTERFACE ZLIB::ZLIB)
|
|
set(ZLIB_PKG_STATUS "interface ZLIB")
|
|
elseif (TARGET PkgConfig::ZLIB)
|
|
target_link_libraries(simh_regexp INTERFACE PkgConfig::ZLIB)
|
|
target_link_libraries(simh_video INTERFACE PkgConfig::ZLIB)
|
|
set(ZLIB_PKG_STATUS "pkg-config ZLIB")
|
|
else ()
|
|
target_include_directories(simh_regexp INTERFACE ${ZLIB_INCLUDE_DIRS})
|
|
target_link_libraries(simh_regexp INTERFACE ${ZLIB_LIBRARIES})
|
|
target_include_directories(simh_video INTERFACE ${ZLIB_INCLUDE_DIRS})
|
|
target_link_libraries(simh_video INTERFACE ${ZLIB_LIBRARIES})
|
|
set(ZLIB_PKG_STATUS "detected ZLIB")
|
|
endif ()
|
|
endif ()
|
|
|
|
|
|
if (WITH_NETWORK)
|
|
set(network_runtime USE_SHARED)
|
|
## pcap is special: Headers only and dynamically loaded.
|
|
if (WITH_PCAP)
|
|
find_package(PCAP)
|
|
|
|
if (NOT PCAP_FOUND)
|
|
list(APPEND NETWORK_PKG_STATUS "PCAP dynamic (unpacked)")
|
|
|
|
message(STATUS "Downloading ${LIBPCAP_SOURCE_URL}")
|
|
message(STATUS "Destination ${CMAKE_BINARY_DIR}/libpcap")
|
|
execute_process(
|
|
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/libpcap"
|
|
RESULT_VARIABLE LIBPCAP_MKDIR
|
|
)
|
|
if (NOT (${LIBPCAP_MKDIR} EQUAL 0))
|
|
message(FATAL_ERROR "Could not create ${CMAKE_CMAKE_BINARY_DIR}/libpcap")
|
|
endif (NOT (${LIBPCAP_MKDIR} EQUAL 0))
|
|
|
|
file(DOWNLOAD "${LIBPCAP_SOURCE_URL}" "${CMAKE_BINARY_DIR}/libpcap/libpcap.${LIBPCAP_ARCHIVE_TYPE}"
|
|
STATUS LIBPCAP_DOWNLOAD
|
|
)
|
|
list(GET LIBPCAP_DOWNLOAD 0 LIBPCAP_DL_STATUS)
|
|
if (NOT (${LIBPCAP_DL_STATUS} EQUAL 0))
|
|
list(GET LIBPCAP_DOWNLOAD 1 LIBPCAP_DL_ERROR)
|
|
message(FATAL_ERROR "Download failed: ${LIBPCAP_DL_ERROR}")
|
|
endif (NOT (${LIBPCAP_DL_STATUS} EQUAL 0))
|
|
|
|
message(STATUS "Extracting headers ${LIBPCAP_SOURCE_URL}")
|
|
execute_process(
|
|
COMMAND ${CMAKE_COMMAND} -E tar xvf "${CMAKE_BINARY_DIR}/libpcap/libpcap.${LIBPCAP_ARCHIVE_TYPE}"
|
|
"${LIBPCAP_PROJECT}-${LIBPCAP_ARCHIVE_NAME}-${LIBPCAP_RELEASE}/pcap.h"
|
|
"${LIBPCAP_PROJECT}-${LIBPCAP_ARCHIVE_NAME}-${LIBPCAP_RELEASE}/pcap/*.h"
|
|
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/libpcap"
|
|
RESULT_VARIABLE LIBPCAP_EXTRACT
|
|
)
|
|
if (NOT (${LIBPCAP_EXTRACT} EQUAL 0))
|
|
message(FATAL_ERROR "Extract failed.")
|
|
endif (NOT (${LIBPCAP_EXTRACT} EQUAL 0))
|
|
|
|
message(STATUS "Copying headers from ${CMAKE_BINARY_DIR}/libpcap/${LIBPCAP_PROJECT}-${LIBPCAP_ARCHIVE_NAME}-${LIBPCAP_RELEASE}/pcap")
|
|
message(STATUS "Destination ${CMAKE_BINARY_DIR}/include/pcap")
|
|
execute_process(
|
|
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
|
"${LIBPCAP_PROJECT}-${LIBPCAP_ARCHIVE_NAME}-${LIBPCAP_RELEASE}/"
|
|
"${CMAKE_BINARY_DIR}/include/"
|
|
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/libpcap"
|
|
RESULT_VARIABLE LIBPCAP_COPYDIR
|
|
)
|
|
if (NOT (${LIBPCAP_COPYDIR} EQUAL 0))
|
|
message(FATAL_ERROR "Copy failed.")
|
|
endif (NOT (${LIBPCAP_COPYDIR} EQUAL 0))
|
|
|
|
## And try finding it again...
|
|
find_package(PCAP)
|
|
else ()
|
|
list (APPEND NETWORK_PKG_STATUS "PCAP dynamic")
|
|
endif ()
|
|
|
|
|
|
if (PCAP_FOUND)
|
|
set(network_runtime USE_SHARED)
|
|
foreach(hdr "${PCAP_INCLUDE_DIRS}")
|
|
file(STRINGS ${hdr}/pcap/pcap.h hdrcontent REGEX "pcap_compile *\\(.*const")
|
|
# message("hdrcontent: ${hdrcontent}")
|
|
list(LENGTH hdrcontent have_bpf_const)
|
|
if (${have_bpf_const} GREATER 0)
|
|
message(STATUS "pcap_compile requires BPF_CONST_STRING")
|
|
list(APPEND network_runtime BPF_CONST_STRING)
|
|
endif()
|
|
endforeach()
|
|
|
|
target_include_directories(simh_network INTERFACE "${PCAP_INCLUDE_DIRS}")
|
|
target_compile_definitions(simh_network INTERFACE HAVE_PCAP_NETWORK)
|
|
endif ()
|
|
endif ()
|
|
|
|
## TAP/TUN devices
|
|
if (WITH_TAP)
|
|
target_compile_definitions(simh_network INTERFACE ${NETWORK_TUN_DEFS})
|
|
endif (WITH_TAP)
|
|
|
|
if (WITH_VDE AND VDE_FOUND)
|
|
if (TARGET PkgConfig::VDE)
|
|
target_compile_definitions(simh_network INTERFACE $<TARGET_PROPERTY:PkgConfig::VDE,INTERFACE_COMPILE_DEFINITIONS>)
|
|
target_include_directories(simh_network INTERFACE $<TARGET_PROPERTY:PkgConfig::VDE,INTERFACE_INCLUDE_DIRECTORIES>)
|
|
target_link_libraries(simh_network INTERFACE PkgConfig::VDE)
|
|
list(APPEND NETWORK_PKG_STATUS "pkg-config VDE")
|
|
else ()
|
|
target_include_directories(simh_network INTERFACE "${VDEPLUG_INCLUDE_DIRS}")
|
|
target_link_libraries(simh_network INTERFACE "${VDEPLUG_LIBRARY}")
|
|
list(APPEND NETWORK_PKG_STATUS "detected VDE")
|
|
endif ()
|
|
|
|
target_compile_definitions(simh_network INTERFACE HAVE_VDE_NETWORK)
|
|
endif ()
|
|
|
|
if (WITH_TAP)
|
|
if (HAVE_TAP_NETWORK)
|
|
target_compile_definitions(simh_network INTERFACE HAVE_TAP_NETWORK)
|
|
|
|
if (HAVE_BSDTUNTAP)
|
|
target_compile_definitions(simh_network INTERFACE HAVE_BSDTUNTAP)
|
|
list(APPEND NETWORK_PKG_STATUS "BSD TUN/TAP")
|
|
else (HAVE_BSDTUNTAP)
|
|
list(APPEND NETWORK_PKG_STATUS "TAP")
|
|
endif (HAVE_BSDTUNTAP)
|
|
|
|
endif (HAVE_TAP_NETWORK)
|
|
endif (WITH_TAP)
|
|
|
|
if (WITH_SLIRP)
|
|
target_link_libraries(simh_network INTERFACE slirp)
|
|
list(APPEND NETWORK_PKG_STATUS "NAT(SLiRP)")
|
|
endif (WITH_SLIRP)
|
|
|
|
## Finally, set the network runtime
|
|
if (NOT network_runtime)
|
|
## Default to USE_SHARED... USE_NETWORK is deprecated.
|
|
set(network_runtime USE_SHARED)
|
|
endif (NOT network_runtime)
|
|
|
|
target_compile_definitions(simh_network INTERFACE ${network_runtime})
|
|
|
|
set(BUILD_WITH_NETWORK TRUE)
|
|
else (WITH_NETWORK)
|
|
set(NETWORK_STATUS "networking disabled")
|
|
set(NETWORK_PKG_STATUS "network disabled")
|
|
set(BUILD_WITH_NETWORK FALSE)
|
|
endif (WITH_NETWORK)
|