How to cross compile from linux host to windows target?

Linux build process works like charm:

git clone https://git.torproject.org/tor.git
cd git
sh autogen.sh && ./configure && make && make install

But how can I target windows x64?

export CFLAGS="-target x86_64-w64-windows-gnu -v -I$OPENSSL/include -I$ZLIB/include -I$LIBEVENT/include"
export LDFLAGS="-Wl,--nxcompat -Wl,--dynamicbase  -L$OPENSSL/lib64 -L$ZLIB -L$LIBEVENT" #-L$OPENSSL
export CC=/usr/bin/clang

./autogen.sh
./configure --enable-static-tor --enable-static-zlib --enable-static-libevent --enable-static-openssl --host=x86_64-w64-mingw32 --disable-tool-name-check --with-libevent-dir=$LIBEVENT --with-openssl-dir=$OPENSSL --with-zlib-dir=$ZLIB
make -j
     "/usr/bin/clang-14" -cc1 -triple x86_64-w64-windows-gnu -emit-obj --mrelax-relocations -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name connection.c -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -mms-bitfields -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debug-info-kind=constructor -dwarf-version=4 -debugger-tuning=gdb -v -v -fcoverage-compilation-dir=tor -resource-dir /usr/lib/clang/14.0.0 -dependency-file src/core/mainloop/.deps/connection.Tpo -MT src/core/mainloop/connection.o -sys-header-deps -MP -D HAVE_CONFIG_H -I . -I ./src -I ./src/ext -I ./src/ext/trunnel -I ./src/trunnel -I ./src/ext -I src/ext -D "SHARE_DATADIR=\"/usr/local/share\"" -D "LOCALSTATEDIR=\"/usr/local/var\"" -D "BINDIR=\"/usr/local/bin\"" -I openssl/dist/usr/local/include -I zlib/dist/usr/local/include -I libevent/dist/usr/local/include -I libevent/dist/usr/local/include -I openssl/dist/usr/local/include -I zlib/dist/usr/local/include -I /usr/local/include -I openssl/dist/usr/local/include -I zlib/dist/usr/local/include -I libevent/dist/usr/local/include -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -internal-isystem /usr/lib/clang/14.0.0/include -internal-isystem /usr/x86_64-w64-mingw32/sys-root/mingw/include -internal-isystem /usr/x86_64-w64-mingw32/include -internal-isystem /usr/include -O2 -Wno-error=redundant-decls -Wno-error=redundant-decls -Wno-error=redundant-decls -Wno-error=redundant-decls -Wstack-protector -Wall -Waddress -Waddress-of-temporary -Wambiguous-macro -Wanonymous-pack-parens -Warc -Warc-bridge-casts-disallowed-in-nonarc -Warc-maybe-repeated-use-of-weak -Warc-performSelector-leaks -Warc-repeated-use-of-weak -Warray-bounds -Warray-bounds-pointer-arithmetic -Wasm -Wasm-operand-widths -Watomic-properties -Watomic-property-with-user-defined-accessor -Wauto-import -Wauto-storage-class -Wauto-var-id -Wavailability -Wbackslash-newline-escape -Wbind-to-temporary-copy -Wbitfield-constant-conversion -Wbool-conversion -Wbool-conversions -Wbuiltin-requires-header -Wchar-align -Wcompare-distinct-pointer-types -Wcomplex-component-init -Wconditional-type-mismatch -Wconfig-macros -Wconstant-conversion -Wconstant-logical-operand -Wconstexpr-not-const -Wcustom-atomic-properties -Wdangling-field -Wdangling-initializer-list -Wdate-time -Wdelegating-ctor-cycles -Wdeprecated-implementations -Wdeprecated-register -Wdirect-ivar-access -Wdiscard-qual -Wdistributed-object-modifiers -Wdivision-by-zero -Wdollar-in-identifier-extension -Wdouble-promotion -Wduplicate-decl-specifier -Wduplicate-enum -Wduplicate-method-arg -Wduplicate-method-match -Wdynamic-class-memaccess -Wembedded-directive -Wempty-translation-unit -Wenum-conversion -Wexit-time-destructors -Wexplicit-ownership-type -Wextern-initializer -Wextra -Wextra-semi -Wextra-tokens -Wflexible-array-extensions -Wfloat-conversion -Wformat-non-iso -Wfour-char-constants -Wgcc-compat -Wglobal-constructors -Wgnu-array-member-paren-init -Wgnu-designator -Wgnu-static-float-init -Wheader-guard -Wheader-hygiene -Widiomatic-parentheses -Wignored-attributes -Wimplicit-atomic-properties -Wimplicit-conversion-floating-point-to-bool -Wimplicit-exception-spec-mismatch -Wimplicit-fallthrough -Wimplicit-fallthrough-per-function -Wimplicit-retain-self -Wimport-preprocessor-directive-pedantic -Wincompatible-library-redeclaration -Wincompatible-pointer-types-discards-qualifiers -Wincomplete-implementation -Wincomplete-module -Wincomplete-umbrella -Winit-self -Wint-conversions -Wint-to-void-pointer-cast -Winteger-overflow -Winvalid-constexpr -Winvalid-iboutlet -Winvalid-noreturn -Winvalid-pp-token -Winvalid-source-encoding -Winvalid-token-paste -Wknr-promoted-parameter -Wliteral-conversion -Wliteral-range -Wlocal-type-template-args -Wloop-analysis -Wmain-return-type -Wmalformed-warning-check -Wmethod-signatures -Wmicrosoft -Wmicrosoft-exists -Wmismatched-parameter-types -Wmismatched-return-types -Wmissing-field-initializers -Wmissing-format-attribute -Wmissing-noreturn -Wmissing-selector-name -Wmissing-sysroot -Wmissing-variable-declarations -Wmodule-conflict -Wnested-anon-types -Wnewline-eof -Wnon-literal-null-conversion -Wnon-pod-varargs -Wnonportable-cfstrings -Wnull-arithmetic -Wnull-character -Wnull-conversion -Wnull-dereference -Wout-of-line-declaration -Wover-aligned -Woverlength-strings -Woverride-init -Woverriding-method-mismatch -Wpointer-type-mismatch -Wpredefined-identifier-outside-function -Wprotocol-property-synthesis-ambiguity -Wreadonly-iboutlet-property -Wreceiver-expr -Wreceiver-forward-class -Wreinterpret-base-class -Wrequires-super-attribute -Wreserved-user-defined-literal -Wreturn-stack-address -Wsection -Wselector-type-mismatch -Wsentinel -Wserialized-diagnostics -Wshadow -Wshift-count-negative -Wshift-count-overflow -Wshift-negative-value -Wshift-sign-overflow -Wshorten-64-to-32 -Wsizeof-array-argument -Wsource-uses-openmp -Wstatic-float-init -Wstatic-in-inline -Wstatic-local-in-inline -Wstrict-overflow=1 -Wstring-compare -Wstring-conversion -Wstrlcpy-strlcat-size -Wstrncat-size -Wsuper-class-method-mismatch -Wswitch-bool -Wtautological-constant-out-of-range-compare -Wtentative-definition-incomplete-type -Wtype-safety -Wtypedef-redefinition -Wtypename-missing -Wundefined-inline -Wundefined-internal -Wundefined-reinterpret-cast -Wunicode -Wunicode-whitespace -Wunknown-warning-option -Wunnamed-type-template-args -Wunneeded-member-function -Wunsequenced -Wunsupported-visibility -Wunused-but-set-parameter -Wunused-but-set-variable -Wunused-command-line-argument -Wunused-exception-parameter -Wunused-local-typedefs -Wunused-member-function -Wunused-volatile-lvalue -Wuser-defined-literals -Wvariadic-macros -Wvector-conversion -Wvector-conversions -Wvexing-parse -Wvisibility -Wvla-extension -Wzero-length-array -W -Wfloat-equal -Wundef -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wwrite-strings -Wredundant-decls -Wchar-subscripts -Wcomment -Wformat=2 -Wwrite-strings -Wnested-externs -Wbad-function-cast -Wswitch-enum -Waggregate-return -Wpacked -Wunused -Wunused-parameter -Wold-style-definition -Wmissing-declarations -fconst-strings -fdebug-compilation-dir=tor -Wlarge-by-value-copy=64 -ferror-limit 19 -stack-protector 3 -stack-protector-buffer-size 1 -fno-use-cxa-atexit -fgnuc-version=4.2.1 -exception-model=seh -fcolor-diagnostics -vectorize-loops -vectorize-slp -faddrsig -o src/core/mainloop/connection.o -x c src/core/mainloop/connection.c
    ​
     clang -cc1 version 14.0.0 based upon LLVM 14.0.0 default target x86_64-pc-linux-gnu
    ignoring nonexistent directory "/usr/x86_64-w64-mingw32/sys-root/mingw/include"
    ignoring duplicate directory "./src/ext"
    ignoring duplicate directory "./src/ext"
    ignoring duplicate directory "libevent/dist/usr/local/include"
    ignoring duplicate directory "openssl/dist/usr/local/include"
    ignoring duplicate directory "zlib/dist/usr/local/include"
    ignoring duplicate directory "openssl/dist/usr/local/include"
    ignoring duplicate directory "zlib/dist/usr/local/include"
    ignoring duplicate directory "libevent/dist/usr/local/include"
    #include "..." search starts here:
    #include <...> search starts here:
     .
     ./src
     ./src/ext
     ./src/ext/trunnel
     ./src/trunnel
     openssl/dist/usr/local/include
     zlib/dist/usr/local/include
     libevent/dist/usr/local/include
     /usr/local/include
     /usr/lib/clang/14.0.0/include
     /usr/x86_64-w64-mingw32/include
     /usr/include
    End of search list.
    In file included from src/core/mainloop/connection.c:137:
    In file included from /usr/include/sys/socket.h:33:
    /usr/include/bits/socket.h:33:9: error: unknown type name '__socklen_t'; did you mean 'socklen_t'?
    typedef __socklen_t socklen_t;
            ^
    ./src/lib/net/nettypes.h:23:13: note: 'socklen_t' declared here
    typedef int socklen_t;
                ^
    In file included from src/core/mainloop/connection.c:137:
    In file included from /usr/include/sys/socket.h:33:
    In file included from /usr/include/bits/socket.h:38:
    /usr/include/bits/socket_type.h:26:3: error: expected identifier
      SOCK_STREAM = 1,              /* Sequenced, reliable, connection-based
      ^
    /usr/x86_64-w64-mingw32/include/winsock2.h:185:21: note: expanded from macro 'SOCK_STREAM'
    #define SOCK_STREAM 1
                        ^
    In file included from src/core/mainloop/connection.c:137:
    In file included from /usr/include/sys/socket.h:33:
    In file included from /usr/include/bits/socket.h:38:
    /usr/include/bits/socket_type.h:29:3: error: expected identifier
      SOCK_DGRAM = 2,               /* Connectionless, unreliable datagrams
      ^
    /usr/x86_64-w64-mingw32/include/winsock2.h:186:20: note: expanded from macro 'SOCK_DGRAM'
    #define SOCK_DGRAM 2
                       ^
    In file included from src/core/mainloop/connection.c:137:
    In file included from /usr/include/sys/socket.h:33:
    In file included from /usr/include/bits/socket.h:38:
    /usr/include/bits/socket_type.h:32:3: error: expected identifier
      SOCK_RAW = 3,                 /* Raw protocol interface.  */
      ^
    /usr/x86_64-w64-mingw32/include/winsock2.h:187:18: note: expanded from macro 'SOCK_RAW'
    #define SOCK_RAW 3
                     ^
    In file included from src/core/mainloop/connection.c:137:
    In file included from /usr/include/sys/socket.h:33:
    In file included from /usr/include/bits/socket.h:38:
    /usr/include/bits/socket_type.h:34:3: error: expected identifier
      SOCK_RDM = 4,                 /* Reliably-delivered messages.  */
      ^
    /usr/x86_64-w64-mingw32/include/winsock2.h:188:18: note: expanded from macro 'SOCK_RDM'
    #define SOCK_RDM 4
                     ^
    In file included from src/core/mainloop/connection.c:137:
    In file included from /usr/include/sys/socket.h:33:
    In file included from /usr/include/bits/socket.h:38:
    /usr/include/bits/socket_type.h:36:3: error: expected identifier
      SOCK_SEQPACKET = 5,           /* Sequenced, reliable, connection-based,
      ^
    /usr/x86_64-w64-mingw32/include/winsock2.h:189:24: note: expanded from macro 'SOCK_SEQPACKET'
    #define SOCK_SEQPACKET 5
                           ^
    In file included from src/core/mainloop/connection.c:137:
    In file included from /usr/include/sys/socket.h:33:
    /usr/include/bits/socket.h:178:8: error: redefinition of 'sockaddr'
    struct sockaddr
           ^
    /usr/x86_64-w64-mingw32/include/psdk_inc/_ip_types.h:70:8: note: previous definition is here
    struct sockaddr {
           ^
    In file included from src/core/mainloop/connection.c:137:
    In file included from /usr/include/sys/socket.h:33:
    /usr/include/bits/socket.h:191:8: error: redefinition of 'sockaddr_storage'
    struct sockaddr_storage
           ^
    /usr/x86_64-w64-mingw32/include/winsock2.h:269:10: note: previous definition is here
      struct sockaddr_storage {
             ^
    In file included from src/core/mainloop/connection.c:137:
    In file included from /usr/include/sys/socket.h:33:
    /usr/include/bits/socket.h:202:5: error: expected identifier
        MSG_OOB             = 0x01, /* Process out-of-band data.  */
        ^
    /usr/x86_64-w64-mingw32/include/winsock2.h:310:17: note: expanded from macro 'MSG_OOB'
    #define MSG_OOB 0x1
                    ^
    In file included from src/core/mainloop/connection.c:137:
    In file included from /usr/include/sys/socket.h:33:
    /usr/include/bits/socket.h:204:5: error: expected identifier
        MSG_PEEK            = 0x02, /* Peek at incoming messages.  */
        ^
    /usr/x86_64-w64-mingw32/include/winsock2.h:311:18: note: expanded from macro 'MSG_PEEK'
    #define MSG_PEEK 0x2
                     ^
    In file included from src/core/mainloop/connection.c:137:
    In file included from /usr/include/sys/socket.h:33:
    /usr/include/bits/socket.h:206:5: error: expected identifier
        MSG_DONTROUTE       = 0x04, /* Don't use local routing.  */
        ^
    /usr/x86_64-w64-mingw32/include/winsock2.h:312:23: note: expanded from macro 'MSG_DONTROUTE'
    #define MSG_DONTROUTE 0x4
                          ^
    In file included from src/core/mainloop/connection.c:137:
    In file included from /usr/include/sys/socket.h:33:
    /usr/include/bits/socket.h:210:20: error: use of undeclared identifier 'MSG_DONTROUTE'
        MSG_TRYHARD         = MSG_DONTROUTE,
                              ^
    /usr/include/bits/socket.h:207:23: note: expanded from macro 'MSG_DONTROUTE'
    #define MSG_DONTROUTE   MSG_DONTROUTE
                            ^
    /usr/include/bits/socket.h:223:5: error: expected identifier
        MSG_WAITALL         = 0x100, /* Wait for a full request.  */
        ^
    /usr/x86_64-w64-mingw32/include/winsock2.h:315:21: note: expanded from macro 'MSG_WAITALL'
    #define MSG_WAITALL 0x8
                        ^
    In file included from src/core/mainloop/connection.c:137:
    In file included from /usr/include/sys/socket.h:33:
    /usr/include/bits/socket.h:306:35: error: expected function body after function declarator
                                          struct cmsghdr *__cmsg) __THROW;
                                                                  ^
    /usr/include/bits/socket.h:347:3: error: unknown type name 'uid_t'; did you mean 'pid_t'?
      uid_t uid;                    /* UID of sending process.  */
      ^
    /usr/x86_64-w64-mingw32/include/sys/types.h:68:16: note: 'pid_t' declared here
    typedef _pid_t  pid_t;
                    ^
    In file included from src/core/mainloop/connection.c:137:
    In file included from /usr/include/sys/socket.h:33:
    /usr/include/bits/socket.h:348:3: error: unknown type name 'gid_t'; did you mean 'pid_t'?
      gid_t gid;                    /* GID of sending process.  */
      ^
    /usr/x86_64-w64-mingw32/include/sys/types.h:68:16: note: 'pid_t' declared here
    typedef _pid_t  pid_t;
                    ^
    In file included from src/core/mainloop/connection.c:137:
    In file included from /usr/include/sys/socket.h:33:
    In file included from /usr/include/bits/socket.h:353:
    /usr/include/bits/types/time_t.h:7:18: error: typedef redefinition with different types ('__time_t' (aka 'long') vs '__time64_t' (aka 'long long'))
    typedef __time_t time_t;
                     ^
    /usr/x86_64-w64-mingw32/include/corecrt.h:143:20: note: previous definition is here
    typedef __time64_t time_t;
                       ^
    In file included from src/core/mainloop/connection.c:137:
    In file included from /usr/include/sys/socket.h:33:
    /usr/include/bits/socket.h:361:8: error: redefinition of 'linger'
    struct linger
           ^
    /usr/x86_64-w64-mingw32/include/psdk_inc/_ip_types.h:63:8: note: previous definition is here
    struct linger {
           ^
    In file included from src/core/mainloop/connection.c:137:
    /usr/include/sys/socket.h:102:62: error: expected function body after function declarator
    extern int socket (int __domain, int __type, int __protocol) __THROW;
                                                                 ^
    fatal error: too many errors emitted, stopping now [-ferror-limit=]

First you need to install the mingw compiler and build from source the windows versions of zlib, openssl and libevent (in that order). This is tor’s dependencies.
This is how I built for i686-mingw:

sudo apt build-dep zlib openssl libevent

cd zlib-1.2.8
make -f win32/Makefile.gcc BINARY_PATH=/home/user/tor-deps/build/zlib/bin INCLUDE_PATH=/home/user/tor-deps/build/zlib/include LIBRARY_PATH=/home/user/tor-deps/build/zlib/lib SHARED_MODE=0 PREFIX=i686-w64-mingw32- install

cd openssl-1.1.1
./Configure mingw --cross-compile-prefix=i686-w64-mingw32- no-shared
make
make install
copy from C: to /home/user/tor-deps/build/openssl

export LD_LIBRARY_PATH=/home/denis/tor-deps/build/openssl/lib:$LD_LIBRARY_PATH
export CPATH=/home/denis/tor-deps/build/openssl/include:$CPATH
export PATH=/home/denis/tor-deps/build/openssl/bin:$PATH
export PKG_CONFIG_PATH=/home/denis/tor-deps/build/openssl/lib/pkgconfig:$PKG_CONFIG_PATH

cd libevent-2.1.11
./autogen.sh
./configure --prefix=/home/user/tor-deps/build/libevent --host=i686-w64-mingw32 --enable-static --disable-shared --disable-debug-mode --enable-silent-rules --disable-libevent-regress --disable-samples --enable-openssl
make
make install

export CC=i686-w64-mingw32-gcc
export CXX=i686-w64-mingw32-g++

cd tor-0.4.7.8
autoreconf -fi
./configure --help
LDFLAGS=“-static” ./configure --prefix=/home/user/tor-deps/build/tor --host=i686-w64-mingw32 --enable-static-tor --enable-silent-rules --disable-lzma --disable-zstd --disable-manpage --disable-html-manual --disable-asciidoc --disable-unittests --enable-static-openssl --with-openssl-dir=/home/user/tor-deps/build/openssl --enable-static-zlib --with-zlib-dir=/home/user/tor-deps/build/zlib --enable-static-libevent --with-libevent-dir=/home/user/tor-deps/build/libevent --disable-seccomp --disable-libscrypt
make
make install

This is a static build, only exe without dll’s (dll’s are inside the exe).
You may need to fix the paths in pkgconfig files.
Replace i686 with x86_64. /home/user to your username.

1 Like