euler314 commited on
Commit
a014231
Β·
verified Β·
1 Parent(s): bf3efba

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +294 -627
app.py CHANGED
@@ -284,22 +284,6 @@ Add this to your requirements.txt and redeploy the space."""
284
  if progress_callback:
285
  progress_callback(0.05, "Checking environment...")
286
 
287
- # Check for Windows cross-compilation requirements
288
- if output_extension == ".exe":
289
- missing_mingw, available_mingw = check_mingw_installation()
290
- if log_queue:
291
- if available_mingw:
292
- log_queue.put(f"βœ… Available MinGW-w64 compilers:\n")
293
- for compiler, arch in available_mingw:
294
- log_queue.put(f" - {compiler} ({arch})\n")
295
- else:
296
- log_queue.put("⚠️ No MinGW-w64 compilers found!\n")
297
-
298
- if missing_mingw:
299
- log_queue.put(f"⚠️ Missing MinGW-w64 components:\n")
300
- for compiler, arch in missing_mingw:
301
- log_queue.put(f" - {compiler} ({arch})\n")
302
-
303
  # Check if static libpython is available
304
  has_static_libpython = check_static_libpython()
305
 
@@ -466,88 +450,13 @@ except ImportError:
466
  # Prepare environment for cross-compilation
467
  env = os.environ.copy()
468
 
469
- # Add Windows-specific options using MinGW-w64
470
- if output_extension == ".exe":
471
- # Check which MinGW-w64 compiler is available
472
- x64_gcc = subprocess.run(["which", "x86_64-w64-mingw32-gcc"], capture_output=True)
473
- i686_gcc = subprocess.run(["which", "i686-w64-mingw32-gcc"], capture_output=True)
474
-
475
- # Use the comprehensive approach to force 64-bit compilation
476
- cmd.extend([
477
- "--mingw64", # Use MinGW-w64 for cross-compilation
478
- "--windows-disable-console", # Disable console window for GUI apps
479
- ])
480
-
481
- # Create wrapper scripts with improved version handling
482
- wrapper_dir = os.path.join(output_dir, "mingw_wrappers")
483
- if log_queue:
484
- log_queue.put("Creating improved version wrapper scripts...\n")
485
- create_improved_version_wrappers(wrapper_dir, log_queue)
486
-
487
- # Prepend wrapper directory to PATH (this is crucial!)
488
- env["PATH"] = wrapper_dir + ":" + env["PATH"]
489
-
490
- # Explicitly set the compiler environment variables
491
- if x64_gcc.returncode == 0:
492
- # Force 64-bit cross-compiler with proper paths to our wrappers
493
- env["CC"] = os.path.join(wrapper_dir, "x86_64-w64-mingw32-gcc")
494
- env["CXX"] = os.path.join(wrapper_dir, "x86_64-w64-mingw32-g++")
495
- env["AR"] = os.path.join(wrapper_dir, "x86_64-w64-mingw32-ar")
496
- env["NM"] = os.path.join(wrapper_dir, "x86_64-w64-mingw32-nm")
497
- env["STRIP"] = os.path.join(wrapper_dir, "x86_64-w64-mingw32-strip")
498
- env["RANLIB"] = os.path.join(wrapper_dir, "x86_64-w64-mingw32-ranlib")
499
- env["OBJCOPY"] = os.path.join(wrapper_dir, "x86_64-w64-mingw32-objcopy")
500
- env["OBJDUMP"] = os.path.join(wrapper_dir, "x86_64-w64-mingw32-objdump")
501
- env["READELF"] = os.path.join(wrapper_dir, "x86_64-w64-mingw32-readelf")
502
- env["SIZE"] = os.path.join(wrapper_dir, "x86_64-w64-mingw32-size")
503
- env["STRINGS"] = os.path.join(wrapper_dir, "x86_64-w64-mingw32-strings")
504
-
505
- # Set additional environment variables for cross-compilation
506
- env["CROSS_COMPILE"] = "x86_64-w64-mingw32-"
507
- env["TARGET"] = "x86_64-w64-mingw32"
508
- env["TARGET_ARCH"] = "x86_64"
509
- env["CFLAGS"] = "-m64"
510
- env["CXXFLAGS"] = "-m64"
511
- env["LDFLAGS"] = "-m64"
512
-
513
- if log_queue:
514
- log_queue.put("=== Forcing 64-bit Windows Compilation with Improved Wrappers ===\n")
515
- log_queue.put("Environment variables set:\n")
516
- log_queue.put(f" PATH={env['PATH'][:100]}...\n")
517
- log_queue.put(f" CC={env['CC']}\n")
518
- log_queue.put(f" CXX={env['CXX']}\n")
519
- log_queue.put(f" CROSS_COMPILE={env['CROSS_COMPILE']}\n")
520
- log_queue.put(f" TARGET={env['TARGET']}\n")
521
- log_queue.put(f" TARGET_ARCH={env['TARGET_ARCH']}\n")
522
- log_queue.put(f" CFLAGS={env['CFLAGS']}\n")
523
- log_queue.put("Wrapper scripts created with robust version handling\n")
524
-
525
- elif i686_gcc.returncode == 0:
526
- # Fall back to 32-bit if 64-bit not available
527
- env["CC"] = os.path.join(wrapper_dir, "i686-w64-mingw32-gcc")
528
- env["CXX"] = os.path.join(wrapper_dir, "i686-w64-mingw32-g++")
529
- env["CROSS_COMPILE"] = "i686-w64-mingw32-"
530
- env["TARGET"] = "i686-w64-mingw32"
531
- env["TARGET_ARCH"] = "i686"
532
- env["CFLAGS"] = "-m32"
533
- env["CXXFLAGS"] = "-m32"
534
- env["LDFLAGS"] = "-m32"
535
-
536
- if log_queue:
537
- log_queue.put("Using 32-bit Windows cross-compilation (fallback)\n")
538
- log_queue.put(f"Set CC={env['CC']}, CXX={env['CXX']}\n")
539
- log_queue.put("Created wrapper scripts for 32-bit compilation\n")
540
- else:
541
- if log_queue:
542
- log_queue.put("No specific MinGW-w64 compiler found, using --mingw64 flag only\n")
543
-
544
  # Run compilation
545
  if progress_callback:
546
  progress_callback(0.4, "Executing Nuitka compilation...")
547
 
548
  if log_queue:
549
  log_queue.put(f"Final compilation command: {' '.join(cmd)}\n")
550
- log_queue.put("Starting compilation with improved environment...\n")
551
 
552
  process = subprocess.Popen(
553
  cmd,
@@ -631,118 +540,54 @@ except ImportError:
631
  log_queue.put(f"Binary info: {binary_info}\n")
632
 
633
  # Extract architecture information from file output
634
- if "PE32+" in binary_info or "x86-64" in binary_info:
635
- arch_info = "64-bit"
636
- elif "PE32" in binary_info and "PE32+" not in binary_info:
637
- arch_info = "32-bit"
 
 
 
638
  else:
639
  arch_info = "unknown"
640
 
641
  log_queue.put(f"Detected architecture: {arch_info}\n")
642
-
643
- # Verify the compilation was successful for 64-bit
644
- if output_extension == ".exe" and arch_info != "64-bit":
645
- log_queue.put("⚠️ WARNING: Expected 64-bit but got different architecture\n")
646
- log_queue.put("Environment variables that were set:\n")
647
- log_queue.put(f" CC={env.get('CC', 'not set')}\n")
648
- log_queue.put(f" CROSS_COMPILE={env.get('CROSS_COMPILE', 'not set')}\n")
649
- log_queue.put(f" TARGET_ARCH={env.get('TARGET_ARCH', 'not set')}\n")
650
- elif output_extension == ".exe" and arch_info == "64-bit":
651
- log_queue.put("βœ… SUCCESS: Confirmed 64-bit Windows executable\n")
652
- log_queue.put("βœ… Version parsing issue resolved with improved wrappers!\n")
653
 
654
  except:
655
  binary_info = "Binary file (unable to get detailed info)"
656
  arch_info = "unknown"
657
 
658
- # Check linking type (only for non-Windows binaries on Linux)
659
- if output_extension != ".exe":
660
- try:
661
- ldd_process = subprocess.run(["ldd", binary_path], capture_output=True, text=True)
662
- if "not a dynamic executable" in ldd_process.stderr or "statically linked" in ldd_process.stdout:
663
- linking_info = "βœ… Statically linked - fully portable!"
 
 
 
 
664
  else:
665
- # Check what dynamic libraries are required
666
- if ldd_process.returncode == 0:
667
- libs = ldd_process.stdout.count("=>")
668
- linking_info = f"πŸ”— Dynamically linked ({libs} libraries) - designed for maximum compatibility"
669
- else:
670
- linking_info = "ℹ️ Compiled binary - should work on compatible systems"
671
- except:
672
- linking_info = "ℹ️ Compiled binary created successfully"
673
- else:
674
- # For Windows, show architecture information
675
- linking_info = f"πŸ“¦ Windows {arch_info} executable"
676
- if env.get("CC"):
677
- linking_info += f" (cross-compiled with improved wrappers)"
678
-
679
- if log_queue:
680
- log_queue.put(f"Final binary architecture: {linking_info}\n")
681
 
682
  # Rename to desired extension
683
- if output_extension in ['.bin', '.sh', '.exe'] and not binary_path.endswith(output_extension):
684
  new_binary_path = binary_path + output_extension
685
  shutil.move(binary_path, new_binary_path)
686
  binary_path = new_binary_path
687
 
688
- # Make executable (for non-Windows)
689
- if output_extension != ".exe":
690
- os.chmod(binary_path, 0o755)
691
 
692
  # Build the result summary string
693
  static_status = "Yes" if has_static_libpython else "No"
694
  file_size = os.path.getsize(binary_path) / 1024
695
  binary_basename = os.path.basename(binary_path)
696
 
697
- # Determine architecture info
698
- if output_extension == ".exe":
699
- if env.get("TARGET_ARCH"):
700
- arch_used = f"{env['TARGET_ARCH']} via improved wrapper scripts"
701
- else:
702
- arch_used = f"Windows {arch_info}"
703
- else:
704
- arch_used = "Native Linux"
705
-
706
- # Fix f-string issue by using separate variables
707
- if output_extension == '.exe':
708
- cross_compilation_details = f'''- Cross-compiler: {env.get('CC', 'default').split('/')[-1] if env.get('CC') else 'default'}
709
- - Target architecture: {env.get('TARGET_ARCH', 'default')}
710
- - Cross-compile prefix: {env.get('CROSS_COMPILE', 'none')}
711
- - Compiler flags: {env.get('CFLAGS', 'none')}
712
- - Verified architecture: {arch_info}
713
- - Wrapper scripts: Improved version parsing
714
- - Version handling: Fixed "12-win32" issue
715
- - Environment variables: {len([k for k in env.keys() if k.startswith(('CC', 'CXX', 'TARGET', 'CROSS'))])} variables'''
716
-
717
- cross_compilation_notes = f'''- Successfully cross-compiled for Windows {arch_info}
718
- - Fixed version parsing with improved wrapper scripts
719
- - Resolved "12-win32" to "12.0.0" issue
720
- - All MinGW-w64 tools properly wrapped
721
- - Version detection now robust and reliable
722
- - Binary verified with file command
723
- - Should run on Windows {arch_info} systems'''
724
-
725
- technical_details = f'''- VERSION FIX: Wrapper scripts now parse "12-win32" correctly
726
- - Robust regex parsing for version strings
727
- - Fallback to "12.0.0" for problematic versions
728
- - PATH manipulation ensures wrappers are used
729
- - Environment variables use wrapper script paths
730
- - Binary architecture verified: {arch_info}
731
- - Network error handling enhanced for better diagnostics'''
732
- else:
733
- cross_compilation_details = "- Native Linux compilation"
734
- cross_compilation_notes = "Native Linux compilation with maximum compatibility"
735
- technical_details = """- Native compilation optimized for compatibility
736
- - Network error handling added for better runtime diagnostics"""
737
-
738
  # Create result summary
739
  result_summary = f"""# βœ… Compilation Successful!
740
 
741
- ## πŸ› οΈ VERSION PARSING FIXED!
742
- - **Issue resolved**: "12-win32" β†’ "12.0.0" conversion
743
- - **Solution**: Improved wrapper scripts with regex parsing
744
- - **Result**: Clean compilation without version errors
745
-
746
  ## Compilation Details:
747
  - **Mode**: {mode_name}
748
  - **Nuitka Version**: {nuitka_version}
@@ -752,8 +597,8 @@ except ImportError:
752
  - **Compiled with Python**: {current_python}
753
  - **Static Libpython Available**: {static_status}
754
  - **Linking**: {linking_info}
755
- - **Target Platform**: {'Windows (via MinGW-w64)' if output_extension == '.exe' else 'Linux'}
756
- - **Architecture**: {arch_used}
757
 
758
  ## Environment Results:
759
  **System Packages**: {packages_result}
@@ -762,19 +607,12 @@ except ImportError:
762
  ## Binary Information:
763
  {binary_info}
764
 
765
- ## πŸš€ Cross-Compilation Details:
766
- {cross_compilation_details}
767
-
768
  ## πŸ“‹ Usage Instructions:
769
  ```bash
770
- {f'# For Windows ({arch_info}):' if output_extension == '.exe' else f'chmod +x {binary_basename}'}
771
- {f'# Download to Windows machine and run:' if output_extension == '.exe' else ''}
772
- {f'{binary_basename}' if output_extension == '.exe' else f'./{binary_basename}'}
773
  ```
774
 
775
- ## ⚠️ Cross-Compilation Notes:
776
- {cross_compilation_notes}
777
-
778
  ## 🌐 Network Dependencies:
779
  - Binary includes enhanced error handling for network issues
780
  - Will provide helpful messages if DNS resolution fails
@@ -782,39 +620,22 @@ except ImportError:
782
  - Consider pre-downloading models/data for offline usage
783
 
784
  ## πŸ§ͺ Testing:
785
- {f'You can test the Windows executable on Linux using wine:' if output_extension == '.exe' else 'Run directly on compatible Linux systems:'}
786
  ```bash
787
- {f'wine {binary_basename}' if output_extension == '.exe' else f'./{binary_basename}'}
788
  ```
789
 
790
  ## πŸ”§ Technical Details:
791
- {technical_details}
792
-
793
- ## βœ… Version Parsing Solution:
794
- ```bash
795
- # The wrapper script now handles:
796
- # Input: "gcc (GCC) 12-win32"
797
- # Output: "12.0.0"
798
- #
799
- # Regex patterns used:
800
- # - ([0-9]+)\.([0-9]+)\.?([0-9]*) for x.y.z versions
801
- # - ([0-9]+)[^0-9] for single major versions
802
- # - Fallback: "12.0.0" for unparseable versions
803
- ```"""
804
 
805
  if progress_callback:
806
- progress_callback(1.0, f"Compilation successful! Version parsing fixed! Created {arch_info} executable πŸŽ‰")
807
 
808
  if log_queue:
809
  log_queue.put("βœ… Compilation completed successfully!\n")
810
- log_queue.put("πŸ”§ VERSION PARSING ISSUE FIXED!\n")
811
- if output_extension == ".exe":
812
- log_queue.put(f"🍷 You can test the Windows {arch_info} executable with: wine " + binary_basename + "\n")
813
- log_queue.put(f"βœ… Verified {arch_info} Windows executable created\n")
814
- if arch_info == "64-bit":
815
- log_queue.put("🎯 SUCCESS: Achieved 64-bit Windows compilation with fixed version parsing!\n")
816
- else:
817
- log_queue.put(f"⚠️ Note: Created {arch_info} executable instead of 64-bit\n")
818
 
819
  return result_summary, binary_path, compile_output, True
820
  else:
@@ -824,7 +645,7 @@ except ImportError:
824
  ## Error Details:
825
  - **Exit Code**: {process.returncode}
826
  - **Mode Attempted**: {mode_name}
827
- - **Target**: {'Windows (via MinGW-w64)' if output_extension == '.exe' else 'Linux'}
828
 
829
  ## Environment Results:
830
  **System Packages**: {packages_result}
@@ -835,26 +656,11 @@ except ImportError:
835
  {compile_output}
836
  ```
837
 
838
- ## Environment Setup:
839
- {f'''- Cross-compiler variables: {len([k for k in env.keys() if k.startswith(('CC', 'CXX', 'TARGET', 'CROSS'))])} set
840
- - Main compiler: {env.get('CC', 'not set')}
841
- - Architecture target: {env.get('TARGET_ARCH', 'not set')}
842
- - Cross-compile prefix: {env.get('CROSS_COMPILE', 'not set')}
843
- - Wrapper scripts: Created for version parsing''' if output_extension == '.exe' else '- Native GCC compilation'}
844
-
845
- ## Version Parsing Status:
846
- {f'''- Wrapper scripts created: {os.path.exists(os.path.join(output_dir, "mingw_wrappers"))}
847
- - PATH modified: {("mingw_wrappers" in env.get("PATH", ""))}
848
- - Version handling: Improved regex-based parsing''' if output_extension == '.exe' else '- Native version parsing used'}
849
-
850
  ## Possible Solutions:
851
  1. Check your code for syntax errors
852
  2. Ensure all imports are available in requirements.txt
853
  3. Try a different compilation mode
854
  4. Review the compilation logs above
855
- {f"5. Verify MinGW-w64 installation and cross-compiler availability" if output_extension == '.exe' else ''}
856
- {f"6. The version parsing issue should now be resolved with wrapper scripts" if output_extension == '.exe' else ''}
857
- {f"7. Some packages may not support Windows cross-compilation" if output_extension == '.exe' else ''}
858
 
859
  ## Missing Dependencies:
860
  {', '.join(missing_deps) if missing_deps else 'None detected'}
@@ -862,10 +668,7 @@ except ImportError:
862
  ## Environment Info:
863
  - **Nuitka Version**: {nuitka_version}
864
  - **Python Version**: {current_python}
865
- - **Platform**: {platform.platform()}
866
- {f"- **Cross-compiler**: {env.get('CC', 'Not set')}" if output_extension == '.exe' else ''}
867
- {f"- **Target Architecture**: {env.get('TARGET_ARCH', 'Not set')}" if output_extension == '.exe' else ''}
868
- {f"- **Version Fix Applied**: Wrapper scripts with regex parsing" if output_extension == '.exe' else ''}"""
869
  if progress_callback:
870
  progress_callback(1.0, "Compilation failed ❌")
871
 
@@ -892,18 +695,11 @@ except ImportError:
892
  - **Python Version**: {current_python}
893
  - **Working Directory**: {os.getcwd()}
894
 
895
- ## Version Parsing Fix:
896
- - Improved wrapper scripts implemented
897
- - Regex patterns for robust version detection
898
- - Fallback mechanisms for unknown formats
899
-
900
  ## Troubleshooting Steps:
901
  1. Check if Nuitka is properly installed
902
  2. Verify your code syntax
903
  3. Check available disk space
904
- 4. Try with simpler code first
905
- {f"5. The version parsing issue has been addressed" if output_extension == '.exe' else ''}
906
- {f"6. Wrapper scripts should handle '12-win32' formats" if output_extension == '.exe' else ''}"""
907
  if progress_callback:
908
  progress_callback(1.0, "Error occurred ❌")
909
 
@@ -918,106 +714,8 @@ def run_compiled_binary(binary_path):
918
  return "❌ No binary available to run."
919
 
920
  try:
921
- # Check if it's a Windows exe on Linux
922
- if binary_path.endswith('.exe'):
923
- # Verify architecture first
924
- file_process = subprocess.run(["file", binary_path], capture_output=True, text=True)
925
- if file_process.returncode == 0:
926
- file_output = file_process.stdout
927
- if "PE32+" in file_output or "x86-64" in file_output:
928
- arch_info = "64-bit"
929
- elif "PE32" in file_output and "PE32+" not in file_output:
930
- arch_info = "32-bit"
931
- else:
932
- arch_info = "unknown"
933
- else:
934
- arch_info = "unknown"
935
-
936
- # Try to run with wine first
937
- wine_result = subprocess.run(["which", "wine"], capture_output=True)
938
- if wine_result.returncode == 0:
939
- return f"""🍷 **Running Windows {arch_info} executable with Wine**
940
-
941
- ## Execution:
942
- ```bash
943
- wine {os.path.basename(binary_path)}
944
- ```
945
-
946
- ## Binary Information:
947
- - **Architecture**: {arch_info}
948
- - **File**: {file_output.strip() if 'file_output' in locals() else 'Windows PE executable'}
949
- - **Version Fix**: Compiled with improved version parsing
950
-
951
- ## ⚠️ Network Error Handling:
952
- This executable includes enhanced error handling. If you see:
953
- - "DNS Resolution Error" - indicates network connectivity issues
954
- - Exit code 6 - means the application couldn't resolve huggingface.co
955
- - Network timeout messages - suggests firewall or DNS problems
956
-
957
- ## Solutions for Network Issues:
958
- 1. **Enable internet access** for the executable
959
- 2. **Pre-download models** if using Hugging Face
960
- 3. **Use offline mode** if available in your libraries
961
- 4. **Check firewall settings** that might block the executable
962
-
963
- ## To run on Windows:
964
- 1. Download the .exe file
965
- 2. Transfer it to a Windows machine
966
- 3. Run it by double-clicking or from command prompt
967
-
968
- ```cmd
969
- # On Windows command prompt:
970
- {os.path.basename(binary_path)}
971
- ```
972
-
973
- ## Note:
974
- - Wine is available on this system for basic testing
975
- - This executable is compiled for Windows {arch_info}
976
- - Full compatibility requires running on actual Windows
977
- - Some features may not work correctly in wine
978
- - Version parsing issue has been resolved in compilation"""
979
- else:
980
- return f"""❌ Cannot run Windows .exe file on Linux system (wine not available).
981
-
982
- ## Binary Information:
983
- - **Architecture**: {arch_info}
984
- - **Type**: Windows PE executable
985
- - **Version Fix**: Compiled with improved version parsing
986
-
987
- ## Network Error Handling Included:
988
- This executable includes enhanced error handling for network issues:
989
- - Will show helpful messages if DNS resolution fails
990
- - Exits with code 6 for network errors (matching original issue)
991
- - Provides guidance on handling offline scenarios
992
-
993
- ## To run this binary:
994
- 1. Download the .exe file
995
- 2. Transfer it to a Windows machine
996
- 3. Run it by double-clicking or from command prompt
997
-
998
- ```cmd
999
- # On Windows command prompt:
1000
- cd /path/to/downloaded/file
1001
- {os.path.basename(binary_path)}
1002
- ```
1003
-
1004
- ## Note:
1005
- - This executable is compiled for Windows {arch_info}
1006
- - Compatible with appropriate Windows systems
1007
- - Includes better error messages for network issues
1008
- - Version parsing issue has been resolved
1009
-
1010
- ## Alternative:
1011
- Install wine to test Windows executables on Linux:
1012
- ```bash
1013
- sudo apt update
1014
- sudo apt install wine
1015
- wine {os.path.basename(binary_path)}
1016
- ```"""
1017
-
1018
- # Make the binary executable (for non-Windows)
1019
- if not binary_path.endswith('.exe'):
1020
- os.chmod(binary_path, 0o755)
1021
 
1022
  # Run the binary with timeout
1023
  process = subprocess.run(
@@ -1055,14 +753,13 @@ wine {os.path.basename(binary_path)}
1055
  return f"❌ **Error running the binary:**\n\n```\n{str(e)}\n```"
1056
 
1057
  # Create Gradio interface
1058
- with gr.Blocks(title="Nuitka Python Compiler (Fixed Version Parsing)", theme=gr.themes.Soft()) as app:
1059
- gr.Markdown("# πŸš€ Nuitka Python Compiler (Fixed Version Parsing)")
1060
- gr.Markdown("Convert your Python code into portable executables using Nuitka, with **FIXED version parsing** and enhanced network error handling.")
1061
 
1062
  # Check environment status
1063
  has_static = check_static_libpython()
1064
  missing_deps = check_dependencies()
1065
- missing_mingw, available_mingw = check_mingw_installation()
1066
 
1067
  if "nuitka" in missing_deps:
1068
  gr.Markdown("⚠️ **Nuitka is not installed!** Add 'nuitka' to your requirements.txt file.")
@@ -1072,41 +769,27 @@ with gr.Blocks(title="Nuitka Python Compiler (Fixed Version Parsing)", theme=gr.
1072
  else:
1073
  gr.Markdown("πŸ”§ **Using alternative portable options.** Static libpython not available.")
1074
 
1075
- if available_mingw:
1076
- gr.Markdown(f"βœ… **MinGW-w64 Available!** Found {len(available_mingw)} compilers.")
1077
- with gr.Accordion("Available MinGW-w64 Compilers", open=False):
1078
- for compiler, arch in available_mingw:
1079
- gr.Markdown(f"- {compiler} ({arch})")
1080
- gr.Markdown("πŸ”§ **VERSION PARSING FIXED!** Improved wrapper scripts handle version detection.")
1081
-
1082
- if missing_mingw:
1083
- gr.Markdown(f"⚠️ **Some MinGW-w64 Components Missing:** {len(missing_mingw)} compilers not found.")
1084
- with gr.Accordion("Missing MinGW-w64 Compilers", open=False):
1085
- for compiler, arch in missing_mingw:
1086
- gr.Markdown(f"- {compiler} ({arch})")
1087
- gr.Markdown("πŸ“ **For Windows .exe generation**, MinGW-w64 should be pre-installed in the environment.")
1088
 
1089
- if [dep for dep in missing_deps if dep != "nuitka" and dep != "mingw-w64"]:
1090
- gr.Markdown(f"⚠️ **Other missing dependencies:** {', '.join([dep for dep in missing_deps if dep != 'nuitka' and dep != 'mingw-w64'])}")
1091
-
1092
- # Version parsing fix information
1093
  gr.Markdown("""
1094
- > πŸ”§ **Version Parsing Issue FIXED!**:
1095
- > - **Problem**: MinGW compilers returning "12-win32" instead of "12.0.0"
1096
- > - **Solution**: Improved wrapper scripts with regex parsing
1097
- > - **Result**: Clean conversion to valid version numbers
1098
- > - **Bonus**: Enhanced network error handling for runtime issues
1099
  """)
1100
 
1101
  with gr.Tabs():
1102
  with gr.TabItem("πŸ”§ Compiler"):
1103
  with gr.Row():
1104
- with gr.Column(scale=2):
 
1105
  code_input = gr.Code(
1106
  value="""# Your Python code here
1107
  print('Hello from compiled Python!')
1108
- print('This cross-platform binary was created with Nuitka!')
1109
- print('Version parsing issues have been FIXED!')
1110
 
1111
  # This will work with automatic compatibility detection
1112
  import os, sys
@@ -1114,18 +797,33 @@ print(f'Running from: {os.getcwd()}')
1114
  print(f'Python executable: {sys.executable}')
1115
  print(f'Platform: {sys.platform}')
1116
 
1117
- # Simple example with user input
1118
- name = input('What is your name? ')
1119
- print(f'Hello, {name}!')
1120
-
1121
- # Wait for user before closing (helpful for Windows .exe)
1122
- input('Press Enter to exit...')""",
 
 
 
 
 
 
 
 
 
 
 
 
1123
  language="python",
1124
- label="Your Python Code",
1125
- lines=20
 
1126
  )
1127
 
1128
  with gr.Column(scale=1):
 
 
1129
  with gr.Tabs():
1130
  with gr.TabItem("Python Requirements"):
1131
  requirements_input = gr.Textbox(
@@ -1137,63 +835,61 @@ input('Press Enter to exit...')""",
1137
  # matplotlib
1138
  # pillow
1139
 
1140
- # Note: Some packages may not work with Windows cross-compilation""",
1141
  lines=8,
1142
  label="requirements.txt content"
1143
  )
1144
 
1145
  with gr.TabItem("System Packages"):
1146
  gr.Markdown("⚠️ **System packages cannot be installed in HF Spaces**")
1147
- gr.Markdown("πŸ“ **For MinGW-w64**, it should be pre-installed in the Docker image")
1148
  packages_input = gr.Textbox(
1149
  placeholder="""# System packages (for reference only)
1150
  # These should be pre-installed in HF Spaces
1151
- # mingw-w64
1152
- # gcc-mingw-w64-x86-64
1153
- # g++-mingw-w64-x86-64""",
1154
  lines=8,
1155
  label="System packages (Reference Only)",
1156
  interactive=True
1157
  )
1158
 
1159
- # Fixed dropdown choices
1160
- compilation_mode = gr.Dropdown(
1161
- choices=[
1162
- "Maximum Compatibility (Recommended)",
1163
- "Portable Binary",
1164
- "Standalone Binary"
1165
- ],
1166
- value="Maximum Compatibility (Recommended)",
1167
- label="Compilation Mode"
1168
- )
1169
-
1170
- output_extension = gr.Dropdown(
1171
- choices=[".bin", ".sh", ".exe"],
1172
- value=".bin",
1173
- label="Output File Extension"
1174
- )
1175
-
1176
- gr.Markdown("### πŸ”§ Environment Status")
1177
- gr.Markdown(f"πŸ“ **Python Version**: {get_current_python_version()}")
1178
- gr.Markdown(f"πŸš€ **Nuitka Version**: {get_nuitka_version()}")
1179
-
1180
- if available_mingw:
1181
- has_64bit = any("x86_64" in comp for comp, arch in available_mingw)
1182
- has_32bit = any("i686" in comp for comp, arch in available_mingw)
1183
- gr.Markdown(f"βœ… **MinGW-w64**: Available ({'64-bit' if has_64bit else ''}{'/' if has_64bit and has_32bit else ''}{'32-bit' if has_32bit else ''})")
1184
- gr.Markdown("πŸ”§ **Version parsing**: FIXED with wrapper scripts")
1185
- else:
1186
- gr.Markdown("⚠️ **MinGW-w64**: Not available")
1187
-
1188
- if check_static_libpython():
1189
- gr.Markdown("πŸ”— **Static libpython will be used for Linux targets!**")
1190
- else:
1191
- gr.Markdown("πŸ”§ **Using portable compilation flags**")
1192
 
1193
- # Add enhanced fix notice
1194
- gr.Markdown("πŸ—οΈ **Enhanced**: Version parsing + network error handling")
 
 
 
 
 
 
 
 
 
 
1195
 
1196
- compile_btn = gr.Button("πŸš€ Compile with Nuitka (Fixed)", variant="primary")
 
1197
 
1198
  # Progress Bar Section
1199
  with gr.Column(visible=False) as progress_section:
@@ -1217,7 +913,7 @@ input('Press Enter to exit...')""",
1217
  result_summary = gr.Markdown()
1218
  with gr.Accordion("πŸ“œ Complete Compilation Logs", open=False):
1219
  compile_logs = gr.Textbox(label="Complete Compilation Output", lines=15)
1220
- download_file = gr.File(label="πŸ“₯ Download Compiled Binary")
1221
 
1222
  # Test run section
1223
  with gr.Row():
@@ -1279,10 +975,10 @@ input('Press Enter to exit...')""",
1279
  # Progress simulation with log updates
1280
  progress_steps = [
1281
  (0.1, "Checking Nuitka installation..."),
1282
- (0.15, f"Creating improved wrapper scripts..." if extension == ".exe" else "Checking environment..."),
1283
  (0.2, "Adding network error handling..."),
1284
  (0.3, "Installing requirements..."),
1285
- (0.4, f"Starting {'64-bit Windows ' if extension == '.exe' else ''}compilation with fixed version parsing..."),
1286
  (0.5, "Processing imports..."),
1287
  (0.6, "Optimizing code..."),
1288
  (0.7, f"Creating {extension} binary..."),
@@ -1327,16 +1023,9 @@ input('Press Enter to exit...')""",
1327
  # Get compilation result
1328
  summary, binary_path, logs, success = compilation_result[0]
1329
 
1330
- # Final progress update with version fix notice
1331
- final_status = "βœ… Compilation successful with version fix!" if success else "❌ Compilation failed"
1332
- if success and extension == ".exe":
1333
- # Try to determine architecture from logs
1334
- if "64-bit" in current_logs or "PE32+" in current_logs:
1335
- final_status += " (Windows 64-bit .exe)"
1336
- elif "32-bit" in current_logs:
1337
- final_status += " (Windows 32-bit .exe)"
1338
- else:
1339
- final_status += " (Windows .exe)"
1340
  final_status += " + Network Error Handling"
1341
 
1342
  yield (
@@ -1362,7 +1051,7 @@ input('Press Enter to exit...')""",
1362
  # Final update with download file
1363
  yield (
1364
  gr.update(visible=True), # progress_section
1365
- gr.update(value=create_progress_bar(1.0, f"βœ… {extension} compilation successful with version fix! Ready to download.")), # progress_bar
1366
  gr.update(visible=True), # logs_section
1367
  gr.update(value=current_logs), # real_time_logs
1368
  gr.update(visible=True), # results_section
@@ -1435,73 +1124,56 @@ input('Press Enter to exit...')""",
1435
 
1436
  with gr.TabItem("πŸ“– How to Use"):
1437
  gr.Markdown("""
1438
- ## 🎯 Enhanced Compilation with Fixed Version Parsing
1439
 
1440
- **Solution for MinGW Version Issues + Network Error Handling**
1441
 
1442
- This app has been updated to fix the critical version parsing issue:
1443
- - **Problem**: MinGW compilers returning "12-win32"
1444
- - **Solution**: Improved wrapper scripts with regex parsing
1445
- - **Result**: Clean conversion to valid version numbers (e.g., "12.0.0")
1446
- - **Bonus**: Enhanced network error handling for runtime issues
1447
 
1448
- **New Version Parsing Features:**
1449
- ```bash
1450
- # Before (causing error):
1451
- gcc --version β†’ "gcc (GCC) 12-win32"
1452
- int("12-win32") β†’ ValueError!
1453
-
1454
- # After (fixed with wrapper):
1455
- gcc --version β†’ "12.0.0"
1456
- int("12") β†’ Success!
1457
  ```
1458
 
1459
  ## πŸ“‹ Usage Instructions
1460
 
1461
  ### 1. Write Your Code
1462
- - Enter your Python code in the code editor
 
1463
  - Add Python package requirements in the requirements tab
1464
- - For Windows .exe, consider adding `input('Press Enter to exit...')`
1465
-
1466
- ### 2. Compilation Process
1467
- - **Linux (.bin)**: Native compilation with network handling
1468
- - **Windows (.exe)**: 64-bit cross-compilation with fixed version parsing
1469
- - The system automatically creates wrapper scripts for version detection
1470
-
1471
- ### 3. Network Considerations
 
 
 
 
 
 
 
 
1472
  If your code uses online services (like Hugging Face):
1473
  - **Development**: Works normally with internet access
1474
  - **Compiled binary**: Includes enhanced error handling
1475
  - **Error messages**: Provide clear guidance on failures
1476
 
1477
- ## πŸ”§ Version Parsing Fix Details
1478
-
1479
- **What's Fixed:**
1480
- ```python
1481
- # Wrapper script with regex patterns:
1482
- if [[ $version_output =~ ([0-9]+)\.([0-9]+)\.?([0-9]*) ]]; then
1483
- # Standard x.y.z format
1484
- echo "${major}.${minor}.${patch}"
1485
- elif [[ $version_output =~ ([0-9]+)[^0-9] ]]; then
1486
- # Just major version (like "12-win32")
1487
- echo "${major}.0.0"
1488
- else
1489
- # Fallback for any unparseable format
1490
- echo "12.0.0"
1491
- fi
1492
- ```
1493
-
1494
- **Benefits:**
1495
- 1. Handles all MinGW version formats
1496
- 2. Converts problematic strings like "12-win32"
1497
- 3. Provides fallback for edge cases
1498
- 4. Ensures Nuitka gets parseable version numbers
1499
-
1500
- ## 🌐 Network Error Handling
1501
 
1502
- **Enhanced for Runtime:**
1503
  ```python
1504
- # Automatic network error detection
1505
  try:
1506
  urllib.request.urlopen(url)
1507
  except urllib.error.URLError as e:
@@ -1516,35 +1188,19 @@ input('Press Enter to exit...')""",
1516
  3. **Error Guidance**: Suggestions for offline operation
1517
  4. **Debugging Info**: Shows exact error cause
1518
 
1519
- ## 🎯 Complete Solution Summary
1520
-
1521
- **Compilation Issues Fixed:**
1522
- - βœ… Version parsing: "12-win32" β†’ "12.0.0"
1523
- - βœ… Wrapper scripts: Handle all MinGW formats
1524
- - βœ… Error prevention: No more ValueError exceptions
1525
- - βœ… Robust fallbacks: Unknown formats handled gracefully
1526
-
1527
- **Runtime Issues Addressed:**
1528
- - βœ… Network error handling: DNS resolution detection
1529
- - βœ… Exit code consistency: Code 6 for network failures
1530
- - βœ… User guidance: Helpful error messages
1531
- - βœ… Offline strategies: Clear recommendations
1532
-
1533
- ## πŸ“Š Error Code Reference
1534
 
1535
- | Exit Code | Meaning | Solution |
1536
- |-----------|---------|----------|
1537
- | 0 | Success | Normal operation |
1538
- | 6 | Network Error | DNS resolution failed |
1539
- | Other | Various Errors | Check error message |
1540
 
1541
- ## ⚠️ Best Practices
1542
-
1543
- **For Compilation:**
1544
- 1. The version parsing issue is now automatically handled
1545
- 2. Wrapper scripts are created transparently
1546
- 3. No manual intervention needed for MinGW version formats
1547
- 4. All MinGW tools are properly wrapped
1548
 
1549
  **For Network-Dependent Applications:**
1550
  1. Always handle network errors gracefully
@@ -1553,43 +1209,71 @@ input('Press Enter to exit...')""",
1553
  4. Use offline modes where available
1554
  5. Display helpful error messages to users
1555
 
1556
- **For Windows .exe Distribution:**
1557
- 1. Test compiled binary on clean Windows system
1558
- 2. Verify network error handling works
1559
- 3. Include instructions for users about network requirements
1560
- 4. Consider bundling required data with executable
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1561
  """)
1562
 
1563
  with gr.TabItem("ℹ️ About"):
1564
  gr.Markdown(f"""
1565
- ## 🧠 Complete Solution: Version Parsing + Runtime Errors
1566
 
1567
  **Technical Implementation:**
1568
 
1569
- ### 1. Version Parsing Fix
1570
- ```bash
1571
- # Created wrapper scripts in mingw_wrappers/ directory
1572
- # Each tool (gcc, g++, ar, etc.) gets a wrapper that:
1573
- # 1. Intercepts --version calls
1574
- # 2. Parses output with robust regex patterns
1575
- # 3. Returns clean version numbers
1576
- # 4. Passes all other commands through normally
1577
- ```
1578
 
1579
- ### 2. Environment Setup
1580
  ```python
1581
- # PATH manipulation ensures wrappers are used first
1582
- env["PATH"] = wrapper_dir + ":" + env["PATH"]
1583
-
1584
- # Compiler environment uses wrapper paths
1585
- env["CC"] = os.path.join(wrapper_dir, "x86_64-w64-mingw32-gcc")
1586
- env["CXX"] = os.path.join(wrapper_dir, "x86_64-w64-mingw32-g++")
1587
- # ... etc for all tools
1588
- ```
1589
-
1590
- ### 3. Network Error Handling
1591
- ```python
1592
- # Automatic urllib patching in compiled code
1593
  def enhanced_urlopen(url, *args, **kwargs):
1594
  try:
1595
  return original_urlopen(url, *args, **kwargs)
@@ -1600,20 +1284,26 @@ input('Press Enter to exit...')""",
1600
  raise
1601
  ```
1602
 
1603
- ## βœ… Comprehensive Fix Results
 
 
 
 
 
 
1604
 
1605
- **Version Parsing:**
1606
- - βœ… **Regex patterns**: Handle all known formats
1607
- - βœ… **Wrapper scripts**: Transparent to Nuitka
1608
- - βœ… **PATH manipulation**: Ensures wrappers are used
1609
- - βœ… **Fallback handling**: Unknown formats β†’ "12.0.0"
1610
- - βœ… **Tool coverage**: All MinGW tools wrapped
1611
 
1612
- **Network Handling:**
1613
- - βœ… **DNS error detection**: Catches resolution failures
1614
- - βœ… **Exit code 6**: Consistent with your issue
1615
- - βœ… **Helpful messages**: Guide users to solutions
1616
- - βœ… **Offline strategies**: Recommendations included
1617
 
1618
  ## ☁️ Environment Status
1619
 
@@ -1623,16 +1313,10 @@ input('Press Enter to exit...')""",
1623
  Python Version: {get_current_python_version()}
1624
  Nuitka Version: {get_nuitka_version()}
1625
 
1626
- Version Parsing Fix:
1627
- βœ… Wrapper scripts: Will be created during compilation
1628
- βœ… Regex patterns: Handle "12-win32" format
1629
- βœ… PATH modification: Wrappers take precedence
1630
- βœ… Tool coverage: All MinGW utilities wrapped
1631
-
1632
- Cross-Compilation:
1633
- {('βœ… 64-bit MinGW-w64: Available + Fixed' if any('x86_64' in comp for comp, arch in available_mingw) else '❌ 64-bit Missing') if available_mingw else '❌ No MinGW-w64 found'}
1634
- {('βœ… Version parsing: Robust wrapper system' if any('x86_64' in comp for comp, arch in available_mingw) else '')}
1635
- {('βœ… Regex handling: "X-winYY" β†’ "X.0.0"' if any('x86_64' in comp for comp, arch in available_mingw) else '')}
1636
 
1637
  Network Handling:
1638
  βœ… DNS error detection: Enabled
@@ -1643,62 +1327,62 @@ input('Press Enter to exit...')""",
1643
 
1644
  ## πŸ“‹ Technical Specifications
1645
 
1646
- **Version Parsing Regex:**
1647
- ```bash
1648
- # Pattern 1: Standard versions (e.g., "12.3.0")
1649
- ([0-9]+)\.([0-9]+)\.?([0-9]*)
1650
-
1651
- # Pattern 2: Major version only (e.g., "12-win32")
1652
- ([0-9]+)[^0-9]
1653
 
1654
- # Fallback: Always return "12.0.0" if nothing matches
 
 
 
 
 
 
 
1655
  ```
1656
 
1657
- **Wrapper Script Features:**
1658
- ```bash
1659
- #!/bin/bash
1660
- # Advanced wrapper for x86_64-w64-mingw32-gcc
1661
-
1662
- if [ "$1" = "--version" ]; then
1663
- # Extract version with regex
1664
- # Convert to standard format
1665
- # Return clean version number
1666
- else
1667
- # Pass through to real compiler
1668
- exec /usr/bin/x86_64-w64-mingw32-gcc "$@"
1669
- fi
1670
- ```
1671
 
1672
- ## πŸ”§ Implementation Details
 
 
 
 
1673
 
1674
- **Problem Solving Process:**
 
 
 
 
1675
 
1676
- 1. **Root Cause**: MinGW version strings like "12-win32"
1677
- 2. **Analysis**: Nuitka expects "X.Y.Z" format only
1678
- 3. **Solution**: Regex-based wrapper scripts
1679
- 4. **Implementation**: PATH manipulation + environment setup
1680
- 5. **Testing**: Architecture verification for success
1681
- 6. **Enhancement**: Network error handling added
1682
 
1683
  ## πŸš€ Success Indicators
1684
 
1685
  **During Compilation:**
1686
- 1. **Wrapper creation**: See "Creating improved wrapper scripts..."
1687
- 2. **Clean version detection**: No ValueError exceptions
1688
- 3. **Correct architecture**: PE32+ for 64-bit Windows
1689
- 4. **Environment logs**: Show wrapper script usage
1690
 
1691
  **In Compiled Binary:**
1692
- 1. **Network handling**: Graceful DNS error management
1693
- 2. **Exit code 6**: Consistent with original issue
1694
- 3. **User guidance**: Helpful offline suggestions
1695
- 4. **Robust operation**: Handles connectivity issues
1696
 
1697
- This ensures **complete solution** for both compilation and runtime issues - no more version parsing errors and better network error handling.
1698
  """)
1699
 
1700
  gr.Markdown("---")
1701
- gr.Markdown("πŸ€– Created by Claude 3.7 Sonnet | πŸš€ Powered by Nuitka + MinGW-w64 | βœ… Fixed Version Parsing + Network Handling")
1702
 
1703
  if __name__ == "__main__":
1704
  # Create necessary directories on startup
@@ -1709,30 +1393,13 @@ if __name__ == "__main__":
1709
  if "nuitka" in check_dependencies():
1710
  print("WARNING: Nuitka is not installed. Please add 'nuitka' to your requirements.txt file.")
1711
 
1712
- # Check MinGW-w64 status
1713
- missing_mingw, available_mingw = check_mingw_installation()
1714
- if available_mingw:
1715
- print(f"INFO: Found {len(available_mingw)} MinGW-w64 compilers:")
1716
- for compiler, arch in available_mingw:
1717
- print(f" - {compiler} ({arch})")
1718
-
1719
- # Check for 64-bit compiler specifically
1720
- has_64bit = any("x86_64" in comp for comp, arch in available_mingw)
1721
- if has_64bit:
1722
- print("INFO: x86_64-w64-mingw32-gcc detected - 64-bit compilation will be enforced")
1723
- print("INFO: Version parsing issue will be fixed with wrapper scripts")
1724
- print("INFO: Comprehensive environment variables will be set for guaranteed 64-bit output")
1725
- print("INFO: Network error handling will be added to compiled binaries")
1726
- else:
1727
- print("WARNING: No 64-bit MinGW-w64 compiler found - may fall back to 32-bit")
1728
- if missing_mingw:
1729
- print(f"WARNING: Missing {len(missing_mingw)} MinGW-w64 compilers:")
1730
- for compiler, arch in missing_mingw:
1731
- print(f" - {compiler} ({arch})")
1732
-
1733
- print("\nπŸ”§ VERSION PARSING FIX READY!")
1734
- print("This app will automatically handle MinGW version parsing issues")
1735
- print("Wrapper scripts will convert '12-win32' to '12.0.0' and similar transformations")
1736
- print("No manual intervention required - the fix is built-in!")
1737
 
1738
  app.launch()
 
284
  if progress_callback:
285
  progress_callback(0.05, "Checking environment...")
286
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
287
  # Check if static libpython is available
288
  has_static_libpython = check_static_libpython()
289
 
 
450
  # Prepare environment for cross-compilation
451
  env = os.environ.copy()
452
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
453
  # Run compilation
454
  if progress_callback:
455
  progress_callback(0.4, "Executing Nuitka compilation...")
456
 
457
  if log_queue:
458
  log_queue.put(f"Final compilation command: {' '.join(cmd)}\n")
459
+ log_queue.put("Starting compilation...\n")
460
 
461
  process = subprocess.Popen(
462
  cmd,
 
540
  log_queue.put(f"Binary info: {binary_info}\n")
541
 
542
  # Extract architecture information from file output
543
+ if "ELF" in binary_info:
544
+ if "64-bit" in binary_info:
545
+ arch_info = "Linux 64-bit"
546
+ elif "32-bit" in binary_info:
547
+ arch_info = "Linux 32-bit"
548
+ else:
549
+ arch_info = "Linux"
550
  else:
551
  arch_info = "unknown"
552
 
553
  log_queue.put(f"Detected architecture: {arch_info}\n")
 
 
 
 
 
 
 
 
 
 
 
554
 
555
  except:
556
  binary_info = "Binary file (unable to get detailed info)"
557
  arch_info = "unknown"
558
 
559
+ # Check linking type
560
+ try:
561
+ ldd_process = subprocess.run(["ldd", binary_path], capture_output=True, text=True)
562
+ if "not a dynamic executable" in ldd_process.stderr or "statically linked" in ldd_process.stdout:
563
+ linking_info = "βœ… Statically linked - fully portable!"
564
+ else:
565
+ # Check what dynamic libraries are required
566
+ if ldd_process.returncode == 0:
567
+ libs = ldd_process.stdout.count("=>")
568
+ linking_info = f"πŸ”— Dynamically linked ({libs} libraries) - designed for maximum compatibility"
569
  else:
570
+ linking_info = "ℹ️ Compiled binary - should work on compatible systems"
571
+ except:
572
+ linking_info = "ℹ️ Compiled binary created successfully"
 
 
 
 
 
 
 
 
 
 
 
 
 
573
 
574
  # Rename to desired extension
575
+ if output_extension in ['.bin', '.sh'] and not binary_path.endswith(output_extension):
576
  new_binary_path = binary_path + output_extension
577
  shutil.move(binary_path, new_binary_path)
578
  binary_path = new_binary_path
579
 
580
+ # Make executable
581
+ os.chmod(binary_path, 0o755)
 
582
 
583
  # Build the result summary string
584
  static_status = "Yes" if has_static_libpython else "No"
585
  file_size = os.path.getsize(binary_path) / 1024
586
  binary_basename = os.path.basename(binary_path)
587
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
588
  # Create result summary
589
  result_summary = f"""# βœ… Compilation Successful!
590
 
 
 
 
 
 
591
  ## Compilation Details:
592
  - **Mode**: {mode_name}
593
  - **Nuitka Version**: {nuitka_version}
 
597
  - **Compiled with Python**: {current_python}
598
  - **Static Libpython Available**: {static_status}
599
  - **Linking**: {linking_info}
600
+ - **Target Platform**: Linux
601
+ - **Architecture**: {arch_info}
602
 
603
  ## Environment Results:
604
  **System Packages**: {packages_result}
 
607
  ## Binary Information:
608
  {binary_info}
609
 
 
 
 
610
  ## πŸ“‹ Usage Instructions:
611
  ```bash
612
+ chmod +x {binary_basename}
613
+ ./{binary_basename}
 
614
  ```
615
 
 
 
 
616
  ## 🌐 Network Dependencies:
617
  - Binary includes enhanced error handling for network issues
618
  - Will provide helpful messages if DNS resolution fails
 
620
  - Consider pre-downloading models/data for offline usage
621
 
622
  ## πŸ§ͺ Testing:
623
+ Run directly on compatible Linux systems:
624
  ```bash
625
+ ./{binary_basename}
626
  ```
627
 
628
  ## πŸ”§ Technical Details:
629
+ - Native compilation optimized for compatibility
630
+ - Network error handling added for better runtime diagnostics
631
+ - Enhanced error messages for common issues"""
 
 
 
 
 
 
 
 
 
 
632
 
633
  if progress_callback:
634
+ progress_callback(1.0, f"Compilation successful! Created {arch_info} executable πŸŽ‰")
635
 
636
  if log_queue:
637
  log_queue.put("βœ… Compilation completed successfully!\n")
638
+ log_queue.put("πŸ”§ Enhanced with network error handling!\n")
 
 
 
 
 
 
 
639
 
640
  return result_summary, binary_path, compile_output, True
641
  else:
 
645
  ## Error Details:
646
  - **Exit Code**: {process.returncode}
647
  - **Mode Attempted**: {mode_name}
648
+ - **Target**: Linux
649
 
650
  ## Environment Results:
651
  **System Packages**: {packages_result}
 
656
  {compile_output}
657
  ```
658
 
 
 
 
 
 
 
 
 
 
 
 
 
659
  ## Possible Solutions:
660
  1. Check your code for syntax errors
661
  2. Ensure all imports are available in requirements.txt
662
  3. Try a different compilation mode
663
  4. Review the compilation logs above
 
 
 
664
 
665
  ## Missing Dependencies:
666
  {', '.join(missing_deps) if missing_deps else 'None detected'}
 
668
  ## Environment Info:
669
  - **Nuitka Version**: {nuitka_version}
670
  - **Python Version**: {current_python}
671
+ - **Platform**: {platform.platform()}"""
 
 
 
672
  if progress_callback:
673
  progress_callback(1.0, "Compilation failed ❌")
674
 
 
695
  - **Python Version**: {current_python}
696
  - **Working Directory**: {os.getcwd()}
697
 
 
 
 
 
 
698
  ## Troubleshooting Steps:
699
  1. Check if Nuitka is properly installed
700
  2. Verify your code syntax
701
  3. Check available disk space
702
+ 4. Try with simpler code first"""
 
 
703
  if progress_callback:
704
  progress_callback(1.0, "Error occurred ❌")
705
 
 
714
  return "❌ No binary available to run."
715
 
716
  try:
717
+ # Make the binary executable
718
+ os.chmod(binary_path, 0o755)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
719
 
720
  # Run the binary with timeout
721
  process = subprocess.run(
 
753
  return f"❌ **Error running the binary:**\n\n```\n{str(e)}\n```"
754
 
755
  # Create Gradio interface
756
+ with gr.Blocks(title="Nuitka Python Compiler for Linux", theme=gr.themes.Soft()) as app:
757
+ gr.Markdown("# πŸš€ Nuitka Python Compiler")
758
+ gr.Markdown("Convert your Python code into portable Linux executables using Nuitka, with enhanced network error handling.")
759
 
760
  # Check environment status
761
  has_static = check_static_libpython()
762
  missing_deps = check_dependencies()
 
763
 
764
  if "nuitka" in missing_deps:
765
  gr.Markdown("⚠️ **Nuitka is not installed!** Add 'nuitka' to your requirements.txt file.")
 
769
  else:
770
  gr.Markdown("πŸ”§ **Using alternative portable options.** Static libpython not available.")
771
 
772
+ if [dep for dep in missing_deps if dep != "nuitka"]:
773
+ gr.Markdown(f"⚠️ **Other missing dependencies:** {', '.join([dep for dep in missing_deps if dep != 'nuitka'])}")
 
 
 
 
 
 
 
 
 
 
 
774
 
775
+ # Enhanced features information
 
 
 
776
  gr.Markdown("""
777
+ > ℹ️ **Enhanced Linux Binary Compilation + Network Error Handling**:
778
+ > - Native Linux compilation with maximum compatibility options
779
+ > - **Enhanced network error handling** for runtime issues
780
+ > - Intelligent error messages for common problems
781
+ > - **Exit code 6 handling** for DNS resolution failures
782
  """)
783
 
784
  with gr.Tabs():
785
  with gr.TabItem("πŸ”§ Compiler"):
786
  with gr.Row():
787
+ with gr.Column(scale=3): # Changed scale to make code area larger
788
+ gr.Markdown("### πŸ“ Python Code")
789
  code_input = gr.Code(
790
  value="""# Your Python code here
791
  print('Hello from compiled Python!')
792
+ print('This portable binary was created with Nuitka!')
 
793
 
794
  # This will work with automatic compatibility detection
795
  import os, sys
 
797
  print(f'Python executable: {sys.executable}')
798
  print(f'Platform: {sys.platform}')
799
 
800
+ # Example with user input
801
+ try:
802
+ name = input('What is your name? ')
803
+ print(f'Hello, {name}!')
804
+ except KeyboardInterrupt:
805
+ print('\\nOperation cancelled by user')
806
+ sys.exit(0)
807
+
808
+ # Simple calculation
809
+ def fibonacci(n):
810
+ if n <= 1:
811
+ return n
812
+ return fibonacci(n-1) + fibonacci(n-2)
813
+
814
+ print(f'Fibonacci of 10: {fibonacci(10)}')
815
+
816
+ # Wait for user before closing
817
+ input('\\nPress Enter to exit...')""",
818
  language="python",
819
+ label="Enter your Python code",
820
+ lines=28, # Increased number of visible lines
821
+ show_label=False
822
  )
823
 
824
  with gr.Column(scale=1):
825
+ gr.Markdown("### βš™οΈ Configuration")
826
+
827
  with gr.Tabs():
828
  with gr.TabItem("Python Requirements"):
829
  requirements_input = gr.Textbox(
 
835
  # matplotlib
836
  # pillow
837
 
838
+ # Keep dependencies minimal for better compatibility""",
839
  lines=8,
840
  label="requirements.txt content"
841
  )
842
 
843
  with gr.TabItem("System Packages"):
844
  gr.Markdown("⚠️ **System packages cannot be installed in HF Spaces**")
 
845
  packages_input = gr.Textbox(
846
  placeholder="""# System packages (for reference only)
847
  # These should be pre-installed in HF Spaces
848
+ # Example:
849
+ # build-essential
850
+ # libssl-dev""",
851
  lines=8,
852
  label="System packages (Reference Only)",
853
  interactive=True
854
  )
855
 
856
+ # Compilation options section
857
+ with gr.Group():
858
+ gr.Markdown("### πŸ› οΈ Compilation Options")
859
+
860
+ compilation_mode = gr.Dropdown(
861
+ choices=[
862
+ "Maximum Compatibility (Recommended)",
863
+ "Portable Binary",
864
+ "Standalone Binary"
865
+ ],
866
+ value="Maximum Compatibility (Recommended)",
867
+ label="Compilation Mode",
868
+ info="Choose the type of binary to create"
869
+ )
870
+
871
+ output_extension = gr.Dropdown(
872
+ choices=[".bin", ".sh"],
873
+ value=".bin",
874
+ label="Output File Extension",
875
+ info="File extension for the compiled binary"
876
+ )
 
 
 
 
 
 
 
 
 
 
 
 
877
 
878
+ # Environment status section
879
+ with gr.Group():
880
+ gr.Markdown("### πŸ“Š Environment Status")
881
+ gr.Markdown(f"πŸ“ **Python Version**: {get_current_python_version()}")
882
+ gr.Markdown(f"πŸš€ **Nuitka Version**: {get_nuitka_version()}")
883
+
884
+ if check_static_libpython():
885
+ gr.Markdown("πŸ”— **Static libpython available for maximum portability!**")
886
+ else:
887
+ gr.Markdown("πŸ”§ **Using portable compilation flags**")
888
+
889
+ gr.Markdown("🌐 **Enhanced**: Network error handling included")
890
 
891
+ # Compile button
892
+ compile_btn = gr.Button("πŸš€ Compile with Nuitka", variant="primary", size="lg")
893
 
894
  # Progress Bar Section
895
  with gr.Column(visible=False) as progress_section:
 
913
  result_summary = gr.Markdown()
914
  with gr.Accordion("πŸ“œ Complete Compilation Logs", open=False):
915
  compile_logs = gr.Textbox(label="Complete Compilation Output", lines=15)
916
+ download_file = gr.File(label="πŸ“₯ Download Compiled Binary", visible=False)
917
 
918
  # Test run section
919
  with gr.Row():
 
975
  # Progress simulation with log updates
976
  progress_steps = [
977
  (0.1, "Checking Nuitka installation..."),
978
+ (0.15, "Checking environment..."),
979
  (0.2, "Adding network error handling..."),
980
  (0.3, "Installing requirements..."),
981
+ (0.4, "Starting compilation..."),
982
  (0.5, "Processing imports..."),
983
  (0.6, "Optimizing code..."),
984
  (0.7, f"Creating {extension} binary..."),
 
1023
  # Get compilation result
1024
  summary, binary_path, logs, success = compilation_result[0]
1025
 
1026
+ # Final progress update
1027
+ final_status = "βœ… Compilation successful!" if success else "❌ Compilation failed"
1028
+ if success:
 
 
 
 
 
 
 
1029
  final_status += " + Network Error Handling"
1030
 
1031
  yield (
 
1051
  # Final update with download file
1052
  yield (
1053
  gr.update(visible=True), # progress_section
1054
+ gr.update(value=create_progress_bar(1.0, f"βœ… {extension} compilation successful! Ready to download.")), # progress_bar
1055
  gr.update(visible=True), # logs_section
1056
  gr.update(value=current_logs), # real_time_logs
1057
  gr.update(visible=True), # results_section
 
1124
 
1125
  with gr.TabItem("πŸ“– How to Use"):
1126
  gr.Markdown("""
1127
+ ## 🎯 Enhanced Linux Compilation with Network Error Handling
1128
 
1129
+ **Native Linux Binary Creation + Network Error Solutions**
1130
 
1131
+ This app creates portable Linux binaries with enhanced error handling:
1132
+ - **Native compilation** for maximum compatibility on Linux
1133
+ - **Enhanced network error handling** for runtime DNS issues
1134
+ - **Exit code 6 handling** (matching your original issue)
1135
+ - **Intelligent error messages** for common problems
1136
 
1137
+ **Network Error Handling Features:**
1138
+ ```python
1139
+ # Automatic error handling for network operations
1140
+ # DNS resolution failure detection
1141
+ # Exit code 6 for network issues
1142
+ # Helpful error messages and guidance
 
 
 
1143
  ```
1144
 
1145
  ## πŸ“‹ Usage Instructions
1146
 
1147
  ### 1. Write Your Code
1148
+ - Enter your Python code in the large editor area
1149
+ - The editor is now larger for better code visibility
1150
  - Add Python package requirements in the requirements tab
1151
+ - Consider adding error handling for user input
1152
+
1153
+ ### 2. Configuration
1154
+ - **Python Requirements**: Add pip-installable packages
1155
+ - **Compilation Mode**: Choose based on your needs
1156
+ - Maximum Compatibility: Best for distribution
1157
+ - Portable Binary: Smaller but still compatible
1158
+ - Standalone Binary: Self-contained
1159
+ - **Output Extension**: Choose .bin or .sh
1160
+
1161
+ ### 3. Compilation Process
1162
+ - Click "Compile with Nuitka" to start
1163
+ - Monitor real-time progress and logs
1164
+ - Download the compiled binary when complete
1165
+
1166
+ ### 4. Network Considerations
1167
  If your code uses online services (like Hugging Face):
1168
  - **Development**: Works normally with internet access
1169
  - **Compiled binary**: Includes enhanced error handling
1170
  - **Error messages**: Provide clear guidance on failures
1171
 
1172
+ ## 🌐 Network Error Handling Details
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1173
 
1174
+ **What's Enhanced:**
1175
  ```python
1176
+ # Automatic urllib error wrapping
1177
  try:
1178
  urllib.request.urlopen(url)
1179
  except urllib.error.URLError as e:
 
1188
  3. **Error Guidance**: Suggestions for offline operation
1189
  4. **Debugging Info**: Shows exact error cause
1190
 
1191
+ ## πŸ”§ Best Practices
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1192
 
1193
+ **For Code Organization:**
1194
+ 1. Use the larger code editor for better visibility
1195
+ 2. Keep functions organized and well-commented
1196
+ 3. Handle user input gracefully (try/except blocks)
1197
+ 4. Add proper error handling throughout your code
1198
 
1199
+ **For Dependencies:**
1200
+ 1. Keep requirements minimal for better compatibility
1201
+ 2. Use specific versions where needed
1202
+ 3. Test with minimal dependencies first
1203
+ 4. Consider offline alternatives for network-dependent packages
 
 
1204
 
1205
  **For Network-Dependent Applications:**
1206
  1. Always handle network errors gracefully
 
1209
  4. Use offline modes where available
1210
  5. Display helpful error messages to users
1211
 
1212
+ ## πŸ“Š Compilation Options Explained
1213
+
1214
+ **Maximum Compatibility (Recommended):**
1215
+ - Single standalone file
1216
+ - Includes all dependencies
1217
+ - Works on most Linux systems
1218
+ - Larger file size but maximum portability
1219
+
1220
+ **Portable Binary:**
1221
+ - Requires compatible system libraries
1222
+ - Smaller file size
1223
+ - Good for similar environments
1224
+ - May need dependency installation
1225
+
1226
+ **Standalone Binary:**
1227
+ - Self-contained executable
1228
+ - Medium file size
1229
+ - Independent of Python installation
1230
+ - Good balance of size and portability
1231
+
1232
+ ## πŸš€ Tips for Success
1233
+
1234
+ 1. **Start Simple**: Test with basic code first
1235
+ 2. **Check Dependencies**: Verify all imports are in requirements.txt
1236
+ 3. **Test Locally**: Run your code successfully before compiling
1237
+ 4. **Handle Errors**: Include proper error handling
1238
+ 5. **Monitor Logs**: Watch the compilation logs for issues
1239
+ 6. **Test Binary**: Always test the compiled binary
1240
+
1241
+ ## ⚠️ Common Issues and Solutions
1242
+
1243
+ **If compilation fails:**
1244
+ 1. Check the compilation logs for specific errors
1245
+ 2. Verify your code syntax
1246
+ 3. Ensure all dependencies are listed
1247
+ 4. Try a different compilation mode
1248
+
1249
+ **If the binary crashes:**
1250
+ 1. Run with verbose output to see errors
1251
+ 2. Check for missing dependencies
1252
+ 3. Verify network connectivity if needed
1253
+ 4. Look for exit code 6 (network issues)
1254
+
1255
+ **If network errors occur:**
1256
+ 1. The binary will show helpful error messages
1257
+ 2. Exit code 6 indicates DNS resolution failure
1258
+ 3. Consider pre-downloading data if possible
1259
+ 4. Use offline modes in your libraries
1260
  """)
1261
 
1262
  with gr.TabItem("ℹ️ About"):
1263
  gr.Markdown(f"""
1264
+ ## 🧠 Native Linux Compilation + Network Error Handling
1265
 
1266
  **Technical Implementation:**
1267
 
1268
+ ### 1. Enhanced Compilation
1269
+ - **Native Linux targeting** with maximum compatibility
1270
+ - **Nuitka optimization** for performance
1271
+ - **Static linking** when available
1272
+ - **Dependency resolution** with fallbacks
 
 
 
 
1273
 
1274
+ ### 2. Network Error Enhancements
1275
  ```python
1276
+ # Automatic urllib patching in compiled binaries
 
 
 
 
 
 
 
 
 
 
 
1277
  def enhanced_urlopen(url, *args, **kwargs):
1278
  try:
1279
  return original_urlopen(url, *args, **kwargs)
 
1284
  raise
1285
  ```
1286
 
1287
+ ### 3. User Experience Improvements
1288
+ - **Larger code editor** for better code visibility
1289
+ - **Progressive status updates** during compilation
1290
+ - **Real-time log streaming** for transparency
1291
+ - **Clear error messages** for troubleshooting
1292
+
1293
+ ## βœ… Comprehensive Solution
1294
 
1295
+ **Compilation Features:**
1296
+ - βœ… **Native Linux compilation** with Nuitka
1297
+ - βœ… **Multiple output formats** (.bin, .sh)
1298
+ - βœ… **Dependency handling** with pip integration
1299
+ - βœ… **Progress monitoring** with real-time logs
1300
+ - βœ… **Error detection** and helpful feedback
1301
 
1302
+ **Runtime Features:**
1303
+ - βœ… **Network error detection** for DNS failures
1304
+ - βœ… **Exit code 6** for network issues (matching your original problem)
1305
+ - βœ… **Helpful error messages** for users
1306
+ - βœ… **Offline operation guidance** when network fails
1307
 
1308
  ## ☁️ Environment Status
1309
 
 
1313
  Python Version: {get_current_python_version()}
1314
  Nuitka Version: {get_nuitka_version()}
1315
 
1316
+ Compilation Target: Native Linux
1317
+ βœ… GCC compilation: Available
1318
+ βœ… Static linking: {'Available' if check_static_libpython() else 'Using alternatives'}
1319
+ βœ… Package management: pip integration
 
 
 
 
 
 
1320
 
1321
  Network Handling:
1322
  βœ… DNS error detection: Enabled
 
1327
 
1328
  ## πŸ“‹ Technical Specifications
1329
 
1330
+ **Compilation Process:**
1331
+ 1. **Code Enhancement**: Automatic network error handling injection
1332
+ 2. **Dependency Resolution**: pip install with requirements.txt
1333
+ 3. **Nuitka Compilation**: Native binary creation
1334
+ 4. **Optimization**: Maximum compatibility settings
1335
+ 5. **Verification**: Binary testing and size reporting
 
1336
 
1337
+ **Network Error Handling:**
1338
+ ```python
1339
+ # Enhanced error handling workflow:
1340
+ # 1. urllib operations are intercepted
1341
+ # 2. DNS resolution errors are detected
1342
+ # 3. Helpful error messages are displayed
1343
+ # 4. Exit code 6 is returned for consistency
1344
+ # 5. Offline operation suggestions are provided
1345
  ```
1346
 
1347
+ ## πŸ”§ Advanced Features
 
 
 
 
 
 
 
 
 
 
 
 
 
1348
 
1349
+ **Code Editor Improvements:**
1350
+ - Larger editing area (3:1 ratio with configuration)
1351
+ - Syntax highlighting for Python
1352
+ - 28 visible lines by default
1353
+ - Better example code with error handling
1354
 
1355
+ **Configuration Options:**
1356
+ - Streamlined interface without Windows options
1357
+ - Focus on Linux-specific features
1358
+ - Clear explanations for each option
1359
+ - Real-time environment status
1360
 
1361
+ **Progress Tracking:**
1362
+ - Visual progress bar with percentages
1363
+ - Real-time log streaming
1364
+ - Clear status messages
1365
+ - Detailed error reporting
 
1366
 
1367
  ## πŸš€ Success Indicators
1368
 
1369
  **During Compilation:**
1370
+ 1. **Progress bar** shows smooth advancement
1371
+ 2. **Real-time logs** show Nuitka activity
1372
+ 3. **No version parsing errors** (Linux-native)
1373
+ 4. **Clean binary creation** with size reporting
1374
 
1375
  **In Compiled Binary:**
1376
+ 1. **Network handling** works automatically
1377
+ 2. **Exit code 6** for DNS resolution failures
1378
+ 3. **User-friendly messages** for common errors
1379
+ 4. **Consistent behavior** with your original issue
1380
 
1381
+ This ensures a **complete solution** for creating portable Linux binaries with intelligent network error handling - no more version parsing issues and better runtime error management.
1382
  """)
1383
 
1384
  gr.Markdown("---")
1385
+ gr.Markdown("πŸ€– Created by Claude 3.7 Sonnet | πŸš€ Powered by Nuitka | 🐧 Linux Native + Network Error Handling")
1386
 
1387
  if __name__ == "__main__":
1388
  # Create necessary directories on startup
 
1393
  if "nuitka" in check_dependencies():
1394
  print("WARNING: Nuitka is not installed. Please add 'nuitka' to your requirements.txt file.")
1395
 
1396
+ print("\n🐧 LINUX NATIVE COMPILATION READY!")
1397
+ print("This app creates portable Linux binaries with enhanced network error handling")
1398
+ print("Features:")
1399
+ print("- Larger code editor for better visibility")
1400
+ print("- Native Linux compilation only (no Windows cross-compilation)")
1401
+ print("- Enhanced network error handling with exit code 6")
1402
+ print("- Real-time compilation logs and progress")
1403
+ print("- Multiple output formats (.bin, .sh)")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1404
 
1405
  app.launch()