euler314 commited on
Commit
06782e4
Β·
verified Β·
1 Parent(s): e295487

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +80 -388
app.py CHANGED
@@ -18,12 +18,12 @@ def check_dependencies():
18
  """Check if required dependencies are available"""
19
  missing_deps = []
20
 
21
- # Check for patchelf
22
  result = subprocess.run(["which", "patchelf"], capture_output=True)
23
  if result.returncode != 0:
24
  missing_deps.append("patchelf")
25
 
26
- # Check for gcc
27
  result = subprocess.run(["which", "gcc"], capture_output=True)
28
  if result.returncode != 0:
29
  missing_deps.append("gcc")
@@ -66,72 +66,23 @@ def get_nuitka_version():
66
  return "unknown"
67
 
68
  def install_system_packages(packages_content, progress=gr.Progress()):
69
- """Install system packages from packages.txt content"""
70
  if not packages_content.strip():
71
  return "No system packages specified."
72
 
73
- progress(0, desc="Starting package installation...")
 
 
74
 
75
- # Create temporary file
76
- fd, temp_path = tempfile.mkstemp(suffix='.txt')
77
- try:
78
- with os.fdopen(fd, 'w') as tmp:
79
- tmp.write(packages_content)
80
-
81
- # Install packages line by line
82
- install_log = ""
83
- failed_packages = []
84
- successful_packages = []
85
-
86
- lines = packages_content.strip().split('\n')
87
- total_packages = len([line for line in lines if line.strip() and not line.strip().startswith('#')])
88
- current_package = 0
89
-
90
- with open(temp_path, 'r') as f:
91
- for line in f:
92
- line = line.strip()
93
- # Skip empty lines and comments
94
- if not line or line.startswith('#'):
95
- continue
96
-
97
- current_package += 1
98
- progress(current_package / total_packages, desc=f"Installing: {line}")
99
-
100
- # Try to install package (Note: this might not work in HF Spaces)
101
- install_process = subprocess.run(
102
- ["apt-get", "update", "-qq"],
103
- capture_output=True,
104
- text=True
105
- )
106
-
107
- install_process = subprocess.run(
108
- ["apt-get", "install", "-y", line],
109
- capture_output=True,
110
- text=True
111
- )
112
-
113
- if install_process.returncode == 0:
114
- successful_packages.append(line)
115
- install_log += f"βœ… Successfully installed: {line}\n"
116
- else:
117
- failed_packages.append(line)
118
- install_log += f"❌ Failed to install: {line}\n"
119
-
120
- summary = f"""
121
- System Packages Summary:
122
- βœ… Successful: {', '.join(successful_packages)}
123
- ❌ Failed: {', '.join(failed_packages)}
124
  """
125
- return summary + "\n" + install_log
126
-
127
- except Exception as e:
128
- error_msg = f"Error installing system packages: {str(e)}"
129
- return error_msg
130
-
131
- finally:
132
- # Clean up
133
- if os.path.exists(temp_path):
134
- os.unlink(temp_path)
135
 
136
  def find_compiled_binary(output_dir, output_filename):
137
  """Find the compiled binary, checking different possible paths"""
@@ -172,8 +123,6 @@ def compile_with_nuitka(code, requirements, packages, compilation_mode, output_e
172
 
173
  # Check dependencies first
174
  missing_deps = check_dependencies()
175
- if missing_deps:
176
- return f"Required dependencies are missing: {', '.join(missing_deps)}", None, None, False
177
 
178
  # Create unique ID for this compilation
179
  job_id = str(uuid.uuid4())
@@ -185,12 +134,10 @@ def compile_with_nuitka(code, requirements, packages, compilation_mode, output_e
185
  ensure_dir(job_dir)
186
  ensure_dir(output_dir)
187
 
188
- progress(0.1, desc="Installing dependencies...")
189
 
190
- # Install system packages if specified
191
- packages_result = "No system packages specified."
192
- if packages.strip():
193
- packages_result = install_system_packages(packages, progress)
194
 
195
  # Write code to a Python file
196
  script_path = os.path.join(job_dir, "user_script.py")
@@ -213,26 +160,20 @@ def compile_with_nuitka(code, requirements, packages, compilation_mode, output_e
213
  )
214
 
215
  if install_process.returncode == 0:
216
- install_result = "Python requirements installed successfully."
217
  else:
218
- install_result = f"Installation completed with return code: {install_process.returncode}\n{install_process.stderr}"
219
  except Exception as e:
220
- install_result = f"Error: {str(e)}"
221
- return str(e), None, None, False
222
 
223
  # Compilation
224
  try:
225
  progress(0.3, desc="Starting compilation...")
226
 
227
- # Define compilation options with adaptive static linking
228
- def build_cmd(base_cmd, use_static=False):
229
- if use_static and has_static_libpython:
230
- base_cmd.append("--static-libpython=yes")
231
- return base_cmd
232
-
233
- # Map compilation mode strings to actual configurations
234
  if compilation_mode == "Maximum Compatibility (Recommended)":
235
- cmd = build_cmd([
236
  sys.executable, "-m", "nuitka",
237
  "--standalone",
238
  "--onefile", # Single portable file
@@ -241,23 +182,32 @@ def compile_with_nuitka(code, requirements, packages, compilation_mode, output_e
241
  "--follow-imports",
242
  "--assume-yes-for-downloads", # Auto-download missing dependencies
243
  "--python-flag=no_site", # Reduce dependencies
 
244
  script_path,
245
  f"--output-dir={output_dir}"
246
- ], use_static=True)
 
 
 
 
 
247
  mode_name = "Maximum Compatibility Binary"
 
248
  elif compilation_mode == "Portable Binary":
249
- cmd = build_cmd([
250
  sys.executable, "-m", "nuitka",
251
  "--show-progress",
252
  "--remove-output",
253
  "--assume-yes-for-downloads",
254
  "--python-flag=no_site",
 
255
  script_path,
256
  f"--output-dir={output_dir}"
257
- ], use_static=True)
258
  mode_name = "Portable Non-Standalone"
 
259
  else: # Standalone Binary
260
- cmd = build_cmd([
261
  sys.executable, "-m", "nuitka",
262
  "--standalone",
263
  "--onefile",
@@ -265,9 +215,10 @@ def compile_with_nuitka(code, requirements, packages, compilation_mode, output_e
265
  "--remove-output",
266
  "--assume-yes-for-downloads",
267
  "--python-flag=no_site",
 
268
  script_path,
269
  f"--output-dir={output_dir}"
270
- ], use_static=True)
271
  mode_name = "Standalone Binary"
272
 
273
  # Run compilation
@@ -291,7 +242,10 @@ def compile_with_nuitka(code, requirements, packages, compilation_mode, output_e
291
 
292
  # Update progress
293
  progress_val = 0.3 + (min(line_count / 200, 0.69) * 0.7)
294
- progress(progress_val, desc="Compiling...")
 
 
 
295
 
296
  process.wait()
297
 
@@ -319,20 +273,26 @@ def compile_with_nuitka(code, requirements, packages, compilation_mode, output_e
319
 
320
  if process.returncode == 0 and binary_path:
321
  # Check if it's really a binary file
322
- file_process = subprocess.run(["file", binary_path], capture_output=True, text=True)
323
- binary_info = file_process.stdout
 
 
 
324
 
325
  # Check linking type
326
- ldd_process = subprocess.run(["ldd", binary_path], capture_output=True, text=True)
327
- if "not a dynamic executable" in ldd_process.stderr or "statically linked" in ldd_process.stdout:
328
- linking_info = "βœ… Statically linked - fully portable!"
329
- else:
330
- # Check what dynamic libraries are required
331
- if ldd_process.returncode == 0:
332
- libs = ldd_process.stdout.count("=>")
333
- linking_info = f"πŸ”— Dynamically linked ({libs} libraries) - designed for maximum compatibility"
334
  else:
335
- linking_info = "ℹ️ Compiled binary - should work on compatible systems"
 
 
 
 
 
 
 
336
 
337
  # Rename to desired extension
338
  if output_extension in ['.bin', '.sh'] and not binary_path.endswith(output_extension):
@@ -348,301 +308,33 @@ def compile_with_nuitka(code, requirements, packages, compilation_mode, output_e
348
 
349
  # Add system info to result
350
  result_summary = f"""
351
- Compilation Details:
352
- - Mode: {mode_name}
353
- - Nuitka Version: {nuitka_version}
354
- - Exit Code: {process.returncode}
355
- - Output Path: {binary_path}
356
- - File Size: {os.path.getsize(binary_path) / 1024:.2f} KB
357
- - Compiled with Python: {current_python}
358
- - Static Libpython Available: {'Yes' if has_static_libpython else 'No'}
359
- - Linking: {linking_info}
 
 
360
 
361
- System Packages: {packages_result}
362
- Python Requirements: {install_result}
 
363
 
364
- Binary Information: {binary_info}
 
365
 
366
- PORTABILITY NOTES:
367
  - This binary was compiled with maximum compatibility settings
368
  - Using --onefile for single-file distribution
369
  - Added --assume-yes-for-downloads for automatic dependency resolution
370
  - Used --python-flag=no_site to reduce system dependencies
371
  - Should work on most compatible Linux systems
372
- """
373
-
374
- progress(1.0, desc="Compilation successful!")
375
- return result_summary, binary_path, compile_output, True
376
- else:
377
- return f"Compilation failed.\n\nSystem Packages: {packages_result}\nPython Requirements: {install_result}", None, compile_output, False
378
-
379
- except Exception as e:
380
- return f"Compilation error: {str(e)}", None, f"Error: {str(e)}", False
381
-
382
- def run_compiled_binary(binary_path):
383
- """Run the compiled binary and return the output"""
384
- if not binary_path or not os.path.exists(binary_path):
385
- return "No binary available to run."
386
-
387
- try:
388
- # Make the binary executable
389
- os.chmod(binary_path, 0o755)
390
-
391
- # Run the binary with timeout
392
- process = subprocess.run(
393
- [binary_path],
394
- capture_output=True,
395
- text=True,
396
- timeout=10
397
- )
398
-
399
- output = ""
400
- if process.stdout:
401
- output += f"[STDOUT]\n{process.stdout}\n"
402
- if process.stderr:
403
- output += f"[STDERR]\n{process.stderr}\n"
404
- if process.returncode != 0:
405
- output += f"[EXIT CODE] {process.returncode}\n"
406
-
407
- return output if output else "No output."
408
- except subprocess.TimeoutExpired:
409
- return "Execution timed out after 10 seconds."
410
- except Exception as e:
411
- return f"Error running the binary: {str(e)}"
412
-
413
- # Create Gradio interface
414
- with gr.Blocks(title="Nuitka Python Compiler", theme=gr.themes.Soft()) as app:
415
- gr.Markdown("# πŸš€ Nuitka Python Compiler (Smart Compilation)")
416
- gr.Markdown("Convert your Python code into portable executables using Nuitka with smart compatibility detection.")
417
-
418
- # Check environment status
419
- has_static = check_static_libpython()
420
- missing_deps = check_dependencies()
421
-
422
- if has_static:
423
- gr.Markdown("🎯 **Static Libpython Available!** Maximum portability enabled.")
424
- else:
425
- gr.Markdown("πŸ”§ **Using alternative portable options.** Static libpython not available.")
426
-
427
- if missing_deps:
428
- gr.Markdown(f"⚠️ **Missing dependencies:** {', '.join(missing_deps)}")
429
- else:
430
- gr.Markdown("βœ… **All required dependencies available!**")
431
-
432
- with gr.Tabs():
433
- with gr.TabItem("πŸ”§ Compiler"):
434
- with gr.Row():
435
- with gr.Column(scale=2):
436
- code_input = gr.Code(
437
- value="""# Your Python code here
438
- print('Hello from compiled Python!')
439
- print('This is a smart-compiled binary!')
440
-
441
- # This will work with automatic compatibility detection
442
- import os, sys
443
- print(f'Running from: {os.getcwd()}')
444
- print(f'Python executable: {sys.executable}')
445
- print('Compilation was optimized for your environment!')""",
446
- language="python",
447
- label="Your Python Code",
448
- lines=20
449
- )
450
-
451
- with gr.Column(scale=1):
452
- with gr.Tabs():
453
- with gr.TabItem("Python Requirements"):
454
- requirements_input = gr.Textbox(
455
- placeholder="""# Add your Python dependencies here
456
- # Example:
457
- # numpy==1.24.0
458
- # pandas==2.0.0
459
- # requests>=2.28.0""",
460
- lines=8,
461
- label="requirements.txt content"
462
- )
463
-
464
- with gr.TabItem("System Packages"):
465
- packages_input = gr.Textbox(
466
- placeholder="""# Add system packages here (one per line)
467
- # Example:
468
- # build-essential
469
- # libssl-dev
470
- # ffmpeg
471
- # imagemagick""",
472
- lines=8,
473
- label="packages.txt content"
474
- )
475
-
476
- # Fixed dropdown choices
477
- compilation_mode = gr.Dropdown(
478
- choices=[
479
- "Maximum Compatibility (Recommended)",
480
- "Portable Binary",
481
- "Standalone Binary"
482
- ],
483
- value="Maximum Compatibility (Recommended)",
484
- label="Compilation Mode"
485
- )
486
-
487
- output_extension = gr.Dropdown(
488
- choices=[".bin", ".sh"],
489
- value=".bin",
490
- label="Output File Extension"
491
- )
492
-
493
- gr.Markdown(f"πŸ“ **Compiling with Python {get_current_python_version()}**")
494
- if check_static_libpython():
495
- gr.Markdown("πŸ”— **Static libpython will be used!**")
496
- else:
497
- gr.Markdown("πŸ”§ **Using portable compilation flags**")
498
-
499
- compile_btn = gr.Button("πŸš€ Compile with Nuitka", variant="primary")
500
-
501
- # Results section
502
- with gr.Column(visible=False) as results_section:
503
- result_summary = gr.Textbox(label="Compilation Results", lines=10)
504
- compile_logs = gr.Textbox(label="Compilation Logs", lines=10)
505
- download_file = gr.File(label="Download Compiled Binary")
506
-
507
- # Test run section
508
- with gr.Row():
509
- run_btn = gr.Button("πŸ§ͺ Test Run")
510
- run_output = gr.Textbox(label="Execution Output", lines=8)
511
-
512
- # Variables to store state
513
- current_binary_path = gr.State(None)
514
- compilation_success = gr.State(False)
515
-
516
- def handle_compilation(code, requirements, packages, mode, extension, progress=gr.Progress()):
517
- summary, binary_path, logs, success = compile_with_nuitka(
518
- code, requirements, packages, mode, extension, progress
519
- )
520
-
521
- if success and binary_path:
522
- # Create download file
523
- download_filename = f"compiled_program{extension}"
524
- download_path = os.path.join(os.path.dirname(binary_path), download_filename)
525
- shutil.copy2(binary_path, download_path)
526
-
527
- return (
528
- gr.update(visible=True), # results_section
529
- gr.update(value=summary), # result_summary
530
- gr.update(value=logs), # compile_logs
531
- gr.update(value=download_path), # download_file
532
- binary_path, # current_binary_path state
533
- True # compilation_success state
534
- )
535
- else:
536
- return (
537
- gr.update(visible=True), # results_section
538
- gr.update(value=summary), # result_summary
539
- gr.update(value=logs), # compile_logs
540
- gr.update(visible=False), # download_file
541
- None, # current_binary_path state
542
- False # compilation_success state
543
- )
544
-
545
- def handle_run(binary_path):
546
- if binary_path:
547
- output = run_compiled_binary(binary_path)
548
- return gr.update(value=output)
549
- else:
550
- return gr.update(value="No binary available to run.")
551
-
552
- compile_btn.click(
553
- handle_compilation,
554
- inputs=[code_input, requirements_input, packages_input, compilation_mode, output_extension],
555
- outputs=[results_section, result_summary, compile_logs, download_file, current_binary_path, compilation_success]
556
- )
557
-
558
- run_btn.click(
559
- handle_run,
560
- inputs=[current_binary_path],
561
- outputs=[run_output]
562
- )
563
-
564
- with gr.TabItem("πŸ“– How to Use"):
565
- gr.Markdown("""
566
- ## 🎯 Smart Compilation
567
-
568
- **Automatic Environment Detection**
569
-
570
- This app automatically detects your Python environment and chooses the best compilation strategy:
571
- - Uses static libpython if available (maximum portability)
572
- - Falls back to highly portable alternatives if not
573
- - Automatically handles missing dependencies
574
- - Optimizes for your specific environment
575
-
576
- ## πŸ“‹ General Instructions
577
-
578
- ```bash
579
- # Download the compiled binary
580
- # Method 1: Direct run (if static libpython was used)
581
- chmod +x compiled_program.bin
582
- ./compiled_program.bin
583
-
584
- # Method 2: Copy to Linux filesystem first (recommended for WSL)
585
- cp /mnt/c/Users/username/Downloads/compiled_program.bin ~/
586
- cd ~
587
- chmod +x compiled_program.bin
588
- ./compiled_program.bin
589
- ```
590
-
591
- ## πŸ“Š Environment Types
592
-
593
- | Environment | Portability | Requirements | Best For |
594
- |-------------|-------------|--------------|----------|
595
- | Static Libpython | Maximum | None | Any Linux system |
596
- | Non-Static Libpython | High | Compatible system | Similar environments |
597
- """)
598
-
599
- with gr.TabItem("ℹ️ About"):
600
- gr.Markdown(f"""
601
- ## 🧠 Smart Compilation Technology
602
-
603
- **How it works:**
604
-
605
- 1. **Environment Detection**: Checks if static libpython is available
606
- 2. **Adaptive Options**: Uses the best available compilation flags
607
- 3. **Fallback Strategy**: Ensures compilation succeeds even without static linking
608
- 4. **Automatic Dependencies**: Resolves missing dependencies automatically
609
-
610
- This approach maximizes compatibility across different Python environments.
611
-
612
- ## βœ… What This Solves
613
-
614
- **Problems addressed:**
615
-
616
- - Static libpython not available error
617
- - Python version mismatches
618
- - WSL compatibility issues
619
- - Dependency resolution
620
- - Cross-environment portability
621
-
622
- ## ☁️ Current Environment Status
623
-
624
- ```
625
- Python Version: {get_current_python_version()}
626
- Nuitka Version: {get_nuitka_version()}
627
- Platform: {platform.platform()}
628
- Architecture: {platform.architecture()[0]}
629
- Machine: {platform.machine()}
630
- Static Libpython: {'βœ… Available' if check_static_libpython() else '❌ Not Available'}
631
- ```
632
-
633
- ## πŸ“‹ Best Practices
634
-
635
- **Recommendations:**
636
-
637
- 1. Always use "Maximum Compatibility" mode
638
- 2. Copy binaries to Linux filesystem in WSL
639
- 3. Test the binary in the target environment
640
- 4. Let the app automatically choose the best settings
641
- 5. Check the compilation details for specific optimization used
642
- """)
643
-
644
- gr.Markdown("---")
645
- gr.Markdown("πŸ€– Created by Claude 3.7 Sonnet | πŸš€ Powered by Nuitka with Smart Compilation")
646
 
647
- if __name__ == "__main__":
648
- app.launch()
 
 
 
18
  """Check if required dependencies are available"""
19
  missing_deps = []
20
 
21
+ # Check for patchelf (usually available in HF Spaces)
22
  result = subprocess.run(["which", "patchelf"], capture_output=True)
23
  if result.returncode != 0:
24
  missing_deps.append("patchelf")
25
 
26
+ # Check for gcc (usually available in HF Spaces)
27
  result = subprocess.run(["which", "gcc"], capture_output=True)
28
  if result.returncode != 0:
29
  missing_deps.append("gcc")
 
66
  return "unknown"
67
 
68
  def install_system_packages(packages_content, progress=gr.Progress()):
69
+ """Note about system packages in HF Spaces - they cannot be installed"""
70
  if not packages_content.strip():
71
  return "No system packages specified."
72
 
73
+ # In HF Spaces, we can't install system packages
74
+ packages_list = [line.strip() for line in packages_content.strip().split('\n')
75
+ if line.strip() and not line.strip().startswith('#')]
76
 
77
+ if packages_list:
78
+ return f"""
79
+ ❌ System packages cannot be installed in Hugging Face Spaces:
80
+ {', '.join(packages_list)}
81
+
82
+ ℹ️ HF Spaces runs in a containerized environment without sudo access.
83
+ These packages need to be pre-installed in the Docker image or available as Python packages.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  """
85
+ return "No system packages specified."
 
 
 
 
 
 
 
 
 
86
 
87
  def find_compiled_binary(output_dir, output_filename):
88
  """Find the compiled binary, checking different possible paths"""
 
123
 
124
  # Check dependencies first
125
  missing_deps = check_dependencies()
 
 
126
 
127
  # Create unique ID for this compilation
128
  job_id = str(uuid.uuid4())
 
134
  ensure_dir(job_dir)
135
  ensure_dir(output_dir)
136
 
137
+ progress(0.1, desc="Processing packages...")
138
 
139
+ # Handle system packages (just log them, can't install in HF Spaces)
140
+ packages_result = install_system_packages(packages, progress)
 
 
141
 
142
  # Write code to a Python file
143
  script_path = os.path.join(job_dir, "user_script.py")
 
160
  )
161
 
162
  if install_process.returncode == 0:
163
+ install_result = "βœ… Python requirements installed successfully."
164
  else:
165
+ install_result = f"⚠️ Installation completed with warnings. Return code: {install_process.returncode}\n{install_process.stderr}"
166
  except Exception as e:
167
+ install_result = f"❌ Error installing requirements: {str(e)}"
168
+ return install_result, None, f"Error: {str(e)}", False
169
 
170
  # Compilation
171
  try:
172
  progress(0.3, desc="Starting compilation...")
173
 
174
+ # Build compilation command based on mode
 
 
 
 
 
 
175
  if compilation_mode == "Maximum Compatibility (Recommended)":
176
+ cmd = [
177
  sys.executable, "-m", "nuitka",
178
  "--standalone",
179
  "--onefile", # Single portable file
 
182
  "--follow-imports",
183
  "--assume-yes-for-downloads", # Auto-download missing dependencies
184
  "--python-flag=no_site", # Reduce dependencies
185
+ "--python-flag=no_warnings", # Reduce warnings
186
  script_path,
187
  f"--output-dir={output_dir}"
188
+ ]
189
+
190
+ # Add static linking if available
191
+ if has_static_libpython:
192
+ cmd.append("--static-libpython=yes")
193
+
194
  mode_name = "Maximum Compatibility Binary"
195
+
196
  elif compilation_mode == "Portable Binary":
197
+ cmd = [
198
  sys.executable, "-m", "nuitka",
199
  "--show-progress",
200
  "--remove-output",
201
  "--assume-yes-for-downloads",
202
  "--python-flag=no_site",
203
+ "--python-flag=no_warnings",
204
  script_path,
205
  f"--output-dir={output_dir}"
206
+ ]
207
  mode_name = "Portable Non-Standalone"
208
+
209
  else: # Standalone Binary
210
+ cmd = [
211
  sys.executable, "-m", "nuitka",
212
  "--standalone",
213
  "--onefile",
 
215
  "--remove-output",
216
  "--assume-yes-for-downloads",
217
  "--python-flag=no_site",
218
+ "--python-flag=no_warnings",
219
  script_path,
220
  f"--output-dir={output_dir}"
221
+ ]
222
  mode_name = "Standalone Binary"
223
 
224
  # Run compilation
 
242
 
243
  # Update progress
244
  progress_val = 0.3 + (min(line_count / 200, 0.69) * 0.7)
245
+ if "INFO:" in line:
246
+ progress(progress_val, desc=f"Compiling: {line.strip()[:50]}...")
247
+ else:
248
+ progress(progress_val, desc="Compiling...")
249
 
250
  process.wait()
251
 
 
273
 
274
  if process.returncode == 0 and binary_path:
275
  # Check if it's really a binary file
276
+ try:
277
+ file_process = subprocess.run(["file", binary_path], capture_output=True, text=True)
278
+ binary_info = file_process.stdout
279
+ except:
280
+ binary_info = "Binary file (unable to get detailed info)"
281
 
282
  # Check linking type
283
+ try:
284
+ ldd_process = subprocess.run(["ldd", binary_path], capture_output=True, text=True)
285
+ if "not a dynamic executable" in ldd_process.stderr or "statically linked" in ldd_process.stdout:
286
+ linking_info = "βœ… Statically linked - fully portable!"
 
 
 
 
287
  else:
288
+ # Check what dynamic libraries are required
289
+ if ldd_process.returncode == 0:
290
+ libs = ldd_process.stdout.count("=>")
291
+ linking_info = f"πŸ”— Dynamically linked ({libs} libraries) - designed for maximum compatibility"
292
+ else:
293
+ linking_info = "ℹ️ Compiled binary - should work on compatible systems"
294
+ except:
295
+ linking_info = "ℹ️ Compiled binary created successfully"
296
 
297
  # Rename to desired extension
298
  if output_extension in ['.bin', '.sh'] and not binary_path.endswith(output_extension):
 
308
 
309
  # Add system info to result
310
  result_summary = f"""
311
+ # βœ… Compilation Successful!
312
+
313
+ ## Compilation Details:
314
+ - **Mode**: {mode_name}
315
+ - **Nuitka Version**: {nuitka_version}
316
+ - **Exit Code**: {process.returncode}
317
+ - **Output Path**: {binary_path}
318
+ - **File Size**: {os.path.getsize(binary_path) / 1024:.2f} KB
319
+ - **Compiled with Python**: {current_python}
320
+ - **Static Libpython Available**: {'Yes' if has_static_libpython else 'No'}
321
+ - **Linking**: {linking_info}
322
 
323
+ ## Environment Results:
324
+ **System Packages**: {packages_result}
325
+ **Python Requirements**: {install_result}
326
 
327
+ ## Binary Information:
328
+ {binary_info}
329
 
330
+ ## πŸš€ Portability Notes:
331
  - This binary was compiled with maximum compatibility settings
332
  - Using --onefile for single-file distribution
333
  - Added --assume-yes-for-downloads for automatic dependency resolution
334
  - Used --python-flag=no_site to reduce system dependencies
335
  - Should work on most compatible Linux systems
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
336
 
337
+ ## πŸ“‹ Usage Instructions:
338
+ ```bash
339
+ chmod +x {os.path.basename(binary_path)}
340
+ ./{os.path.basename(binary_path)}