# pyhton nuitka cross build 可行性與反編譯 在開發產品中,遇到了要在 linux 上面 build 出 windows 版本 和 linux 版本,經過實驗來講找了蠻多資料 nuitka 其實在 windows 版本和 linux 版本 產生出來的 c code 是不一樣的,大概從幾個地方去切入, 下面打包 比較常見的 大型 lib numpy, matplotlib,pandas ```python= import os import sys import numpy import matplotlib import pandas def main(): print("NumPy version:", numpy.__version__) a = numpy.array([1, 2, 3]) print(a) mydataset = { 'cars': ["BMW", "Volvo", "Ford"], 'passings': [3, 7, 2] } myvar = pandas.DataFrame(mydataset) print(myvar) if __name__ == "__main__": main() ``` # 常見問題 https://nuitka.net/user-documentation/common-issue-solutions.html 這幾個參數嘗試過,在比較大型的程式碼規模--low-memory 可以降低記憶體使用率不然極有可能會遇到 cc1.exe: out of memory allocating 65536 bytes ```bash= python3 -m nuitka --standalone --onefile --show-memory --show-progress --nofollow-imports --low-memory --mingw64 --show-scons --output-dir=out ./test.py ``` # 克制化 scons build command ```bash= 但是要直接下 scons command 不透過Nuitka 編譯可能要繞過一些地方 File "/usr/local/lib/python3.9/site-packages/nuitka/build/SconsUtils.py", line 644: def createDefinitionsFile(source_dir, filename, definitions): print(os.environ["_NUITKA_BUILD_DEFINITIONS_CATALOG"]) #for env_name in os.environ["_NUITKA_BUILD_DEFINITIONS_CATALOG"].split(","): <== 這邊先關掉才算ok ,才可以不用加載 nuitka 可以直接透過 scons command 進行編譯 # definitions[env_name] = os.environ[env_name] ``` # linux ```bash= export NUITKA_PACKAGE_DIR=/usr/local/lib/python3.9/site-packages/nuitka export _NUITKA_BUILD_DEFINITIONS_CATALOG=/usr/local/lib/python3.9/site-packages/nuitka/build/include /usr/local/bin/python3 -W ignore /usr/local/lib/python3.9/site-packages/nuitka/build/inline_copy/bin/scons.py -f /usr/local/lib/python3.9/site-packages/nuitka/build/Backend.scons --jobs 12 --warn=no-deprecated --no-site-dir --debug=stacktrace result_name=/shared_data/mingw-w64-build/output/test source_dir=. nuitka_python=false debug_mode=false debugger_mode=false python_debug=false module_mode=false full_compat=false experimental= trace_mode=false file_reference_mode=original module_count=1 result_exe=/shared_data/mingw-w64-build/output/test.bin python_sysflag_utf8=true nuitka_src=/usr/local/lib/python3.9/site-packages/nuitka/build python_version=3.9 python_prefix=/usr/local no_deployment= show_scons=true target_arch=x86_64 ``` # windows ```bash= set NUITKA_PACKAGE_DIR=C:\Users\x213212\AppData\Local\Programs\Python\Python39\Lib\site-packages\nuitka rams\Python\Python39\python.exe -W ignore C:\Users\ x213212\AppData\Local\Programs\Python\Python39\Lib\site-packages\nuitka\build\inline_copy\bin\scons.py -f C:\Users\ x213212\AppData\Local\Programs\Python\Python39\Lib\site-packages\nuitka\build\Backend.scons --jobs 12 --warn=no-deprecated --no-site-dir --debug=stacktrace result_name=C:\Users\ x213212\AppData\Local\Programs\Python\Python39\output\test source_dir=. nuitka_python=false debug_mode=false debugger_mode=false python_debug=false module_mode=false full_compat=false experimental= trace_mode=false file_reference_mode=original module_count=1 result_exe=C:\Users\ x213212\AppData\Local\Programs\Python\Python39\output\test.exe uninstalled_python=true nuitka_src=C:\Users\ x213212\AppData\Local\Programs\Python\Python39\Lib\site-packages\nuitka\build python_version=3.9 python_prefix=C:\Users\ x213212\AppData\Local\Programs\Python\Python39 no_deployment= show_scons=true mingw_mode=true noelf_mode=true target_arch=x86_64 ``` # env vaiable ``` AS=as CC="C:/msys64/home/rex603/ddddd/AUTOTU~1/NUITKA~1/DOWNLO~1/gcc/x86_64/13.2.0-16.0.6-11.0.1-msvcrt-r1/mingw64/bin/ccache.exe" "C:/msys64/home/rex603/ddddd/AUTOTU~1/NUITKA~1/DOWNLO~1/gcc/x86_64/13.2.0-16.0.6-11.0.1-msvcrt-r1/mingw64/bin/gcc.exe" CCACHE_DIR=C:/msys64/home/rex603/ddddd/AUTOTU~1/NUITKA~1/ccache CCACHE_LOGFILE=C:/msys64/home/rex603/ddddd/AUTOTU~1/out/ANDES_~1.ONE/ccache-29308.txt CCCOM=$CC -o $TARGET -c $CFLAGS $CCFLAGS $_CCCOMCOM $SOURCES CFILESUFFIX=.c CPPDEFINES=['_WIN32_WINNT=0x0501', '__NUITKA_NO_ASSERT__', 'MS_WIN64', '_NUITKA_ONEFILE_MODE', '_NUITKA_PLUGIN_MULTIPROCESSING_ENABLED=1'] CPPDEFPREFIX=-D CPPDEFSUFFIX= CPPPATH=['C:/msys64/mingw64/lib/python3.11/SITE-P~1/nuitka/build/inline_copy/zlib', '.', 'C:/msys64/mingw64/lib/python3.11/SITE-P~1/nuitka/build/include', 'C:/msys64/mingw64/lib/python3.11/SITE-P~1/nuitka/build/static_src', 'C:/msys64/mingw64/lib/python3.11/SITE-P~1/nuitka/build/inline_copy/zstd'] CPPSUFFIXES=['.c', '.C', '.cxx', '.cpp', '.c++', '.cc', '.h', '.H', '.hxx', '.hpp', '.hh', '.F', '.fpp', '.FPP', '.m', '.mm', '.S', '.spp', '.SPP', '.sx'] CXX="C:/msys64/home/rex603/ddddd/AUTOTU~1/NUITKA~1/DOWNLO~1/gcc/x86_64/13.2.0-16.0.6-11.0.1-msvcrt-r1/mingw64/bin/ccache.exe" "C:/msys64/home/rex603/ddddd/AUTOTU~1/NUITKA~1/DOWNLO~1/gcc/x86_64/13.2.0-16.0.6-11.0.1-msvcrt-r1/mingw64/bin/gcc.exe" CXXCOM=$CXX -o $TARGET -c $CXXFLAGS $CCFLAGS $_CCCOMCOM $SOURCES CXXFILESUFFIX=.cc HOST_ARCH=x86_64 HOST_OS=win32 INCPREFIX=-I INCSUFFIX= LDMODULE=$SHLINK LDMODULEFLAGS=$SHLINKFLAGS LDMODULENAME=${LDMODULEPREFIX}$_get_ldmodule_stem${_LDMODULESUFFIX} LDMODULEPREFIX=$SHLIBPREFIX LDMODULESUFFIX=$SHLIBSUFFIX LDMODULEVERSION=$SHLIBVERSION LDMODULE_NOVERSION_SYMLINK=$_get_shlib_dir${LDMODULEPREFIX}$_get_ldmodule_stem${LDMODULESUFFIX} LDMODULE_SONAME_SYMLINK=$_get_shlib_dir$_LDMODULESONAME LIBDIRPREFIX=-L LIBDIRSUFFIX= LIBLINKPREFIX=-l LIBLINKSUFFIX= LIBPATH=[] LIBPREFIX=lib LIBPREFIXES=['$LIBPREFIX'] LIBS=[] LIBSUFFIX=.a LIBSUFFIXES=['$LIBSUFFIX'] LINK="C:/msys64/home/rex603/ddddd/AUTOTU~1/NUITKA~1/DOWNLO~1/gcc/x86_64/13.2.0-16.0.6-11.0.1-msvcrt-r1/mingw64/bin/gcc.exe" LINKCOM=$LINK -o $TARGET $LINKFLAGS $__RPATH @"./@link_input.txt" $_LIBDIRFLAGS $_LIBFLAGS OBJPREFIX= OBJSUFFIX=.o PLATFORM=win32 PROGPREFIX= PROGSUFFIX=.exe RC=windres RCCOM=$RC $_CPPDEFFLAGS $RCINCFLAGS ${RCINCPREFIX} ${SOURCE.dir} $RCFLAGS -i $SOURCE -o $TARGET RCINCFLAGS=${_concat(RCINCPREFIX, CPPPATH, RCINCSUFFIX, __env__, RDirs, TARGET, SOURCE, affect_signature=False)} RCINCPREFIX=--include-dir RCINCSUFFIX= RPATHPREFIX=-Wl,-rpath= RPATHSUFFIX= SHCC=$CC SHCCCOM=$SHCC -o $TARGET -c $SHCFLAGS $SHCCFLAGS $_CCCOMCOM $SOURCES SHCXX=$CXX SHCXXCOM=$SHCXX -o $TARGET -c $SHCXXFLAGS $SHCCFLAGS $_CCCOMCOM $SOURCES SHELL=C:\Windows/System32\cmd.exe SHLIBNAME=${_get_shlib_dir}${SHLIBPREFIX}$_get_shlib_stem${_SHLIBSUFFIX} SHLIBPREFIX= SHLIBSONAMEFLAGS=-Wl,-soname=$_SHLIBSONAME SHLIBSUFFIX=.dll SHLIB_NOVERSION_SYMLINK=${_get_shlib_dir}${SHLIBPREFIX}$_get_shlib_stem${SHLIBSUFFIX} SHLIB_SONAME_SYMLINK=${_get_shlib_dir}$_SHLIBSONAME SHLINK=$LINK SHOBJPREFIX=$OBJPREFIX SHOBJSUFFIX=.o TARGET_ARCH=x86_64 TEMPFILEARGJOIN= TEMPFILEPREFIX=@ TOOLS=['mingw', 'gcc', 'g++', 'gnulink'] WINDOWSDEFPREFIX= WINDOWSDEFSUFFIX=.def gcc_mode=True clang_mode=False msvc_mode=False mingw_mode=True clangcl_mode=False PATH=C:/msys64/home/rex603/ddddd/AUTOTU~1/NUITKA~1/DOWNLO~1/gcc/x86_64/13.2.0-16.0.6-11.0.1-msvcrt-r1/mingw64\bin;C:\msys64\mingw64\bin;C:\msys64\usr\local\bin;C:\msys64\usr\bin;C:\msys64\usr\bin;C:\Windows\System32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\msys64\usr\bin\site_perl;C:\msys64\usr\bin\vendor_perl;C:\msys64\usr\bin\core_perl TARGET=C:/msys64/home/rex603/ddddd/AUTOTU~1/out/andes_autotuning.exe ``` 看到這邊就可以實現從中間干擾 build command ,就是假設今天要修改 cross compiler mingw 版本 ``` export CC="WWWW" ``` 然後在目錄下的 \out\{test}.onefile-build\ 再重下剛剛的scons build ,就可以override compiler cfags ,也就是其實可以在這邊cflags 再去插入一些混淆的lib 比如說換成ollvm https://heroims.github.io/2019/01/06/OLLVM%E4%BB%A3%E7%A0%81%E6%B7%B7%E6%B7%86%E7%A7%BB%E6%A4%8D%E4%B8%8E%E4%BD%BF%E7%94%A8/ 昨天看到這種方式的混用也是相當不錯哈哈 https://youtu.be/L2PK7hrCxjA 或者在跨平台的時候引入https://github.com/jart/cosmopolitan 也可以讓你的c/c++ 編譯一次 放到任何平台上