include c headers and modify compiler flags with inline c

Everything else that doesn't fall into one of the other PB categories.
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

include c headers and modify compiler flags with inline c

Post by idle »

Linux Raspberry pi, windows hopefully someone can adapt for mac.

A quick hack to facilitate setting command line and importing c headers so you can utilise almost any c lib directly with inline c with the constant and macros intact.
Just include and use :D

Usage
do compiler flags before imports.
use an inline c comment !// and keyword gccflags followed by flags and end in ;
!//gccflags -fno-schedule-insns -fno-schedule-insns2 ;
;if you need to add a header use inline c comment !// with #include keyword and the header and end in ;
ImportC "-lasound" : EndImport
!//#include /usr/include/alsa/asoundlib.h;
Linux code:
compile it as gcc to purebaisc\compilers folder

Code: Select all

;fake gcc to add compiler flags and make c header includes available with inline c  
;compile this as gcc into purebasic compilers folder 
;when you compile programs from a terminal it should catch the output  
;when you compile from the ide it should remain unaffected 
;useage
;you can specify additional compiler flags on the command line as below 
;use an inline c comment !// and keyword gccflags followed by flags and end in ;  
;   !//gccflags -fno-schedule-insns -fno-schedule-insns2 ;
;if you need to add a header use inline c comment !// with #include keyword and header end in ;
;   !//#include /usr/include/portaudio.h ;  
; this will ensure that the macros and constants are available 

;tested on manjaro x64 and raspberry pi
;add this to the end of your .bashrc or /etc/rc.local or addit to the launch.sh if you want it from ide 
;export PUREBASIC_HOME=/home/andrew/purebasic
;export PATH=$PUREBASIC_HOME/compilers:$PATH
EnableExplicit 
 
OpenConsole() 

Global Flags.s,Fn,a,Command.s,Param.s,ParamCount,Find.s,CompilerHome.s,Pos,Pos1
Global Output.s,Gcc,Len,tCommand.s,error.s 
If ExamineEnvironmentVariables()
  CompilerHome = GetEnvironmentVariable("PUREBASIC_HOME")
  
  If CompilerHome <> "" 
    ParamCount = CountProgramParameters()
    If ParamCount 
      For a = 0 To ParamCount-1 
        Param = ProgramParameter(a)
        Command + Param + " " 
      Next 
      Command + ProgramParameter(a) 
    
      If FileSize("purebasic.c")
        Fn = OpenFile(#PB_Any,"purebasic.c")  
        If Fn 
          Repeat 
            Flags.s = ReadString(Fn,#PB_UTF8)
            Pos =  FindString(Flags,"//gccflags",1) 
            Pos1 = FindString(Flags,"//#include",1) 
            If Pos 
              tCommand.s = " " + Right(flags,Len(flags)-10) 
              pos = FindString(tCommand,";") 
              If pos   
                Command.s + Trim(Left(tCommand,pos-1))
              EndIf   
            EndIf   
            If Pos1
              tCommand = " -include "  + Right(flags,Len(flags)-10) 
              pos = FindString(tCommand,";") 
               If pos   
                Command.s + Trim(Left(tCommand,pos-1))
              EndIf  
            EndIf
         Until Eof(Fn) 
         CloseFile(Fn)   
        EndIf 
      EndIf 
;      SetClipboardText(command) 
;      MessageRequester("fake gcc",command) 
      Gcc = RunProgram("/usr/bin/gcc",Command,GetCurrentDirectory(),#PB_Program_Open) 
      If WaitProgram(gcc)
        End ProgramExitCode(gcc)
      EndIf
    EndIf 
  EndIf 
EndIf  



you need to have PUREBASIC_HOME set and PATH needs to have compilers set as the 1st entry so the fake gcc gets called before the real gcc (which may need changing if it's not /usr/bin/gcc)
Add this to the end of your .bashrc or launch.sh if you want it available form the ide
export PUREBASIC_HOME=/home/andrew/purebasic
export PATH=$PUREBASIC_HOME/compilers:$PATH
For windows

Code: Select all

;fake gcc to add compiler flags and make c header includes available with inline c  
;windows 11,  windows xp
;in the pbcompilers folder rename gcc to gccreal and compile this as gcc.exe 

;Useage
;you can specify additional compiler flags on the command line as below 
;use an inline c comment !// and keyword gccflags followed by the flags and end in ;  
;   !//gccflags -fno-schedule-insns -fno-schedule-insns2 ;
;if you need to add a header use inline c comment !// with #include keyword and header end in ;
;   !//#include /usr/include/portaudio.h ;  
; this will ensure that the macros and constants are availableto use from the header in c  
;if you want to compile with clang rather than gcc  
;   !//UseClang";
; 
; mingw64-clang13 build can be downloaded here 
; https://github.com/mstorsjo/llvm-mingw/releases/download/20211002/llvm-mingw-20211002-msvcrt-x86_64.zip

EnableExplicit 
OpenConsole() 

Global Flags.s,Fn,a,Command.s,Param.s,ParamCount,Find.s,CompilerHome.s,Pos,Pos1
Global Output.s,Gcc,Len,tCommand.s,error.s,usellvm

If ExamineEnvironmentVariables()
    
  CompilerHome = #PB_Compiler_Home
  
  If CompilerHome <> "" 
    ParamCount = CountProgramParameters()
    If ParamCount 
      For a = 0 To ParamCount-1 
        Param = ProgramParameter(a)
        Command + Param + " " 
      Next 
      Command + ProgramParameter(a) 
      
      If FileSize("purebasic.c")
        Fn = OpenFile(#PB_Any,"purebasic.c")  
        If Fn 
          Repeat 
            Flags.s = ReadString(Fn,#PB_UTF8)
            Pos =  FindString(Flags,"//gccflags",1) 
            Pos1 = FindString(Flags,"//#include",1) 
            usellvm = FindString(Flags,"//UseClang",1) 
            If Pos 
              tCommand.s = " " + Right(flags,Len(flags)-10) 
              pos = FindString(tCommand,";") 
              If pos   
                Command.s +  " " + Trim(Left(tCommand,pos-1))
              EndIf   
            EndIf   
            If Pos1
              tCommand = "-include "  + Right(flags,Len(flags)-10) 
              pos = FindString(tCommand,";") 
               If pos   
                Command.s + " " + Trim(Left(tCommand,pos-1))
              EndIf  
            EndIf
         Until Eof(Fn) 
         CloseFile(Fn)   
        EndIf 
      EndIf 
      MessageRequester("fake gcc",command + " " + GetCurrentDirectory()) 
      If usellvm
        Gcc = RunProgram("C:\llvm-mingw-20211002-msvcrt-x86_64\bin\clang.exe",command,GetCurrentDirectory(),#PB_Program_Open);
      Else   
        Gcc = RunProgram(CompilerHome + "Compilers\gccreal.exe",command,GetCurrentDirectory(),#PB_Program_Open);
      EndIf   
      If WaitProgram(Gcc) 
        End ProgramExitCode(Gcc)
      EndIf   
    EndIf 
  EndIf 
EndIf 




examples

Code: Select all

;Alsa example for joris 
ImportC "-lasound" : EndImport
!//#include /usr/include/alsa/asoundlib.h;

Procedure Send_to_midi_port()
    Protected *midiinp, *midiout,  status.l
    Protected *name  = UTF8("hw:1,0,0")
    Protected mode.l = 0
    Protected noteon.l = RGB(90, 60, 100) ; 90 is note on in the alsa headers  
    Protected noteof.l = RGB(90, 60, 0)   ; 
    
    !v_mode = SND_RAWMIDI_SYNC;
    !v_status=snd_rawmidi_open(0, &p_midiout, p_name, v_mode);
    If status=0
      !snd_rawmidi_write(p_midiout, v_noteon, 3);
      Delay(25)
      !snd_rawmidi_write(p_midiout, v_noteof, 3);
      !snd_rawmidi_drain(p_midiout);
      !snd_rawmidi_close(p_midiout);
      
    Else
       MessageRequester("No Card.", "Problem opening MIDI output: " + PeekS(*name,-1,#PB_UTF8), #PB_MessageRequester_Ok)
    EndIf
    
    FreeMemory(*name) 
    
  EndProcedure
    
  Send_to_midi_port()

lua test

Code: Select all

CompilerIf Not Defined(PB_Compiler_Backend,#PB_Constant)
  CompilerError "Please use PureBasic Version 6.00 Beta1" 
CompilerElseIf #PB_Compiler_Backend<>#PB_Backend_C
  CompilerError "Please use Compiler-Option C Backend."
CompilerEndIf 

CompilerIf #PB_Compiler_OS = #PB_OS_Linux 
  ImportC "-llua5.2" : EndImport  
  !//#include /usr/include/lua5.2/lua.h
CompilerElseIf #PB_Compiler_OS = #PB_OS_Windows
   CompilerError "Please add windows imports"
CompilerElseIf #PB_Compiler_OS = #PB_OS_MacOS
   CompilerError "Please add osx imports"
CompilerEndIf  

Global lua

!v_lua = luaL_newstate();
!luaL_openlibs(v_lua);

*code = UTF8("print('Hello, World from Lua')")

!if (luaL_loadstring(v_lua, p_code) == LUA_OK) {
!   if (lua_pcall(v_lua, 0, 0, 0) == LUA_OK) {
!     lua_pop(v_lua, lua_gettop(v_lua));
!     }
!   }
FreeMemory(*code) 
!lua_close(v_lua);

test of optimized asm output

Code: Select all

;pbcompiler -z testasm.pb 

!//gccflags -fno-schedule-insns -fno-schedule-insns2; 

; With optimizer optimize ?Code_Start and ?Code_End away. 
DisableDebugger 
Code_Start:
a = (Random(100) * 5) + 2000
Code_End:

Text$ ="?Code_Start:"+Hex(?Code_Start)+ Chr(13)+"?Code_End:"+Hex(?Code_End)+ Chr(13)
Text$ + "Disassemblierter Code:" + Chr(13)  
If ExamineAssembly(?Code_Start, ?Code_End)
  While NextInstruction()
    Text$ + RSet(Hex(InstructionAddress()), SizeOf(Integer)*2, "0")
    Text$ + " " + InstructionString() + Chr(13)
  Wend
EndIf
SetClipboardText(Text$)
MessageRequester("", Text$)
CompilerIf Not Defined(PB_Compiler_Backend,#PB_Constant) 
  CompilerError "Please use PB Version>=6.00"
CompilerElseIf #PB_Compiler_Backend<>#PB_Backend_C
  CompilerWarning "C Backend test."
CompilerEndIf 

;?Code_Start:402364
;?Code_End:40237D
;Disassemblierter Code:
;0000000000402364 mov edi, 0x64
;0000000000402369 call dword 0x407910
;000000000040236E lea rax, [rax+rax*4+0x7d0]
;0000000000402376 mov [rip+0x15293], rax

User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: include c headers and modify compiler flags with inline c

Post by idle »

added windows version.
I still haven't figured out how to get any c errors to display, I probably need to call gcc again with a syntax check.

Code: Select all

;fake gcc to add compiler flags and to make c header includes available with inline c  
;In the pb compliers folder rename gcc to realgcc and compile this as gcc.exe 
;note c errors won't be displayed after this just the exit code. 

;useage
;you can specify additional compiler flags on the command line as below 
;use an inline c comment !// and keyword gccflags followed by flags and end in ;  
;   !//gccflags -fno-schedule-insns -fno-schedule-insns2 ;

;if you need to add a header use inline c comment !// with #include keyword and header end in ;
;   !//#include /usr/include/portaudio.h ;  
; this will ensure that the macros and constants of the header are available. 

; Tested on windows xp

EnableExplicit 
OpenConsole() 

Global Flags.s,Fn,a,Command.s,Param.s,ParamCount,Find.s,CompilerHome.s,Pos,Pos1
Global Output.s,Gcc,Len,tCommand.s,error.s

If ExamineEnvironmentVariables()
    
  CompilerHome = #PB_Compiler_Home
  
  If CompilerHome <> "" 
    ParamCount = CountProgramParameters()
    If ParamCount 
      For a = 0 To ParamCount-1 
        Param = ProgramParameter(a)
        Command + Param + " " 
      Next 
      Command + ProgramParameter(a) 
      
      If FileSize("purebasic.c")
        Fn = OpenFile(#PB_Any,"purebasic.c")  
        If Fn 
          Repeat 
            Flags.s = ReadString(Fn,#PB_UTF8)
            Pos =  FindString(Flags,"//gccflags",1) 
            Pos1 = FindString(Flags,"//#include",1) 
            If Pos 
              tCommand.s = " " + Right(flags,Len(flags)-10) 
              pos = FindString(tCommand,";") 
              If pos   
                Command.s + Trim(Left(tCommand,pos-1))
              EndIf   
            EndIf   
            If Pos1
              tCommand = " -include "  + Right(flags,Len(flags)-10) 
              pos = FindString(tCommand,";") 
               If pos   
                Command.s + Trim(Left(tCommand,pos-1))
              EndIf  
            EndIf
         Until Eof(Fn) 
         CloseFile(Fn)   
        EndIf 
      EndIf 
      
      ;MessageRequester("fake gcc",command) 
      ;RunProgram("gccreal.exe",Command,GetCurrentDirectory()+"\",#PB_Program_Wait) 
           
      Gcc = RunProgram(CompilerHome + "Compilers\gccreal.exe",command,GetCurrentDirectory(), #PB_Program_Open | #PB_Program_Read | #PB_Program_Error )
      Output = ""
      If Gcc
        While ProgramRunning(Gcc)
          If AvailableProgramOutput(Gcc)
            Output + ReadProgramString(Gcc) + #CRLF$
            error + ReadProgramError(Gcc) + #CRLF$
           EndIf
        Wend
        If ProgramExitCode(Gcc) <> 0 
         error + ReadProgramError(Gcc) + #CRLF$
         MessageRequester("Error " +  GetCurrentDirectory(),error)
        EndIf   
        CloseProgram(Gcc) 
      EndIf            
    EndIf 
  EndIf 
EndIf 

jack
Addict
Addict
Posts: 1336
Joined: Fri Apr 25, 2003 11:10 pm

Re: include c headers and modify compiler flags with inline c

Post by jack »

thank you idle :)
User avatar
ChrisR
Addict
Addict
Posts: 1127
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: include c headers and modify compiler flags with inline c

Post by ChrisR »

Tested on windows10, It works well, thanks :)
It's a good idea to store the additional switches using !//gccflags inline c comment.

Otherwise, minor things, it may be a good to return the gcc exit code even if it doesn't seem to be currently used in pbcompilerc
And in case of error, it could be good to copy it in the clipboard to be able to post it then.
In comment at the top: "rename gcc to realgcc" -> "rename gcc to gccreal"

Code: Select all

If ProgramExitCode(Gcc) <> 0 
  error + ReadProgramError(Gcc) + #CRLF$
  SetClipboardText("Compile Error:" +#CRLF$+ error)
  MessageRequester("Error " +  GetCurrentDirectory(), "Compile Exit Code: " + ProgramExitCode(Gcc) + ". The error is copied to the clipboard." +#CRLF$+#CRLF$+ error)
EndIf   
CloseProgram(Gcc)
End ProgramExitCode(Gcc)
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: include c headers and modify compiler flags with inline c

Post by idle »

@ChrisR thanks for testing it and the corrections and additions.. I will fix it later today
juergenkulow
Enthusiast
Enthusiast
Posts: 544
Joined: Wed Sep 25, 2019 10:18 am

Re: include c headers and modify compiler flags with inline c

Post by juergenkulow »

@idle if you fix it, please read all lines from strerr, not only one.
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: include c headers and modify compiler flags with inline c

Post by idle »

Ok well I got it working on linux and windows xp, but I don't have any control over what it prints.

@Chrisr thanks for the End ProgramExitCode(Gcc), that sorted out the problem I was having on linux.
I haven't put the clipboard text in yet.
User avatar
ChrisR
Addict
Addict
Posts: 1127
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: include c headers and modify compiler flags with inline c

Post by ChrisR »

Glad it serves on Linux :)
It seems to have no effect on Windows, Polink is still called

Code: Select all

Error: Linker
POLINK: fatal error: File not found: 'PureBasic.obj'.
It would be good if the gcc error was handled in pbcompilerc and with the stderr written to the console or IDE output, rather than the error linker.

For the text of the clipboard, as you prefer, I thought it could be good to post it, if needed, on the forum.
juergenkulow
Enthusiast
Enthusiast
Posts: 544
Joined: Wed Sep 25, 2019 10:18 am

Re: include c headers and modify compiler flags with inline c

Post by juergenkulow »

Code: Select all

End  ProgramExitCode(Gcc)
With a x86 xp 32-bit writing Code for x64 11 64-bit is not fun.
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: include c headers and modify compiler flags with inline c

Post by idle »

I can't run windows 10 it overheats the cpu in a few minutes but I can still use linux and run xp in a vm. I need a new motherboard. The holder for strap that holds the heat sink down to the board broke off. I need to replace it.
User avatar
ChrisR
Addict
Addict
Posts: 1127
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: include c headers and modify compiler flags with inline c

Post by ChrisR »

I just retested on my windows 10, with the code updated on your 1st post, everything works fine :)
It is fully transparent now, with pbcompilerc that can read the gcc error, if there is one, and print it.
Perfect for adding switches to the gcc compiler or for including a C headers or even to compile without any addition, as currently.
Good luck and good repair of your computer.
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: include c headers and modify compiler flags with inline c

Post by idle »

Thats good to hear, The c header imports probably won't be as useful for windows unless you have a full mingw or visual studio set up. and then it might need some help to find libs and includes.

I might just swap the Motherboard with the wifes as its same specs just with a different color box. :twisted:
Joris
Addict
Addict
Posts: 885
Joined: Fri Oct 16, 2009 10:12 am
Location: BE

Re: include c headers and modify compiler flags with inline c

Post by Joris »

Just to let people now here, that I've seen this coding from idle (and I told him in PM), as he created a sample code for me. But to me this is far to complicated to understand. Using it migth be an other thing, but even starting with the
Usage :
do compiler flags before imports.
use an inline c comment !// and keyword gccflags followed by flags and end in ;
Yeah sorry guys, a selfmade coder has it's limits.
'do compiler flags'' which on, when, why ??? Yeah, quit outside my 'basic coding' range.
A header ??? I know about those files in C with the extention .h, but that's it.
Maybe one day it becomes more clear knowing what and why. :oops:
I'll give the sample code a chance, but as I already started and got it working the Prototype way, it will be a thing for later.

Still, thanks idle.
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: include c headers and modify compiler flags with inline c

Post by idle »

Hopefully Fred will add a gcc option flag to the command line, then this tool can be retired but it's necessary to make inline c usable and it makes a whole lot of sense on raspberry pi and linux. since they're c eco systems.
Now I can hack around on the PI like I would with python and that's way better with PB.

once you've got past the novelty and remembered a few simple rules it opens up a whole range of c libs and you don't have to bother writing imports to them at all, you can just use them as they are.

I was going to write an automated c importer but to be honest it's not needed at all.
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: include c headers and modify compiler flags with inline c

Post by idle »

Interesting got it compiling with clang and outputting llvm IR and llvm bytecode it's not really useful yet. Next is to try web assembly.
Post Reply