diff --git a/README.md b/README.md index f4c0752..60678ab 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,34 @@ cmake .. make ``` +### Building on Windows + +While most of RADAE is in Python, there is a `lpcnet_demo` application +that is required to be compiled. To do this for Windows, you can run +something like the following from a Linux machine: + +``` +wget https://github.com/mstorsjo/llvm-mingw/releases/download/20240619/llvm-mingw-20240619-ucrt-ubuntu-20.04-x86_64.tar.xz +tar xzf llvm-mingw-20240619-ucrt-ubuntu-20.04-x86_64.tar.xz +export PATH=`pwd`/llvm-mingw-20240619-ucrt-ubuntu-20.04-x86_64/bin:$PATH +export RADAE_PATH=`pwd`/radae +cd $RADAE_PATH +mkdir build_windows +cd build_windows +cmake -DCMAKE_TOOLCHAIN_FILE=$RADAE_PATH/cross-compile/mingw-llvm-x86_64.cmake .. +make +``` + +(Replace `x86_64` in `mingw-llvm-x86_64.cmake` with either `i686` or `aarch64` for 32-bit x86 or 64-bit ARM, respectively.) + +Once done, `lpcnet_demo.exe` will be inside the `src` folder inside `build_windows`. + +#### Limitations + +* ctests are untested and likely do not work without additional changes. +* Visual Studio is not supported, only MinGW. +* Generating a Windows installer is currently not supported. `lpcnet_demo.exe` is intended to be included with other applications built with MinGW (such as freedv-gui). + # Automated Tests The `cmake/ctest` framework is being used as a build and test framework. The command lines in `CmakeLists.txt` are a good source of examples, if you are interested in running the code in this repo. The ctests are a work in progress and may not pass on all systems (see Scope above). diff --git a/cmake/BuildOpus.cmake b/cmake/BuildOpus.cmake index 24667b3..91f1b9b 100644 --- a/cmake/BuildOpus.cmake +++ b/cmake/BuildOpus.cmake @@ -1,11 +1,19 @@ message(STATUS "Will build opus with FARGAN") +set(CONFIGURE_COMMAND ./autogen.sh && ./configure --enable-dred --disable-shared) + +if (CMAKE_CROSSCOMPILING) +set(CONFIGURE_COMMAND ${CONFIGURE_COMMAND} --host=${CMAKE_C_COMPILER_TARGET} --target=${CMAKE_C_COMPILER_TARGET}) +endif (CMAKE_CROSSCOMPILING) + +message(STATUS "${CONFIGURE_COMMAND}") + include(ExternalProject) ExternalProject_Add(build_opus URL https://gitlab.xiph.org/xiph/opus/-/archive/main/opus-main.tar.gz DOWNLOAD_EXTRACT_TIMESTAMP NO BUILD_IN_SOURCE 1 - CONFIGURE_COMMAND ./autogen.sh && ./configure --enable-dred --disable-shared + CONFIGURE_COMMAND ${CONFIGURE_COMMAND} BUILD_COMMAND $(MAKE) INSTALL_COMMAND "" ) @@ -17,7 +25,7 @@ add_dependencies(opus build_opus) set_target_properties(opus PROPERTIES IMPORTED_LOCATION "${BINARY_DIR}/.libs/libopus${CMAKE_STATIC_LIBRARY_SUFFIX}" - IMPORTED_IMPLIB "${BINARY_DIR}/.libs/libopus${CMAKE_IMPORT_LIBRARY_SUFFIX}" + IMPORTED_IMPLIB "${BINARY_DIR}/.libs/libopus${CMAKE_STATIC_LIBRARY_SUFFIX}" ) include_directories(${SOURCE_DIR}/dnn ${SOURCE_DIR}/celt ${SOURCE_DIR}/include) diff --git a/cross-compile/mingw-llvm-aarch64.cmake b/cross-compile/mingw-llvm-aarch64.cmake new file mode 100644 index 0000000..2e7ab0e --- /dev/null +++ b/cross-compile/mingw-llvm-aarch64.cmake @@ -0,0 +1,26 @@ +set(CMAKE_SYSTEM_NAME Windows) +set(CMAKE_SYSTEM_PROCESSOR aarch64) + +set(triple ${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32) + +set(CMAKE_C_COMPILER ${triple}-clang) +set(CMAKE_C_COMPILER_TARGET ${triple}) +set(CMAKE_CXX_COMPILER ${triple}-clang++) +set(CMAKE_CXX_COMPILER_TARGET ${triple}) +set(CMAKE_AR ${triple}-ar) +set(CMAKE_RANLIB ${triple}-ranlib) +set(CMAKE_RC_COMPILER ${triple}-windres) + +set(CMAKE_C_FLAGS "-Wno-unused-command-line-argument -gcodeview") +set(CMAKE_CXX_FLAGS "-Wno-unused-command-line-argument -gcodeview") +set(CMAKE_EXE_LINKER_FLAGS -Wl,--pdb=) + +# For make package use. +set(CMAKE_OBJDUMP ${triple}-objdump) +set(FREEDV_USING_LLVM_MINGW 1) + +# adjust the default behaviour of the FIND_XXX() commands: +# search headers and libraries in the target environment, search +# programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) diff --git a/cross-compile/mingw-llvm-i686.cmake b/cross-compile/mingw-llvm-i686.cmake new file mode 100644 index 0000000..c73338c --- /dev/null +++ b/cross-compile/mingw-llvm-i686.cmake @@ -0,0 +1,28 @@ +set(CMAKE_SYSTEM_NAME Windows) +set(CMAKE_SYSTEM_PROCESSOR i686) + +set(triple ${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32) + +set(CMAKE_C_COMPILER ${triple}-clang) +set(CMAKE_C_COMPILER_TARGET ${triple}) +set(CMAKE_CXX_COMPILER ${triple}-clang++) +set(CMAKE_CXX_COMPILER_TARGET ${triple}) + +set(CMAKE_AR ${triple}-ar) +set(CMAKE_RANLIB ${triple}-ranlib) +set(CMAKE_RC_COMPILER ${triple}-windres) + +set(CMAKE_C_FLAGS "-Wno-unused-command-line-argument -gcodeview") +set(CMAKE_CXX_FLAGS "-Wno-unused-command-line-argument -gcodeview") +set(CMAKE_EXE_LINKER_FLAGS -Wl,--pdb=) + +# For make package use. +set(CMAKE_OBJDUMP ${triple}-objdump) +set(FREEDV_USING_LLVM_MINGW 1) + +# adjust the default behaviour of the FIND_XXX() commands: +# search headers and libraries in the target environment, search +# programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/cross-compile/mingw-llvm-x86_64.cmake b/cross-compile/mingw-llvm-x86_64.cmake new file mode 100644 index 0000000..9161463 --- /dev/null +++ b/cross-compile/mingw-llvm-x86_64.cmake @@ -0,0 +1,28 @@ +set(CMAKE_SYSTEM_NAME Windows) +set(CMAKE_SYSTEM_PROCESSOR x86_64) + +set(triple ${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32) + +set(CMAKE_C_COMPILER ${triple}-clang) +set(CMAKE_C_COMPILER_TARGET ${triple}) +set(CMAKE_CXX_COMPILER ${triple}-clang++) +set(CMAKE_CXX_COMPILER_TARGET ${triple}) + +set(CMAKE_AR ${triple}-ar) +set(CMAKE_RANLIB ${triple}-ranlib) +set(CMAKE_RC_COMPILER ${triple}-windres) + +set(CMAKE_C_FLAGS "-Wno-unused-command-line-argument -gcodeview") +set(CMAKE_CXX_FLAGS "-Wno-unused-command-line-argument -gcodeview") +set(CMAKE_EXE_LINKER_FLAGS -Wl,--pdb=) + +# For make package use. +set(CMAKE_OBJDUMP ${triple}-objdump) +set(FREEDV_USING_LLVM_MINGW 1) + +# adjust the default behaviour of the FIND_XXX() commands: +# search headers and libraries in the target environment, search +# programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/src/lpcnet_demo.c b/src/lpcnet_demo.c index d110715..4ce3d94 100644 --- a/src/lpcnet_demo.c +++ b/src/lpcnet_demo.c @@ -39,6 +39,12 @@ #include "fargan.h" #include "cpu_support.h" +#ifdef _WIN32 +// For _setmode(). +#include +#include +#endif // _WIN32 + #ifdef USE_WEIGHTS_FILE # if __unix__ # include @@ -120,7 +126,14 @@ int main(int argc, char **argv) { if (argc != 4) usage(); if (strcmp(argv[2], "-") == 0) + { +#ifdef _WIN32 + // Note: freopen() returns NULL if filename is NULL, so + // we have to use setmode() to make it a binary stream instead. + _setmode(_fileno(stdin), O_BINARY); +#endif // _WIN32 fin = stdin; + } else fin = fopen(argv[2], "rb"); if (fin == NULL) { @@ -129,7 +142,14 @@ int main(int argc, char **argv) { } if (strcmp(argv[3], "-") == 0) + { +#ifdef _WIN32 + // Note: freopen() returns NULL if filename is NULL, so + // we have to use setmode() to make it a binary stream instead. + _setmode(_fileno(stdout), O_BINARY); +#endif // _WIN32 fout = stdout; + } else fout = fopen(argv[3], "wb"); if (fout == NULL) {