Skip to content

Commit 13b31a5

Browse files
committed
add en docs
1 parent 4eff578 commit 13b31a5

File tree

10 files changed

+1374
-0
lines changed

10 files changed

+1374
-0
lines changed
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
---
2+
title: Adding Dependencies and Auto-detection Mechanism
3+
tags: [xmake, dependencies, auto-detection]
4+
date: 2016-08-06
5+
author: Ruki
6+
outline: deep
7+
---
8+
9+
xmake encapsulates dependency libraries, dependency headers, dependency types, and dependency interfaces uniformly using the option mechanism, and further introduces a package mechanism at a higher level, making adding and detecting dependencies more modular and simpler.
10+
11+
Let's look at how xmake's package mechanism works through a specific example.
12+
13+
Suppose your project already has two packages: `zlib.pkg` and `polarssl.pkg` (how to build packages will be explained in detail later; for now, you can refer to the examples of existing packages in [TBOX dependencies](https://github.com/waruqi/tbox/tree/master/pkg)). Your project directory structure is as follows:
14+
15+
```
16+
demo
17+
- xmake.lua
18+
- src
19+
main.c
20+
- pkg
21+
zlib.pkg
22+
polarssl.pkg
23+
```
24+
25+
You can modify `xmake.lua` to use the two dependency packages above:
26+
27+
```lua
28+
-- Add dependency package directory, all required packages will be searched from this directory
29+
add_packagedirs("pkg")
30+
31+
-- Add target
32+
target("demo")
33+
34+
-- Set program type to binary executable
35+
set_kind("binary")
36+
37+
-- Add source files
38+
add_files("src/*.c")
39+
40+
-- Add polarssl and zlib packages through option mechanism, if detection passes, they will be automatically linked
41+
-- The first time you run xmake config or xmake build, it will automatically detect them and cache the configuration
42+
-- To re-detect, you can run xmake config -c to clear the original configuration and reconfigure everything
43+
add_options("polarssl", "zlib")
44+
45+
-- Set auto-generated configuration header file, if mysql detection passes, it will generate CONFIG_PACKAGE_HAVE_MYSQL switch
46+
set_config_h("$(buildir)/config.h")
47+
48+
-- Set config.h macro switch prefix: CONFIG_xxxx
49+
set_config_h_prefix("CONFIG")
50+
51+
-- Add header file search directory, here to search for config.h
52+
add_includedirs("$(buildir)")
53+
```
54+
55+
Next, here's how to use it in your code:
56+
57+
```c
58+
#include <stdio.h>
59+
60+
// Include auto-generated config.h header file
61+
// Search path is set in ./build directory
62+
#include "config.h"
63+
64+
// If zlib exists on current platform, use it
65+
#ifdef CONFIG_PACKAGE_HAVE_ZLIB
66+
# include "zlib/zlib.h"
67+
#endif
68+
69+
// If polarssl exists on current platform, use it
70+
#ifdef CONFIG_PACKAGE_HAVE_POLARSSL
71+
# include "polarssl/polarssl.h"
72+
#endif
73+
74+
int main(int argc, char** argv)
75+
{
76+
printf("hello world!\n");
77+
return 0;
78+
}
79+
```
80+
81+
The above is the simplest example of package usage. Now let's see how this `zlib.pkg` is generated:
82+
83+
If this package is developed by your own project `xxx`, you only need to run `xmake p` to package it, and it will automatically generate an `xxx.pkg` package in the `./build` directory, which you can directly use in other projects.
84+
85+
If it's a third-party library, you need to build it yourself, but it's also very convenient. If you can't, you can refer to some packages in the existing [TBOX dependencies](https://github.com/waruqi/tbox/tree/master/pkg) and modify them.
86+
87+
A pkg package directory structure:
88+
89+
```
90+
zlib.pkg
91+
- inc (header file directory, optional)
92+
- zlib/zlib.h
93+
- lib (link library directory, optional)
94+
- linux/i386/libz.a
95+
- windows/i386/zlib.lib
96+
- xmake.lua (package description file)
97+
```
98+
99+
Among them, `inc` and `lib` are optional. The specific logic is described in `xmake.lua`. The default package logic generated by xmake will first detect whether there are available libraries and header files in the `zlib.pkg` directory for the current platform. If the detection fails, it will then detect the system platform.
100+
101+
Of course, you can also modify the detection logic yourself. You don't have to do it this way. You only need to describe the `xxx.pkg/xmake.lua` file according to your needs.
102+
103+
Let's look at the description logic of `zlib.pkg/xmake.lua` I provided here:
104+
105+
```lua
106+
-- Add a zlib package auto-configuration option
107+
option("zlib")
108+
109+
-- Set whether to display in xmake f -h configuration menu
110+
-- If you want your package to allow users to manually disable it in the project, then enable this
111+
set_showmenu(true)
112+
113+
-- Display related description information in xmake f -h
114+
set_description("The mysql package")
115+
116+
-- If detection passes, define macro switch to config.h
117+
add_defines_h_if_ok("$(prefix)_PACKAGE_HAVE_ZLIB")
118+
119+
-- Detect linking
120+
add_links("z")
121+
122+
-- Add detected link library directory, here set to first detect if link library exists in zlib.pkg/lib/ for related platform, then detect system
123+
-- If this is not set, xmake can only detect link libraries in some system directories, such as: /usr/lib, /usr/local/lib
124+
-- If it cannot be detected in common system directories, but you have installed this library, you can set the search directory for detection yourself
125+
add_linkdirs("lib/$(plat)/$(arch)")
126+
127+
-- Detect if #include "zlib/zlib.h" can compile successfully
128+
add_cincludes("zlib/zlib.h")
129+
130+
-- Add some detected header file directories, by default it will search in zlib.pkg/inc, of course you can also specify other directories
131+
add_includedirs("inc/$(plat)", "inc")
132+
```
133+
134+
As long as you describe `xxx.pkg/xmake.lua` well, a package can be used by xmake and automatically detected. It uses xmake's option mechanism. Of course, in the package, you can not only detect dependency libraries and header files, but also detect whether certain required interfaces, type definitions, etc. exist.
135+
136+
And the detection mechanism completely uses lua syntax, supports if conditional logic, you can do some special processing for some specific platforms, making your package more universal.
137+
138+
For example, the description of this base package `base.pkg`:
139+
140+
```lua
141+
-- Base package base.pkg
142+
option("base")
143+
144+
-- If current platform is windows, detect ws2_32 link library dependency
145+
if os("windows") then add_links("ws2_32")
146+
-- If it's other platforms, detect -lm, -ldl, -lpthread dependencies (since they are all system libraries, no search directory is set here)
147+
else add_links("m", "dl", "pthread") end
148+
```
149+
150+
If your package is only described through `xmake.lua` without other file directories, you can also embed your package `xmake.lua` description content directly into the project description file `xmake.lua`. These two are originally universal. In other words, the mechanism of `add_packagedirs("pkg")` is to call the project description API: `add_subdirs("pkg/*")` to add sub-projects. And `xxx.pkg` is just a sub-project description file.
151+
152+
If you want to add interface detection in your package detection, you only need to use:
153+
154+
* `add_cfuncs`
155+
* `add_cxxfuncs`
156+
* `add_ctypes`
157+
* `add_cxxtypes`
158+
159+
So using the package mechanism can maximize the reuse of your dependency environment across different projects. It's a very useful feature.
160+

docs/posts/api-import.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
---
2+
title: Plugin Development: Import Libraries
3+
tags: [xmake, plugin, import, library, custom script]
4+
date: 2016-06-09
5+
author: Ruki
6+
outline: deep
7+
---
8+
9+
`import` is mainly used to import xmake's extension libraries and some custom library modules. It is generally used in custom scripts (`on_build`, `on_run` ..), plugin development, template development, platform extensions, custom tasks, etc.
10+
11+
The import mechanism is as follows:
12+
13+
1. First import from the current script directory
14+
2. Then import from extension libraries
15+
16+
Import syntax rules:
17+
18+
Based on `.` library path rules, for example:
19+
20+
Import core extension modules:
21+
22+
```lua
23+
import("core.base.option")
24+
import("core.project")
25+
import("core.project.task")
26+
import("core")
27+
28+
function main()
29+
30+
-- Get argument options
31+
print(option.get("version"))
32+
33+
-- Run tasks and plugins
34+
task.run("hello")
35+
project.task.run("hello")
36+
core.project.task.run("hello")
37+
end
38+
```
39+
40+
Import custom modules from current directory:
41+
42+
Directory structure:
43+
44+
```lua
45+
plugin
46+
- xmake.lua
47+
- main.lua
48+
- modules
49+
- hello1.lua
50+
- hello2.lua
51+
```
52+
53+
Import modules in `main.lua`:
54+
55+
```lua
56+
import("modules.hello1")
57+
import("modules.hello2")
58+
```
59+
60+
After importing, you can directly use all public interfaces. Private interfaces are prefixed with `_` to indicate they will not be exported and will not be called externally.
61+
62+
In addition to the current directory, we can also import libraries from other specified directories, for example:
63+
64+
```lua
65+
import("hello3", {rootdir = "/home/xxx/modules"})
66+
```
67+
68+
To prevent naming conflicts, you can also specify an alias after importing:
69+
70+
```lua
71+
import("core.platform.platform", {alias = "p"})
72+
73+
function main()
74+
75+
-- This way we can use p to call the plats interface of the platform module to get all platforms supported by xmake
76+
table.dump(p.plats())
77+
end
78+
```
79+
80+
`import` can not only import libraries, but also support inheritance import at the same time, implementing inheritance relationships between modules:
81+
82+
```lua
83+
import("xxx.xxx", {inherit = true})
84+
```
85+
86+
This way, what is imported is not a reference to this module, but all public interfaces of the imported module itself, which will be merged with the current module's interfaces to implement inheritance between modules.
87+

0 commit comments

Comments
 (0)