Repository navigation
modern Foreignlib
Home › Foreign Library Linking › #foreignlib
📘 Also in this category: #foreignlib Tutorial, the step-by-step introduction
Preprocessor directive
#foreignlib name (static|dynamic) "spec" [, "spec" ...]Binds name to a set of libraries and adds them to the link.
Unlike #inclib, a spec that does not start with system: is a library file, found relative to the source file containing the directive, not to the directory the compiler runs in. The file for the target being built is chosen by a naming convention, and whether the library is linked statically or dynamically must be stated.
The bound name may also be used in a Lib clause of a hand-written declaration.
name |
An identifier. Visible to the end of the compilation, including in files that include this one. |
static / dynamic
|
Required. Decides which file endings are eligible. A file of the other kind is never used as a fallback. |
"spec" |
"system:foo" hands foo to the linker to find, as #inclib "foo" does. Anything else is a library path without its ending: relative to this file, or absolute. |
Several specs are linked in the order given. This is how a static library brings the system libraries it needs:
#foreignlib RAYLIB static "vendor/raylib/raylib", _
"system:winmm", "system:gdi32", "system:user32", "system:shell32"For a file spec "dir/base", these names are tried, most specific first:
dir/base_<os>_<arch><ext>
dir/base_<os><ext>
dir/base_<arch><ext>
dir/base<ext>
| windows-x86_64 | linux-x86_64 | macos-arm64 | |
|---|---|---|---|
<os> |
windows |
linux |
macos |
<arch> |
x86_64 |
x86_64 |
arm64 |
<ext>, static
|
.a, .lib
|
.a |
.a |
<ext>, dynamic
|
.dll.a, .lib, .dll
|
.so |
.dylib |
Every ending for the kind is tried at each step, and the first file that exists is used. It is passed to the linker by its exact file name.
No lib prefix is added or removed: the base name is used exactly as written, so libfoo.a is "dir/libfoo".
When nothing matches, the error lists every path that was tried:
error TKO0329: #foreignlib found no matching library file: GREET dynamic vendor/greet/gret; tried: vendor/greet/gret_windows_x86_64.dll.a
vendor/greet/gret_windows_x86_64.lib
vendor/greet/gret_windows_x86_64.dll
vendor/greet/gret_windows.dll.a
vendor/greet/gret_windows.lib
vendor/greet/gret_windows.dll
vendor/greet/gret_x86_64.dll.a
vendor/greet/gret_x86_64.lib
vendor/greet/gret_x86_64.dll
vendor/greet/gret.dll.a
vendor/greet/gret.lib
vendor/greet/gret.dll
So one folder can hold every platform's files, and the source needs no #ifdef:
vendor/greet/greet_windows_x86_64.lib
vendor/greet/greet_linux_x86_64.so
TKO0327 |
expected a name, STATIC or DYNAMIC, then a quoted spec after #foreignlib |
TKO0328 |
expected STATIC or DYNAMIC after the #foreignlib name |
TKO0329 |
#foreignlib found no matching library file, listing every path tried |
TKO0330 |
#foreignlib name already bound to a different library set |
TKO0172 |
cannot make an import library for '...': it is not a 64-bit x86-64 DLL (see below) |
Declaring the same name again with an identical set is allowed, which is what happens when two files include the same binding header. A different set is TKO0330.
-
A
#foreignliblinks its libraries whether or not any declaration names them, exactly as#inclibdoes. Declarations made by#cincludecarry nolibclause and need none. -
lib namein a declaration is not checked. A misspelt name compiles and links, because the directive has already linked the library. Treat the clause as a note to the reader. -
On Windows,
.libis eligible for both kinds. A static library and an import library share the ending, and nothing in the name tells them apart, sostaticcan match an import library. Give the two different base names, such asfoo-staticandfoo. -
The kind is not checked for
system:specs. tiko does not look for the file, so the linker takes whatever it finds. On Linux it preferslibfoo.sooverlibfoo.awhen both exist. -
A
.dllwith no import library (windows-x86_64). When adynamicspec matches only a.dll, tiko reads the DLL's export table and makes an import library for it while linking, withllvm-dlltoolfrom clang's LLVM directory, and deletes it with the other intermediate files. The import library names the DLL as the DLL names itself, not by its file name, so a renamed copy invendor/still loads the original beside the program. A file that is not a 64-bit x86-64 DLL isTKO0172. A.dll.aor.libof a matching name is found first and used as it is. -
Separately compiled modules carry their own libraries. The resolved library file and its absolute directory are recorded in the object file, so a module compiled with
-clinks correctly later, from any working directory. -
Running the program is up to you. A dynamically linked program needs its DLL beside the
.exeon Windows, its.soon the loader's path on Linux (LD_LIBRARY_PATH, the system's library directories, or an rpath such as#cmdline "-Wl -rpath,$ORIGIN"), and on macOS its.dylibwhere its install name points (a program that links a.dylibfile from#foreignlibgets the run path@loader_path, so@rpath/<name>resolves beside it).#foreignlibdoes not copy library files. -
#incliband#libpathwork alongside it and can be used in the same program.#libpathis relative to the working directory, which is why a shipped binding uses#foreignlibinstead.
Binding to a C library is two jobs. #foreignlib does the linkage half, where is the code?, and #cinclude does the header half, what are these things?, turning the library's own .h into tiko declarations for the target being built.
Together they let a binding ship entirely inside your own source tree:
'' mylib/mylib.ti
#pragma once
#cinclude once "vendor/mylib.h" '' declarations, from the real header
#foreignlib MYLIB dynamic "vendor/mylib" '' the library, per targetBoth paths are relative to mylib.ti, and the using code needs no declare and no #ifdef.
- #foreignlib Tutorial, building a library and linking it both ways
-
#cinclude, the header half of the same job - Using C Libraries, from download to running program for four real libraries
-
#inclib·#libpath·Lib - Compiler Option: -l · Compiler Option: -p
'' A library kept inside the project, linked as a shared library:
''
'' vendor/greet/greet.h
'' vendor/greet/greet_windows_x86_64.lib import library
'' vendor/greet/greet_linux_x86_64.so
#cinclude once "vendor/greet/greet.h"
#foreignlib GREET dynamic "vendor/greet/greet"
print "2 + 3 ="; greet_add( 2, 3 )'' Static or dynamic, chosen at build time with -d GREET_STATIC.
#cinclude once "vendor/greet/greet.h"
#ifdef GREET_STATIC
#foreignlib GREET static "vendor/greet/greet-static"
#else
#foreignlib GREET dynamic "vendor/greet/greet"
#endif'' A system library, with a declaration written by hand.
#foreignlib WINMM dynamic "system:winmm"
declare function timeGetTime lib WINMM alias "timeGetTime" ( ) as uint32
print "Windows has been running for"; timeGetTime( ) \ 60000; " minutes"Category: Foreign Library Linking
Kind: keyword
tiko-lang · Home · Feature Index · Keyword Index · License
FreeBASIC manual pages reproduced under the GNU FDL 1.3.
- Home
- What Is tiko-lang
- Quick Start
- Installing on macOS
- Debugging
- Feature Index
- Compatibility
- FAQ
- AI Cheatsheet
- Generics
- Interfaces
- For Each
- Iterators
- Tuples
- Array Results
- Defer
- Lambdas
- Block Strings
- Partial Types
- String Slices
- Embed
- Typed Variadics
- C Header Import
- Foreign Library Linking
- UString
- Fixed-Width Types
- Nullptr
- String Library
- Format
- Array
- Map
- Set
- LinkedList
- OrderedMap
- OrderedSet
- Sorting
- Optional
- Result
- Smart Pointers
- Date and Time (Chrono)
- Time Zones
- Filesystem
- File Streams
- Config (INI and TOML)
- Codec
- Hash
- UUID
- OS
- Process
- Net
- HTTP and TLS
- Math Library
- Finance
- Logging
- Terminal TUI Library
- PsControls
- tkControls
- sys/win
- Goroutines and Channels
- LLVM Backend
- tiko build
- TIKO_COMPILER
- Variable Declarations
- Standard Data Types
- User Defined Types
- Procedures
- Operators
- Control Flow Statements
- Converting Data Types
- Array Functions
- String Functions
- Mathematical Functions
- Bit Manipulation
- Date and Time Functions
- File I/O Functions
- Console Functions
- User Input (Runtime Library)
- User Input Functions (Graphics Library)
- Screen Functions
- 2D Drawing Functions
- Graphics Library Reference
- Graphics Keyword List
- Memory Functions
- Threading Support Functions
- Error Handling Functions
- Operating System Functions
- Preprocessor
- Intrinsic Defines
- Miscellaneous Keywords
- Modularizing