find_package

This interface refers to the design of CMake for the find_* interfaces, which finds and adds package dependencies in the project target.

target ( "test" ) set_kind ( "binary" ) add_files ( "*.c" ) on_load ( function ( target ) import ( "lib.detect.find_package" ) target : add ( find_package ( "zlib" )) end )

Package Dependency Management 2.0

Now through find_package and option , we can achieve better package management.

option ( "zlib" ) set_showmenu ( true ) before_check ( function ( option ) import ( "lib.detect.find_package" ) option : add ( find_package ( "zlib" )) end ) target ( "test" ) add_options ( "zlib" )

If you want to manually disable this zlib package and automatic detection and linking, you only need:

$ xmake f --zlib = n $ xmake

Note: We will implement package management 3.0 in the 2.2.1 version, if you want to known more info, please see：Remote package management。

For example:

add_requires ( "mbedtls master optional" ) add_requires ( "pcre2 >=1.2.0" , "zlib >= 1.2.11" ) add_requires ( "git@github.com:glennrp/libpng.git@libpng >=1.6.28" ) target ( "test" ) add_packages ( "pcre2" , "zlib" , "libpng" , "mbedtls" )

We are currently working to develop …

Custom Extensions for Modules

We can specify the extended modules directory in the project file ( xmake.lua ):

add_moduledirs ( "$(projectdir)/xmake/modules" )

And add custom detect.package.find_openssl module to this directory.

projectdir - xmake - modules - detect/package/find_openssl.lua

Now we can get more package info about openssl by lib.detect.find_package("openssl") .

The search order of find_package :

Find the local package “openssl.pkg” from the argument { packagedirs = "./pkg" } Call detect.packages.find_openssl to find it from the custom module directory xmake/modules in the project. If pkg-config exists in the current system, we can use it to get more info and find it. If homebrew exists in the current system, we can use brew --prefix openssl to get more info and find it. Find it from the some system library directories, .e.g /usr/lib , /usr/include

Fast compiler feature detection support

This is also a reference to the design of CMake, details see: issues#83。

target ( "test" ) on_load ( function ( target ) import ( "core.tool.compiler" ) if compiler . has_features ( "cxx_constexpr" ) then target : add ( "defines" , "HAS_CXX_CONSTEXPR=1" ) end end )

We can also add some parameters to control the compilation option for detection.

if compiler . has_features ({ "c_static_assert" , "cxx_constexpr" }, { languages = "cxx11" }) then -- ok end

Even we can pass the target and inherit all of it’s compiled configuration.

if compiler . has_features ( "cxx_constexpr" , { target = target , defines = ".." , includedirs = ".." }) then -- ok end

Detect specified c/c++ headers

import ( "lib.detect.has_cincludes" ) local ok = has_cincludes ( "stdio.h" ) local ok = has_cincludes ({ "stdio.h" , "stdlib.h" }, { target = target })

The interface of c++ is has_cxxincludes :

import ( "lib.detect.has_cxxincludes" ) local ok = has_cxxincludes ({ "stdio.h" , "stdlib.h" }, { defines = "_GNU_SOURCE=1" , languages = "cxx11" })

Detect specified c/c++ functions

import ( "lib.detect.has_cfuncs" ) local ok = has_cfuncs ( "setjmp" ) local ok = has_cfuncs ({ "sigsetjmp((void*)0, 0)" , "setjmp" }, { includes = "setjmp.h" })

The interface of c++ is has_cxxfuncs .

Detect specified c/c++ types

import ( "lib.detect.has_ctypes" ) local ok = has_ctypes ( "wchar_t" ) local ok = has_ctypes ({ "char" , "wchar_t" }, { includes = "stdio.h" }) local ok = has_ctypes ( "wchar_t" , { includes = { "stdio.h" , "stdlib.h" }, "defines = " _GNU_SOURCE = 1 ", languages = " cxx11 "})

The interface of c++ is has_cxxtypes .

Check specified c/c++ snippets

import ( "lib.detect.check_cxsnippets" ) local ok = check_cxsnippets ( "void test() {}" ) local ok = check_cxsnippets ({ "void test(){}" , "#define TEST 1" }, { types = "wchar_t" , includes = "stdio.h" })

And we can pass some detection condition (types, functions, includes, and links).

local ok = check_cxsnippets ( "void test() {}" , { types = { "wchar_t" , "char*" }, includes = "stdio.h" , funcs = { "sigsetjmp" , "sigsetjmp((void*)0, 0)" }})

Quick Test Module interface

The xmake lua plugin has supported REPL (READ-EVAL-PRINT) to test modules in 2.1.4 version:

$ xmake lua > 1 + 2 3 > a = 1 > a 1 > for _, v in pairs ({ 1, 2, 3 }) do >> print ( v ) >> end 1 2 3

we can now test the module interface more quickly through a line of commands:

$ xmake lua lib.detect.find_package openssl

The results: {links = {"ssl", "crypto", "z"}, linkdirs = {"/usr/local/lib"}, includedirs = {"/usr/local/include"}}

Precompiled header File Support

We can add a precompiled header file to speed up the c/c++ program compile, currently supported compilers are: gcc, clang and msvc.

Set c precompiled header:

target ( "test" ) set_pcheader ( "header.h" )

Set c++ precompiled header:

target ( "test" ) set_pcxxheader ( "header.h" )

Generate compiler_commands.json

$ xmake project -k compile_commands

The output content like:

[ { "directory": "/home/user/llvm/build", "command": "/usr/bin/clang++ -Irelative -DSOMEDEF=\"With spaces, quotes and \\-es.\" -c -o file.o file.cc", "file": "file.cc" }, ... ]

About the format and description of compile_commands.json , you can see JSONCompilationDatabase

Custom option script

Add some configuration conditions dynamically before option detection:

option ( "zlib" ) before_check ( function ( option ) import ( "lib.detect.find_package" ) option : add ( find_package ( "zlib" )) end )

Control the detection results of the options by the on_check script:

option ( "test" ) add_deps ( "small" ) set_default ( true ) on_check ( function ( option ) if option : dep ( "small" ): enabled () then option : enable ( false ) end end )

We can also disable the option after checking option:

option ( "test" ) add_deps ( "small" ) add_links ( "pthread" ) after_check ( function ( option ) option : enable ( false ) end )

Custom Target Load Script

We can add and modify target configuration dynamically by target:add , target:set in the on_load script.

target ( "test" ) on_load ( function ( target ) target : add ( "defines" , "DEBUG" , "TEST=\" hello \ "" ) target : add ( "linkdirs" , "/usr/lib" , "/usr/local/lib" ) target : add ({ includedirs = "/usr/include" , "links" = "pthread" }) end )

Differentiate platform and architecture for custom script

For iphoneos platform and arm architecture:

target ( "test" ) on_build ( "iphoneos|arm*" , function ( target ) -- TODO end )

For macosx platform and all architecture:

target ( "test" ) after_build ( "macosx" , function ( target ) -- TODO end )

For all platform and architecture:

target ( "test" ) on_package ( function ( target ) -- TODO end )

并不能对不同架构、平台分别处理。

Get builtin variable

print ( val ( "host" )) print ( val ( "env PATH" )) local s = val ( "shell echo hello" )

We can add includedirs , links , linkdirs and rpathdirs to target automatically if it’s target deps is static / shared library.

Before:

target ( "library1" ) set_kind ( "static" ) add_files ( "*.c" ) add_headers ( "inc1/*.h" ) target ( "library2" ) set_kind ( "static" ) add_deps ( "library1" ) add_files ( "*.c" ) add_headers ( "inc2/*.h" ) add_includes ( "$(buildir)/inc1" ) target ( "test" ) set_kind ( "binary" ) add_deps ( "library2" ) add_includes ( "$(buildirs)/inc2" ) add_links ( "library2" , "library1" ) add_linkdirs ( "$(buildir)" )

Now:

target ( "library1" ) set_kind ( "static" ) add_files ( "*.c" ) add_headers ( "inc1/*.h" ) target ( "library2" ) set_kind ( "static" ) add_deps ( "library1" ) add_files ( "*.c" ) add_headers ( "inc2/*.h" ) target ( "test" ) set_kind ( "binary" ) add_deps ( "library2" )

Detect tool

import ( "lib.detect.find_tool" ) local tool = find_tool ( "clang" ) local tool = find_tool ( "clang" , { check = "--help" }) local tool = find_tool ( "clang" , { check = function ( tool ) os . run ( "%s -h" , tool ) end }) local tool = find_tool ( "clang" , { version = true , { pathes = { "/usr/bin" , "/usr/local/bin" , "$(env PATH)" , function () return "/usr/xxx/bin" end }})

More Secure Root Permissions compilation

You can see: pull#113

More expansion Modules

You can see: modules