diff --git a/linux.md b/linux.md index 1013f0b9..c1416611 100644 --- a/linux.md +++ b/linux.md @@ -35,13 +35,15 @@ Almost everything works, except the serial port. The UI has been rewritten in Qt or ImGui. The rest works very well. -Uthernet is supported, but it requires elevated capabilities: +Uthernet I is supported via `libpcap`, but it requires elevated capabilities: `sudo setcap cap_net_raw=ep ./sa2` Unfortunately, this must be reapplied after every build. -Uthernet II is supported too (only MACRAW) and by default uses `libslirp` which does *not* require elevated capabilities. Use the ImGui settings to enable it. +Uthernet II is supported too and by default uses `libslirp` which does *not* require elevated capabilities. Use the ImGui settings to enable it. + +`libslirp` is not packaged on Raspberry Pi OS. `libpcap` will be used instead, unless the user manually compiles and installs [libslirp](https://gitlab.freedesktop.org/slirp/libslirp). Most of the debugger now works (in the ImGui version). diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index dd4a2b91..faefae91 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -1,5 +1,33 @@ include(FindPkgConfig) +pkg_check_modules(YAML REQUIRED yaml-0.1) +pkg_check_modules(MINIZIP REQUIRED minizip) +pkg_check_modules(SLIRP slirp) + +if ("${SLIRP_FOUND}" STREQUAL "") + message(WARNING "'libslirp' not found. Will use 'libpcap' instead") +endif() + +pkg_check_modules(PCAP libpcap) +if ("${PCAP_FOUND}" STREQUAL "") + # old versions of pcap do not work with pkg-config + # this is necessary on Rapsberri Pi OS + execute_process(COMMAND pcap-config --cflags + OUTPUT_VARIABLE PCAP_INCLUDE_DIRS + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE STATUS) + if ("${STATUS}" STREQUAL "0") + message("Found 'libpcap' via pcap-config") + else() + message(FATAL_ERROR "Cannot locate 'libpcap-dev'") + endif() + execute_process(COMMAND pcap-config --libs + OUTPUT_VARIABLE PCAP_LIBRARIES + OUTPUT_STRIP_TRAILING_WHITESPACE) +endif() + +find_package(Boost REQUIRED) + set(SOURCE_FILES Tfe/tfe.cpp Tfe/tfearch.cpp @@ -197,13 +225,8 @@ add_library(appleii SHARED ${HEADER_FILES} ) -pkg_check_modules(YAML REQUIRED yaml-0.1) -pkg_check_modules(MINIZIP REQUIRED minizip) -pkg_check_modules(PCAP REQUIRED libpcap) -pkg_check_modules(SLIRP REQUIRED slirp) -find_package(Boost REQUIRED) - target_include_directories(appleii PRIVATE + ${CMAKE_CURRENT_BINARY_DIR} # for config.h ${YAML_INCLUDE_DIRS} ${PCAP_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} @@ -232,5 +255,7 @@ add_custom_command( COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/bin/*.SYM ${CMAKE_BINARY_DIR} ) +configure_file(linux/config.h.in linux/config.h) + install(TARGETS appleii DESTINATION lib) diff --git a/source/frontends/libretro/CMakeLists.txt b/source/frontends/libretro/CMakeLists.txt index 750a6420..165879f4 100644 --- a/source/frontends/libretro/CMakeLists.txt +++ b/source/frontends/libretro/CMakeLists.txt @@ -48,5 +48,5 @@ if (EXISTS ${LIBRETRO_COMMON_PATH}/include/libretro.h) set_target_properties(applewin_libretro PROPERTIES PREFIX "") else() - message("Bad LIBRETRO_COMMON_PATH=${LIBRETRO_COMMON_PATH}, skipping libretro code") + message(WARNING "Bad LIBRETRO_COMMON_PATH=${LIBRETRO_COMMON_PATH}, skipping 'libretro' core") endif() diff --git a/source/linux/config.h.in b/source/linux/config.h.in new file mode 100644 index 00000000..d6fd654b --- /dev/null +++ b/source/linux/config.h.in @@ -0,0 +1 @@ +#cmakedefine SLIRP_FOUND "@SLIRP_FOUND@" diff --git a/source/linux/network/slirp2.cpp b/source/linux/network/slirp2.cpp index 3ca17b1b..01d13085 100644 --- a/source/linux/network/slirp2.cpp +++ b/source/linux/network/slirp2.cpp @@ -1,12 +1,15 @@ #include + +#include "linux/network/slirp2.h" + +#ifdef U2_USE_SLIRP + #include #include "Log.h" #include "CPU.h" #include "Core.h" -#include "linux/network/slirp2.h" - #define IP_PACK(a,b,c,d) htonl( ((a)<<24) | ((b)<<16) | ((c)<<8) | (d)) namespace @@ -179,3 +182,5 @@ void SlirpNet::clearQueue() { std::queue>().swap(myQueue); } + +#endif diff --git a/source/linux/network/slirp2.h b/source/linux/network/slirp2.h index 8eeb6f86..b4a89b34 100644 --- a/source/linux/network/slirp2.h +++ b/source/linux/network/slirp2.h @@ -1,4 +1,14 @@ #pragma once + +#include "linux/config.h" + +#ifdef SLIRP_FOUND +// disable to use libpcap in all cases +#define U2_USE_SLIRP +#endif + +#ifdef U2_USE_SLIRP + #include #include #include @@ -29,3 +39,5 @@ private: std::queue> myQueue; }; + +#endif diff --git a/source/linux/network/uthernet2.cpp b/source/linux/network/uthernet2.cpp index d50979e1..5a241456 100644 --- a/source/linux/network/uthernet2.cpp +++ b/source/linux/network/uthernet2.cpp @@ -13,15 +13,12 @@ // #define U2_LOG_STATE // #define U2_LOG_UNKNOWN -// if this is defined, libslirp is used as opposed to libpcap -#define U2_USE_SLIRP - #include "linux/network/uthernet2.h" #include "linux/network/registers.h" -#ifdef U2_USE_SLIRP #include "linux/network/slirp2.h" -#else + +#ifndef U2_USE_SLIRP #include "linux/network/tfe2.h" #include "Tfe/tfe.h" #endif @@ -570,7 +567,7 @@ namespace const int fd = socket(AF_INET, type | SOCK_NONBLOCK, protocol); if (fd < -1) { -#ifdef U2_LOG_STATE +#ifdef U2_LOG_STATE const char * proto = state == SN_SR_SOCK_UDP ? "UDP" : "TCP"; LogFileOutput("U2: %s[%d]: %s\n", proto, i, strerror(errno)); #endif @@ -608,7 +605,7 @@ namespace #endif } resetRXTXBuffers(i); // needed? -#ifdef U2_LOG_STATE +#ifdef U2_LOG_STATE LogFileOutput("U2: OPEN[%d]: %02x\n", i, sr); #endif } @@ -617,7 +614,7 @@ namespace { Socket & socket = sockets[i]; socket.clearFD(); -#ifdef U2_LOG_STATE +#ifdef U2_LOG_STATE LogFileOutput("U2: CLOSE[%d]\n", i); #endif }