PBCex tools for using inlinec and making static libs

Applications, Games, Tools, User libs and useful stuff coded in PureBasic
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

PBCex tools for using inlinec and making static libs

Post by idle »

PBCex tools for Pb 6 c backend to facilitate using inline c and making static libs / precompiled libs for projects
Currently only Window provided in this initial release

TLDR;
All you need is gcc.pb and polink.pb to get started, compile them as gcc and polink in the source folder then rename gcc and polink in the pb compilers folder and copy in the gcc and polink you just made.
Also I recommend installing mingw64, all sorts of cool stuff can be done with that and a bit of creativity

Full download with examples for Raylib4, PortAudio, MiniAudio
https://github.com/idle-PB/pbcex

OR

Gcc

Code: Select all

;fake gcc to facitlate working with inline c  
;compile this to the source folder as gcc and then rename gcc in the pb compliers folder to gcc_real and copy in this version of gcc 

;useage
;you can specify additional compiler flags on the command line as below use an inline c comment !// and keyword followed by parameters and end the line in ;  
;   !//gccflags -fno-schedule-insns -fno-schedule-insns2 ;
;if you need to add a header use !//#include followed by file path.h and end in ;
;   !//#include /usr/include/portaudio.h ;  
;this will ensure that the macros and constants are availableto for use from the header in c  
;if you want to compile with clang rather than gcc  
;   !//useclang;
;and if you want to make a static lib use !//makestatic
;   !//makestatic  e:\idle\pbstuff\portaudio\libringbuffer.a; 
;but make sure it's the last compilerflag 

; mingw64-clang13 build can be downloaded here 
; https://github.com/mstorsjo/llvm-mingw/releases/download/20211002/llvm-mingw-20211002-msvcrt-x86_64.zip
; Edit your environment PATH variable to include llvm-mingw-20211002-msvcrt-x86_64;llvm-mingw-20211002-msvcrt-x86_64\bin;llvm-mingw-20211002-msvcrt-x86_64\include
; windows 10,  windows xp
; 1.02 
EnableExplicit 

#DisplayMessages = 1
#CopyMessages=0

Macro _SetClipboardText(message) 
  SetClipboardText("Cd /D " + GetCurrentDirectory() +#CRLF$+ "PATH=%PATH%;" + GetPathPart(ProgramFilename()) + ";" + GetCurrentDirectory() +#CRLF$+ message +#CRLF$+ "")
EndMacro 

OpenConsole() 

Global Flags.s,Fn,a,Command.s,Param.s,ParamCount,Find.s,CompilerHome.s,Pos,Precomp,len,*data,fn1,fn2
Global Output.s,Gcc,Len,tCommand.s,error.s,usellvm,clangpath.s,libname.s,objname.s,err

clangpath="C:\llvm\bin\clang.exe"

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) 
            If Not precomp 
              If FindString(Flags,"//useclang",1)
                usellvm = 1 
                command = RemoveString(command,"-fno-tree-vrp")
                command = RemoveString(command,"-fno-schedule-insns2") 
                command = RemoveString(command,"-fno-schedule-insns") 
                command = RemoveString(command,"-freorder-blocks-algorithm=simple") 
              EndIf   
              If FindString(Flags,"//gccflags",1) 
                tCommand.s = " " + Right(flags,Len(flags)-10) 
                pos = FindString(tCommand,";") 
                If pos   
                  Command.s +  " " + Trim(Left(tCommand,pos-1))
                EndIf   
              EndIf   
              If FindString(Flags,"//#include",1) 
                tCommand = "-include "  + Right(flags,Len(flags)-10) 
                pos = FindString(tCommand,";") 
                 If pos   
                  Command.s + " " + Trim(Left(tCommand,pos-1))
                EndIf  
              EndIf
              If (FindString(Flags,"//makestatic",1) Or FindString(Flags,"//precompile",1)) 
                precomp=1 
                libname = Right(flags,Len(flags)-12) 
                pos = FindString(libname,";") 
                If pos   
                  libname = Trim(Left(libname,pos-1))
                  fn2 = CreateFile(#PB_Any,"makestatic.txt") 
                  If fn2 
                    WriteStringN(fn2,libname) 
                  EndIf   
                EndIf   
                pos = FindString(libname,".") 
                libname = Left(libname,pos) + "o" 
                objname = GetFilePart(libname) 
                FileSeek(fn,1)
                Continue 
              EndIf   
            EndIf 
            If Precomp 
              If FindString(flags,"int PB_Compiler_Thread=1;",1) 
                WriteStringN(fn2,"threaded") 
              ElseIf FindString(flags,"int PB_ExecutableType=",1)  
                len = Loc(fn) 
                *Data = AllocateMemory(len) 
                FileSeek(fn,0) 
                ReadData(fn,*data,len)
                fn1 = CreateFile(#PB_Any,"purebasic1.c") 
                If fn1 
                  WriteData(fn1,*data,len) 
                  CloseFile(fn1)
                  
                  CompilerIf #DisplayMessages 
                     RunProgram("notepad.exe",GetCurrentDirectory()+"purebasic1.c","") 
                  CompilerEndIf 
                  
                  pos = FindString(command,"-c -o PureBasic.obj") 
                  tCommand = Left(command,pos-1) 
                  tcommand + " -o " + objname + " " + "purebasic1.c -c"
                  
CompilerIf  #CopyMessages
                         _SetClipboardText(tcommand) 
CompilerEndIf
                  CompilerIf #DisplayMessages 
                     MessageRequester("gcc 1 do not Link Before", "gcc_real.exe " + tcommand)
                  CompilerEndIf 
                  
                  If usellvm
                    Gcc = RunProgram(clangpath,tcommand,GetCurrentDirectory(),#PB_Program_Open);
                  Else   
                    Gcc = RunProgram(CompilerHome + "Compilers\gcc_real.exe",tcommand,GetCurrentDirectory(),#PB_Program_Open);
                  EndIf   
                  If WaitProgram(Gcc) 
                    err = ProgramExitCode(Gcc)
                    If Err 
                      MessageRequester("error",Str(err))
                    EndIf 
                  EndIf                     
                                    
                EndIf   
                FreeMemory(*data)
                Break 
              EndIf   
            EndIf  
         Until Eof(Fn) 
         CloseFile(Fn)   
        EndIf 
      EndIf 
      If IsFile(fn2) 
        CloseFile(fn2) 
      EndIf   
            
         CompilerIf  #CopyMessages
    _SetClipboardText(command) 
CompilerEndIf
      CompilerIf #DisplayMessages 
         Select MessageRequester("gcc 3 Before real", "gcc_real.exe " + command, #PB_MessageRequester_YesNoCancel|#MB_DEFBUTTON2)
         Case #PB_MessageRequester_Yes
         RunProgram("notepad.exe", #DQUOTE$+GetCurrentDirectory()+"purebasic.c"+#DQUOTE$, "", #PB_Program_Wait)
         Case #PB_MessageRequester_Cancel
         DeleteDirectory(GetCurrentDirectory(), "", #PB_FileSystem_Force)
         End
         EndSelect
      CompilerEndIf     
      
      If usellvm
        Gcc = RunProgram(clangpath,command,GetCurrentDirectory(),#PB_Program_Open);
      Else   
        Gcc = RunProgram(CompilerHome + "Compilers\gcc\gcc_real.exe",command,GetCurrentDirectory(),#PB_Program_Open);
      EndIf   
      If WaitProgram(Gcc) 
        End ProgramExitCode(Gcc)
      EndIf   
    EndIf 
  EndIf 
EndIf 



Bat.script

Code: Select all

@echo off
cd /d %~dp0
set "compiler32=c:\program files (x86)\purebasic\compilers\gcc"
set "compiler64=c:\program files\purebasic\compilers\gcc"

REM x64
if not exist "%compiler64%\gcc_real.exe" (
move "%compiler64%\gcc.exe" "%compiler64%\gcc_real.exe"
if %ERRORLEVEL% NEQ 0 goto err
)
copy /B "gcc.exe" "%compiler64%\gcc.exe"
if %ERRORLEVEL% NEQ 0 goto err
REM x86
if not exist "%compiler32%\gcc_real.exe" (
move "%compiler32%\gcc.exe" "%compiler32%\gcc_real.exe"
if %ERRORLEVEL% NEQ 0 goto err
)
copy /B "gcc.exe" "%compiler32%\gcc.exe"
if %ERRORLEVEL% NEQ 0 goto err
goto done
:err
echo An error happened.
goto afterdone
:done
echo done!
:afterdone
pause


Polink

Code: Select all

 
 EnableExplicit

#DispalyMessages = 1

CompilerIf #PB_Compiler_OS = #PB_OS_Windows 
   #Cdir = "\" 
CompilerElse 
   #Cdir = "/"
CompilerEndIf 

Structure folderContents
   type.b
   value.s
EndStructure

Procedure GetFileList(StartDir.s,List Lfiles.folderContents(),pattern.s="*.*",Recursive=1,bset=0)
   Protected mDir,Directory.s,Filename.s,FullFileName.s, tdir.s,ct,a,depth,bmatch
   
   Static NewList Lpattern.s()
   Static FileCount
      
   If Not bset
      StartDir = RTrim(StartDir, #Cdir) 
      pattern = RemoveString(pattern,"*.")
      ct = CountString(pattern,"|") + 1
      ClearList(lpattern())
      For a = 1 To ct 
           AddElement(Lpattern())
           Lpattern() = UCase(StringField(pattern,a,"|"))
        Next
        filecount=0
        bset=1
   EndIf 
 
  mDir = ExamineDirectory(#PB_Any, StartDir, "*.*") 
  If mDir 
    While NextDirectoryEntry(mDir)
      If DirectoryEntryType(mDir) = #PB_DirectoryEntry_File
          Directory = startdir
          FileName.s = DirectoryEntryName(mDir)
           ForEach Lpattern()
              If  Lpattern() = GetExtensionPart(UCase(Filename))
                  bmatch=1
              ElseIf  Lpattern() = "*"
                 bmatch =1 
              EndIf   
              If bmatch 
                  FullFileName.s = StartDir + #Cdir + FileName
                   AddElement(LFiles()) 
                   Lfiles()\value = FullFileName
                   Lfiles()\type = #PB_DirectoryEntry_File
                  FileCount+1
                  bmatch =0    
               EndIf
            Next  
        Else
         tdir = DirectoryEntryName(mDir)
         If tdir <> "." And tdir <> ".."
            If Recursive = 1
              depth + 1
            GetFileList(startDir + #Cdir + tdir,LFiles(),Pattern,Recursive,bset)
           EndIf
         EndIf
      EndIf
   Wend
   FinishDirectory(mDir)
  EndIf
    
  ProcedureReturn FileCount

EndProcedure

Macro _SetClipboardText(message,prog) 
  SetClipboardText("Cd /D " + GetCurrentDirectory() +#CRLF$+ "PATH=%PATH%; " + GetPathPart(ProgramFilename()) + ";" + GetCurrentDirectory() +#CRLF$+ prog + message +#CRLF$+ "")
EndMacro   

Global NewList myfiles.folderContents() 
Global tmp.s,cmd.s,libname.s,prog,name.s,pos   

If FileSize("makestatic.txt") 
  
  If ReadFile(0,"makestatic.txt")
   
    libname = ReadString(0) 
    cmd = GetFilePart(libname,#PB_FileSystem_NoExtension) + ".o " 
    
    tmp = ReadString(0)  ;might need to inlude some system libs based on setting like threadsafe  
    If FindString(tmp,"threaded") 
      CopyFile(#PB_Compiler_Home + "Compilers\" + "StringManagerCThread.lib",GetCurrentDirectory()+"ObjectManagerThread.lib")  
      CopyFile(#PB_Compiler_Home + "Compilers\" + "StringManagerCThread.lib",GetCurrentDirectory()+"StringManagerCThread.lib")  
      CopyFile(#PB_Compiler_Home + "Compilers\" + "libgcc.a",GetCurrentDirectory()+"libgcc.a")  
    EndIf 
        
    If GetFileList(GetCurrentDirectory(),myfiles(),"*.lib|*.a",0)  
       ForEach myfiles() 
         cmd + myfiles()\value + " "   
       Next   
    EndIf 
        
    cmd +  " /OUT:" + libname 
    
    CloseFile(0) 
    
    CompilerIf  #DispalyMessages
      _SetClipboardText(cmd,"polib.exe")
      MessageRequester("polib Before", "polib.exe " + cmd)
    CompilerEndIf 
  
    RunProgram(#PB_Compiler_Home + "Compilers\polib.exe",cmd,GetCurrentDirectory(),#PB_Program_Wait) 
    
    MessageRequester("polib",cmd) 
  EndIf    
EndIf 

cmd = ""
cmd = PeekS( GetCommandLine_())
cmd = RemoveString(cmd, #DOUBLEQUOTE$ + ProgramFilename() + #DOUBLEQUOTE$, #PB_String_NoCase, 1, 1)
cmd = Mid(cmd,2)


CompilerIf #DispalyMessages
   _SetClipboardText(cmd,"polink.exe") 
   MessageRequester("polink",cmd)
 CompilerEndIf 
 
prog = RunProgram(#PB_Compiler_Home + "Compilers\polink_real.exe", cmd, GetCurrentDirectory(), #PB_Program_Open)
While IsProgram(prog)
	If ProgramRunning(prog) 
		Delay(100)
	Else
		CloseProgram(prog)	
	EndIf
Wend
End ProgramExitCode(prog)




PBCEX tools to facilitate using inline c and to make precompiled static libs
Author idle 2022
Version 1.0 for windows purebasic 6.00 c backend
Linux and Raspberry PI version will be on their way
It's my hope that Fred will eventually add this to the c backend.

Set up:
Compile gcc and polink to the source folder.
navigate to your purebasic compilers directory and rename Gcc and polink to gcc_real and polink_real
copy your compiled gcc and polink to the purebasic compilers directory.

Use:

The tool facilitates you to control gcc compiler flags and utilize c libs directly in PB and also make precompiled libs to save compile times
flags are entered as inline c comments !// followed by command and arguments that end in ;
!//gccflags -O3; optimize to O3
!//useclang; if you've installed mingw64 and added the enviroment path to the compiler you can use that in place of the supplied gcc
!//#include path\to\some\clibheader.h; ;this will include the entire c lib so it's available to use with inline c
!//makestatic path\to\your\lib.a; ;this will generate a static lib all function marked as procedureCDll will be exported


Some examples make use of llvm mingw64 you can download it here and install c:\ or where ever
https://github.com/mstorsjo/llvm-mingw/ ... x86_64.zip
;Edit your environment PATH variable to include the paths
c:\llvm-mingw-20211002-msvcrt-x86_64
c:\llvm-mingw-20211002-msvcrt-x86_64\bin
c:\llvm-mingw-20211002-msvcrt-x86_64\include
Tool files
gcc.pb tool source instructions to install mingw64 in readme
polink.pb source to facilitate making static libs


Examples
*Note you will need to modify the inline c paths used on all examples and use c backend for compile

librb - ringbuffer static lib.
portaudio - ffttest and dueltest requires librb.a
raylib4 - screen and julia set.

librb a static lib example librb.a allows you to create a static lib and compile as a dll
the file pattern used allows you to easily work on and precompile a lib and use it in a project easily.
Set compiler to c backend, set to the compile type to shared dll, turn off debugger and hit F5 to compile to static lib

files:
librb.a the generated static lib compiled with optional !//useclang;
librb.dll the compiled dll from using create executable
librb.lib the import lib to the dll
testlibrb.pb test for librb compile as thread safe for debug messages
ringbuffer.pbi lockfree ring buffer to produce librb.a

Notes the filepattern used in ringbuffer.pbi facilitates you to easily create test and use precompiled libs in a project to save compile times
while the static libary generated is usable with pb it may not be usable from another language as it misses out the intialization functions
also note that while the generated static libs are large, the resultant executable won't be anywhere near as large.

Example PortAudio
Portaudio x64 build only uses gcc as compiler
Dueltest ;example of bridging streams via a ring buffer from two threads (note you need to build the ring buffer librb first)
FFTtest ;uses a single callback on the input output streams and runs an FFT iFFT

Example Raylib4
Raylib4 x64, requires Mingw64 to be installed
Screen basic hello world example
juliaset creates an animate fullscreen juilia set fractal with glsl shader
User avatar
ChrisR
Addict
Addict
Posts: 1127
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: PBCex tools for using inlinec and making static libs

Post by ChrisR »

Thanks Idle for your research and for sharing it :)
I was able to create my first static library with success.

I also hope Fred l will add these options to the C backend to avoid going through the fake gcc & polink.
At least, an option to create a static library would be nice and not too complicated according to your discoveries, everything is there in pbcompilerc.
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: PBCex tools for using inlinec and making static libs

Post by idle »

Fixed up to use clang. I had disabled it and forgot to add the fix so it would remove the gcc only options.

There is still an issue creating static libs with interfaces and or data sections.
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: PBCex tools for using inlinec and making static libs

Post by idle »

Added MiniAudio libray and example miniaudio_duplex

Code: Select all

!//gccflags -IC:\llvm-mingw-20211002-msvcrt-x86_64\lib\clang\13.0.0\include; 
!//#include "d:\idle\pbstuff\pbcex\examples\miniaudio\miniaudio.h";
!//useclang;

ImportC  "miniaudiox64.lib" : EndImport 

ProcedureC data_callback(*Device,*Output,*Input,frameCount)
  Protected amount 
  If frameCount  
    !ma_device* pDevice; 
    !pDevice = p_device; 
    !v_amount = v_framecount * ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels);
    If amount <> 0  
      CopyMemory(*input,*Output,amount) 
    EndIf
  EndIf 
EndProcedure 

PrototypeC pcbcallback(*device,*output,*input,framecount)
Global pcb.pcbcallback 
pcb = @data_callback() ;use a prototype set a refertence to the data_callback otherwise pb won't include it 

OpenConsole()

!ma_result result;
!ma_device_config deviceConfig;
!ma_device device;

!deviceConfig = ma_device_config_init(ma_device_type_duplex);
!deviceConfig.capture.pDeviceID  = NULL;
!deviceConfig.capture.format     = ma_format_s16;
!deviceConfig.capture.channels   = 2;
!deviceConfig.capture.shareMode  = ma_share_mode_shared;
!deviceConfig.playback.pDeviceID = NULL;
!deviceConfig.playback.format    = ma_format_s16;
!deviceConfig.playback.channels  = 2;
!deviceConfig.dataCallback       = v_pcb;;

!result = ma_device_init(NULL, &deviceConfig, &device);

!if (result != MA_SUCCESS) {
   MessageRequester("error","failed to config")  
   End 
!}

!ma_device_start(&device);

PrintN("press enter to end") 
Input();

!ma_device_uninit(&device);
nsstudios
Enthusiast
Enthusiast
Posts: 274
Joined: Wed Aug 28, 2019 1:01 pm
Location: Serbia
Contact:

Re: PBCex tools for using inlinec and making static libs

Post by nsstudios »

Thank you for this!

I just unzipped llvm-mingw and set things up (hopefully right), and I'm trying it with Bass64 (bass.dll, bass.h, bass.lib), and either way I do it, I get an error.
If I do

Code: Select all

!//gccflags -I "C:\llvm-mingw-20220323-msvcrt-x86_64\lib\clang\14.0.0\include";
!//#include "d:\bass\bass.h";
!//useclang;
ImportC "bass.lib": EndImport
It says:

Code: Select all

error: typedef redefinition with different types ('void' vs 'char')

typedef void TCHAR;

             ^

C:/llvm-mingw-20220323-msvcrt-x86_64/include/winnt.h:373:16: note: previous definition is here

  typedef char TCHAR, *PTCHAR;

               ^

purebasic.c:306:5: error: conflicting types for 'WinMain'

...

2 errors generated.
If I, however, do this:

Code: Select all

!//gccflags -I "C:\llvm-mingw-20220323-msvcrt-x86_64\include";
!//#include "d:\bass\bass.h";
ImportC "bass.lib": EndImport
It complains:

Code: Select all

error: x86intrin.h: No such file or directory

 # include <x86intrin.h>

           ^~~~~~~~~~~~~

compilation terminated.
Adding the clang path

Code: Select all

!//gccflags -I "C:\llvm-mingw-20220323-msvcrt-x86_64\include";
!//gccflags -I "C:\llvm-mingw-20220323-msvcrt-x86_64\lib\clang\14.0.0\include";
!//#include "d:\bass\bass.h";
ImportC "bass.lib": EndImport
seems to fix it, but then I get this:

Code: Select all

error: expected expression before 'unsigned'

   return __builtin_bit_cast(unsigned int, __A);

                             ^~~~~~~~

C:\llvm-mingw-20220323-msvcrt-x86_64\lib\clang\14.0.0\include/ia32intrin.h: In function '_castf64_u64':

C:\llvm-mingw-20220323-msvcrt-x86_64\lib\clang\14.0.0\include/ia32intrin.h:237:29: error: expected expression before 'unsigned'

   return __builtin_bit_cast(unsigned long long, __A);

                             ^~~~~~~~

...

              ^~~~~~~
It could just be that I have things set up wrong, I followed the readme, I haven't really played with C compilations before and Mingw...
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: PBCex tools for using inlinec and making static libs

Post by idle »

A quick test and this this worked, you were missing the \ at the end of the path -I path

copy bass.h bass.lib and bass.dll into the c\x64 folder save your test code in there and run it

Code: Select all

!//gccflags -I "C:\llvm-mingw-20211002-msvcrt-x86_64\include\";
!//#include "D:\bass24\c\x64\bass.h";

ImportC "D:\bass24\c\x64\bass.lib" : EndImport 


!if (BASS_Init(0, 44100, 0, 0, 0)) { 
		Debug "initialize device" 
!} 

ps you don't need to use clang to compile either but it can be useful
nsstudios
Enthusiast
Enthusiast
Posts: 274
Joined: Wed Aug 28, 2019 1:01 pm
Location: Serbia
Contact:

Re: PBCex tools for using inlinec and making static libs

Post by nsstudios »

Whooops! Thanks. I wasn't aware a trailing backslash was required.
Now it works, except it does not seem to see any of the typedefs, so something like

Code: Select all

!HSTREAM snd=BASS_StreamCreateFile(0, L"c:/windows/media/ding.wav", 0, -1, BASS_UNICODE);
Seems to require me to typedef/#define things manually?

Code: Select all

!unsigned long snd=BASS_StreamCreateFile(0, L"c:/windows/media/ding.wav", 0, -1, 0x80000000);
Thank you for all of your help, and thank you for making all of this possible.
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: PBCex tools for using inlinec and making static libs

Post by idle »

I'm not sure what's going on, it's made for VS so maybe that's the issue.
I don't have time to address it at the moment either but I will try and get it working for you
In the mean time just use one of the already converted bass import libs
nsstudios
Enthusiast
Enthusiast
Posts: 274
Joined: Wed Aug 28, 2019 1:01 pm
Location: Serbia
Contact:

Re: PBCex tools for using inlinec and making static libs

Post by nsstudios »

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

Re: PBCex tools for using inlinec and making static libs

Post by idle »

nsstudios
Enthusiast
Enthusiast
Posts: 274
Joined: Wed Aug 28, 2019 1:01 pm
Location: Serbia
Contact:

Re: PBCex tools for using inlinec and making static libs

Post by nsstudios »

Thanks! :) Checked it out, it's about what I have. Normally I use a setup with bass_wrapper and bass.pbi that I got from... this forum pretty sure, and it works well, but I thought if I could call it directly from inlineC it would be a bit easier, and a good way to test the inlineC stuff.
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: PBCex tools for using inlinec and making static libs

Post by idle »

nsstudios wrote: Mon Sep 05, 2022 12:12 am Thanks! :) Checked it out, it's about what I have. Normally I use a setup with bass_wrapper and bass.pbi that I got from... this forum pretty sure, and it works well, but I thought if I could call it directly from inlineC it would be a bit easier, and a good way to test the inlineC stuff.


set the compiler options Executable format to console.

At 1st message requester find the temp purebasic folder in C:\Users\username\AppData\Local\Temp\PureBasic...\
open purebasic c in notepad and delete the "typedef void TCHAR" then save it and click ok on the message requester

Code: Select all

ImportC "C:\Users\OEM\Downloads\bass24\c\x64\bass.lib" : EndImport 
!//gccflags -IC:\llvm-mingw-20211002-msvcrt-x86_64\lib\clang\13.0.0\include; 
!//#include "C:\Users\OEM\Downloads\bass24\c\x64\bass.h";
!//useclang;

Global ver  

!if (BASS_Init(0, 44100, 0, 0, 0)) { 
		Debug "initialize device" 
		!v_ver = BASSVERSION;
		Debug Hex(ver) 
		!integer snd=BASS_StreamCreateFile(0, "c:/windows/media/ding.wav", 0, -1, BASS_UNICODE);	
!} 
nsstudios
Enthusiast
Enthusiast
Posts: 274
Joined: Wed Aug 28, 2019 1:01 pm
Location: Serbia
Contact:

Re: PBCex tools for using inlinec and making static libs

Post by nsstudios »

Wow! That works! Thanks. Just wish it didn't require console.
novablue
Enthusiast
Enthusiast
Posts: 165
Joined: Sun Nov 27, 2016 6:38 am

Re: PBCex tools for using inlinec and making static libs

Post by novablue »

So can i use this to create a simple user library for Purebasic like TailBite did? If so can someone show me how i can make simple code like this into a user lib?

Code: Select all

Procedure HelloWorld(A, B) 
    ProcedureReturn A + B
EndProcedure
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: PBCex tools for using inlinec and making static libs

Post by idle »

I can do a demo here later but what's wrong with the example librb.a in the download.
if you don't want all the examples heres a copy of librb.a source here
https://dnscope.io/idlefiles/librb.zip

with your hello world example

Code: Select all

;set compiler options to create a shared dll and also to create temporary exe in source folder 
;use the c backend 
;test this code with debugger  
;then create the dll -> create executable as "hello.dll"   

CompilerIf #PB_Compiler_IsMainFile  
  
  CompilerIf #PB_Compiler_Backend = #PB_Backend_C   
    
    !//makestatic "e:\test\hello.a";  <======change the path to the source folder name the static lib as .a  
    
  CompilerEndIf 
     
  ProcedureCDLL HelloWorld(a.s,b.s)  ;use procedureCDLL to export functions 
    Static gout.s 
    
    gout = a + b 
    ProcedureReturn @gout   
    
  EndProcedure 
  
  CompilerIf #PB_Compiler_Debugger       ;do debug tests of lib      
    
    Debug PeekS(HelloWorld("hello","world")) 
    
  CompilerEndIf 
  
CompilerElse        ;this is the import part to your lib so you can use it with xincludefile in application      
  
  CompilerIf #PB_Compiler_Backend = #PB_Backend_C 
    #USESTATIC=1
  CompilerElse 
    #USESTATIC=0
  CompilerEndIf  
  
  CompilerIf #USESTATIC   ;if c backend is used in your application it will link in the static       
    
    ImportC "hello.a"
      HelloWorld(a.s,b.s) As "f_helloworld"
    EndImport   
    
  CompilerElse            ;else it will use the dll you created via it's import lib      
    
    ImportC "hello.lib"
      HelloWorld(a.s,b.s) 
    EndImport   
    
  CompilerEndIf 
CompilerEndIf 
then in test application

Code: Select all

XIncludeFile "hello.pb" 
Debug PeekS(HelloWorld("hello","pbworld"))
Post Reply